# Limitations

## Global limitations

&LIBGDA;'s global limitations are:

### Multi threaded environment

&LIBGDA; is not thread safe. However it supports working with threads as long as any object (except otherwise stated) created by the API is used by one single thread (that is there is no situation when two threads try to access the same object at the same time). Exceptions are:

- &LIBGDA;'s configuration can be accessed from any thread

- Any object which implements the GdaLockable interface can be accessed from any thread. However one can use the gda_lockable_lock() method to specifically lock an object's usage (especially when getting and setting properties before or after calling methods).

- Any GdaConnection object can be accessed from any thread (that object implements the GdaLockable interface). Also some database providers may impose other limitations (inherited from the database's specific client APIs) such as only one thread can use the connection object, or even that only one thread can use the database provider.

- Any GdaAttributesManager can safely be accessed from any thread.

Note that multi threading support is still at an early stage and may contain bugs

## For MySQL

### Multi threaded environment

If MySQL client was not compiled with the `--enable-thread-safe-client` flag, then the database provider will only allow connections to be opened from the thread which initializes &LIBGDA;. Otherwise there is no limitation.

### Statements execution

- It is not possible to execute a SELECT statement with invalid parameters and with the GDA_STATEMENT_MODEL_ALLOW_NOPARAM flag as this feature is currently not implemented.

### Timezone information

Timezone information associated with time and timestamp data types is not stored by MySQL, so when executing statements all the variables containing a time or timestamp information are converted to GMT (timezone 0) before the execution happens. The consequence is that for example if a variable holds the "11:23:55+2" time (11 hours, 23 minutes and 55 seconds, at GMT + 2), then the actual time stored in the database will be "09:23:55", the same time but GMT.

## For Oracle

The following limitations apply to Oracle databases accessed via Libgda:

- At the moment tables' fields schema information retrieval is very slow, so as a work around, use a dictionary to store the database schema and do incremental updates on modified/created tables.

## For PostgreSQL

The following limitations apply to PostgreSQL databases accessed via Libgda:

### BLOB handling

- Postgres uses the "Oid" data type to internally store BLOBs, but this type is also used to store other information within the database. Libgda assumes that any column of type "Oid" represents a blob. If this is not the case, then you must cast it to the correct data type within your SQL query (for example as "SELECT oid::varchar FROM...")

- &LIBGDA; does not try to avoid orphaned BLOBs, to solve the problem of orphaned BLOBs, set up the "lo" extension from PostgreSQL's contrib, and/or use the "vacuumlo" also from the contrib.

  Note that in the future the PostgreSQL's provider will have an option to ensure that there are no orphaned BLOBs itself.

- BLOB manipulations can only occur within a transaction, so you should start a transaction before any operation on BLOBs, otherwise Libgda will automatically start one

### Last inserted row's values

The gda_connection_statement_execute_non_select()'s last_insert_row parameter will return a new GdaSet object only if the table has OIDs (to ensure this, the "WITH OIDS" option should be added at the end of a CREATE TABLE query).

### Multi threaded environment

If PostgreSQL was not compiled with the `--enable-thread-safety` flag, then the database provider will only allow connections to be opened from the thread which initializes &LIBGDA;. Otherwise there is no limitation.

### Statements execution

- It is not possible to execute a SELECT statement with invalid parameters and with the GDA_STATEMENT_MODEL_ALLOW_NOPARAM flag if the GDA_STATEMENT_MODEL_CURSOR_FORWARD flag is also specified

### Timezone information

Timezone information associated with time and timestamp data types is not stored by PostgreSQL, so when executing statements all the variables containing a time or timestamp information are converted to GMT (timezone 0) before the execution happens. The consequence is that for example if a variable holds the "11:23:55+2" time (11 hours, 23 minutes and 55 seconds, at GMT + 2), then the actual time stored in the database will be "09:23:55", the same time but GMT.

## For SQLite

The following limitations apply to SQLite databases accessed via Libgda:

### Last inserted row's values

The gda_connection_statement_execute_non_select()'s last_insert_row attribute uses the hidden "_ROWID_" column for each table, but it may fail if the table has a column with the same name.

### Date and time

As SQLite stores dates and times as strings, &LIBGDA; only handles dates in the format recommended by SQLite, which is "YYYY-MM-DD" for dates, "HH:MM:SS" for times and "YYYY-MM-DD HH:MM:SS" for timestamps (see SQLite's documentation).

### Timezone information

Timezone information associated with time and timestamp data types is not stored by PostgreSQL, so when executing statements all the variables containing a time or timestamp information are converted to GMT (timezone 0) before the execution happens. The consequence is that for example if a variable holds the "11:23:55+2" time (11 hours, 23 minutes and 55 seconds, at GMT + 2), then the actual time stored in the database will be "09:23:55", the same time but GMT.

### Multi threaded environment

No limitation if sqlite has been compiled with the SQLITE_THREADSAFE=1 flag (which is the case for the embedded version of SQLite). If the system installed SQLite is used and if it was not compiled using that flag, then &LIBGDA; sets the SQLite library in a state where multi threading is fully supported.

### Error reporting

If there is not enough free space on the disk which stores an SQLite database, you may have some "Disk I/O error" errors. This is also true for meta data connections which are by default created in a temporary location.

## For SQLCipher

The following limitations apply to SQLite database accessed through the SQLCipher database provider. The SQLCipher database provider allows one to connect to a database encrypted using the SQLCipher adaptations to the SQLite database.

The SQLite provider's limitations also apply in this context and it is also currently not possible to uncrypt an encrypted database.

## For LDAP

### User name

LDAP requires a Distinguished Name (DN) to bind a connection. Libgda also accepts a user name which is not a DN; in this case it will first connect anonymously to the server, search for the DN corresponding to the user name, and then bind again using the found DN. The search is done on the "uid" attribute matching the username, and the object class being "inetOrgPerson" (the LDAP filter is "(&(uid=?)(objectclass=inetOrgPerson))" where the question mark is replaced by the username).

### SSL/TLS certificate validation

The TLS_REQCERT and TLS_CACERT options are taken into account by the LDAP provider, and passed to the OpenLDAP library which is actually used. These options are global and set by the first opened LDAP connection (i.e. all other LDAP connections share the same settings, regardless of their TLS_REQCERT and TLS_CACERT options).

The TLS_REQCERT and TLS_CACERT options have a higher priority compared to the options set in the `$HOME/.ldaprc`.

If the server certificate can't he checked (i.e. the certification chain established and verified) when it is required that it be, then the connection will not he established and the returned error will be "Can't contact LDAP server".

## For JDBC based providers

The following limitations apply to databases accessed via Libgda through a JDBC driver. When loading the database providers, &LIBGDA; creates a JDBC provider per JDBC driver found (to work at all it needs to load the Java Virtual Machine (JVM) runtime first).

### Last inserted row's values

Not yet supported.

### Multi threaded environment

No specific limitation.