Line data Source code
1 : /* File: data_database_iterator_classifiers.c; Copyright and License: see below */
2 :
3 : #include "storage/data_database_iterator_classifiers.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 search statement to iterate over all classifiers sorted by number of parent-containers
13 : *
14 : * The "order by cnt" is important to ensure parent objects are iterated first, e.g. for xmi export
15 : * The "order by id" is important to get reproducable results
16 : */
17 : static const char DATA_DATABASE_ITERATOR_CLASSIFIERS_SELECT_ALL_HIERARCHICAL[] =
18 : "SELECT id,main_type,stereotype,name,description,x_order,y_order,list_order,uuid,"
19 : "(SELECT count(*) FROM relationships "
20 : "WHERE (relationships.to_classifier_id=classifiers.id) AND (relationships.to_feature_id IS NULL) "
21 : "AND (relationships.main_type=300)) AS cnt "
22 : "FROM classifiers "
23 : "ORDER BY cnt ASC,id ASC;";
24 :
25 : /*!
26 : * \brief search statement to iterate over all classifiers
27 : *
28 : * The "order by id" is important to get reproducable results, e.g. for json export
29 : */
30 : static const char DATA_DATABASE_ITERATOR_CLASSIFIERS_SELECT_ALL[] =
31 : "SELECT id,main_type,stereotype,name,description,x_order,y_order,list_order,uuid,-1 "
32 : "FROM classifiers "
33 : "ORDER BY id ASC;";
34 :
35 : /*!
36 : * \brief the column id of the result where this parameter is stored: id
37 : */
38 : static const int RESULT_CLASSIFIER_ID_COLUMN = 0;
39 :
40 : /*!
41 : * \brief the column id of the result where this parameter is stored: main_type
42 : */
43 : static const int RESULT_CLASSIFIER_MAIN_TYPE_COLUMN = 1;
44 :
45 : /*!
46 : * \brief the column id of the result where this parameter is stored: stereotype
47 : */
48 : static const int RESULT_CLASSIFIER_STEREOTYPE_COLUMN = 2;
49 :
50 : /*!
51 : * \brief the column id of the result where this parameter is stored: name
52 : */
53 : static const int RESULT_CLASSIFIER_NAME_COLUMN = 3;
54 :
55 : /*!
56 : * \brief the column id of the result where this parameter is stored: description
57 : */
58 : static const int RESULT_CLASSIFIER_DESCRIPTION_COLUMN = 4;
59 :
60 : /*!
61 : * \brief the column id of the result where this parameter is stored: x_order
62 : */
63 : static const int RESULT_CLASSIFIER_X_ORDER_COLUMN = 5;
64 :
65 : /*!
66 : * \brief the column id of the result where this parameter is stored: y_order
67 : */
68 : static const int RESULT_CLASSIFIER_Y_ORDER_COLUMN = 6;
69 :
70 : /*!
71 : * \brief the column id of the result where this parameter is stored: list_order
72 : */
73 : static const int RESULT_CLASSIFIER_LIST_ORDER_COLUMN = 7;
74 :
75 : /*!
76 : * \brief the column id of the result where this parameter is stored: uuid
77 : */
78 : static const int RESULT_CLASSIFIER_UUID_COLUMN = 8;
79 :
80 : /*!
81 : * \brief the column id of the result where this parameter is stored: count of containment parents
82 : */
83 : static const int RESULT_CLASSIFIER_CONTAINMENT_PARENTS_COLUMN = 9;
84 :
85 1 : u8_error_t data_database_iterator_classifiers_init_empty ( data_database_iterator_classifiers_t *this_ )
86 : {
87 1 : U8_TRACE_BEGIN();
88 1 : u8_error_t result = U8_ERROR_NONE;
89 :
90 1 : (*this_).is_valid = false;
91 1 : (*this_).database = NULL;
92 1 : (*this_).statement_all_classifiers = NULL;
93 1 : (*this_).is_at_end = true;
94 :
95 1 : U8_TRACE_END_ERR(result);
96 1 : return result;
97 : }
98 :
99 1 : u8_error_t data_database_iterator_classifiers_reinit ( data_database_iterator_classifiers_t *this_,
100 : data_database_t *database,
101 : bool hierarchical )
102 : {
103 1 : U8_TRACE_BEGIN();
104 1 : assert( NULL != database );
105 1 : u8_error_t result = U8_ERROR_NONE;
106 :
107 : /* destroy old state */
108 1 : result = data_database_iterator_classifiers_destroy( this_ );
109 1 : (*this_).statement_all_classifiers = NULL;
110 :
111 : /* init new state */
112 1 : (*this_).is_valid = true;
113 1 : (*this_).database = database;
114 : {
115 1 : const char *const string_statement
116 : = hierarchical
117 : ? DATA_DATABASE_ITERATOR_CLASSIFIERS_SELECT_ALL_HIERARCHICAL
118 1 : : DATA_DATABASE_ITERATOR_CLASSIFIERS_SELECT_ALL;
119 1 : const size_t string_size
120 : = hierarchical
121 : ? sizeof( DATA_DATABASE_ITERATOR_CLASSIFIERS_SELECT_ALL_HIERARCHICAL )
122 1 : : sizeof( DATA_DATABASE_ITERATOR_CLASSIFIERS_SELECT_ALL );
123 1 : sqlite3 *db = data_database_get_database_ptr ( (*this_).database );
124 : const char *first_unused_statement_char;
125 1 : U8_TRACE_INFO_STR( "sqlite3_prepare_v2():", string_statement );
126 1 : const int sqlite_err = sqlite3_prepare_v2( db,
127 : string_statement,
128 : string_size,
129 : &((*this_).statement_all_classifiers),
130 : &first_unused_statement_char
131 : );
132 1 : if (( SQLITE_OK != sqlite_err )
133 1 : || ( first_unused_statement_char != &(string_statement[string_size-1]) ))
134 : {
135 0 : U8_LOG_ERROR_STR( "sqlite3_prepare_v2() failed:", string_statement );
136 0 : U8_LOG_ERROR_INT( "sqlite3_prepare_v2() failed:", sqlite_err );
137 0 : U8_LOG_ERROR_STR( "sqlite3_prepare_v2() failed:", sqlite3_errmsg( db ) );
138 0 : result |= U8_ERROR_AT_DB;
139 : }
140 : }
141 1 : result |= data_database_iterator_private_step_to_next( this_ );
142 :
143 1 : U8_TRACE_END_ERR(result);
144 1 : return result;
145 : }
146 :
147 2 : u8_error_t data_database_iterator_classifiers_destroy ( data_database_iterator_classifiers_t *this_ )
148 : {
149 2 : U8_TRACE_BEGIN();
150 2 : u8_error_t result = U8_ERROR_NONE;
151 :
152 2 : if ( (*this_).is_valid )
153 : {
154 1 : assert( NULL != (*this_).statement_all_classifiers );
155 1 : U8_TRACE_INFO_STR( "sqlite3_finalize():", sqlite3_sql( (*this_).statement_all_classifiers ) );
156 1 : const int sqlite_err = sqlite3_finalize( (*this_).statement_all_classifiers );
157 1 : if ( SQLITE_OK != sqlite_err )
158 : {
159 0 : U8_LOG_ERROR_STR( "sqlite3_finalize() failed:", sqlite3_sql( (*this_).statement_all_classifiers ) );
160 0 : U8_LOG_ERROR_INT( "sqlite3_finalize() failed:", sqlite_err );
161 0 : result = U8_ERROR_AT_DB;
162 : }
163 : }
164 :
165 2 : (*this_).is_valid = false;
166 2 : (*this_).database = NULL;
167 2 : (*this_).statement_all_classifiers = NULL;
168 2 : (*this_).is_at_end = true;
169 :
170 2 : U8_TRACE_END_ERR(result);
171 2 : return result;
172 : }
173 :
174 3 : bool data_database_iterator_classifiers_has_next ( const data_database_iterator_classifiers_t *this_ )
175 : {
176 3 : return ( ! (*this_).is_at_end );
177 : }
178 :
179 3 : u8_error_t data_database_iterator_classifiers_next ( data_database_iterator_classifiers_t *this_, data_classifier_t *out_classifier )
180 : {
181 3 : U8_TRACE_BEGIN();
182 3 : assert( NULL != out_classifier );
183 3 : u8_error_t result = U8_ERROR_NONE;
184 :
185 3 : if ( (*this_).is_valid )
186 : {
187 3 : if ( ! (*this_).is_at_end )
188 : {
189 2 : sqlite3_stmt *const sql_statement = (*this_).statement_all_classifiers;
190 2 : data_row_id_t classifier_id = sqlite3_column_int64( sql_statement, RESULT_CLASSIFIER_ID_COLUMN );
191 4 : result |= data_classifier_reinit( out_classifier,
192 : classifier_id,
193 2 : sqlite3_column_int( sql_statement, RESULT_CLASSIFIER_MAIN_TYPE_COLUMN ),
194 2 : (const char*) sqlite3_column_text( sql_statement, RESULT_CLASSIFIER_STEREOTYPE_COLUMN ),
195 2 : (const char*) sqlite3_column_text( sql_statement, RESULT_CLASSIFIER_NAME_COLUMN ),
196 2 : (const char*) sqlite3_column_text( sql_statement, RESULT_CLASSIFIER_DESCRIPTION_COLUMN ),
197 : sqlite3_column_int( sql_statement, RESULT_CLASSIFIER_X_ORDER_COLUMN ),
198 : sqlite3_column_int( sql_statement, RESULT_CLASSIFIER_Y_ORDER_COLUMN ),
199 : sqlite3_column_int( sql_statement, RESULT_CLASSIFIER_LIST_ORDER_COLUMN ),
200 2 : (const char*) sqlite3_column_text( sql_statement, RESULT_CLASSIFIER_UUID_COLUMN )
201 : );
202 2 : data_classifier_trace( out_classifier );
203 2 : U8_TRACE_INFO_INT( "count of containment parents:", sqlite3_column_int( sql_statement, RESULT_CLASSIFIER_CONTAINMENT_PARENTS_COLUMN ));
204 :
205 : /* step to next */
206 2 : result |= data_database_iterator_private_step_to_next( this_ );
207 : }
208 : else
209 : {
210 1 : U8_TRACE_INFO( "iterator already at end" );
211 1 : (*this_).is_at_end = true;
212 1 : result |= U8_ERROR_INVALID_REQUEST;
213 : }
214 : }
215 : else
216 : {
217 0 : result |= U8_ERROR_NO_DB;
218 0 : U8_TRACE_INFO( "No valid sql statement, cannot request data." );
219 : }
220 :
221 3 : U8_TRACE_END_ERR( result );
222 3 : return result;
223 : }
224 :
225 3 : u8_error_t data_database_iterator_private_step_to_next ( data_database_iterator_classifiers_t *this_ )
226 : {
227 3 : U8_TRACE_BEGIN();
228 3 : assert( (*this_).is_valid );
229 3 : assert( NULL != (*this_).statement_all_classifiers );
230 3 : u8_error_t result = U8_ERROR_NONE;
231 :
232 : /* do one step, check if is_at_end */
233 : {
234 : int sqlite_err;
235 3 : U8_TRACE_INFO( "sqlite3_step()" );
236 3 : sqlite_err = sqlite3_step( (*this_).statement_all_classifiers );
237 3 : if ( SQLITE_DONE == sqlite_err )
238 : {
239 1 : U8_TRACE_INFO( "sqlite3_step finished: SQLITE_DONE" );
240 1 : (*this_).is_at_end = true;
241 : }
242 2 : else if ( SQLITE_ROW == sqlite_err )
243 : {
244 2 : (*this_).is_at_end = false;
245 : }
246 : else
247 : {
248 0 : U8_LOG_ERROR_INT( "sqlite3_step failed:", sqlite_err );
249 0 : (*this_).is_at_end = true;
250 0 : result |= data_database_iterator_classifiers_destroy( this_ );
251 0 : result |= U8_ERROR_AT_DB;
252 : }
253 : }
254 :
255 3 : U8_TRACE_END_ERR(result);
256 3 : return result;
257 : }
258 :
259 :
260 : /*
261 : Copyright 2020-2024 Andreas Warnke
262 :
263 : Licensed under the Apache License, Version 2.0 (the "License");
264 : you may not use this file except in compliance with the License.
265 : You may obtain a copy of the License at
266 :
267 : http://www.apache.org/licenses/LICENSE-2.0
268 :
269 : Unless required by applicable law or agreed to in writing, software
270 : distributed under the License is distributed on an "AS IS" BASIS,
271 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
272 : See the License for the specific language governing permissions and
273 : limitations under the License.
274 : */
|