# Migration from 3.x versions to 4.x and 5.x versions

## Overview

Version 4.0 of &LIBGDA; is a major rework of the library for the following benefits:

- easier to understand and to use API, with less strange path usage (which were inherited from modifications above modifications where no global coherence was addressed)

- reduce the size of the library (now 1.3M compared to 1.7M once stripped) and the number of symbols (845 compared to 1420) and have less complicated and thus more maintainable code (190 files compared to 250).

- removal of the GdaClient object from which connections were created: this object did not offer any significant features and made the API more difficult to use

- merge the GdaQuery and GdaCommand into only one object to represent statements

- improve the quantity of information stored in the dictionary and make it easy to include some application-specific data, while at the same time reduce the memory footprint of the dictionary

- rework provider's code to make it more common and provide skeletal implementations to make it easy to write new database providers

- provide more efficient and complete SQL parsing (don't use Lex/Yacc anymore since there can be difficult to track problems when several parsers are used at the same time)

## New unique parser

Previous &LIBGDA; versions had several builtin parsers relying on Lex/Yacc (or Flex/Bison) to analyze SQL with the following limitations:

- not all the SELECT, INSERT, DELETE and UPDATE constructions were recognized

- the parsers were generic and could not be adapted to the different database's SQL dialects

- there were some difficult to track problems when several parsers are used at the same time

All the parsers have been removed in favor of a new parser GdaSqlParser object which can be generic or specific to a database provider if the provider has specified it.

To create a generic GdaSqlParser object, one can use the gda_sql_parser_new() method, and for a parser adapted to a specific database's SQL dialect, use the gda_connection_create_parser() method.

The new parser uses LEMON generated parsers.

## GdaQuery and GdaCommand merge into GdaStatement

Previous &LIBGDA; versions proposed the GdaCommand and GdaQuery objects to execute SQL statements, with different features (GdaCommand was more generic but did not allow parameters bindings while GdaQuery allowed parameters bindings but could not execute some kind of problems)

Both of these objects have been removed and replaced by a new GdaStatement object which combines the features of both GdaCommand and GdaQuery. Most of the time GdaStatement object are created by GdaSqlParser objects. See this object's documentation for more information.

## Dictionary changes

The GdaDict object has been removed and the GdaMetaStore object introduced to replace it, but with slightly different features.

The GdaDict object used an XML file to store its data which imposed parsing potentially big XML files and creating its own internal structures from it (before discarding the XML tree) which was both CPU and memory intensive. Memory was also wasted as most of the time not all the dictionary would be exploited. The new GdaMetaStore object relies on a database (an SQLite file by default) to store its data which solves the problems mentioned above.

It was difficult for applications to add their own data in the dictionary (the API existed but was difficult to understand and use), this has been solved by allowing applications to create DBMS objects into the GdaMetaStore's associated database.

There was a strange relation between a GdaDict object and a GdaConnection object as a connection needed to be assigned to a GdaDict object; this is not the case as now each GdaConnection object builts a GdaMetaStore when it needs it (providers implementations may benefit from it) and the user can provide his own GdaMetaStore object when needed.

## Statement execution

&LIBGDA; still offers several methods to execute a statement, depending on the type of statement to execute (there is still of course the gda_connection_statement_execute() method which works for any type of statement), but the methods have been improved:

- For SELECT statements, it is now possible to specify the way the resulting data model will be accessed (random access or using a cursor) which enables applications to better manage memory consumption.

- For INSERT statements, it is possible to obtain a list of all the values inserted in the table (not only the columns for which a value was specified)

- The execution of a SELECT statement returns a GdaDataSelect data model which can (after having provided some information) be modified using the traditional GdaDataModel's data modification methods (modifications are translated into INSERT, UPDATE or DELETE statements).

## Reports

&LIBGDA;'s reports API has not changed, but the syntax of the XML nodes specific to &LIBGDA; (those nodes are replaced by contents when the report is generated) has changed:

- The parameter name to access a data model's column name by its name is now <query_name>|@<column_name> instead of <query_name>/@<column_name>

- The parameter name to access a data model's column name by its index is now <query_name>|#<column_index> instead of <query_name>/#<column_index>

- The parameter name to access the total number of rows of a data model is now <query_name>|?nrows instead of <query_name>/%nrows

## Other changes

### Multi threading environment

Previous versions of &LIBGDA; only supported being used in a single thread at a time; this new version still keeps this limitation except for objects which implement the GdaLockable interface which can be used from any thread at the same time: the GdaConnection and GdaSqlParser objects implement that interface.

### Configuration management

- Data sources and installed providers are now handled using the GdaConfig object, with the particularity that there can only be one such object instantiated per program.

- The GDA_DSN_LIST_IN_MEMORY environment variable which , if set, prevented &LIBGDA; from writing the list of defined data sources to a file has been removed. To obtain the same result, one must force the creation of the unique GdaConfig object with the user-file property set to NULL.

### Database provider's changes

- BLOB handling in the PostgreSQL provider has changed and is now similar to JDBC and ODBC: the provider does not handle orphaned BLOBs (which is a problem specific to PostgreSQL). See the section about PostgreSQL's limitations for more information.

### API changes

- Connections are now opened using gda_connection_open_from_dsn () or gda_connection_open_from_string () depending on how the connection is defined

- Upon opening a connection, the `username` and `password` arguments have been replaced by a more flexible arguments passing mechanism where providers can specify what authorization parameters they use

- gda_server_provider_get_last_insert_id() has been removed in favor of the "last_insert_row" argument of the gda_connection_statement_execute () and gda_connection_statement_execute_non_select () methods. If that argument is not NULL, then if the statement is an INSERT statement, the argument will contain a list of values, one for each column of the modified table.

- The GdaServerProviderInfo structure has been removed as it was useless, and the gda_server_provider_get_info() has been replaced by a gda_server_provider_get_name () method to access the provider's name.

- gda_data_model_get_value_at () now has an extra GError argument to return an error if getting the value has failed

- gda_data_model_get_column_index_by_name() has been replaced by gda_data_model_get_column_index()

- gda_data_model_get_value_at_col_name() has been replaced by gda_data_model_get_value_at_column()

### List of removed objects and interfaces

- GdaClient

- GdaRenderer, GdaXmlStorage, GdaEntity, GdaEntityField and GdaReferer interfaces

- GdaDict, GdaDictType, GdaDictDatabase, GdaDictTable, GdaDictAggregate, GdaDictField, GdaDictConstraint and GdaDictFunction dictionary related objects

- GdaQuery, GdaQueryObject, GdaQueryFieldAgg, GdaQueryFieldAll, GdaQueryCondition, GdaQueryJoin, GdaQueryFieldField, GdaQueryTarget, GdaQueryFieldFunc, GdaQueryFieldValue and GdaQueryField query related objects

- GdaCommand

- GdaParameterList (replaced by GdaSet), GdaParameter (replaced by GdaHolder)

- GdaObject, GdaObjectRef

- GdaDataModelFilterSQL

- GdaGraph, GdaGraphItem, GdaGraphQuery

- GdaGraphviz

- GdaDataModelQuery (features redundant with the GdaDataSelect object)

### List of removed functions

- gda_delimiter_*()

- gda_sql_transaction_parse*()

- sql_*() (from the libsql library)

- gda_server_provider_change_database()

- gda_value_compare_ext()

- gda_data_access_wrapper_row_exists()