/**
@mainpage
@section introduction Introduction
<p>Mayfly is an SQL implementation in Java which is intended
for unit testing. You'll be linking the Mayfly jars into your
application, and then writing unit tests which create mayfly
databases (as in-memory objects) and connect to them (using
the JDBC database interface or slight variations thereof).</p>
<p>One key feature is the ability to very cheaply snapshot the database
(both metadata and data) and restore from that point. This is further
described at {@link net.sourceforge.mayfly.Database#dataStore()}.</p>
@section installation Installation
Download mayfly-<var>version</var>.zip and put the supplied jar files in your classpath. You
probably want to first write a simple unit test which just creates
a mayfly database, connects to it, and executes a few SQL commands.
It's easier to make that work first and subsequently hook in Mayfly to the
rest of your application.
The file mayfly-<var>version</var>-src-ide.zip within the main
download is designed to make it easy to browse Mayfly source (for example,
using the "attach sources"
feature found in Java development tools). Either the sources or the
Mayfly documentation can help you distinguish between
methods you would ordinarily call and methods which are public but would
generally only be called from within Mayfly.
The source download mayfly-<var>version</var>-src.zip contains everything
you need to rebuild Mayfly and run the Mayfly tests. Because it contains
jar files for non-Mayfly databases, it is rather large.
@section connecting Connecting
The easiest way to create a database and connect to it is to call
{@link net.sourceforge.mayfly.Database#Database()} to create a database object
and then call {@link net.sourceforge.mayfly.Database#openConnection()} to open a
JDBC connection to it.
Alternately, Mayfly supplies a JDBC Driver, described in
{@link net.sourceforge.mayfly.JdbcDriver}.
The most commonly used parts of JDBC are implemented, including PreparedStatement
and parameters. As usual, if you get an
{@link net.sourceforge.mayfly.UnimplementedException}, we'd love to hear
what features you'd like to see us add (via the mayfly mailing list).
@section errors Errors
Because Mayfly is intended to be used during development,
it is a Mayfly goal to detect errors as soon as possible, and give
an informative message. For example, if you specify <tt>WHERE a = NULL</tt>
(instead of <tt>WHERE a IS NULL</tt>), Mayfly complains. For another
example, if you specify a <tt>CREATE TABLE</tt> with duplicate column
names, Mayfly tells you which column was duplicated. And so on.
If you find a problem with your SQL, and Mayfly gives an unclear or
less than helpful message, we consider that to be a bug. Please
let us know, on the mayfly mailing list, what you were doing and what
would have helped you find your problem faster.
@section dump SQL Dumps
Mayfly has the ability to dump a database as an SQL script. See
{@link net.sourceforge.mayfly.dump.SqlDumper}.
@section syntax SQL Syntax
We don't want you to have to rewrite your SQL for Mayfly versus your
production database. Of course, this ideal is not 100% realized due
to the wide variation in SQL dialects, and the fact that we simply
haven't gotten around to adding everything to Mayfly which we'd like
to. Your odds are generally better if you stay close to standard
SQL. Mayfly does deliberately omit some syntaxes which seem to
be little-used and/or non-portable, but in this case there is an
alternate syntax which will also work with non-Mayfly databases.
This section describes the syntax supported in Mayfly. In this description,
Square brackets "[]" indicate optional
elements, vertical bars "|" indicate choices, curly braces "{}" simply group
elements, "..." indicates that the previous element can be repeated,
and ", ..." indicates
that the previous element can be repeated, with commas separating each
repeat. Parentheses "()" stand for themselves.
These descriptions should be read with reference to a more comprehensive
SQL guide, such as those found at <a href="http://www.sqlzoo.net/" >sqlzoo.net</a>.
Here we emphasis conciseness and identifying our SQL subset, instead of a full
description of the semantics and syntax.
@subsection comments
Text from -- to a newline, or between
<tt>/*</tt> and <tt>*</tt><tt>/</tt>, is a comment.
@subsection createindex CREATE INDEX
<pre>
CREATE [UNIQUE] INDEX <var>index-name</var>
ON <var>table</var>(<var>column</var> [(<var>width</var>)], ...)
</pre>
This is mostly a no-op except:
* if the word UNIQUE is specified in which case it
is the same as defining a unique constraint (for example, in a
CREATE TABLE statement). The latter syntax is generally preferred,
as it separates constraints (defining correct behavior) from indexes
(performance optimization),
* the index-name must be unique across tables, and
* the index appears in dumps.
The rationale behind not having real indexes is that we expect
they would slow down Mayfly for the anticipated use cases (small
data sets and as many writes as reads).
@subsection dropindex DROP INDEX
<pre>
DROP INDEX <var>index-name</var>
DROP INDEX <var>index-name</var> ON <var>table</var>
</pre>
Mayfly supports the version without a table for compatibility
with most databases (and the SQL standard), and the version with
a table for compatibility with MySQL. If the table name is
specified it must match the table where the index is defined,
though.
@subsection create CREATE TABLE
<pre>
CREATE TABLE <var>table-name</var> (
{
{<var>column-name</var> <var>data-type</var>
[ DEFAULT <var>default-value</var> ]
[ AUTO_INCREMENT |
GENERATED BY DEFAULT AS IDENTITY
[(STARTS WITH <var>value</var>)]
]
{[ NOT NULL | UNIQUE | PRIMARY KEY ]}...
} |
[ CONSTRAINT <var>name</var> ] UNIQUE(<var>column</var>, ...) |
[ CONSTRAINT <var>name</var> ] PRIMARY KEY(<var>column</var>, ...) |
[ CONSTRAINT <var>name</var> ]
FOREIGN KEY(<var>column</var>) REFERENCES <var>table</var>(<var>column</var>)
[ ON DELETE <var>action</var> [ ON UPDATE <var>action</var> ] |
ON UPDATE <var>action</var> [ ON DELETE <var>action</var> ]
]
}, ...
)
[ ENGINE = <var>engine</var> ]
[ CHARACTER SET <var>character-set</var> ]
</pre>
For the most part, the data type is enforced fairly strictly. Mayfly
does not automatically convert between one type and another as readily
as some SQL databases.
Supported data types for numbers are TINYINT, SMALLINT, INTEGER and BIGINT (8, 16, 32, and 64
bit integers, respectively). DECIMAL(x,y) is supported.
For strings, there is VARCHAR(<var>size</var>) (with TEXT
as a non-standard synonym). There is partial support for DATE.
Mayfly has two kinds of incrementing columns:
<ul>
<li>An identity column is enabled by GENERATED BY DEFAULT syntax.
It is based on
a sequence (that is, the value to be inserted by default is not affected
by other insert statements into the table).</li>
<li>An auto-increment column is enabled by the AUTO_INCREMENT syntax.
It is based on the existing values (that is, inserting another value
into the table will change the value to be inserted).</li>
</ul>
Also, IDENTITY or SERIAL as datatypes indicate an incrementing column
(for compatibility with Hypersonic and Postgres, respectively,
IDENTITY is an auto-increment column and SERIAL is a sequence-style column.
The type in both cases is INTEGER).
Foreign key actions for ON DELETE are NO ACTION, CASCADE, SET NULL,
and SET DEFAULT. Foreign key actions for ON UPDATE are NO ACTION only.
Foreign keys which are not given a name will be named according to
the scheme <i>referringTable</i>_ibfk_<i>sequence</i>,
where <i>sequence</i> is 1 for the first foreign key in this table, 2 for
the second, and so on. This can be kind of ugly in dumps (although not
as problematic as if the name were set in an unpredictable way,
such as based on times
or database internal state), but seems to be the best way to make
ALTER TABLE DROP FOREIGN KEY usable where a constraint name was not
initially assigned.
The engine may be specified as innodb or myisam (case-insensitive) and is
for MySQL compatibility. A future version of mayfly may choose to do
something with the engine (for example, turning off foreign keys, or
warning about an attempt to use them, for myisam), but currently it is
ignored.
The character set is for MySQL compatibility and is currently ignored
(mayfly always is capable of storing general unicode characters).
A future version of mayfly may change this, for example, to warn about
storing data which is not compatible with the character set, or try to
emulate MySQL in terms of being able to test code which converts a
database from one character set to another.
@subsection drop DROP TABLE
<pre>
DROP TABLE <var>name</var>
DROP TABLE <var>name</var> IF EXISTS
DROP TABLE IF EXISTS <var>name</var>
</pre>
Remove the table <var>name</var> and all its contents.
Without IF EXISTS, there must be a table by that name.
With the IF EXISTS (in either position), if there is no
table by that name, the command does nothing, without
an error.
@subsection alter ALTER TABLE
<pre>
ALTER TABLE <var>table-name</var> DROP COLUMN <var>column-name</var>
ALTER TABLE <var>table-name</var> ADD COLUMN <var>column-definition</var>
ALTER TABLE <var>table-name</var> MODIFY COLUMN <var>column-definition</var>
ALTER TABLE <var>table-name</var>
CHANGE COLUMN <var>old-name</var> <var>column-definition</var>
ALTER TABLE <var>table-name</var> DROP FOREIGN KEY <var>constraint-name</var>
ALTER TABLE <var>table-name</var> DROP CONSTRAINT <var>constraint-name</var>
ALTER TABLE <var>table-name</var> ADD <var>constraint</var>
ALTER TABLE <var>table-name</var> ENGINE = <var>engine</var>
ALTER TABLE <var>table-name</var> CHARACTER SET <var>character-set</var>
</pre>
where <var>column-definition</var> is as in CREATE TABLE (a column
name and data type, roughly), and <var>constraint</var> is as in
CREATE TABLE (that is, starts with CONSTRAINT, UNIQUE, PRIMARY KEY,
or FOREIGN KEY).
See CREATE TABLE for more on engine and character set (which are no-ops,
for MySQL compatibility).
@subsection insert INSERT
<pre>
INSERT INTO <var>table</var> [ ( <var>column-name</var>, ... ) ]
VALUES ( <var>expression</var>, ... )
</pre>
If <var>expression</var> is DEFAULT, the default value that was
specified when creating the table is inserted.
<pre>
INSERT INTO <var>table</var>() VALUES ()
</pre>
Insert default values into every column (different databases have
different syntaxes for this).
<pre>
INSERT INTO <var>table</var> SET { <var>column-name</var> = <var>expression</var> }, ...
</pre>
This version is not standard SQL; it is an extension taken from MySQL.
So don't use it if you want portability. But the potential added readibility
gained by putting the column name next to the corresponding expression may
justify it.
<pre>
INSERT INTO <var>table</var> [ ( <var>column-name</var>, ... ) ] <var>select-statement</var>
</pre>
Used, for example, for copying data from an old table to a rearranged table.
The number of columns selected in the SELECT must match the number being inserted.
@subsection select SELECT
<pre>
SELECT {
* |
<var>alias</var>.* |
<var>expression</var> [ AS <var>column-alias</var> ], ...
FROM <var>table-reference</var>, ...
[ WHERE <var>condition</var> ]
[ ORDER BY { [<var>alias</var> .] <var>column</var> }, ... ]
[ LIMIT <var>count</var> [ OFFSET <var>start</var> ] ]
</pre>
A <var>table-reference</var> is:
<pre>
<var>tablename</var> [ <var>alias</var> ] |
<var>table-reference</var>
{ INNER | LEFT OUTER } JOIN <var>table-reference</var>]
ON <var>condition</var>
</pre>
A <var>condition</var> is:
<pre>
<var>condition</var> OR <var>condition</var> |
<var>condition</var> AND <var>condition</var> |
NOT <var>condition</var> |
<var>expression</var> = <var>expression</var> |
<var>expression</var> { != | <> } <var>expression</var> |
<var>expression</var> < <var>expression</var> |
<var>expression</var> > <var>expression</var> |
<var>expression</var> <= <var>expression</var> |
<var>expression</var> >= <var>expression</var> |
<var>expression</var> IS [ NOT ] NULL |
<var>expression</var> IN ( <var>expression</var>, ... )
<var>expression</var> IN ( <var>subselect</var> )
<var>expression</var> LIKE <var>pattern</var> |
</pre>
An <var>expression</var> is:
<pre>
<var>0-9...</var> |
<var>x'<var>hexdigit</var>...'</var> |
<var>'<var>character</var>...'</var> |
[ <var>alias</var> . ] <var>column</var> |
<var>expression</var> + <var>expression</var> |
<var>expression</var> - <var>expression</var> |
<var>expression</var> * <var>expression</var> |
<var>expression</var> / <var>expression</var> |
<var>expression</var> || <var>expression</var> |
CONCAT(<var>expression</var>, ...) |
( <var>expression</var> ) |
( <var>subselect</var> ) |
MAX ( [ ALL | DISTINCT ] <var>expression</var> ) |
MIN ( [ ALL | DISTINCT ] <var>expression</var> ) |
SUM ( [ ALL | DISTINCT ] <var>expression</var> ) |
AVG ( [ ALL | DISTINCT ] <var>expression</var> ) |
COUNT ( { [ ALL | DISTINCT ] <var>expression</var> } | * ) }
NULL |
CASE { WHEN <var>condition</var> THEN <var>expression</var> }...
[ ELSE <var>else-expression</var> ]
END
</pre>
A <var>subselect</var> is just a SELECT statement.
There is also some support for GROUP BY and HAVING.
The SQL standard syntax for string concatenation is
<var>expression</var> || <var>expression</var>. If you want compatibility
with MySQL, you can either tell MySQL to accept the || syntax
(set sql_mode='PIPES_AS_CONCAT' or set sql_mode='ANSI'), or you can use
the CONCAT(<var>expression</var>, ...) syntax, which is also provided
by Mayfly.
@subsection select UPDATE
UPDATE <var>table</var> {SET <var>column</var> = <var>expression</var> }, ...
[WHERE <var>condition</var>]
If <var>expression</var> is DEFAULT, the default value that was
specified when creating the table is used.
@section schemas Schemas
A Database object can contain several <i>schemas</i> - each one
has its own tables and they do not interact with each other.
Currently, you must call the SET SCHEMA command to select which
schema you are going to operate on. Support for the syntax
schema.table or schema.table.column is planned for the future
but is not there now.
The syntax of the schema commands is:
<pre>
CREATE SCHEMA <var>name</var> [AUTHORIZATION DBA]
[ { <var>create-table-command</var> } ... ]
SET SCHEMA <var>name</var>
ALTER SCHEMA <var>name</var> CHARACTER SET <var>character-set</var>
</pre>
The character set is ignored (see discussion of character set
under CREATE TABLE above).
@section transactions Transactions and Threads
It is not yet safe to share a database between several threads.
Furthermore, even those aspects of transactions which are
visible from within a single thread (for example, rollback)
are not yet implemented.
@section optimize Query Optimization
For the most part, queries are un-optimized. Most unit tests will
only have a few rows in each table, and in that environment it will
generally be faster for Mayfly to look at every row (a table scan)
on read rather than build an index on writes.
One can declare an index but this is a no-op. For example:
<pre>
CREATE TABLE(a INTEGER, INDEX(a))
</pre>
Having said that, it is now possible to,
for example, implicitly join 3 tables of 1000 rows each,
in certain specific cases. The query optimizer is still dead simple -
it proceeds from left to right and can decompose a WHERE
clause made up of AND. For example,
"SELECT * from foo, bar, baz where foo.x = bar.x"
will get optimized to
<pre>
inner join foo and bar on foo.x = bar.x
inner join that with baz
</pre>
whereas
"SELECT * from foo, bar, baz where bar.x = baz.x"
will perform all the joins, and only
then apply the WHERE (requiring temporary storage
of the number of rows in foo times the number of rows
in bar times the number of rows in baz). Explicit
joins are executed as they are written. For example
"SELECT * from foo, bar INNER JOIN baz ON bar.x = baz.x"
will select based on the ON before joining with the foo table.
@section References
One good reference is <i>SQL in a Nutshell</i>, by Kline, Kline and Hunt,
published by O'Reilly.
It has a detailed guide to syntax and semantics, including the SQL2003 standard and
the differences among the most common SQL implementations.
A more introductory book is <i>The Practical SQL Handbook: Using Structured Query Language</i>,
by Judith S. Bowman, Sandra L. Emerson, and Marcy Darnovsky (third edition is from 1996).
One good SQL reference/tutorial web site is <a href="http://www.sqlzoo.net/" >SQLzoo</a>.
*/