Merge branch 'master' of git://github.com/openemr/openemr
[openemr.git] / library / adodb / docs-datadict.htm
blobaa795c0e76d13d923c53dc27b0e8fdad01fd0a47
1 <html>
2 <head>
3 <title>ADODB Data Dictionary Manual</title>
4 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
5 <style type="text/css">
6 body, td {
7 /*font-family: Arial, Helvetica, sans-serif;*/
8 font-size: 11pt;
10 pre {
11 font-size: 9pt;
13 .toplink {
14 font-size: 8pt;
16 </style>
17 </head>
18 <body bgcolor="#FFFFFF">
20 <h2>ADOdb Data Dictionary Library for PHP</h2>
21 <p>V4.20 22 Feb 2004 (c) 2000-2004 John Lim (<a href="mailto:jlim#natsoft.com.my">jlim#natsoft.com.my</a>).<br> AXMLS (c) 2004 ars Cognita, Inc</p>
22 <p><font size="1">This software is dual licensed using BSD-Style and LGPL. This means you can use it in compiled proprietary and commercial products.</font></p>
23 <p>Useful ADOdb links: <a href=http://php.weblogs.com/adodb?dd=1>Download</a> &nbsp; <a href=http://php.weblogs.com/adodb_manual?dd=1>Other Docs</a></p>
25 <p>This documentation describes a PHP class library to automate the creation of tables,
26 indexes and foreign key constraints portably for multiple databases. Richard Tango-Lowy and Dan Cech
27 have been kind enough to contribute <a href=#xmlschema>AXMLS</a>, an XML schema system for defining databases.</p>
29 <p>Currently the following databases are supported:</p>
30 <p>
31 <b>Well-tested:</b> PostgreSQL, MySQL, Oracle, MSSQL.<br />
32 <b>Beta-quality:</b> DB2, Informix, Sybase, Interbase, Firebird.<br />
33 <b>Alpha-quality:</b> MS Access (does not support DEFAULT values) and generic ODBC.
34 </p>
36 <h3>Example Usage</h3>
37 <pre>
38 include_once('adodb.inc.php');
39 <font color="#006600"># First create a normal connection</font>
40 $db->NewADOConnection('mysql');
41 $db->Connect(...);
43 <font color="#006600"># Then create a data dictionary object, using this connection</font>
44 $dict = <strong>NewDataDictionary</strong>($db);
46 <font color="#006600"># We have a portable declarative data dictionary format in ADOdb, similar to SQL.
47 # Field types use 1 character codes, and fields are separated by commas.
48 # The following example creates three fields: "col1", "col2" and "col3":</font>
49 $flds = "
50 <font color="#663300"><strong> col1 C(32) NOTNULL DEFAULT 'abc',
51 col2 I DEFAULT 0,
52 col3 N(12.2)</strong></font>
55 <font color="#006600"># We demonstrate creating tables and indexes</font>
56 $sqlarray = $dict-><strong>CreateTableSQL</strong>($tabname, $flds, $taboptarray);
57 $dict-><strong>ExecuteSQLArray</strong>($sqlarray);<br>
58 $idxflds = 'co11, col2';
59 $sqlarray = $dict-><strong>CreateIndexSQL</strong>($idxname, $tabname, $idxflds);
60 $dict-><strong>ExecuteSQLArray</strong>($sqlarray);
61 </pre>
63 <h3>Functions</h3>
65 <h4>function CreateDatabase($dbname, $optionsarray=false)</h4>
66 <p>Create a database with the name $dbname;</p>
68 <h4>function CreateTableSQL($tabname, $fldarray, $taboptarray=false)</h4>
69 <pre>
70 RETURNS: an array of strings, the sql to be executed, or false
71 $tabname: name of table
72 $fldarray: string (or array) containing field info
73 $taboptarray: array containing table options
74 </pre>
75 <p>The new format of $fldarray uses a free text format, where each field is comma-delimited.
76 The first token for each field is the field name, followed by the type and optional
77 field size. Then optional keywords in $otheroptions:</p>
78 <pre> "$fieldname $type $colsize $otheroptions"</pre>
79 <p>The older (and still supported) format of $fldarray is a 2-dimensional array, where each row in the 1st dimension represents one field. Each row has this format:</p>
80 <pre> array($fieldname, $type, [,$colsize] [,$otheroptions]*)</pre>
82 <p>The first 2 fields must be the field name and the field type. The field type can be a portable type codes or the actual type for that database.</p>
83 <p>Legal portable type codes include:</p>
84 <pre>
85 C: varchar
86 X: Largest varchar size
87 XL: For Oracle, returns CLOB, otherwise same as 'X' above
89 C2: Multibyte varchar
90 X2: Multibyte varchar (largest size)
92 B: BLOB (binary large object)
94 D: Date (some databases do not support this, and we return a datetime type)
95 T: Datetime or Timestamp
96 L: Integer field suitable for storing booleans (0 or 1)
97 I: Integer (mapped to I4)
98 I1: 1-byte integer
99 I2: 2-byte integer
100 I4: 4-byte integer
101 I8: 8-byte integer
102 F: Floating point number
103 N: Numeric or decimal number
104 </pre>
105 <p>The $colsize field represents the size of the field. If a decimal number is used, then it is assumed that the number following the dot is the precision, so 6.2 means a number of size 6 digits and 2 decimal places. It is recommended that the default for number types be represented as a string to avoid any rounding errors.</p>
106 <p>The $otheroptions include the following keywords (case-insensitive):</p>
107 <pre>
108 AUTO For autoincrement number. Emulated with triggers if not available.
109 Sets NOTNULL also.
110 AUTOINCREMENT Same as auto.
111 KEY Primary key field. Sets NOTNULL also. Compound keys are supported.
112 PRIMARY Same as KEY.
113 DEF Synonym for DEFAULT for lazy typists.
114 DEFAULT The default value. Character strings are auto-quoted unless
115 the string begins and ends with spaces, eg ' SYSDATE '.
116 NOTNULL If field is not null.
117 DEFDATE Set default value to call function to get today's date.
118 DEFTIMESTAMP Set default to call function to get today's datetime.
119 NOQUOTE Prevents autoquoting of default string values.
120 CONSTRAINTS Additional constraints defined at the end of the field
121 definition.
122 </pre>
123 <p>The Data Dictonary accepts two formats, the older array specification:</p>
124 <pre>
125 $flds = array(
126 array('COLNAME', 'DECIMAL', '8.4', 'DEFAULT' => 0, 'NOTNULL'),
127 array('id', 'I' , 'AUTO'),
128 array('`MY DATE`', 'D' , 'DEFDATE'),
129 array('NAME', 'C' , '32', 'CONSTRAINTS' => 'FOREIGN KEY REFERENCES reftable')
131 </pre>
132 <p>Or the simpler declarative format:</p>
133 <pre>
134 $flds = "<font color="#660000"><strong>
135 COLNAME DECIMAL(8.4) DEFAULT 0 NOTNULL,
136 id I AUTO,
137 `MY DATE` D DEFDATE,
138 NAME C(32) CONSTRAINTS 'FOREIGN KEY REFERENCES reftable'</strong></font>
140 </pre>
141 <p>Note that if you have special characters in the field name (e.g. My Date), you should enclose it in back-quotes. Normally field names are not case-sensitive, but if you enclose it in back-quotes, some databases treat the names as case-sensitive, and some don't. So be careful.</p>
143 <p>The $taboptarray is the 3rd parameter of the CreateTableSQL function. This contains table specific settings. Legal keywords include:</p>
144 <ul>
145 <li><b>REPLACE</b><br />
146 Indicates that the previous table definition should be removed (dropped)together with ALL data. See first example below.
147 </li>
148 <li><b>DROP</b><br />
149 Drop table. Useful for removing unused tables.
150 </li>
151 <li><b>CONSTRAINTS</b><br />
152 Define this as the key, with the constraint as the value. See the postgresql example below.
153 Additional constraints defined for the whole table. You will probably need to prefix this with a comma.
154 </li>
155 </ul>
157 <p>Database specific table options can be defined also using the name of the database type as the array key. In the following example, <em>create the table as ISAM with MySQL, and store the table in the &quot;users&quot; tablespace if using Oracle</em>. And because we specified REPLACE, drop the table first.</p>
158 <pre> $taboptarray = array('mysql' => 'TYPE=ISAM', 'oci8' => 'tablespace users', 'REPLACE');</pre>
160 <p>You can also define foreignkey constraints. The following is syntax for postgresql:
161 <pre> $taboptarray = array('constraints' => ', FOREIGN KEY (col1) REFERENCES reftable (refcol)');</pre>
163 <h4>function DropTableSQL($tabname)</h4>
164 <p>Returns the SQL to drop the specified table.</p>
166 <h4>function ChangeTableSQL($tabname, $flds)</h4>
167 <p>Checks to see if table exists, if table does not exist, behaves like CreateTableSQL.
168 If table exists, generates appropriate ALTER TABLE MODIFY COLUMN commands if
169 field already exists, or ALTER TABLE ADD $column if field does not exist.</p>
170 <p>The class must be connected to the database for ChangeTableSQL to detect the
171 existence of the table. Idea and code contributed by Florian Buzin.</p>
173 <h4>function CreateIndexSQL($idxname, $tabname, $flds, $idxoptarray=false)</h4>
174 <pre>
175 RETURNS: an array of strings, the sql to be executed, or false
176 $idxname: name of index
177 $tabname: name of table
178 $flds: list of fields as a comma delimited string or an array of strings
179 $idxoptarray: array of index creation options
180 </pre>
181 <p>$idxoptarray is similar to $taboptarray in that index specific information can be embedded in the array. Other options include:</p>
182 <pre>
183 CLUSTERED Create clustered index (only mssql)
184 BITMAP Create bitmap index (only oci8)
185 UNIQUE Make unique index
186 FULLTEXT Make fulltext index (only mysql)
187 HASH Create hash index (only postgres)
188 DROP Drop legacy index
189 </pre>
191 <h4>function DropIndexSQL ($idxname, $tabname = NULL)</h4>
192 <p>Returns the SQL to drop the specified index.</p>
194 <h4>function AddColumnSQL($tabname, $flds)</h4>
195 <p>Add one or more columns. Not guaranteed to work under all situations.</p>
197 <h4>function AlterColumnSQL($tabname, $flds)</h4>
198 <p>Warning, not all databases support this feature.</p>
200 <h4>function DropColumnSQL($tabname, $flds)</h4>
201 <p>Drop 1 or more columns.</p>
203 <h4>function SetSchema($schema)</h4>
204 <p>Set the schema.</p>
206 <h4>function &amp;MetaTables()</h4>
207 <h4>function &amp;MetaColumns($tab, $upper=true, $schema=false)</h4>
208 <h4>function &amp;MetaPrimaryKeys($tab,$owner=false,$intkey=false)</h4>
209 <h4>function &amp;MetaIndexes($table, $primary = false, $owner = false)</h4>
210 <p>These functions are wrappers for the corresponding functions in the connection object. However, the table names will be autoquoted by the TableName function (see below) before being passed to the connection object.</p>
212 <h4>function NameQuote($name = NULL)</h4>
213 <p>If the provided name is quoted with backquotes (`) or contains special characters, returns the name quoted with the appropriate quote character, otherwise the name is returned unchanged.</p>
215 <h4>function TableName($name)</h4>
216 <p>The same as NameQuote, but will prepend the current schema if specified</p>
218 <h4>function MetaType($t,$len=-1,$fieldobj=false)</h4>
219 <h4>function ActualType($meta)</h4>
220 <p>Convert between database-independent 'Meta' and database-specific 'Actual' type codes.</p>
222 <h4>function ExecuteSQLArray($sqlarray, $contOnError = true)</h4>
223 <pre>
224 RETURNS: 0 if failed, 1 if executed all but with errors, 2 if executed successfully
225 $sqlarray: an array of strings with sql code (no semicolon at the end of string)
226 $contOnError: if true, then continue executing even if error occurs
227 </pre>
228 <p>Executes an array of SQL strings returned by CreateTableSQL or CreateIndexSQL.</p>
230 <hr />
232 <a name=xmlschema></a>
233 <h2>ADOdb XML Schema (AXMLS)</h2>
234 <p>This is a class contributed by Richard Tango-Lowy and Dan Cech that allows the user to quickly
235 and easily build a database using the excellent ADODB database library and a simple XML formatted file.
236 You can <a href=http://sourceforge.net/projects/adodb-xmlschema/>download the latest version of AXMLS here</a>.</p>
238 <h3>Quick Start</h3>
239 <p>First, create an XML database schema. Let's call it "schema.xml:"</p>
240 <pre>
241 &lt;?xml version="1.0"?&gt;
242 &lt;schema version=&quot;0.2&quot;&gt;
243 &lt;table name="mytable"&gt;
244 &lt;field name="row1" type="I"&gt;
245 &lt;descr&gt;An integer row that's a primary key and autoincrements&lt;/descr&gt;
246 &lt;KEY/&gt;
247 &lt;AUTOINCREMENT/&gt;
248 &lt;/field&gt;
249 &lt;field name="row2" type="C" size="16"&gt;
250 &lt;descr&gt;A 16 character varchar row that can't be null&lt;/descr&gt;
251 &lt;NOTNULL/&gt;
252 &lt;/field&gt;
253 &lt;index name=&quot;myindex&quot;&gt;
254 &lt;col&gt;row1&lt;/col&gt;
255 &lt;col&gt;row2&lt;/col&gt;
256 &lt;/index&gt;
257 &lt;/table&gt;
258 &lt;sql&gt;
259 &lt;descr&gt;SQL to be executed only on specific platforms&lt;/descr&gt;
260 &lt;query platform="postgres|postgres7"&gt;
261 insert into mytable ( row1, row2 ) values ( 12, 'stuff' )
262 &lt;/query&gt;
263 &lt;query platform="mysql"&gt;
264 insert into mytable ( row1, row2 ) values ( 12, 'different stuff' )
265 &lt;/query&gt;
266 &lt;/sql&gt;
267 &lt;/schema&gt;
268 </pre>
270 <p>Create a new database using the appropriate tool for your platform.<br />
271 Executing the following PHP code will create the a <i>mytable</i> and <i>myindex</i>
272 in the database and insert one row into <i>mytable</i> if the platform is postgres or mysql.</p>
274 <pre>
275 include_once('/path/to/adodb.inc.php');
276 include_once('/path/to/adodb-xmlschema.inc.php');
278 <font color="#006600">// To build the schema, start by creating a normal ADOdb connection:</font>
279 $db->NewADOConnection( 'mysql' );
280 $db->Connect( ... );
282 <font color="#006600">// Create the schema object and build the query array.</font>
283 $schema = new <b>adoSchema</b>( $db );
285 <font color="#006600">// Optionally, set a prefix for newly-created tables. In this example
286 // the prefix "myprefix_" will result in a table named "myprefix_tablename".</font>
287 $schema-><b>SetPrefix</b>( 'myprefix_' );
289 <font color="#006600">// Build the SQL array</font>
290 $schema-><b>ParseSchema</b>( 'schema.xml' );
292 <font color="#006600">// Execute the SQL on the database</font>
293 $result = $schema-><b>ExecuteSchema</b>();
295 <font color="#006600">// Finally, clean up after the XML parser
296 // (PHP won't do this for you!)</font>
297 $schema-><b>Destroy</b>();
298 </pre>
301 <h3>Using AXMLS in Your
302 Application</h3>
305 There are two steps involved in using
306 AXMLS in your application: first,
307 you must create a schema, or XML representation of your
308 database, and second, you must create the PHP code that will
309 parse and execute the schema.</p>
310 <p>Let's begin with a schema that describes a typical, if simplistic
311 user management table for an application.</p>
312 <pre class="listing"><pre>
313 &lt;?xml version=&quot;1.0&quot;?&gt;
314 &lt;schema version=&quot;0.2&quot;&gt;
316 &lt;table name=&quot;users&quot;&gt;
317 &lt;desc&gt;A typical users table for our application.&lt;/desc&gt;
318 &lt;field name=&quot;userId&quot; type=&quot;I&quot;&gt;
319 &lt;descr&gt;A unique ID assigned to each user.&lt;/descr&gt;
320 &lt;KEY/&gt;
321 &lt;AUTOINCREMENT/&gt;
322 &lt;/field&gt;
324 &lt;field name=&quot;userName&quot; type=&quot;C&quot; size=&quot;16&quot;&gt;&lt;NOTNULL/&gt;&lt;/field&gt;
326 &lt;index name=&quot;userName&quot;&gt;
327 &lt;descr&gt;Put a unique index on the user name&lt;/descr&gt;
328 &lt;col&gt;userName&lt;/col&gt;
329 &lt;UNIQUE/&gt;
330 &lt;/index&gt;
331 &lt;/table&gt;
333 &lt;sql&gt;
334 &lt;descr&gt;Insert some data into the users table.&lt;/descr&gt;
335 &lt;query&gt;insert into users (userName) values ( 'admin' )&lt;/query&gt;
336 &lt;query&gt;insert into users (userName) values ( 'Joe' )&lt;/query&gt;
337 &lt;/sql&gt;
338 &lt;/schema&gt;
339 </pre></pre>
340 <p>Let's take a detailed look at this schema.</p>
341 <p>The opening &lt;?xml version=&quot;1.0&quot;?&gt; tag is
342 required by XML. The &lt;schema&gt; tag
343 tells the parser that the enclosed markup defines an XML
344 schema. The version=&quot;0.2&quot; attribute sets
345 <em>the version of the AXMLS DTD used by the XML
346 schema.</em> <p>All versions of AXMLS prior
347 to version 1.0 have a schema version of &quot;0.1&quot;. The current
348 schema version is &quot;0.2&quot;.</p></p>
349 <pre class="listing"><pre>
350 &lt;?xml version=&quot;1.0&quot;?&gt;
351 &lt;schema version=&quot;0.2&quot;&gt;
353 &lt;/schema&gt;
354 </pre></pre>
355 <p>Next we define one or more tables. A table consists of a
356 fields (and other objects) enclosed by
357 &lt;table&gt; tags. The
358 name=&quot;&quot; attribute specifies the name of
359 the table that will be created in the database.</p>
360 <pre class="listing"><pre>
361 &lt;table name=&quot;users&quot;&gt;
363 &lt;desc&gt;A typical users table for our application.&lt;/desc&gt;
364 &lt;field name=&quot;userId&quot; type=&quot;I&quot;&gt;
365 &lt;descr&gt;A unique ID assigned to each user.&lt;/descr&gt;
366 &lt;KEY/&gt;
367 &lt;AUTOINCREMENT/&gt;
368 &lt;/field&gt;
370 &lt;field name=&quot;userName&quot; type=&quot;C&quot; size=&quot;16&quot;&gt;&lt;NOTNULL/&gt;&lt;/field&gt;
372 &lt;/table&gt;
373 </pre></pre>
374 <p>This table is called &quot;users&quot; and has a description and
375 two fields. The description is optional, and is currently
376 only for your own information; it is not applied to the
377 database.</p>
378 <p>The first &lt;field&gt; tag will create
379 a field named &quot;userId&quot; of type &quot;I&quot;, or integer. (See the
380 ADOdb Data Dictionary
381 documentation for a list of valid types.) This
382 &lt;field&gt; tag encloses two special
383 field options: &lt;KEY/&gt;, which
384 specifies this field as a primary key, and
385 &lt;AUTOINCREMENT/&gt;, which specifies
386 that the database engine should automatically fill this
387 field with the next available value when a new row is
388 inserted.</p>
389 <p>The second &lt;field&gt; tag will create
390 a field named &quot;userName&quot; of type &quot;C&quot;, or character, and of
391 length 16 characters. The &lt;NOTNULL/&gt;
392 option specifies that this field does not allow
393 NULLs.</p>
394 <p>There are two ways to add indexes to a table. The
395 simplest is to mark a field with the
396 &lt;KEY/&gt; option as described above; a
397 primary key is a unique index. The second and more powerful
398 method uses the &lt;index&gt; tags.</p>
399 <pre class="listing"><pre>
400 &lt;table name=&quot;users&quot;&gt;
403 &lt;index name=&quot;userName&quot;&gt;
404 &lt;descr&gt;Put a unique index on the user name&lt;/descr&gt;
405 &lt;col&gt;userName&lt;/col&gt;
406 &lt;UNIQUE/&gt;
407 &lt;/index&gt;
409 &lt;/table&gt;
410 </pre></pre>
411 <p>The &lt;index&gt; tag specifies that an
412 index should be created on the enclosing table. The
413 name=&quot;&quot; attribute provides the name of the
414 index that will be created in the database. The
415 description, as above, is for your information only. The
416 &lt;col&gt; tags list each column that
417 will be included in the index. Finally, the
418 &lt;UNIQUE/&gt; tag specifies that this
419 will be created as a unique index.</p>
420 <p>Finally, AXMLS allows you to include arbitrary SQL that
421 will be applied to the database when the schema is
422 executed.</p>
423 <pre class="listing"><pre>
424 &lt;sql&gt;
425 &lt;descr&gt;Insert some data into the users table.&lt;/descr&gt;
426 &lt;query&gt;insert into users (userName) values ( 'admin' )&lt;/query&gt;
427 &lt;query&gt;insert into users (userName) values ( 'Joe' )&lt;/query&gt;
428 &lt;/sql&gt;
429 </pre></pre>
430 <p>The &lt;sql&gt; tag encloses any number
431 of SQL queries that you define for your own use.</p>
432 <p>Now that we've defined an XML schema, you need to know how to
433 apply it to your database. Here's a simple PHP script that shows
434 how to load the schema.</p>
435 <p><pre class="listing"><pre>
436 &lt;?PHP
437 /* You must tell the script where to find the ADOdb and
438 * the AXMLS libraries.
440 require( &quot;path_to_adodb/adodb.inc.php&quot;);
441 require( &quot;path_to_adodb/adodb-xmlschema.inc.php&quot; );
443 /* Configuration information. Define the schema filename,
444 * RDBMS platform (see the ADODB documentation for valid
445 * platform names), and database connection information here.
447 $schemaFile = 'example.xml';
448 $platform = 'mysql';
449 $dbHost = 'localhost';
450 $dbName = 'database';
451 $dbUser = 'username';
452 $dbPassword = 'password';
454 /* Start by creating a normal ADODB connection.
456 $db = ADONewConnection( $platform );
457 $db-&gt;Connect( $dbHost, $dbUser, $dbPassword, $dbName );
459 /* Use the database connection to create a new adoSchema object.
461 $schema = new adoSchema( $db );
463 /* Call ParseSchema() to build SQL from the XML schema file.
464 * Then call ExecuteSchema() to apply the resulting SQL to
465 * the database.
467 $sql = $schema-&gt;ParseSchema( $schemaFile );
468 $result = $schema-&gt;ExecuteSchema();
469 ?&gt;
470 </pre></pre></p>
471 <p>Let's look at each part of the example in turn. After you
472 manually create the database, there are three steps required to
473 load (or upgrade) your schema.</p>
474 <p>First, create a normal ADOdb connection. The variables
475 and values here should be those required to connect to your
476 database.</p>
477 <pre class="listing"><pre>
478 $db = ADONewConnection( 'mysql' );
479 $db-&gt;Connect( 'host', 'user', 'password', 'database' );
480 </pre></pre>
481 <p>Second, create the adoSchema object that load and
482 manipulate your schema. You must pass an ADOdb database
483 connection object in order to create the adoSchema
484 object.</p>
485 <pre class="listing"><pre>
486 $schema = new adoSchema( $db );
487 </pre></pre>
488 <p>Third, call ParseSchema() to parse the
489 schema and then ExecuteSchema() to apply
490 it to the database. You must pass
491 ParseSchema() the path and filename of
492 your schema file.</p>
493 <pre class="listing"><pre>
494 $schema-&gt;ParseSchema( $schemaFile );
495 $schema-&gt;ExecuteSchema();
496 </pre></pre>
497 <p>Execute the above code and then log into your database. If you've
498 done all this right, you should see your tables, indexes, and
499 SQL.</p>
500 <p>You can find the source files for this tutorial in the
501 examples directory as
502 tutorial_shema.xml and
503 tutorial.php. See the class documentation for
504 a more detailed description of the adoSchema methods, including
505 methods and schema elements that are not described in this
506 tutorial.</p>
508 <H3>XML Schema Format:</H3>
509 <P>(See <a href="xmlschema.dtd">xmlschema.dtd</a> for the full specification)</P>
510 <PRE>
511 &lt;?xml version="1.0"?&gt;
512 &lt;schema version=&quot;0.2&quot;&gt;
513 &lt;table name="tablename" platform="platform1|platform2|..."&gt;
514 &lt;descr&gt;Optional description&lt;/descr&gt;
515 &lt;field name="fieldname" type="datadict_type" size="size"&gt;
516 &lt;KEY/&gt;
517 &lt;NOTNULL/&gt;
518 &lt;AUTOINCREMENT/&gt;
519 &lt;DEFAULT value="value"/&gt;
520 &lt;/field&gt;
521 <i> ... more fields</i>
522 &lt;index name="indexname" platform="platform1|platform2|..."&gt;
523 &lt;descr&gt;Optional description&lt;/descr&gt;
524 &lt;col&gt;fieldname&lt;/col&gt;
525 <i> ... more columns</i>
526 &lt;/index&gt;
527 <i> ... more indexes</i>
528 &lt;/table&gt;
529 <i> ... more tables</i>
531 &lt;sql platform="platform1|platform2|..."&gt;
532 &lt;descr&gt;Optional description&lt;/descr&gt;
533 &lt;query platform="platform1|platform2|..."&gt;SQL query&lt;/query&gt;
534 <i> ... more queries</i>
535 &lt;/sql&gt;
536 <i> ... more SQL</i>
537 &lt;/schema&gt;
538 </pre>
540 <h3>Upgrading</h3>
541 If your schema version is older, than XSLT is used to transform the schema to the newest version.
542 This means that if you are using an older XML schema format, you need to have the XSLT extension installed.
543 If you do not want to require your users to have the XSLT extension installed, make sure you
544 modify your XML schema to conform to the latest version.
545 <hr />
547 <address>If you have any questions or comments, please email them to Richard at richtl#arscognita.com.
548 </address>
550 </body>
551 </html>