Line data Source code
1 : /* File: data_classifier_iterator.c; Copyright and License: see below */
2 :
3 : #include "storage/data_classifier_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 : * The "order by cnt" is important to ensure parent objects are iterated first, e.g. for xmi export
13 : * The "order by id" is important to get reproducable results
14 : */
15 : const char *const DATA_CLASSIFIER_ITERATOR_SELECT_ALL_HIERARCHICAL =
16 : "SELECT id,main_type,stereotype,name,description,x_order,y_order,list_order,uuid,"
17 : "(SELECT count(*) FROM relationships "
18 : "WHERE (relationships.to_classifier_id=classifiers.id) AND (relationships.to_feature_id IS NULL) "
19 : "AND (relationships.main_type=300)) AS cnt "
20 : "FROM classifiers "
21 : "ORDER BY cnt ASC,id ASC;";
22 :
23 : /*
24 : * The "order by id" is important to get reproducable results, e.g. for json export
25 : */
26 : const char *const DATA_CLASSIFIER_ITERATOR_SELECT_ALL =
27 : "SELECT id,main_type,stereotype,name,description,x_order,y_order,list_order,uuid,-1 "
28 : "FROM classifiers "
29 : "ORDER BY id ASC;";
30 :
31 : /*!
32 : * \brief the column id of the result where this parameter is stored: id
33 : */
34 : static const int RESULT_CLASSIFIER_ID_COLUMN = 0;
35 :
36 : /*!
37 : * \brief the column id of the result where this parameter is stored: main_type
38 : */
39 : static const int RESULT_CLASSIFIER_MAIN_TYPE_COLUMN = 1;
40 :
41 : /*!
42 : * \brief the column id of the result where this parameter is stored: stereotype
43 : */
44 : static const int RESULT_CLASSIFIER_STEREOTYPE_COLUMN = 2;
45 :
46 : /*!
47 : * \brief the column id of the result where this parameter is stored: name
48 : */
49 : static const int RESULT_CLASSIFIER_NAME_COLUMN = 3;
50 :
51 : /*!
52 : * \brief the column id of the result where this parameter is stored: description
53 : */
54 : static const int RESULT_CLASSIFIER_DESCRIPTION_COLUMN = 4;
55 :
56 : /*!
57 : * \brief the column id of the result where this parameter is stored: x_order
58 : */
59 : static const int RESULT_CLASSIFIER_X_ORDER_COLUMN = 5;
60 :
61 : /*!
62 : * \brief the column id of the result where this parameter is stored: y_order
63 : */
64 : static const int RESULT_CLASSIFIER_Y_ORDER_COLUMN = 6;
65 :
66 : /*!
67 : * \brief the column id of the result where this parameter is stored: list_order
68 : */
69 : static const int RESULT_CLASSIFIER_LIST_ORDER_COLUMN = 7;
70 :
71 : /*!
72 : * \brief the column id of the result where this parameter is stored: uuid
73 : */
74 : static const int RESULT_CLASSIFIER_UUID_COLUMN = 8;
75 :
76 : /*!
77 : * \brief the column id of the result where this parameter is stored: count of containment parents
78 : */
79 : static const int RESULT_CLASSIFIER_CONTAINMENT_PARENTS_COLUMN = 9;
80 :
81 5 : u8_error_t data_classifier_iterator_init_empty ( data_classifier_iterator_t *this_ )
82 : {
83 5 : U8_TRACE_BEGIN();
84 5 : u8_error_t result = U8_ERROR_NONE;
85 :
86 5 : data_database_borrowed_stmt_init_void( &((*this_).statement) );
87 5 : (*this_).is_at_end = true;
88 :
89 5 : U8_TRACE_END_ERR(result);
90 5 : return result;
91 : }
92 :
93 5 : u8_error_t data_classifier_iterator_reinit ( data_classifier_iterator_t *this_,
94 : data_database_borrowed_stmt_t statement )
95 : {
96 5 : U8_TRACE_BEGIN();
97 5 : assert( data_database_borrowed_stmt_is_valid( &statement ) );
98 5 : u8_error_t result = U8_ERROR_NONE;
99 :
100 : /* destroy old state */
101 5 : result = data_classifier_iterator_destroy( this_ );
102 :
103 : /* init new state */
104 5 : (*this_).statement = statement;
105 5 : (*this_).is_at_end = false;
106 5 : result |= data_classifier_iterator_private_step_to_next( this_ );
107 :
108 5 : U8_TRACE_END_ERR(result);
109 5 : return result;
110 : }
111 :
112 10 : u8_error_t data_classifier_iterator_destroy ( data_classifier_iterator_t *this_ )
113 : {
114 10 : U8_TRACE_BEGIN();
115 10 : u8_error_t result = U8_ERROR_NONE;
116 :
117 10 : result |= data_database_borrowed_stmt_destroy( &((*this_).statement) );
118 10 : (*this_).is_at_end = true;
119 :
120 10 : U8_TRACE_END_ERR(result);
121 10 : return result;
122 : }
123 :
124 7 : bool data_classifier_iterator_has_next ( const data_classifier_iterator_t *this_ )
125 : {
126 7 : return ( ! (*this_).is_at_end );
127 : }
128 :
129 3 : u8_error_t data_classifier_iterator_next ( data_classifier_iterator_t *this_, data_classifier_t *out_classifier )
130 : {
131 3 : U8_TRACE_BEGIN();
132 3 : assert( NULL != out_classifier );
133 3 : assert( data_database_borrowed_stmt_is_valid( &((*this_).statement) ) );
134 3 : u8_error_t result = U8_ERROR_NONE;
135 :
136 3 : if ( ! (*this_).is_at_end )
137 : {
138 2 : sqlite3_stmt *const sql_statement = data_database_borrowed_stmt_get_statement( &((*this_).statement) );
139 2 : data_row_t classifier_id = sqlite3_column_int64( sql_statement, RESULT_CLASSIFIER_ID_COLUMN );
140 4 : result |= data_classifier_reinit( out_classifier,
141 : classifier_id,
142 2 : sqlite3_column_int( sql_statement, RESULT_CLASSIFIER_MAIN_TYPE_COLUMN ),
143 2 : (const char*) sqlite3_column_text( sql_statement, RESULT_CLASSIFIER_STEREOTYPE_COLUMN ),
144 2 : (const char*) sqlite3_column_text( sql_statement, RESULT_CLASSIFIER_NAME_COLUMN ),
145 2 : (const char*) sqlite3_column_text( sql_statement, RESULT_CLASSIFIER_DESCRIPTION_COLUMN ),
146 : sqlite3_column_int( sql_statement, RESULT_CLASSIFIER_X_ORDER_COLUMN ),
147 : sqlite3_column_int( sql_statement, RESULT_CLASSIFIER_Y_ORDER_COLUMN ),
148 : sqlite3_column_int( sql_statement, RESULT_CLASSIFIER_LIST_ORDER_COLUMN ),
149 2 : (const char*) sqlite3_column_text( sql_statement, RESULT_CLASSIFIER_UUID_COLUMN )
150 : );
151 2 : data_classifier_trace( out_classifier );
152 2 : U8_TRACE_INFO_INT( "count of containment parents:", sqlite3_column_int( sql_statement, RESULT_CLASSIFIER_CONTAINMENT_PARENTS_COLUMN ));
153 :
154 : /* step to next */
155 2 : result |= data_classifier_iterator_private_step_to_next( this_ );
156 : }
157 : else
158 : {
159 1 : U8_TRACE_INFO( "iterator already at end" );
160 1 : (*this_).is_at_end = true;
161 1 : result |= U8_ERROR_INVALID_REQUEST;
162 : }
163 :
164 3 : U8_TRACE_END_ERR( result );
165 3 : return result;
166 : }
167 :
168 7 : u8_error_t data_classifier_iterator_private_step_to_next ( data_classifier_iterator_t *this_ )
169 : {
170 7 : U8_TRACE_BEGIN();
171 7 : assert( data_database_borrowed_stmt_is_valid( &((*this_).statement) ) );
172 7 : u8_error_t result = U8_ERROR_NONE;
173 :
174 : /* do one step, check if is_at_end */
175 : {
176 : int sqlite_err;
177 7 : U8_TRACE_INFO( "sqlite3_step()" );
178 7 : sqlite_err = sqlite3_step( data_database_borrowed_stmt_get_statement( &((*this_).statement) ) );
179 7 : if ( SQLITE_DONE == sqlite_err )
180 : {
181 5 : U8_TRACE_INFO( "sqlite3_step finished: SQLITE_DONE" );
182 5 : (*this_).is_at_end = true;
183 : }
184 2 : else if ( SQLITE_ROW == sqlite_err )
185 : {
186 2 : (*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_classifier_iterator_destroy( this_ );
193 0 : result |= U8_ERROR_AT_DB;
194 : }
195 : }
196 :
197 7 : U8_TRACE_END_ERR(result);
198 7 : return result;
199 : }
200 :
201 :
202 : /*
203 : Copyright 2020-2024 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 : */
|