LCOV - code coverage report
Current view: top level - data/source/storage - data_classifier_iterator.c (source / functions) Coverage Total Hit
Test: crystal-facet-uml_v1.63.2_covts Lines: 93.8 % 65 61
Test Date: 2025-05-01 10:10:14 Functions: 100.0 % 6 6

            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-2025 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              : */
        

Generated by: LCOV version 2.0-1