File: abstraction.xml

package info (click to toggle)
libgda5 5.2.10-8
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 76,168 kB
  • sloc: ansic: 495,319; xml: 10,486; yacc: 5,165; sh: 4,451; makefile: 4,095; php: 1,416; java: 1,300; javascript: 1,298; python: 896; sql: 879; perl: 116
file content (124 lines) | stat: -rw-r--r-- 6,670 bytes parent folder | download | duplicates (6)
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>$&lt;number&gt;</code>, <code>:&lt;name&gt;</code>, <code>?&lt;number&gt;</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>