Line data Source code
1 : /* File: data_relationship_iterator.c; Copyright and License: see below */
2 :
3 : #include "storage/data_relationship_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 : const char *const DATA_RELATIONSHIP_ITERATOR_SELECT_RELATIONSHIPS_BY_DIAGRAM_ID =
12 : "SELECT relationships.id,relationships.main_type,relationships.from_classifier_id,relationships.to_classifier_id,"
13 : "relationships.stereotype,relationships.name,relationships.description,relationships.list_order,"
14 : "relationships.from_feature_id,relationships.to_feature_id,relationships.uuid,"
15 : "source.id, dest.id " /* source.id, dest.id needed only for debugging */
16 : "FROM relationships "
17 : "INNER JOIN diagramelements AS source "
18 : "ON source.classifier_id=relationships.from_classifier_id "
19 : "INNER JOIN diagramelements AS dest "
20 : "ON (dest.classifier_id=relationships.to_classifier_id)AND(dest.diagram_id=source.diagram_id) "
21 : "WHERE source.diagram_id=? "
22 : "GROUP BY relationships.id "
23 : "ORDER BY relationships.list_order ASC;";
24 :
25 : /*
26 : * Order by id to ensure a defined, non-changeing order of relationships in json export
27 : */
28 : const char *const DATA_RELATIONSHIP_ITERATOR_SELECT_RELATIONSHIPS_BY_CLASSIFIER_ID =
29 : "SELECT id,main_type,from_classifier_id,to_classifier_id,stereotype,name,description,list_order,"
30 : "from_feature_id,to_feature_id,uuid,-1,-1 "
31 : "FROM relationships "
32 : "WHERE from_classifier_id=? OR to_classifier_id=? "
33 : "ORDER BY id ASC;";
34 :
35 : const char *const DATA_RELATIONSHIP_ITERATOR_SELECT_RELATIONSHIPS_BY_FEATURE_ID =
36 : "SELECT id,main_type,from_classifier_id,to_classifier_id,stereotype,name,description,list_order,"
37 : "from_feature_id,to_feature_id,uuid,-1,-1 "
38 : "FROM relationships "
39 : "WHERE from_feature_id=? OR to_feature_id=?;";
40 :
41 : /*!
42 : * \brief the column id of the result where this parameter is stored: id
43 : */
44 : static const int RESULT_RELATIONSHIP_ID_COLUMN = 0;
45 :
46 : /*!
47 : * \brief the column id of the result where this parameter is stored: main_type
48 : */
49 : static const int RESULT_RELATIONSHIP_MAIN_TYPE_COLUMN = 1;
50 :
51 : /*!
52 : * \brief the column id of the result where this parameter is stored: from_classifier_id
53 : */
54 : static const int RESULT_RELATIONSHIP_FROM_CLASSIFIER_ID_COLUMN = 2;
55 :
56 : /*!
57 : * \brief the column id of the result where this parameter is stored: to_classifier_id
58 : */
59 : static const int RESULT_RELATIONSHIP_TO_CLASSIFIER_ID_COLUMN = 3;
60 :
61 : /*!
62 : * \brief the column id of the result where this parameter is stored: name
63 : */
64 : static const int RESULT_RELATIONSHIP_STEREOTYPE_COLUMN = 4;
65 :
66 : /*!
67 : * \brief the column id of the result where this parameter is stored: name
68 : */
69 : static const int RESULT_RELATIONSHIP_NAME_COLUMN = 5;
70 :
71 : /*!
72 : * \brief the column id of the result where this parameter is stored: description
73 : */
74 : static const int RESULT_RELATIONSHIP_DESCRIPTION_COLUMN = 6;
75 :
76 : /*!
77 : * \brief the column id of the result where this parameter is stored: list_order
78 : */
79 : static const int RESULT_RELATIONSHIP_LIST_ORDER_COLUMN = 7;
80 :
81 : /*!
82 : * \brief the column id of the result where this parameter is stored: from_feature_id
83 : */
84 : static const int RESULT_RELATIONSHIP_FROM_FEATURE_ID_COLUMN = 8;
85 :
86 : /*!
87 : * \brief the column id of the result where this parameter is stored: to_feature_id
88 : */
89 : static const int RESULT_RELATIONSHIP_TO_FEATURE_ID_COLUMN = 9;
90 :
91 : /*!
92 : * \brief the column id of the result where this parameter is stored: uuid
93 : */
94 : static const int RESULT_RELATIONSHIP_UUID_COLUMN = 10;
95 :
96 : /*!
97 : * \brief the column id of the result where this parameter is stored: source diagramelements.id
98 : */
99 : static const int RESULT_RELATIONSHIP_SOURCE_DIAGRAMELEMENTS_ID_COLUMN = 11;
100 :
101 : /*!
102 : * \brief the column id of the result where this parameter is stored: dest diagramelements.id
103 : */
104 : static const int RESULT_RELATIONSHIP_DEST_DIAGRAMELEMENTS_ID_COLUMN = 12;
105 :
106 71 : void data_relationship_iterator_init_empty ( data_relationship_iterator_t *this_ )
107 : {
108 71 : U8_TRACE_BEGIN();
109 :
110 71 : data_database_borrowed_stmt_init_void( &((*this_).statement) );
111 71 : (*this_).is_at_end = true;
112 :
113 71 : U8_TRACE_END();
114 71 : }
115 :
116 71 : u8_error_t data_relationship_iterator_reinit ( data_relationship_iterator_t *this_,
117 : data_database_borrowed_stmt_t statement )
118 : {
119 71 : U8_TRACE_BEGIN();
120 71 : assert( data_database_borrowed_stmt_is_valid( &statement ) );
121 71 : u8_error_t result = U8_ERROR_NONE;
122 :
123 : /* destroy old state */
124 71 : result |= data_relationship_iterator_destroy( this_ );
125 :
126 : /* init new state */
127 71 : (*this_).statement = statement;
128 71 : (*this_).is_at_end = false;
129 71 : result |= data_relationship_iterator_private_step_to_next( this_ );
130 :
131 71 : U8_TRACE_END_ERR(result);
132 71 : return result;
133 : }
134 :
135 145 : u8_error_t data_relationship_iterator_destroy ( data_relationship_iterator_t *this_ )
136 : {
137 145 : U8_TRACE_BEGIN();
138 145 : u8_error_t result = U8_ERROR_NONE;
139 :
140 145 : result |= data_database_borrowed_stmt_destroy( &((*this_).statement) );
141 145 : (*this_).is_at_end = true;
142 :
143 145 : U8_TRACE_END_ERR(result);
144 145 : return result;
145 : }
146 :
147 497 : bool data_relationship_iterator_has_next ( const data_relationship_iterator_t *this_ )
148 : {
149 497 : return ( ! (*this_).is_at_end );
150 : }
151 :
152 432 : u8_error_t data_relationship_iterator_next ( data_relationship_iterator_t *this_, data_relationship_t *out_relationship )
153 : {
154 432 : U8_TRACE_BEGIN();
155 432 : assert( NULL != out_relationship );
156 432 : assert( data_database_borrowed_stmt_is_valid( &((*this_).statement) ) );
157 432 : u8_error_t result = U8_ERROR_NONE;
158 :
159 432 : if ( ! (*this_).is_at_end )
160 : {
161 431 : sqlite3_stmt *const sql_statement = data_database_borrowed_stmt_get_statement( &((*this_).statement) );
162 :
163 431 : result |= data_relationship_init( out_relationship,
164 431 : sqlite3_column_int64( sql_statement, RESULT_RELATIONSHIP_ID_COLUMN ),
165 431 : sqlite3_column_int64( sql_statement, RESULT_RELATIONSHIP_FROM_CLASSIFIER_ID_COLUMN ),
166 431 : sqlite3_column_int64( sql_statement, RESULT_RELATIONSHIP_FROM_FEATURE_ID_COLUMN ),
167 431 : sqlite3_column_int64( sql_statement, RESULT_RELATIONSHIP_TO_CLASSIFIER_ID_COLUMN ),
168 431 : sqlite3_column_int64( sql_statement, RESULT_RELATIONSHIP_TO_FEATURE_ID_COLUMN ),
169 431 : sqlite3_column_int( sql_statement, RESULT_RELATIONSHIP_MAIN_TYPE_COLUMN ),
170 431 : (const char*) sqlite3_column_text( sql_statement, RESULT_RELATIONSHIP_STEREOTYPE_COLUMN ),
171 431 : (const char*) sqlite3_column_text( sql_statement, RESULT_RELATIONSHIP_NAME_COLUMN ),
172 431 : (const char*) sqlite3_column_text( sql_statement, RESULT_RELATIONSHIP_DESCRIPTION_COLUMN ),
173 431 : sqlite3_column_int( sql_statement, RESULT_RELATIONSHIP_LIST_ORDER_COLUMN ),
174 431 : (const char*) sqlite3_column_text( sql_statement, RESULT_RELATIONSHIP_UUID_COLUMN )
175 : );
176 431 : if ( SQLITE_NULL == sqlite3_column_type( sql_statement, RESULT_RELATIONSHIP_FROM_FEATURE_ID_COLUMN ) )
177 : {
178 409 : data_relationship_set_from_feature_row ( out_relationship, DATA_ROW_VOID );
179 : }
180 431 : if ( SQLITE_NULL == sqlite3_column_type( sql_statement, RESULT_RELATIONSHIP_TO_FEATURE_ID_COLUMN ) )
181 : {
182 412 : data_relationship_set_to_feature_row ( out_relationship, DATA_ROW_VOID );
183 : }
184 431 : U8_TRACE_INFO_INT( "(source)diagramelements.id:", sqlite3_column_int64( sql_statement, RESULT_RELATIONSHIP_SOURCE_DIAGRAMELEMENTS_ID_COLUMN ) );
185 431 : U8_TRACE_INFO_INT( "(dest)diagramelements.id:", sqlite3_column_int64( sql_statement, RESULT_RELATIONSHIP_DEST_DIAGRAMELEMENTS_ID_COLUMN ) );
186 431 : data_relationship_trace( out_relationship );
187 :
188 : /* step to next */
189 431 : result |= data_relationship_iterator_private_step_to_next( this_ );
190 : }
191 : else
192 : {
193 1 : U8_TRACE_INFO( "iterator already at end" );
194 1 : (*this_).is_at_end = true;
195 1 : result |= U8_ERROR_INVALID_REQUEST;
196 : }
197 :
198 432 : U8_TRACE_END_ERR( result );
199 432 : return result;
200 : }
201 :
202 502 : u8_error_t data_relationship_iterator_private_step_to_next ( data_relationship_iterator_t *this_ )
203 : {
204 502 : U8_TRACE_BEGIN();
205 502 : assert( data_database_borrowed_stmt_is_valid( &((*this_).statement) ) );
206 502 : u8_error_t result = U8_ERROR_NONE;
207 :
208 : /* do one step, check if is_at_end */
209 : {
210 : int sqlite_err;
211 502 : U8_TRACE_INFO( "sqlite3_step()" );
212 502 : sqlite_err = sqlite3_step( data_database_borrowed_stmt_get_statement( &((*this_).statement) ) );
213 502 : if ( SQLITE_DONE == sqlite_err )
214 : {
215 67 : U8_TRACE_INFO( "sqlite3_step finished: SQLITE_DONE" );
216 67 : (*this_).is_at_end = true;
217 : }
218 435 : else if ( SQLITE_ROW == sqlite_err )
219 : {
220 432 : (*this_).is_at_end = false;
221 : }
222 : else
223 : {
224 3 : U8_LOG_ERROR_INT( "sqlite3_step failed:", sqlite_err );
225 3 : (*this_).is_at_end = true;
226 3 : result |= data_relationship_iterator_destroy( this_ );
227 3 : result |= U8_ERROR_AT_DB;
228 : }
229 : }
230 :
231 502 : U8_TRACE_END_ERR(result);
232 502 : return result;
233 : }
234 :
235 :
236 : /*
237 : Copyright 2024-2026 Andreas Warnke
238 :
239 : Licensed under the Apache License, Version 2.0 (the "License");
240 : you may not use this file except in compliance with the License.
241 : You may obtain a copy of the License at
242 :
243 : http://www.apache.org/licenses/LICENSE-2.0
244 :
245 : Unless required by applicable law or agreed to in writing, software
246 : distributed under the License is distributed on an "AS IS" BASIS,
247 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
248 : See the License for the specific language governing permissions and
249 : limitations under the License.
250 : */
|