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
|
<?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>
<title>Foreword about abstraction</title>
<para>
&LIBGDA; aims both at making it easier to use databases and, for applications written using it,
at making it easier to switch to a different database or to to be able to use different types of databases
with a minimum or no code modifications. To achieve the 2nd goal, &LIBGDA; proposes an abstraction of
most of database's engine features, which has to be understood to write portable code.
</para>
<sect1 id="placeholders">
<title>Variables syntax in SQL</title>
<para>
Each database engine has its own way of specifying variables (i.e. place holders) in SQL code (for example:
<code>$<number></code>, <code>:<name></code>, <code>?<number></code>, or <code>?</code>).
&LIBGDA; has specified yet another format for variables which can be used with all the databases and which
has the following advantages:
<itemizedlist>
<listitem><para>allow to specify a name (and optionally a description)</para></listitem>
<listitem><para>allow to specify a type, see <link linkend="gda-g-type-from-string">gda_g_type_from_string()</link></para></listitem>
<listitem><para>allow to specify if the variable can be NULL</para></listitem>
</itemizedlist>
</para>
<para>For more information, refer to the <link linkend="GdaSqlParser.description">GdaSqlParser object's documentation</link></para>
</sect1>
<sect1 id="null_handling">
<title>NULL handling when using variables</title>
<para>
When using variables in statements (see <link linkend="placeholders">Variables syntax in SQL</link>)
for example like <programlisting>SELECT * FROM users WHERE name = ##name::string::null;</programlisting>,
database engines will generally not handle correctly the case where a variable is valued to NULL. For instance
this example would result in the code being executed as <programlisting>SELECT * FROM users WHERE name = NULL;</programlisting> which would probably give no result, whereas the expected equivalent code would be
<programlisting>SELECT * FROM users WHERE name IS NULL;</programlisting>
</para>
<para>
&LIBGDA; automatically handles theses cases and makes sure the <code>IS NULL</code> or <code>IS NOT NULL</code>
constructions are used when necessary. It won't of course handle variable's NULL values when using other
operators that equal or different, tough.
</para>
</sect1>
<sect1 id="gen_sql_identifiers">
<title>SQL identifiers</title>
<para>
The SQL standard has never defined if SQL identifiers (database object's names) have to be case sensitive
or not, leaving that
subject to each database engine implementation. All of them accept two syntaxes for SQL identifiers:
<itemizedlist>
<listitem><para>the first is if the SQL identifier is surrounded by double quotes (sometimes backquotes
or other characters), usually making the SQL identifier case sensitive (and also making
it possible to use reserved SQL keywords as identifiers).</para></listitem>
<listitem><para>the second is if it's not enquoted, usually meaning that the SQL identifier is not
case sensitive.</para></listitem>
</itemizedlist>
<note>
<para>Sometimes those rules don't apply or apply only partially. For example a MySQL server, depending
on how it is configured and on what kind of OS it is running on, will have different sets of meanings
for these notations.
</para>
</note>
</para>
<para>
As a result, &LIBGDA; has to be the least intrusive possible when the user wants to execute an SQL statement,
and lets the database being accessed apply its own rules. However &LIBGDA; features meta data information
retrieval (getting the list of tables, views,...) and there some representation conventions have been fixed,
see the <link linkend="information_schema:sql_identifiers">meta data section about SQL identifiers</link>
for more information.
</para>
<para>
The following diagram illustrates how &LIBGDA; handles SQL identifiers' representations depending where
they are used:
<mediaobject>
<imageobject role="html">
<imagedata fileref="SqlIdentifiers.png" format="PNG"/>
</imageobject>
<textobject>
<phrase>Diagram illustrating how &LIBGDA; handles SQL identifiers' representations</phrase>
</textobject>
</mediaobject>
</para>
</sect1>
<sect1 id="gen_blobs">
<title>Binary large objects (BLOBs)</title>
<para>
Binary large objects (BLOBs) are potentially very big (several GigaBytes) pieces of binary
data which databases can store. Because of their potential size, they are not manipulated
like any other data, and are usually not transfered to the database engine at the same time
as the SQL text is transfered: first
a reference to a blob is created for an existing or a new blob, and then
that reference is used, <emphasis>before or after the statement is being executed,
depending on the database engine accessed</emphasis>, to get or set some parts of the blob.
</para>
<para>
&LIBGDA; makes its best to hide the complexity of this and most of the time blobs can be used
like any other type of values with the following limitations:
<itemizedlist>
<listitem><para>When getting a blob through a SELECT statement, a transaction will automatically
be started if it's not already started, and usually the transaction (implicitly or explicitly)
will be locked untill all the ressources associated to the fetched blobs are liberated (by
calling <link linkend="g-object-unref">g_object_unref()</link> on the model).</para></listitem>
<listitem><para>When fetching a blob value (using
<link linkend="gda-data-model-get-value-at()">gda_data_model_get_value_at()</link> for example), the blob
itself is not fetched, only a reference to the blob is fetched, and one has to use the
<link linkend="GdaBlobOp">GdaBlobOp</link> object embedded in a blob value to get the blob's
contents.</para></listitem>
</itemizedlist>
</para>
<para>
Please consult each database provider's <link linkend="provider-notes">notes</link> and
<link linkend="limitations">limitations</link> for database specific rules
regarding BLOBs. Also have a look at the
<link linkend="blobs_example">Blobs manipulation source code example</link>.
</para>
</sect1>
</chapter>
|