Line data Source code
1 : /* File: data_feature_iterator.c; Copyright and License: see below */
2 :
3 : #include "storage/data_feature_iterator.h"
4 : #include "u8/u8_trace.h"
5 : #include "u8/u8_log.h"
6 : #include "utf8stringbuf/utf8stringbuf.h"
7 : #include <sqlite3.h>
8 : #include <assert.h>
9 : #include <stdint.h>
10 :
11 : /*!
12 : * \brief predefined search statement to find features by diagram-id
13 : */
14 : const char *const DATA_FEATURE_ITERATOR_SELECT_FEATURES_BY_DIAGRAM_ID =
15 : "SELECT features.id,features.main_type,features.classifier_id,"
16 : "features.key,features.value,features.description,features.list_order,features.uuid,"
17 : "diagramelements.id " /* diagramelements.id needed only for debugging */
18 : "FROM features INNER JOIN diagramelements ON diagramelements.classifier_id=features.classifier_id "
19 : /* "WHERE diagramelements.diagram_id=? " */
20 : "WHERE diagramelements.diagram_id=? AND ( diagramelements.focused_feature_id=features.id OR features.main_type<>3 ) "
21 : "GROUP BY features.id "
22 : "ORDER BY features.list_order ASC,features.id ASC;"; /* ensure always the same order */
23 : /* Note: 3 == DATA_FEATURE_TYPE_LIFELINE */
24 :
25 : /* if you ignore the type, "non-scenario features" of "classifiers that have a lifeline" would be skipped: */
26 : /* "WHERE diagramelements.diagram_id=? AND ( (diagramelements.focused_feature_id=features.id) OR (diagramelements.focused_feature_id ISNULL) ) " */
27 : /* but we want to skip only lifelines and only if these belong to foreign diagrams */
28 :
29 : /*!
30 : * \brief predefined search statement to find features by classifier-id
31 : *
32 : * Order by id to ensure a defined, non-changeing order of relationships in json export
33 : */
34 : const char *const DATA_FEATURE_ITERATOR_SELECT_FEATURES_BY_CLASSIFIER_ID =
35 : "SELECT id,main_type,classifier_id,key,value,description,list_order,uuid,-1 "
36 : "FROM features "
37 : "WHERE classifier_id=? ORDER BY id ASC;"; /* ensure always the same order */
38 :
39 : /*!
40 : * \brief the column id of the result where this parameter is stored: id
41 : */
42 : static const int RESULT_FEATURE_ID_COLUMN = 0;
43 :
44 : /*!
45 : * \brief the column id of the result where this parameter is stored: main_type
46 : */
47 : static const int RESULT_FEATURE_MAIN_TYPE_COLUMN = 1;
48 :
49 : /*!
50 : * \brief the column id of the result where this parameter is stored: classifier_id
51 : */
52 : static const int RESULT_FEATURE_CLASSIFIER_ID_COLUMN = 2;
53 :
54 : /*!
55 : * \brief the column id of the result where this parameter is stored: key
56 : */
57 : static const int RESULT_FEATURE_KEY_COLUMN = 3;
58 :
59 : /*!
60 : * \brief the column id of the result where this parameter is stored: value
61 : */
62 : static const int RESULT_FEATURE_VALUE_COLUMN = 4;
63 :
64 : /*!
65 : * \brief the column id of the result where this parameter is stored: description
66 : */
67 : static const int RESULT_FEATURE_DESCRIPTION_COLUMN = 5;
68 :
69 : /*!
70 : * \brief the column id of the result where this parameter is stored: list_order
71 : */
72 : static const int RESULT_FEATURE_LIST_ORDER_COLUMN = 6;
73 :
74 : /*!
75 : * \brief the column id of the result where this parameter is stored: uuid
76 : */
77 : static const int RESULT_FEATURE_LIST_UUID_COLUMN = 7;
78 :
79 : /*!
80 : * \brief the column id of the result where this parameter is stored: diagramelements.id
81 : */
82 : static const int RESULT_FEATURE_DIAGRAMELEMENTS_ID_COLUMN = 8;
83 :
84 33 : void data_feature_iterator_init_empty ( data_feature_iterator_t *this_ )
85 : {
86 33 : U8_TRACE_BEGIN();
87 :
88 33 : data_database_borrowed_stmt_init_void( &((*this_).statement) );
89 33 : (*this_).is_at_end = true;
90 :
91 33 : U8_TRACE_END();
92 33 : }
93 :
94 33 : u8_error_t data_feature_iterator_reinit ( data_feature_iterator_t *this_,
95 : data_database_borrowed_stmt_t statement )
96 : {
97 33 : U8_TRACE_BEGIN();
98 33 : assert( data_database_borrowed_stmt_is_valid( &statement ) );
99 33 : u8_error_t result = U8_ERROR_NONE;
100 :
101 : /* destroy old state */
102 33 : result = data_feature_iterator_destroy( this_ );
103 :
104 : /* init new state */
105 33 : (*this_).statement = statement;
106 33 : (*this_).is_at_end = false;
107 33 : result |= data_feature_iterator_private_step_to_next( this_ );
108 :
109 33 : U8_TRACE_END_ERR(result);
110 33 : return result;
111 : }
112 :
113 66 : u8_error_t data_feature_iterator_destroy ( data_feature_iterator_t *this_ )
114 : {
115 66 : U8_TRACE_BEGIN();
116 66 : u8_error_t result = U8_ERROR_NONE;
117 :
118 66 : result |= data_database_borrowed_stmt_destroy( &((*this_).statement) );
119 66 : (*this_).is_at_end = true;
120 :
121 66 : U8_TRACE_END_ERR(result);
122 66 : return result;
123 : }
124 :
125 302 : bool data_feature_iterator_has_next ( const data_feature_iterator_t *this_ )
126 : {
127 302 : return ( ! (*this_).is_at_end );
128 : }
129 :
130 282 : u8_error_t data_feature_iterator_next ( data_feature_iterator_t *this_, data_feature_t *out_feature )
131 : {
132 282 : U8_TRACE_BEGIN();
133 282 : assert( NULL != out_feature );
134 282 : assert( data_database_borrowed_stmt_is_valid( &((*this_).statement) ) );
135 282 : u8_error_t result = U8_ERROR_NONE;
136 :
137 282 : if ( ! (*this_).is_at_end )
138 : {
139 280 : sqlite3_stmt *const sql_statement = data_database_borrowed_stmt_get_statement( &((*this_).statement) );
140 :
141 280 : result |= data_feature_init( out_feature,
142 280 : sqlite3_column_int64( sql_statement, RESULT_FEATURE_ID_COLUMN ),
143 280 : sqlite3_column_int( sql_statement, RESULT_FEATURE_MAIN_TYPE_COLUMN ),
144 280 : sqlite3_column_int64( sql_statement, RESULT_FEATURE_CLASSIFIER_ID_COLUMN ),
145 280 : (const char*) sqlite3_column_text( sql_statement, RESULT_FEATURE_KEY_COLUMN ),
146 280 : (const char*) sqlite3_column_text( sql_statement, RESULT_FEATURE_VALUE_COLUMN ),
147 280 : (const char*) sqlite3_column_text( sql_statement, RESULT_FEATURE_DESCRIPTION_COLUMN ),
148 280 : sqlite3_column_int( sql_statement, RESULT_FEATURE_LIST_ORDER_COLUMN ),
149 280 : (const char*) sqlite3_column_text( sql_statement, RESULT_FEATURE_LIST_UUID_COLUMN )
150 : );
151 280 : U8_TRACE_INFO_INT( "diagramelements.id:", sqlite3_column_int64( sql_statement, RESULT_FEATURE_DIAGRAMELEMENTS_ID_COLUMN ) );
152 280 : data_feature_trace( out_feature );
153 :
154 : /* step to next */
155 280 : result |= data_feature_iterator_private_step_to_next( this_ );
156 : }
157 : else
158 : {
159 2 : U8_TRACE_INFO( "iterator already at end" );
160 2 : (*this_).is_at_end = true;
161 2 : result |= U8_ERROR_INVALID_REQUEST;
162 : }
163 :
164 282 : U8_TRACE_END_ERR( result );
165 282 : return result;
166 : }
167 :
168 313 : u8_error_t data_feature_iterator_private_step_to_next ( data_feature_iterator_t *this_ )
169 : {
170 313 : U8_TRACE_BEGIN();
171 313 : assert( data_database_borrowed_stmt_is_valid( &((*this_).statement) ) );
172 313 : u8_error_t result = U8_ERROR_NONE;
173 :
174 : /* do one step, check if is_at_end */
175 : {
176 : int sqlite_err;
177 313 : U8_TRACE_INFO( "sqlite3_step()" );
178 313 : sqlite_err = sqlite3_step( data_database_borrowed_stmt_get_statement( &((*this_).statement) ) );
179 313 : if ( SQLITE_DONE == sqlite_err )
180 : {
181 32 : U8_TRACE_INFO( "sqlite3_step finished: SQLITE_DONE" );
182 32 : (*this_).is_at_end = true;
183 : }
184 281 : else if ( SQLITE_ROW == sqlite_err )
185 : {
186 281 : (*this_).is_at_end = false;
187 : }
188 : else
189 : {
190 0 : U8_LOG_ERROR_INT( "sqlite3_step failed:", sqlite_err );
191 0 : (*this_).is_at_end = true;
192 0 : result |= data_feature_iterator_destroy( this_ );
193 0 : result |= U8_ERROR_AT_DB;
194 : }
195 : }
196 :
197 313 : U8_TRACE_END_ERR(result);
198 313 : return result;
199 : }
200 :
201 :
202 : /*
203 : Copyright 2024-2026 Andreas Warnke
204 :
205 : Licensed under the Apache License, Version 2.0 (the "License");
206 : you may not use this file except in compliance with the License.
207 : You may obtain a copy of the License at
208 :
209 : http://www.apache.org/licenses/LICENSE-2.0
210 :
211 : Unless required by applicable law or agreed to in writing, software
212 : distributed under the License is distributed on an "AS IS" BASIS,
213 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
214 : See the License for the specific language governing permissions and
215 : limitations under the License.
216 : */
|