1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252
|
<?xml version="1.0"?>
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd"[
<!ENTITY LIBGDA "<application>Libgda</application>">
]>
<chapter id="limitations">
<title>Limitations</title>
<sect1 id="limitations_global"><title>Global limitations</title>
<para>
&LIBGDA;'s global limitations are:
<sect2 id="threads"><title>Multi threaded environment</title>
<para>&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:
<itemizedlist>
<listitem><para>&LIBGDA;'s <link linkend="init_config">configuration</link> can be accessed from any thread</para></listitem>
<listitem><para>Any object which implements the <link linkend="GdaLockable">GdaLockable</link> interface
can be accessed from any thread. However
one can use the <link linkend="gda-lockable-lock">gda_lockable_lock()</link> method to specifically
lock an object's usage (especially when getting and
setting properties before or after calling methods).</para></listitem>
<listitem><para>Any <link linkend="GdaConnection">GdaConnection</link> object can be accessed from any thread
(that object implements the <link linkend="GdaLockable">GdaLockable</link> 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.</para></listitem>
<listitem><para>Any <link linkend="GdaAttributesManager">GdaAttributesManager</link> can safely be accessed from
any thread.</para></listitem>
</itemizedlist>
</para>
<para>Note that multi threading support is still at an early stage and may contain bugs</para>
</sect2>
</para>
</sect1>
<sect1 id="limitations_mysql"><title>For MySQL</title>
<sect2><title>Multi threaded environment</title>
<para>
If MySQL client was not compiled with the <option>--enable-thread-safe-client</option> flag,
then the database provider will only allow
connections to be opened from the thread which initializes &LIBGDA;. Otherwise there is no limitation.
</para>
</sect2>
<sect2><title>Statements execution</title>
<para>
<itemizedlist>
<listitem><para>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.
</para></listitem>
</itemizedlist>
</para>
</sect2>
<sect2>
<title>Timezone information</title>
<para>
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.
</para>
</sect2>
</sect1>
<sect1 id="limitations_oracle"><title>For Oracle</title>
<para>
The following limitations apply to Oracle databases accessed via Libgda:
<itemizedlist>
<listitem><para>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.</para></listitem>
</itemizedlist>
</para>
</sect1>
<sect1 id="limitations_postgres"><title>For PostgreSQL</title>
<para>
The following limitations apply to PostgreSQL databases accessed via Libgda:
</para>
<sect2><title>BLOB handling</title>
<para>
<itemizedlist>
<listitem><para>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...")</para></listitem>
<listitem><para>&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.</para>
<para>Note that in the future the PostgreSQL's provider will have an option to ensure that there are no
orphaned BLOBs itself.</para></listitem>
<listitem><para>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</para></listitem>
</itemizedlist>
</para>
</sect2>
<sect2><title>Last inserted row's values</title>
<para>
The <link linkend="gda-connection-statement-execute-non-select">gda_connection_statement_execute_non_select()</link>'s
last_insert_row parameter will return a new <link linkend="GdaSet">GdaSet</link> 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).
</para>
</sect2>
<sect2><title>Multi threaded environment</title>
<para>
If PostgreSQL was not compiled with the <option>--enable-thread-safety</option> flag,
then the database provider will only allow
connections to be opened from the thread which initializes &LIBGDA;. Otherwise there is no limitation.
</para>
</sect2>
<sect2><title>Statements execution</title>
<para>
<itemizedlist>
<listitem><para>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</para></listitem>
</itemizedlist>
</para>
</sect2>
<sect2>
<title>Timezone information</title>
<para>
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.
</para>
</sect2>
</sect1>
<sect1 id="limitations_sqlite"><title>For SQLite</title>
<para>
The following limitations apply to SQLite databases accessed via Libgda:
</para>
<sect2><title>Last inserted row's values</title>
<para>
The <link linkend="gda-connection-statement-execute-non-select">gda_connection_statement_execute_non_select()</link>'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.
</para>
</sect2>
<sect2><title>Date and time</title>
<para>
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
<ulink url="http://www.sqlite.org/cvstrac/wiki?p=DateAndTimeFunctions">SQLite's documentation</ulink>).
</para>
</sect2>
<sect2>
<title>Timezone information</title>
<para>
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.
</para>
</sect2>
<sect2><title>Multi threaded environment</title>
<para>
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.
</para>
</sect2>
<sect2><title>Error reporting</title>
<para>
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.
</para>
</sect2>
</sect1>
<sect1 id="limitations_sqlcipher"><title>For SQLCipher</title>
<para>
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
<ulink url="http://www.zetetic.net/code/sqlcipher">SQLCipher</ulink> adaptations to the SQLite
database.
</para>
<para>
The <link linkend="limitations_sqlite">SQLite provider's limitations</link> also apply in this context
and it is also currently not possible to uncrypt an encrypted database.
</para>
</sect1>
<sect1 id="limitations_ldap">
<title>For LDAP</title>
<sect2>
<title>User name</title>
<para>
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).
</para>
</sect2>
<sect2>
<title>SSL/TLS certificate validation</title>
<para>
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).
</para>
<para>
The TLS_REQCERT and TLS_CACERT options have a higher priority compared to the
options set in the <filename>$HOME/.ldaprc</filename>.
</para>
<para>
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".
</para>
</sect2>
</sect1>
<sect1 id="limitations_jdbc"><title>For JDBC based providers</title>
<para>
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).
</para>
<sect2><title>Last inserted row's values</title>
<para>
Not yet supported.
</para>
</sect2>
<sect2><title>Multi threaded environment</title>
<para>
No specific limitation.
</para>
</sect2>
</sect1>
</chapter>
|