Line data Source code
1 : /* File: data_database_classifier_reader.c; Copyright and License: see below */
2 :
3 : #include "storage/data_database_classifier_reader.h"
4 : #include "storage/data_database_borrowed_stmt.h"
5 : #include "u8/u8_trace.h"
6 : #include "u8/u8_log.h"
7 : #include "utf8stringbuf/utf8stringbuf.h"
8 : #include <sqlite3.h>
9 : #include <assert.h>
10 :
11 101 : u8_error_t data_database_classifier_reader_init ( data_database_classifier_reader_t *this_, data_database_t *database )
12 : {
13 101 : U8_TRACE_BEGIN();
14 101 : assert( NULL != database );
15 101 : u8_error_t result = U8_ERROR_NONE;
16 :
17 101 : (*this_).database = database;
18 :
19 101 : (*this_).statement_classifier_by_id = NULL;
20 101 : (*this_).statement_classifier_by_name = NULL;
21 101 : (*this_).statement_classifier_by_uuid = NULL;
22 101 : (*this_).statement_classifiers_all = NULL;
23 101 : (*this_).statement_classifiers_all_hierarchical = NULL;
24 :
25 101 : (*this_).statement_feature_by_id = NULL;
26 101 : (*this_).statement_feature_by_uuid = NULL;
27 101 : (*this_).statement_features_by_classifier_id = NULL;
28 101 : (*this_).statement_features_by_diagram_id = NULL;
29 :
30 101 : (*this_).statement_relationship_by_id = NULL;
31 101 : (*this_).statement_relationship_by_uuid = NULL;
32 101 : (*this_).statement_relationships_by_classifier_id = NULL;
33 101 : (*this_).statement_relationships_by_feature_id = NULL;
34 101 : (*this_).statement_relationships_by_diagram_id = NULL;
35 :
36 101 : result |= data_database_classifier_reader_private_open( this_ );
37 :
38 101 : U8_TRACE_END_ERR(result);
39 101 : return result;
40 : }
41 :
42 101 : u8_error_t data_database_classifier_reader_destroy ( data_database_classifier_reader_t *this_ )
43 : {
44 101 : U8_TRACE_BEGIN();
45 101 : u8_error_t result = U8_ERROR_NONE;
46 :
47 101 : result |= data_database_classifier_reader_private_close( this_ );
48 :
49 101 : (*this_).database = NULL;
50 :
51 101 : U8_TRACE_END_ERR(result);
52 101 : return result;
53 : }
54 :
55 : /* ================================ CLASSIFIER ================================ */
56 :
57 : /*!
58 : * \brief predefined search statement to find a classifier by id
59 : */
60 : static const char DATA_DATABASE_READER_SELECT_CLASSIFIER_BY_ID[] =
61 : "SELECT id,main_type,stereotype,name,description,x_order,y_order,list_order,uuid "
62 : "FROM classifiers WHERE id=?;";
63 :
64 : /*!
65 : * \brief predefined search statement to find a classifier by uuid
66 : */
67 : static const char DATA_DATABASE_READER_SELECT_CLASSIFIER_BY_UUID[] =
68 : "SELECT id,main_type,stereotype,name,description,x_order,y_order,list_order,uuid "
69 : "FROM classifiers WHERE uuid=?;";
70 :
71 : /*!
72 : * \brief predefined search statement to find a classifier by name
73 : */
74 : static const char DATA_DATABASE_READER_SELECT_CLASSIFIER_BY_NAME[] =
75 : "SELECT id,main_type,stereotype,name,description,x_order,y_order,list_order,uuid "
76 : "FROM classifiers WHERE name=?;";
77 :
78 : /*!
79 : * \brief the column id of the result where this parameter is stored: id
80 : */
81 : static const int RESULT_CLASSIFIER_ID_COLUMN = 0;
82 :
83 : /*!
84 : * \brief the column id of the result where this parameter is stored: main_type
85 : */
86 : static const int RESULT_CLASSIFIER_MAIN_TYPE_COLUMN = 1;
87 :
88 : /*!
89 : * \brief the column id of the result where this parameter is stored: stereotype
90 : */
91 : static const int RESULT_CLASSIFIER_STEREOTYPE_COLUMN = 2;
92 :
93 : /*!
94 : * \brief the column id of the result where this parameter is stored: name
95 : */
96 : static const int RESULT_CLASSIFIER_NAME_COLUMN = 3;
97 :
98 : /*!
99 : * \brief the column id of the result where this parameter is stored: description
100 : */
101 : static const int RESULT_CLASSIFIER_DESCRIPTION_COLUMN = 4;
102 :
103 : /*!
104 : * \brief the column id of the result where this parameter is stored: x_order
105 : */
106 : static const int RESULT_CLASSIFIER_X_ORDER_COLUMN = 5;
107 :
108 : /*!
109 : * \brief the column id of the result where this parameter is stored: y_order
110 : */
111 : static const int RESULT_CLASSIFIER_Y_ORDER_COLUMN = 6;
112 :
113 : /*!
114 : * \brief the column id of the result where this parameter is stored: list_order
115 : */
116 : static const int RESULT_CLASSIFIER_LIST_ORDER_COLUMN = 7;
117 :
118 : /*!
119 : * \brief the column id of the result where this parameter is stored: uuid
120 : */
121 : static const int RESULT_CLASSIFIER_UUID_COLUMN = 8;
122 :
123 12 : u8_error_t data_database_classifier_reader_get_classifier_by_id( data_database_classifier_reader_t *this_,
124 : data_row_t id,
125 : data_classifier_t *out_classifier )
126 : {
127 12 : U8_TRACE_BEGIN();
128 12 : assert( NULL != out_classifier );
129 12 : u8_error_t result = U8_ERROR_NONE;
130 : int sqlite_err;
131 : sqlite3_stmt *prepared_statement;
132 :
133 : {
134 12 : prepared_statement = (*this_).statement_classifier_by_id;
135 :
136 12 : result |= data_database_classifier_reader_private_bind_id_to_statement( this_, prepared_statement, id );
137 :
138 12 : U8_TRACE_INFO( "sqlite3_step()" );
139 12 : sqlite_err = sqlite3_step( prepared_statement );
140 12 : if ( SQLITE_ROW != sqlite_err )
141 : {
142 : /* this situation may happen if a classifier is deleted that is shown in the attributes editor */
143 0 : U8_TRACE_INFO_INT( "sqlite3_step did not find a row for id", id );
144 0 : result |= U8_ERROR_DB_STRUCTURE; /* non-existing ids are worse than U8_ERROR_NOT_FOUND */
145 : }
146 :
147 12 : if ( SQLITE_ROW == sqlite_err )
148 : {
149 24 : result |= data_classifier_init( out_classifier,
150 12 : sqlite3_column_int64( prepared_statement, RESULT_CLASSIFIER_ID_COLUMN ),
151 12 : sqlite3_column_int( prepared_statement, RESULT_CLASSIFIER_MAIN_TYPE_COLUMN ),
152 12 : (const char*) sqlite3_column_text( prepared_statement, RESULT_CLASSIFIER_STEREOTYPE_COLUMN ),
153 12 : (const char*) sqlite3_column_text( prepared_statement, RESULT_CLASSIFIER_NAME_COLUMN ),
154 12 : (const char*) sqlite3_column_text( prepared_statement, RESULT_CLASSIFIER_DESCRIPTION_COLUMN ),
155 : sqlite3_column_int( prepared_statement, RESULT_CLASSIFIER_X_ORDER_COLUMN ),
156 : sqlite3_column_int( prepared_statement, RESULT_CLASSIFIER_Y_ORDER_COLUMN ),
157 : sqlite3_column_int( prepared_statement, RESULT_CLASSIFIER_LIST_ORDER_COLUMN ),
158 12 : (const char*) sqlite3_column_text( prepared_statement, RESULT_CLASSIFIER_UUID_COLUMN )
159 : );
160 :
161 12 : data_classifier_trace( out_classifier );
162 :
163 12 : sqlite_err = sqlite3_step( prepared_statement );
164 12 : if ( SQLITE_DONE != sqlite_err )
165 : {
166 0 : U8_LOG_ERROR_INT( "sqlite3_step failed:", sqlite_err );
167 0 : result |= U8_ERROR_DB_STRUCTURE;
168 : }
169 : }
170 : }
171 :
172 12 : U8_TRACE_END_ERR( result );
173 12 : return result;
174 : }
175 :
176 57 : u8_error_t data_database_classifier_reader_get_classifier_by_name( data_database_classifier_reader_t *this_,
177 : const char *name,
178 : data_classifier_t *out_classifier )
179 : {
180 57 : U8_TRACE_BEGIN();
181 57 : assert( NULL != out_classifier );
182 57 : assert( NULL != name );
183 57 : u8_error_t result = U8_ERROR_NONE;
184 : int sqlite_err;
185 : sqlite3_stmt *prepared_statement;
186 :
187 : {
188 57 : prepared_statement = (*this_).statement_classifier_by_name;
189 :
190 57 : result |= data_database_classifier_reader_private_bind_text_to_statement( this_, prepared_statement, name );
191 :
192 57 : U8_TRACE_INFO( "sqlite3_step()" );
193 57 : sqlite_err = sqlite3_step( prepared_statement );
194 57 : if ( SQLITE_ROW != sqlite_err )
195 : {
196 6 : U8_TRACE_INFO_STR( "sqlite3_step did not find a row for name", name );
197 6 : result |= U8_ERROR_NOT_FOUND;
198 : }
199 :
200 57 : if ( SQLITE_ROW == sqlite_err )
201 : {
202 102 : result |= data_classifier_init( out_classifier,
203 51 : sqlite3_column_int64( prepared_statement, RESULT_CLASSIFIER_ID_COLUMN ),
204 51 : sqlite3_column_int( prepared_statement, RESULT_CLASSIFIER_MAIN_TYPE_COLUMN ),
205 51 : (const char*) sqlite3_column_text( prepared_statement, RESULT_CLASSIFIER_STEREOTYPE_COLUMN ),
206 51 : (const char*) sqlite3_column_text( prepared_statement, RESULT_CLASSIFIER_NAME_COLUMN ),
207 51 : (const char*) sqlite3_column_text( prepared_statement, RESULT_CLASSIFIER_DESCRIPTION_COLUMN ),
208 : sqlite3_column_int( prepared_statement, RESULT_CLASSIFIER_X_ORDER_COLUMN ),
209 : sqlite3_column_int( prepared_statement, RESULT_CLASSIFIER_Y_ORDER_COLUMN ),
210 : sqlite3_column_int( prepared_statement, RESULT_CLASSIFIER_LIST_ORDER_COLUMN ),
211 51 : (const char*) sqlite3_column_text( prepared_statement, RESULT_CLASSIFIER_UUID_COLUMN )
212 : );
213 :
214 51 : data_classifier_trace( out_classifier );
215 :
216 51 : sqlite_err = sqlite3_step( prepared_statement );
217 51 : if ( SQLITE_DONE != sqlite_err )
218 : {
219 0 : U8_LOG_ERROR_INT( "sqlite3_step not done yet:", sqlite_err );
220 0 : result |= U8_ERROR_DB_STRUCTURE;
221 : }
222 : }
223 : }
224 :
225 57 : U8_TRACE_END_ERR( result );
226 57 : return result;
227 : }
228 :
229 72 : u8_error_t data_database_classifier_reader_get_classifier_by_uuid ( data_database_classifier_reader_t *this_,
230 : const char *uuid,
231 : data_classifier_t *out_classifier )
232 : {
233 72 : U8_TRACE_BEGIN();
234 72 : assert( NULL != out_classifier );
235 72 : assert( NULL != uuid );
236 72 : u8_error_t result = U8_ERROR_NONE;
237 : int sqlite_err;
238 : sqlite3_stmt *prepared_statement;
239 :
240 : {
241 72 : prepared_statement = (*this_).statement_classifier_by_uuid;
242 :
243 72 : result |= data_database_classifier_reader_private_bind_text_to_statement( this_, prepared_statement, uuid );
244 :
245 72 : U8_TRACE_INFO( "sqlite3_step()" );
246 72 : sqlite_err = sqlite3_step( prepared_statement );
247 72 : if ( SQLITE_ROW != sqlite_err )
248 : {
249 : /* Do not log this incident, the caller may not expect to find a row. */
250 31 : U8_TRACE_INFO_STR( "sqlite3_step did not find a row for uuid", uuid );
251 31 : result |= U8_ERROR_NOT_FOUND;
252 : }
253 :
254 72 : if ( SQLITE_ROW == sqlite_err )
255 : {
256 82 : result |= data_classifier_init( out_classifier,
257 41 : sqlite3_column_int64( prepared_statement, RESULT_CLASSIFIER_ID_COLUMN ),
258 41 : sqlite3_column_int( prepared_statement, RESULT_CLASSIFIER_MAIN_TYPE_COLUMN ),
259 41 : (const char*) sqlite3_column_text( prepared_statement, RESULT_CLASSIFIER_STEREOTYPE_COLUMN ),
260 41 : (const char*) sqlite3_column_text( prepared_statement, RESULT_CLASSIFIER_NAME_COLUMN ),
261 41 : (const char*) sqlite3_column_text( prepared_statement, RESULT_CLASSIFIER_DESCRIPTION_COLUMN ),
262 : sqlite3_column_int( prepared_statement, RESULT_CLASSIFIER_X_ORDER_COLUMN ),
263 : sqlite3_column_int( prepared_statement, RESULT_CLASSIFIER_Y_ORDER_COLUMN ),
264 : sqlite3_column_int( prepared_statement, RESULT_CLASSIFIER_LIST_ORDER_COLUMN ),
265 41 : (const char*) sqlite3_column_text( prepared_statement, RESULT_CLASSIFIER_UUID_COLUMN )
266 : );
267 :
268 41 : data_classifier_trace( out_classifier );
269 :
270 41 : sqlite_err = sqlite3_step( prepared_statement );
271 41 : if ( SQLITE_DONE != sqlite_err )
272 : {
273 0 : U8_LOG_ERROR_INT( "sqlite3_step not done yet:", sqlite_err );
274 0 : result |= U8_ERROR_DB_STRUCTURE;
275 : }
276 : }
277 : }
278 :
279 72 : U8_TRACE_END_ERR( result );
280 72 : return result;
281 : }
282 :
283 5 : u8_error_t data_database_classifier_reader_get_all_classifiers( data_database_classifier_reader_t *this_,
284 : bool hierarchical,
285 : data_classifier_iterator_t *io_classifier_iterator
286 : )
287 : {
288 5 : U8_TRACE_BEGIN();
289 5 : assert( NULL != io_classifier_iterator );
290 5 : u8_error_t result = U8_ERROR_NONE;
291 :
292 5 : sqlite3_stmt *const db_statement
293 : = hierarchical
294 : ? (*this_).statement_classifiers_all_hierarchical
295 5 : : (*this_).statement_classifiers_all;
296 5 : bool *const borrow_flag
297 : = hierarchical
298 : ? &((*this_).statement_classifiers_all_hierarchical_borrowed)
299 5 : : &((*this_).statement_classifiers_all_borrowed);
300 : data_database_borrowed_stmt_t sql_statement;
301 5 : data_database_borrowed_stmt_init( &sql_statement, (*this_).database, db_statement, borrow_flag );
302 :
303 5 : result |= data_classifier_iterator_reinit( io_classifier_iterator, sql_statement );
304 : /* do not destroy sql_statement; the object is transferred to the iterator and consumed there. */
305 :
306 5 : U8_TRACE_END_ERR( result );
307 5 : return result;
308 : }
309 :
310 : /* ================================ FEATURE ================================ */
311 :
312 : /*!
313 : * \brief predefined search statement to find a feature by id
314 : */
315 : static const char DATA_DATABASE_READER_SELECT_FEATURE_BY_ID[] =
316 : "SELECT id,main_type,classifier_id,key,value,description,list_order,uuid "
317 : "FROM features WHERE id=?;";
318 :
319 : /*!
320 : * \brief predefined search statement to find a feature by uuid
321 : */
322 : static const char DATA_DATABASE_READER_SELECT_FEATURE_BY_UUID[] =
323 : "SELECT id,main_type,classifier_id,key,value,description,list_order,uuid "
324 : "FROM features WHERE uuid=?;";
325 :
326 : /*!
327 : * \brief the column id of the result where this parameter is stored: id
328 : */
329 : static const int RESULT_FEATURE_ID_COLUMN = 0;
330 :
331 : /*!
332 : * \brief the column id of the result where this parameter is stored: main_type
333 : */
334 : static const int RESULT_FEATURE_MAIN_TYPE_COLUMN = 1;
335 :
336 : /*!
337 : * \brief the column id of the result where this parameter is stored: classifier_id
338 : */
339 : static const int RESULT_FEATURE_CLASSIFIER_ID_COLUMN = 2;
340 :
341 : /*!
342 : * \brief the column id of the result where this parameter is stored: key
343 : */
344 : static const int RESULT_FEATURE_KEY_COLUMN = 3;
345 :
346 : /*!
347 : * \brief the column id of the result where this parameter is stored: value
348 : */
349 : static const int RESULT_FEATURE_VALUE_COLUMN = 4;
350 :
351 : /*!
352 : * \brief the column id of the result where this parameter is stored: description
353 : */
354 : static const int RESULT_FEATURE_DESCRIPTION_COLUMN = 5;
355 :
356 : /*!
357 : * \brief the column id of the result where this parameter is stored: list_order
358 : */
359 : static const int RESULT_FEATURE_LIST_ORDER_COLUMN = 6;
360 :
361 : /*!
362 : * \brief the column id of the result where this parameter is stored: uuid
363 : */
364 : static const int RESULT_FEATURE_LIST_UUID_COLUMN = 7;
365 :
366 31 : u8_error_t data_database_classifier_reader_get_feature_by_id ( data_database_classifier_reader_t *this_,
367 : data_row_t id,
368 : data_feature_t *out_feature )
369 : {
370 31 : U8_TRACE_BEGIN();
371 31 : assert( NULL != out_feature );
372 31 : u8_error_t result = U8_ERROR_NONE;
373 : int sqlite_err;
374 : sqlite3_stmt *prepared_statement;
375 :
376 : {
377 31 : prepared_statement = (*this_).statement_feature_by_id;
378 :
379 31 : result |= data_database_classifier_reader_private_bind_id_to_statement( this_, prepared_statement, id );
380 :
381 31 : U8_TRACE_INFO( "sqlite3_step()" );
382 31 : sqlite_err = sqlite3_step( prepared_statement );
383 31 : if ( SQLITE_ROW != sqlite_err )
384 : {
385 5 : U8_TRACE_INFO_INT( "sqlite3_step did not find a row for id", id );
386 5 : result |= U8_ERROR_DB_STRUCTURE; /* non-existing ids are worse than U8_ERROR_NOT_FOUND */
387 : }
388 :
389 31 : if ( SQLITE_ROW == sqlite_err )
390 : {
391 52 : result |= data_feature_init( out_feature,
392 26 : sqlite3_column_int64( prepared_statement, RESULT_FEATURE_ID_COLUMN ),
393 26 : sqlite3_column_int( prepared_statement, RESULT_FEATURE_MAIN_TYPE_COLUMN ),
394 26 : sqlite3_column_int64( prepared_statement, RESULT_FEATURE_CLASSIFIER_ID_COLUMN ),
395 26 : (const char*) sqlite3_column_text( prepared_statement, RESULT_FEATURE_KEY_COLUMN ),
396 26 : (const char*) sqlite3_column_text( prepared_statement, RESULT_FEATURE_VALUE_COLUMN ),
397 26 : (const char*) sqlite3_column_text( prepared_statement, RESULT_FEATURE_DESCRIPTION_COLUMN ),
398 : sqlite3_column_int( prepared_statement, RESULT_FEATURE_LIST_ORDER_COLUMN ),
399 26 : (const char*) sqlite3_column_text( prepared_statement, RESULT_FEATURE_LIST_UUID_COLUMN )
400 : );
401 :
402 26 : data_feature_trace( out_feature );
403 :
404 26 : sqlite_err = sqlite3_step( prepared_statement );
405 26 : if ( SQLITE_DONE != sqlite_err )
406 : {
407 0 : U8_LOG_ERROR_INT( "sqlite3_step failed:", sqlite_err );
408 0 : result |= U8_ERROR_DB_STRUCTURE;
409 : }
410 : }
411 : }
412 :
413 31 : U8_TRACE_END_ERR( result );
414 31 : return result;
415 : }
416 :
417 35 : u8_error_t data_database_classifier_reader_get_feature_by_uuid ( data_database_classifier_reader_t *this_,
418 : const char *uuid,
419 : data_feature_t *out_feature )
420 : {
421 35 : U8_TRACE_BEGIN();
422 35 : assert( NULL != uuid );
423 35 : assert( NULL != out_feature );
424 35 : u8_error_t result = U8_ERROR_NONE;
425 : int sqlite_err;
426 : sqlite3_stmt *prepared_statement;
427 :
428 : {
429 35 : prepared_statement = (*this_).statement_feature_by_uuid;
430 :
431 35 : result |= data_database_classifier_reader_private_bind_text_to_statement( this_, prepared_statement, uuid );
432 :
433 35 : U8_TRACE_INFO( "sqlite3_step()" );
434 35 : sqlite_err = sqlite3_step( prepared_statement );
435 35 : if ( SQLITE_ROW != sqlite_err )
436 : {
437 : /* Do not log this incident, the caller may not expect to find a row. */
438 27 : U8_TRACE_INFO_STR( "sqlite3_step did not find a row for uuid", uuid );
439 27 : result |= U8_ERROR_NOT_FOUND;
440 : }
441 :
442 35 : if ( SQLITE_ROW == sqlite_err )
443 : {
444 16 : result |= data_feature_init( out_feature,
445 8 : sqlite3_column_int64( prepared_statement, RESULT_FEATURE_ID_COLUMN ),
446 8 : sqlite3_column_int( prepared_statement, RESULT_FEATURE_MAIN_TYPE_COLUMN ),
447 8 : sqlite3_column_int64( prepared_statement, RESULT_FEATURE_CLASSIFIER_ID_COLUMN ),
448 8 : (const char*) sqlite3_column_text( prepared_statement, RESULT_FEATURE_KEY_COLUMN ),
449 8 : (const char*) sqlite3_column_text( prepared_statement, RESULT_FEATURE_VALUE_COLUMN ),
450 8 : (const char*) sqlite3_column_text( prepared_statement, RESULT_FEATURE_DESCRIPTION_COLUMN ),
451 : sqlite3_column_int( prepared_statement, RESULT_FEATURE_LIST_ORDER_COLUMN ),
452 8 : (const char*) sqlite3_column_text( prepared_statement, RESULT_FEATURE_LIST_UUID_COLUMN )
453 : );
454 :
455 8 : data_feature_trace( out_feature );
456 :
457 8 : sqlite_err = sqlite3_step( prepared_statement );
458 8 : if ( SQLITE_DONE != sqlite_err )
459 : {
460 0 : U8_LOG_ERROR_INT( "sqlite3_step not done yet:", sqlite_err );
461 0 : result |= U8_ERROR_DB_STRUCTURE;
462 : }
463 : }
464 : }
465 :
466 35 : U8_TRACE_END_ERR( result );
467 35 : return result;
468 : }
469 :
470 13 : u8_error_t data_database_classifier_reader_get_features_by_classifier_id ( data_database_classifier_reader_t *this_,
471 : data_row_t classifier_id,
472 : data_feature_iterator_t *io_feature_iterator )
473 : {
474 13 : U8_TRACE_BEGIN();
475 13 : assert( NULL != io_feature_iterator );
476 13 : u8_error_t result = U8_ERROR_NONE;
477 :
478 13 : sqlite3_stmt *const prepared_statement = (*this_).statement_features_by_classifier_id;
479 13 : result |= data_database_classifier_reader_private_bind_id_to_statement( this_, prepared_statement, classifier_id );
480 :
481 : data_database_borrowed_stmt_t sql_statement;
482 13 : data_database_borrowed_stmt_init( &sql_statement,
483 : (*this_).database,
484 : prepared_statement,
485 : &((*this_).statement_features_by_classifier_id_borrowed)
486 : );
487 13 : result |= data_feature_iterator_reinit( io_feature_iterator, sql_statement );
488 : /* do not destroy sql_statement; the object is transferred to the iterator and consumed there. */
489 :
490 13 : U8_TRACE_END_ERR( result );
491 13 : return result;
492 : }
493 :
494 8 : u8_error_t data_database_classifier_reader_get_features_by_diagram_id ( data_database_classifier_reader_t *this_,
495 : data_row_t diagram_id,
496 : data_feature_iterator_t *io_feature_iterator )
497 : {
498 8 : U8_TRACE_BEGIN();
499 8 : assert( NULL != io_feature_iterator );
500 8 : u8_error_t result = U8_ERROR_NONE;
501 :
502 8 : sqlite3_stmt *const prepared_statement = (*this_).statement_features_by_diagram_id;
503 8 : result |= data_database_classifier_reader_private_bind_id_to_statement( this_, prepared_statement, diagram_id );
504 :
505 : data_database_borrowed_stmt_t sql_statement;
506 8 : data_database_borrowed_stmt_init( &sql_statement,
507 : (*this_).database,
508 : prepared_statement,
509 : &((*this_).statement_features_by_diagram_id_borrowed)
510 : );
511 8 : result |= data_feature_iterator_reinit( io_feature_iterator, sql_statement );
512 : /* do not destroy sql_statement; the object is transferred to the iterator and consumed there. */
513 :
514 8 : U8_TRACE_END_ERR( result );
515 8 : return result;
516 : }
517 :
518 : /* ================================ RELATIONSHIP ================================ */
519 :
520 : /*!
521 : * \brief predefined search statement to find a relationship by id
522 : */
523 : static const char DATA_DATABASE_READER_SELECT_RELATIONSHIP_BY_ID[] =
524 : "SELECT id,main_type,from_classifier_id,to_classifier_id,stereotype,name,description,list_order,"
525 : "from_feature_id,to_feature_id,uuid "
526 : "FROM relationships WHERE id=?;";
527 :
528 : /*!
529 : * \brief predefined search statement to find a relationship by uuid
530 : */
531 : static const char DATA_DATABASE_READER_SELECT_RELATIONSHIP_BY_UUID[] =
532 : "SELECT id,main_type,from_classifier_id,to_classifier_id,stereotype,name,description,list_order,"
533 : "from_feature_id,to_feature_id,uuid "
534 : "FROM relationships WHERE uuid=?;";
535 :
536 : /*!
537 : * \brief the column id of the result where this parameter is stored: id
538 : */
539 : static const int RESULT_RELATIONSHIP_ID_COLUMN = 0;
540 :
541 : /*!
542 : * \brief the column id of the result where this parameter is stored: main_type
543 : */
544 : static const int RESULT_RELATIONSHIP_MAIN_TYPE_COLUMN = 1;
545 :
546 : /*!
547 : * \brief the column id of the result where this parameter is stored: from_classifier_id
548 : */
549 : static const int RESULT_RELATIONSHIP_FROM_CLASSIFIER_ID_COLUMN = 2;
550 :
551 : /*!
552 : * \brief the column id of the result where this parameter is stored: to_classifier_id
553 : */
554 : static const int RESULT_RELATIONSHIP_TO_CLASSIFIER_ID_COLUMN = 3;
555 :
556 : /*!
557 : * \brief the column id of the result where this parameter is stored: name
558 : */
559 : static const int RESULT_RELATIONSHIP_STEREOTYPE_COLUMN = 4;
560 :
561 : /*!
562 : * \brief the column id of the result where this parameter is stored: name
563 : */
564 : static const int RESULT_RELATIONSHIP_NAME_COLUMN = 5;
565 :
566 : /*!
567 : * \brief the column id of the result where this parameter is stored: description
568 : */
569 : static const int RESULT_RELATIONSHIP_DESCRIPTION_COLUMN = 6;
570 :
571 : /*!
572 : * \brief the column id of the result where this parameter is stored: list_order
573 : */
574 : static const int RESULT_RELATIONSHIP_LIST_ORDER_COLUMN = 7;
575 :
576 : /*!
577 : * \brief the column id of the result where this parameter is stored: from_feature_id
578 : */
579 : static const int RESULT_RELATIONSHIP_FROM_FEATURE_ID_COLUMN = 8;
580 :
581 : /*!
582 : * \brief the column id of the result where this parameter is stored: to_feature_id
583 : */
584 : static const int RESULT_RELATIONSHIP_TO_FEATURE_ID_COLUMN = 9;
585 :
586 : /*!
587 : * \brief the column id of the result where this parameter is stored: uuid
588 : */
589 : static const int RESULT_RELATIONSHIP_UUID_COLUMN = 10;
590 :
591 25 : u8_error_t data_database_classifier_reader_get_relationship_by_id ( data_database_classifier_reader_t *this_,
592 : data_row_t id,
593 : data_relationship_t *out_relationship )
594 : {
595 25 : U8_TRACE_BEGIN();
596 25 : assert( NULL != out_relationship );
597 25 : u8_error_t result = U8_ERROR_NONE;
598 : int sqlite_err;
599 : sqlite3_stmt *prepared_statement;
600 :
601 : {
602 25 : prepared_statement = (*this_).statement_relationship_by_id;
603 :
604 25 : result |= data_database_classifier_reader_private_bind_id_to_statement( this_, prepared_statement, id );
605 :
606 25 : U8_TRACE_INFO( "sqlite3_step()" );
607 25 : sqlite_err = sqlite3_step( prepared_statement );
608 25 : if ( SQLITE_ROW != sqlite_err )
609 : {
610 7 : U8_TRACE_INFO_INT( "sqlite3_step did not find a row for id", id );
611 7 : result |= U8_ERROR_DB_STRUCTURE; /* non-existing ids are worse than U8_ERROR_NOT_FOUND */
612 : }
613 :
614 25 : if ( SQLITE_ROW == sqlite_err )
615 : {
616 36 : result |= data_relationship_init( out_relationship,
617 18 : sqlite3_column_int64( prepared_statement, RESULT_RELATIONSHIP_ID_COLUMN ),
618 18 : sqlite3_column_int64( prepared_statement, RESULT_RELATIONSHIP_FROM_CLASSIFIER_ID_COLUMN ),
619 18 : sqlite3_column_int64( prepared_statement, RESULT_RELATIONSHIP_FROM_FEATURE_ID_COLUMN ),
620 18 : sqlite3_column_int64( prepared_statement, RESULT_RELATIONSHIP_TO_CLASSIFIER_ID_COLUMN ),
621 18 : sqlite3_column_int64( prepared_statement, RESULT_RELATIONSHIP_TO_FEATURE_ID_COLUMN ),
622 18 : sqlite3_column_int( prepared_statement, RESULT_RELATIONSHIP_MAIN_TYPE_COLUMN ),
623 18 : (const char*) sqlite3_column_text( prepared_statement, RESULT_RELATIONSHIP_STEREOTYPE_COLUMN ),
624 18 : (const char*) sqlite3_column_text( prepared_statement, RESULT_RELATIONSHIP_NAME_COLUMN ),
625 18 : (const char*) sqlite3_column_text( prepared_statement, RESULT_RELATIONSHIP_DESCRIPTION_COLUMN ),
626 : sqlite3_column_int( prepared_statement, RESULT_RELATIONSHIP_LIST_ORDER_COLUMN ),
627 18 : (const char*) sqlite3_column_text( prepared_statement, RESULT_RELATIONSHIP_UUID_COLUMN )
628 : );
629 18 : if ( SQLITE_NULL == sqlite3_column_type( prepared_statement, RESULT_RELATIONSHIP_FROM_FEATURE_ID_COLUMN ) )
630 : {
631 15 : data_relationship_set_from_feature_row_id ( out_relationship, DATA_ROW_VOID );
632 : }
633 18 : if ( SQLITE_NULL == sqlite3_column_type( prepared_statement, RESULT_RELATIONSHIP_TO_FEATURE_ID_COLUMN ) )
634 : {
635 2 : data_relationship_set_to_feature_row_id ( out_relationship, DATA_ROW_VOID );
636 : }
637 :
638 18 : data_relationship_trace( out_relationship );
639 :
640 18 : sqlite_err = sqlite3_step( prepared_statement );
641 18 : if ( SQLITE_DONE != sqlite_err )
642 : {
643 0 : U8_LOG_ERROR_INT( "sqlite3_step failed:", sqlite_err );
644 0 : result |= U8_ERROR_DB_STRUCTURE;
645 : }
646 : }
647 : }
648 :
649 25 : U8_TRACE_END_ERR( result );
650 25 : return result;
651 : }
652 :
653 9 : u8_error_t data_database_classifier_reader_get_relationship_by_uuid ( data_database_classifier_reader_t *this_,
654 : const char *uuid,
655 : data_relationship_t *out_relationship )
656 : {
657 9 : U8_TRACE_BEGIN();
658 9 : assert( NULL != uuid );
659 9 : assert( NULL != out_relationship );
660 9 : u8_error_t result = U8_ERROR_NONE;
661 : int sqlite_err;
662 : sqlite3_stmt *prepared_statement;
663 :
664 : {
665 9 : prepared_statement = (*this_).statement_relationship_by_uuid;
666 :
667 9 : result |= data_database_classifier_reader_private_bind_text_to_statement( this_, prepared_statement, uuid );
668 :
669 9 : U8_TRACE_INFO( "sqlite3_step()" );
670 9 : sqlite_err = sqlite3_step( prepared_statement );
671 9 : if ( SQLITE_ROW != sqlite_err )
672 : {
673 : /* Do not log this incident, the caller may not expect to find a row. */
674 7 : U8_TRACE_INFO_STR( "sqlite3_step did not find a row for uuid", uuid );
675 7 : result |= U8_ERROR_NOT_FOUND;
676 : }
677 :
678 9 : if ( SQLITE_ROW == sqlite_err )
679 : {
680 4 : result |= data_relationship_init( out_relationship,
681 2 : sqlite3_column_int64( prepared_statement, RESULT_RELATIONSHIP_ID_COLUMN ),
682 2 : sqlite3_column_int64( prepared_statement, RESULT_RELATIONSHIP_FROM_CLASSIFIER_ID_COLUMN ),
683 2 : sqlite3_column_int64( prepared_statement, RESULT_RELATIONSHIP_FROM_FEATURE_ID_COLUMN ),
684 2 : sqlite3_column_int64( prepared_statement, RESULT_RELATIONSHIP_TO_CLASSIFIER_ID_COLUMN ),
685 2 : sqlite3_column_int64( prepared_statement, RESULT_RELATIONSHIP_TO_FEATURE_ID_COLUMN ),
686 2 : sqlite3_column_int( prepared_statement, RESULT_RELATIONSHIP_MAIN_TYPE_COLUMN ),
687 2 : (const char*) sqlite3_column_text( prepared_statement, RESULT_RELATIONSHIP_STEREOTYPE_COLUMN ),
688 2 : (const char*) sqlite3_column_text( prepared_statement, RESULT_RELATIONSHIP_NAME_COLUMN ),
689 2 : (const char*) sqlite3_column_text( prepared_statement, RESULT_RELATIONSHIP_DESCRIPTION_COLUMN ),
690 : sqlite3_column_int( prepared_statement, RESULT_RELATIONSHIP_LIST_ORDER_COLUMN ),
691 2 : (const char*) sqlite3_column_text( prepared_statement, RESULT_RELATIONSHIP_UUID_COLUMN )
692 : );
693 2 : if ( SQLITE_NULL == sqlite3_column_type( prepared_statement, RESULT_RELATIONSHIP_FROM_FEATURE_ID_COLUMN ) )
694 : {
695 1 : data_relationship_set_from_feature_row_id ( out_relationship, DATA_ROW_VOID );
696 : }
697 2 : if ( SQLITE_NULL == sqlite3_column_type( prepared_statement, RESULT_RELATIONSHIP_TO_FEATURE_ID_COLUMN ) )
698 : {
699 1 : data_relationship_set_to_feature_row_id ( out_relationship, DATA_ROW_VOID );
700 : }
701 :
702 2 : data_relationship_trace( out_relationship );
703 :
704 2 : sqlite_err = sqlite3_step( prepared_statement );
705 2 : if ( SQLITE_DONE != sqlite_err )
706 : {
707 0 : U8_LOG_ERROR_INT( "sqlite3_step not done yet:", sqlite_err );
708 0 : result |= U8_ERROR_DB_STRUCTURE;
709 : }
710 : }
711 : }
712 :
713 9 : U8_TRACE_END_ERR( result );
714 9 : return result;
715 : }
716 :
717 13 : u8_error_t data_database_classifier_reader_get_relationships_by_classifier_id ( data_database_classifier_reader_t *this_,
718 : data_row_t classifier_id,
719 : data_relationship_iterator_t *io_relationship_iterator )
720 : {
721 13 : U8_TRACE_BEGIN();
722 13 : assert( NULL != io_relationship_iterator );
723 13 : u8_error_t result = U8_ERROR_NONE;
724 :
725 13 : sqlite3_stmt *const prepared_statement = (*this_).statement_relationships_by_classifier_id;
726 13 : result |= data_database_classifier_reader_private_bind_two_ids_to_statement( this_, prepared_statement, classifier_id, classifier_id );
727 :
728 : data_database_borrowed_stmt_t sql_statement;
729 13 : data_database_borrowed_stmt_init( &sql_statement,
730 : (*this_).database,
731 : prepared_statement,
732 : &((*this_).statement_relationships_by_classifier_id_borrowed)
733 : );
734 13 : result |= data_relationship_iterator_reinit( io_relationship_iterator, sql_statement );
735 : /* do not destroy sql_statement; the object is transferred to the iterator and consumed there. */
736 :
737 13 : U8_TRACE_END_ERR( result );
738 13 : return result;
739 : }
740 :
741 10 : u8_error_t data_database_classifier_reader_get_relationships_by_feature_id ( data_database_classifier_reader_t *this_,
742 : data_row_t feature_id,
743 : data_relationship_iterator_t *io_relationship_iterator )
744 : {
745 10 : U8_TRACE_BEGIN();
746 10 : assert( NULL != io_relationship_iterator );
747 10 : u8_error_t result = U8_ERROR_NONE;
748 :
749 10 : sqlite3_stmt *const prepared_statement = (*this_).statement_relationships_by_feature_id;
750 10 : result |= data_database_classifier_reader_private_bind_two_ids_to_statement( this_, prepared_statement, feature_id, feature_id );
751 :
752 : data_database_borrowed_stmt_t sql_statement;
753 10 : data_database_borrowed_stmt_init( &sql_statement,
754 : (*this_).database,
755 : prepared_statement,
756 : &((*this_).statement_relationships_by_feature_id_borrowed)
757 : );
758 10 : result |= data_relationship_iterator_reinit( io_relationship_iterator, sql_statement );
759 : /* do not destroy sql_statement; the object is transferred to the iterator and consumed there. */
760 :
761 10 : U8_TRACE_END_ERR( result );
762 10 : return result;
763 : }
764 :
765 8 : u8_error_t data_database_classifier_reader_get_relationships_by_diagram_id ( data_database_classifier_reader_t *this_,
766 : data_row_t diagram_id,
767 : data_relationship_iterator_t *io_relationship_iterator )
768 : {
769 8 : U8_TRACE_BEGIN();
770 8 : assert( NULL != io_relationship_iterator );
771 8 : u8_error_t result = U8_ERROR_NONE;
772 :
773 8 : sqlite3_stmt *const prepared_statement = (*this_).statement_relationships_by_diagram_id;
774 8 : result |= data_database_classifier_reader_private_bind_id_to_statement( this_, prepared_statement, diagram_id );
775 :
776 : data_database_borrowed_stmt_t sql_statement;
777 8 : data_database_borrowed_stmt_init( &sql_statement,
778 : (*this_).database,
779 : prepared_statement,
780 : &((*this_).statement_relationships_by_diagram_id_borrowed)
781 : );
782 8 : result |= data_relationship_iterator_reinit( io_relationship_iterator, sql_statement );
783 : /* do not destroy sql_statement; the object is transferred to the iterator and consumed there. */
784 :
785 8 : U8_TRACE_END_ERR( result );
786 8 : return result;
787 : }
788 :
789 : /* ================================ private ================================ */
790 :
791 101 : u8_error_t data_database_classifier_reader_private_open ( data_database_classifier_reader_t *this_ )
792 : {
793 101 : U8_TRACE_BEGIN();
794 101 : u8_error_t result = U8_ERROR_NONE;
795 :
796 : {
797 101 : result |= data_database_prepare_statement( (*this_).database,
798 : DATA_DATABASE_READER_SELECT_CLASSIFIER_BY_ID,
799 : sizeof( DATA_DATABASE_READER_SELECT_CLASSIFIER_BY_ID ),
800 : &((*this_).statement_classifier_by_id)
801 : );
802 :
803 101 : result |= data_database_prepare_statement( (*this_).database,
804 : DATA_DATABASE_READER_SELECT_CLASSIFIER_BY_UUID,
805 : sizeof( DATA_DATABASE_READER_SELECT_CLASSIFIER_BY_UUID ),
806 : &((*this_).statement_classifier_by_uuid)
807 : );
808 :
809 101 : result |= data_database_prepare_statement( (*this_).database,
810 : DATA_DATABASE_READER_SELECT_CLASSIFIER_BY_NAME,
811 : sizeof( DATA_DATABASE_READER_SELECT_CLASSIFIER_BY_NAME ),
812 : &((*this_).statement_classifier_by_name)
813 : );
814 :
815 101 : result |= data_database_prepare_statement( (*this_).database,
816 : DATA_CLASSIFIER_ITERATOR_SELECT_ALL,
817 : DATA_DATABASE_SQL_LENGTH_AUTO_DETECT,
818 : &((*this_).statement_classifiers_all)
819 : );
820 101 : (*this_).statement_classifiers_all_borrowed = false;
821 :
822 101 : result |= data_database_prepare_statement( (*this_).database,
823 : DATA_CLASSIFIER_ITERATOR_SELECT_ALL_HIERARCHICAL,
824 : DATA_DATABASE_SQL_LENGTH_AUTO_DETECT,
825 : &((*this_).statement_classifiers_all_hierarchical)
826 : );
827 101 : (*this_).statement_classifiers_all_hierarchical_borrowed = false;
828 :
829 101 : result |= data_database_prepare_statement( (*this_).database,
830 : DATA_DATABASE_READER_SELECT_FEATURE_BY_ID,
831 : sizeof( DATA_DATABASE_READER_SELECT_FEATURE_BY_ID ),
832 : &((*this_).statement_feature_by_id)
833 : );
834 :
835 101 : result |= data_database_prepare_statement( (*this_).database,
836 : DATA_DATABASE_READER_SELECT_FEATURE_BY_UUID,
837 : sizeof( DATA_DATABASE_READER_SELECT_FEATURE_BY_UUID ),
838 : &((*this_).statement_feature_by_uuid)
839 : );
840 :
841 101 : result |= data_database_prepare_statement( (*this_).database,
842 : DATA_FEATURE_ITERATOR_SELECT_FEATURES_BY_CLASSIFIER_ID,
843 : DATA_DATABASE_SQL_LENGTH_AUTO_DETECT,
844 : &((*this_).statement_features_by_classifier_id)
845 : );
846 101 : (*this_).statement_features_by_classifier_id_borrowed = false;
847 :
848 101 : result |= data_database_prepare_statement( (*this_).database,
849 : DATA_FEATURE_ITERATOR_SELECT_FEATURES_BY_DIAGRAM_ID,
850 : DATA_DATABASE_SQL_LENGTH_AUTO_DETECT,
851 : &((*this_).statement_features_by_diagram_id)
852 : );
853 101 : (*this_).statement_features_by_diagram_id_borrowed = false;
854 :
855 101 : result |= data_database_prepare_statement( (*this_).database,
856 : DATA_DATABASE_READER_SELECT_RELATIONSHIP_BY_ID,
857 : sizeof( DATA_DATABASE_READER_SELECT_RELATIONSHIP_BY_ID ),
858 : &((*this_).statement_relationship_by_id)
859 : );
860 :
861 101 : result |= data_database_prepare_statement( (*this_).database,
862 : DATA_DATABASE_READER_SELECT_RELATIONSHIP_BY_UUID,
863 : sizeof( DATA_DATABASE_READER_SELECT_RELATIONSHIP_BY_UUID ),
864 : &((*this_).statement_relationship_by_uuid)
865 : );
866 :
867 101 : result |= data_database_prepare_statement( (*this_).database,
868 : DATA_RELATIONSHIP_ITERATOR_SELECT_RELATIONSHIPS_BY_CLASSIFIER_ID,
869 : DATA_DATABASE_SQL_LENGTH_AUTO_DETECT,
870 : &((*this_).statement_relationships_by_classifier_id)
871 : );
872 101 : (*this_).statement_relationships_by_classifier_id_borrowed = false;
873 :
874 101 : result |= data_database_prepare_statement( (*this_).database,
875 : DATA_RELATIONSHIP_ITERATOR_SELECT_RELATIONSHIPS_BY_FEATURE_ID,
876 : DATA_DATABASE_SQL_LENGTH_AUTO_DETECT,
877 : &((*this_).statement_relationships_by_feature_id)
878 : );
879 101 : (*this_).statement_relationships_by_feature_id_borrowed = false;
880 :
881 101 : result |= data_database_prepare_statement( (*this_).database,
882 : DATA_RELATIONSHIP_ITERATOR_SELECT_RELATIONSHIPS_BY_DIAGRAM_ID,
883 : DATA_DATABASE_SQL_LENGTH_AUTO_DETECT,
884 : &((*this_).statement_relationships_by_diagram_id)
885 : );
886 101 : (*this_).statement_relationships_by_diagram_id_borrowed = false;
887 :
888 101 : if ( result != U8_ERROR_NONE )
889 : {
890 0 : U8_LOG_ERROR( "A prepared statement could not be prepared." );
891 : }
892 : }
893 :
894 101 : U8_TRACE_END_ERR(result);
895 101 : return result;
896 : }
897 :
898 101 : u8_error_t data_database_classifier_reader_private_close ( data_database_classifier_reader_t *this_ )
899 : {
900 101 : U8_TRACE_BEGIN();
901 101 : u8_error_t result = U8_ERROR_NONE;
902 :
903 : {
904 101 : result |= data_database_finalize_statement( (*this_).database, (*this_).statement_classifier_by_id );
905 101 : (*this_).statement_classifier_by_id = NULL;
906 :
907 101 : result |= data_database_finalize_statement( (*this_).database, (*this_).statement_classifier_by_name );
908 101 : (*this_).statement_classifier_by_name = NULL;
909 :
910 101 : result |= data_database_finalize_statement( (*this_).database, (*this_).statement_classifier_by_uuid );
911 101 : (*this_).statement_classifier_by_uuid = NULL;
912 :
913 101 : assert( (*this_).statement_classifiers_all_borrowed == false );
914 101 : result |= data_database_finalize_statement( (*this_).database, (*this_).statement_classifiers_all );
915 101 : (*this_).statement_classifiers_all = NULL;
916 :
917 101 : assert( (*this_).statement_classifiers_all_hierarchical_borrowed == false );
918 101 : result |= data_database_finalize_statement( (*this_).database, (*this_).statement_classifiers_all_hierarchical );
919 101 : (*this_).statement_classifiers_all_hierarchical = NULL;
920 :
921 101 : result |= data_database_finalize_statement( (*this_).database, (*this_).statement_feature_by_id );
922 101 : (*this_).statement_feature_by_id = NULL;
923 :
924 101 : result |= data_database_finalize_statement( (*this_).database, (*this_).statement_feature_by_uuid );
925 101 : (*this_).statement_feature_by_uuid = NULL;
926 :
927 101 : assert( (*this_).statement_features_by_classifier_id_borrowed == false );
928 101 : result |= data_database_finalize_statement( (*this_).database, (*this_).statement_features_by_classifier_id );
929 101 : (*this_).statement_features_by_classifier_id = NULL;
930 :
931 101 : assert( (*this_).statement_features_by_diagram_id_borrowed == false );
932 101 : result |= data_database_finalize_statement( (*this_).database, (*this_).statement_features_by_diagram_id );
933 101 : (*this_).statement_features_by_diagram_id = NULL;
934 :
935 101 : result |= data_database_finalize_statement( (*this_).database, (*this_).statement_relationship_by_id );
936 101 : (*this_).statement_relationship_by_id = NULL;
937 :
938 101 : result |= data_database_finalize_statement( (*this_).database, (*this_).statement_relationship_by_uuid );
939 101 : (*this_).statement_relationship_by_uuid = NULL;
940 :
941 101 : assert( (*this_).statement_relationships_by_classifier_id_borrowed == false );
942 101 : result |= data_database_finalize_statement( (*this_).database, (*this_).statement_relationships_by_classifier_id );
943 101 : (*this_).statement_relationships_by_classifier_id = NULL;
944 :
945 101 : assert( (*this_).statement_relationships_by_feature_id_borrowed == false );
946 101 : result |= data_database_finalize_statement( (*this_).database, (*this_).statement_relationships_by_feature_id );
947 101 : (*this_).statement_relationships_by_feature_id = NULL;
948 :
949 101 : assert( (*this_).statement_relationships_by_diagram_id_borrowed == false );
950 101 : result |= data_database_finalize_statement( (*this_).database, (*this_).statement_relationships_by_diagram_id );
951 101 : (*this_).statement_relationships_by_diagram_id = NULL;
952 : }
953 :
954 101 : U8_TRACE_END_ERR(result);
955 101 : return result;
956 : }
957 :
958 :
959 : /*
960 : Copyright 2016-2024 Andreas Warnke
961 :
962 : Licensed under the Apache License, Version 2.0 (the "License");
963 : you may not use this file except in compliance with the License.
964 : You may obtain a copy of the License at
965 :
966 : http://www.apache.org/licenses/LICENSE-2.0
967 :
968 : Unless required by applicable law or agreed to in writing, software
969 : distributed under the License is distributed on an "AS IS" BASIS,
970 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
971 : See the License for the specific language governing permissions and
972 : limitations under the License.
973 : */
|