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 21 : u8_error_t data_feature_iterator_init_empty ( data_feature_iterator_t *this_ )
85 : {
86 21 : U8_TRACE_BEGIN();
87 21 : u8_error_t result = U8_ERROR_NONE;
88 :
89 21 : data_database_borrowed_stmt_init_void( &((*this_).statement) );
90 21 : (*this_).is_at_end = true;
91 :
92 21 : U8_TRACE_END_ERR(result);
93 21 : return result;
94 : }
95 :
96 21 : u8_error_t data_feature_iterator_reinit ( data_feature_iterator_t *this_,
97 : data_database_borrowed_stmt_t statement )
98 : {
99 21 : U8_TRACE_BEGIN();
100 21 : assert( data_database_borrowed_stmt_is_valid( &statement ) );
101 21 : u8_error_t result = U8_ERROR_NONE;
102 :
103 : /* destroy old state */
104 21 : result = data_feature_iterator_destroy( this_ );
105 :
106 : /* init new state */
107 21 : (*this_).statement = statement;
108 21 : (*this_).is_at_end = false;
109 21 : result |= data_feature_iterator_private_step_to_next( this_ );
110 :
111 21 : U8_TRACE_END_ERR(result);
112 21 : return result;
113 : }
114 :
115 42 : u8_error_t data_feature_iterator_destroy ( data_feature_iterator_t *this_ )
116 : {
117 42 : U8_TRACE_BEGIN();
118 42 : u8_error_t result = U8_ERROR_NONE;
119 :
120 42 : result |= data_database_borrowed_stmt_destroy( &((*this_).statement) );
121 42 : (*this_).is_at_end = true;
122 :
123 42 : U8_TRACE_END_ERR(result);
124 42 : return result;
125 : }
126 :
127 281 : bool data_feature_iterator_has_next ( const data_feature_iterator_t *this_ )
128 : {
129 281 : return ( ! (*this_).is_at_end );
130 : }
131 :
132 273 : u8_error_t data_feature_iterator_next ( data_feature_iterator_t *this_, data_feature_t *out_feature )
133 : {
134 273 : U8_TRACE_BEGIN();
135 273 : assert( NULL != out_feature );
136 273 : assert( data_database_borrowed_stmt_is_valid( &((*this_).statement) ) );
137 273 : u8_error_t result = U8_ERROR_NONE;
138 :
139 273 : if ( ! (*this_).is_at_end )
140 : {
141 271 : sqlite3_stmt *const sql_statement = data_database_borrowed_stmt_get_statement( &((*this_).statement) );
142 :
143 271 : result |= data_feature_init( out_feature,
144 271 : sqlite3_column_int64( sql_statement, RESULT_FEATURE_ID_COLUMN ),
145 271 : sqlite3_column_int( sql_statement, RESULT_FEATURE_MAIN_TYPE_COLUMN ),
146 271 : sqlite3_column_int64( sql_statement, RESULT_FEATURE_CLASSIFIER_ID_COLUMN ),
147 271 : (const char*) sqlite3_column_text( sql_statement, RESULT_FEATURE_KEY_COLUMN ),
148 271 : (const char*) sqlite3_column_text( sql_statement, RESULT_FEATURE_VALUE_COLUMN ),
149 271 : (const char*) sqlite3_column_text( sql_statement, RESULT_FEATURE_DESCRIPTION_COLUMN ),
150 271 : sqlite3_column_int( sql_statement, RESULT_FEATURE_LIST_ORDER_COLUMN ),
151 271 : (const char*) sqlite3_column_text( sql_statement, RESULT_FEATURE_LIST_UUID_COLUMN )
152 : );
153 271 : U8_TRACE_INFO_INT( "diagramelements.id:", sqlite3_column_int64( sql_statement, RESULT_FEATURE_DIAGRAMELEMENTS_ID_COLUMN ) );
154 271 : data_feature_trace( out_feature );
155 :
156 : /* step to next */
157 271 : result |= data_feature_iterator_private_step_to_next( this_ );
158 : }
159 : else
160 : {
161 2 : U8_TRACE_INFO( "iterator already at end" );
162 2 : (*this_).is_at_end = true;
163 2 : result |= U8_ERROR_INVALID_REQUEST;
164 : }
165 :
166 273 : U8_TRACE_END_ERR( result );
167 273 : return result;
168 : }
169 :
170 292 : u8_error_t data_feature_iterator_private_step_to_next ( data_feature_iterator_t *this_ )
171 : {
172 292 : U8_TRACE_BEGIN();
173 292 : assert( data_database_borrowed_stmt_is_valid( &((*this_).statement) ) );
174 292 : u8_error_t result = U8_ERROR_NONE;
175 :
176 : /* do one step, check if is_at_end */
177 : {
178 : int sqlite_err;
179 292 : U8_TRACE_INFO( "sqlite3_step()" );
180 292 : sqlite_err = sqlite3_step( data_database_borrowed_stmt_get_statement( &((*this_).statement) ) );
181 292 : if ( SQLITE_DONE == sqlite_err )
182 : {
183 20 : U8_TRACE_INFO( "sqlite3_step finished: SQLITE_DONE" );
184 20 : (*this_).is_at_end = true;
185 : }
186 272 : else if ( SQLITE_ROW == sqlite_err )
187 : {
188 272 : (*this_).is_at_end = false;
189 : }
190 : else
191 : {
192 0 : U8_LOG_ERROR_INT( "sqlite3_step failed:", sqlite_err );
193 0 : (*this_).is_at_end = true;
194 0 : result |= data_feature_iterator_destroy( this_ );
195 0 : result |= U8_ERROR_AT_DB;
196 : }
197 : }
198 :
199 292 : U8_TRACE_END_ERR(result);
200 292 : return result;
201 : }
202 :
203 :
204 : /*
205 : Copyright 2024-2025 Andreas Warnke
206 :
207 : Licensed under the Apache License, Version 2.0 (the "License");
208 : you may not use this file except in compliance with the License.
209 : You may obtain a copy of the License at
210 :
211 : http://www.apache.org/licenses/LICENSE-2.0
212 :
213 : Unless required by applicable law or agreed to in writing, software
214 : distributed under the License is distributed on an "AS IS" BASIS,
215 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
216 : See the License for the specific language governing permissions and
217 : limitations under the License.
218 : */
|