diff options
Diffstat (limited to 'docs')
-rw-r--r-- | docs/00_index.mkd | 65 | ||||
-rw-r--r-- | docs/01_model_classes.mkd | 170 | ||||
-rw-r--r-- | docs/02_table_versioning.mkd | 29 | ||||
-rw-r--r-- | docs/02_usage.mkd | 164 | ||||
-rw-r--r-- | docs/03_natural_syntax.mkd | 23 | ||||
-rw-r--r-- | docs/04_examples.mkd | 118 | ||||
-rw-r--r-- | docs/04_tools.mkd | 95 | ||||
-rw-r--r-- | docs/05_building.mkd | 33 | ||||
-rw-r--r-- | docs/05_javadoc.mkd | 7 | ||||
-rw-r--r-- | docs/05_releases.mkd | 38 | ||||
-rw-r--r-- | docs/resources/iciql-favicon.png | bin | 0 -> 386 bytes | |||
-rw-r--r-- | docs/resources/iciql.css | 152 | ||||
-rw-r--r-- | docs/resources/iciql.png | bin | 0 -> 1888 bytes | |||
-rw-r--r-- | docs/resources/iciql.xcf | bin | 0 -> 6543 bytes | |||
-rw-r--r-- | docs/resources/javadoc.css | 52 | ||||
-rw-r--r-- | docs/resources/markdown.css | 67 | ||||
-rw-r--r-- | docs/resources/prettify.css | 1 | ||||
-rw-r--r-- | docs/resources/prettify.js | 33 | ||||
-rw-r--r-- | docs/resources/site_footer.html | 7 | ||||
-rw-r--r-- | docs/resources/site_header.html | 32 |
20 files changed, 1086 insertions, 0 deletions
diff --git a/docs/00_index.mkd b/docs/00_index.mkd new file mode 100644 index 0000000..3371ce2 --- /dev/null +++ b/docs/00_index.mkd @@ -0,0 +1,65 @@ +## Overview
+
+iciql **is**...
+
+- a model-based, database access wrapper for JDBC
+- for modest database schemas and basic statement generation
+- for those who want to write code, instead of SQL, using IDE completion and compile-time type-safety
+- small (100KB) with no runtime dependencies
+- pronounced *icicle* (although it could be French: *ici ql* - here query language)
+- a friendly fork of the H2 [JaQu][jaqu] project
+
+iciql **is not**...
+
+- a complete alternative to JDBC
+- designed to compete with more powerful database query tools like [jOOQ][jooq] or [Querydsl][querydsl]
+- designed to compete with enterprise [ORM][orm] tools like [Hibernate][hibernate] or [mybatis][mybatis]
+
+### Example Usage
+<table>
+<tr>
+<th>iciql</th><th>sql</th>
+</tr>
+<tr>
+<td>
+%BEGINCODE%
+Product p = new Product();
+List<Product> restock = db.from(p).where(p.unitsInStock).is(0).select();
+List<Product> all = db.executeQuery(Product.class, "select * from products");
+%ENDCODE%
+</td><td>
+<br/>
+select * from products p where p.unitsInStock = 0<br/>
+select * from products
+</td>
+</tr>
+</table>
+
+### Supported Databases
+[H2](http://h2database.com)
+
+Support for others is planned and should only require creating a simple "dialect" class.
+
+### Java Runtime Requirement
+
+iciql requires a Java 6 Runtime Environment (JRE) or a Java 6 Development Kit (JDK).
+
+### Current Release
+
+**%VERSION%** ([zip](http://code.google.com/p/iciql/downloads/detail?name=%ZIP%)|[jar](http://code.google.com/p/iciql/downloads/detail?name=%JAR%)) *released %BUILDDATE%*
+
+issues, binaries, & source @ [Google Code][googlecode]<br/>
+sources @ [Github][github]
+
+### License
+iciql is distributed under the terms of the [Apache Software Foundation license, version 2.0][apachelicense]
+
+[jaqu]: http://h2database.com/html/jaqu.html "H2 JaQu project"
+[orm]: http://en.wikipedia.org/wiki/Object-relational_mapping "Object Relational Mapping"
+[jooq]: http://jooq.sourceforge.net "jOOQ"
+[querydsl]: http://source.mysema.com/display/querydsl/Querydsl "Querydsl"
+[hibernate]: http://www.hibernate.org "Hibernate"
+[mybatis]: http://www.mybatis.org "mybatis"
+[github]: http://github.com/gitblit/iciql "iciql git repository"
+[googlecode]: http://code.google.com/p/iciql "iciql project management"
+[apachelicense]: http://www.apache.org/licenses/LICENSE-2.0 "Apache License, Version 2.0"
\ No newline at end of file diff --git a/docs/01_model_classes.mkd b/docs/01_model_classes.mkd new file mode 100644 index 0000000..3ca7630 --- /dev/null +++ b/docs/01_model_classes.mkd @@ -0,0 +1,170 @@ +## Model Classes
+A model class represents a single table within your database. Fields within your model class represent columns in the table. The object types of your fields are reflectively mapped to SQL types by iciql at runtime.
+
+Models can be manually written using one of two approaches: *annotation configuration* or *interface configuration*. Both approaches can be used within a project and both can be used within a single model class, although that is discouraged.
+
+Alternatively, model classes can be automatically generated by iciql using the model generation tool. Please see the [tools](tools.html) page for details.
+
+### Supported Data Types
+<table>
+
+<tr><td>java.lang.String</td>
+<td>VARCHAR *(maxLength > 0)* or TEXT *(maxLength == 0)*</td></tr>
+
+<tr><td>java.lang.Boolean</td>
+<td>BIT</td></tr>
+
+<tr><td>java.lang.Byte</td>
+<td>TINYINT</td></tr>
+
+<tr><td>java.lang.Short</td>
+<td>SMALLINT</td></tr>
+
+<tr><td>java.lang.Integer</td>
+<td>INT</td></tr>
+
+<tr><td>java.lang.Long</td>
+<td>BIGINT</td></tr>
+
+<tr><td>java.lang.Float</td>
+<td>REAL</td></tr>
+
+<tr><td>java.lang.Double</td>
+<td>DOUBLE</td></tr>
+
+<tr><td>java.math.BigDecimal</td>
+<td>DECIMAL</td></tr>
+
+<tr><td>java.sql.Date</td>
+<td>DATE</td></tr>
+
+<tr><td>java.sql.Time</td>
+<td>TIME</td></tr>
+
+<tr><td>java.sql.Timestamp</td>
+<td>TIMESTAMP</td></tr>
+
+<tr><td>java.util.Date</td>
+<td>TIMESTAMP</td></tr>
+
+</table>
+
+**NOTE:**<br/>
+The reverse lookup used for model generation, SQL type -> Java type, contains more mappings.<br/>
+Please consult the `com.iciql.ModelUtils` class for details.
+
+### Unsupported Types
+- Java primitives (use their object counterparts instead)
+- binary types (BLOB, etc)
+- array types
+- custom types
+
+### Configuration Rules
+1. field mappings must be Objects not primitives
+2. the model class must have a default public constructor
+
+### Configuration Limitations
+1. index names can not be specified
+2. triggers, views, and other advanced database features are unimplemented
+
+## Annotation Configuration
+The recommended approach to setup a model class is to annotate the class and field declarations.
+
+### advantages
+
+- annotated fields may have any scope
+- annotated models support annotated field inheritance making it possible to design a single base class that defines the fields and then create table subclasses that specify the table mappings.
+- model runtime dependency is limited to the small, portable `com.iciql.Iciql` class file which contains the annotation definitions
+
+### disadvantages
+
+- more verbose model classes
+- indexes are defined using "fragile" string column names
+- compound primary keys are defined using "fragile" string column names
+
+### Example Annotated Model
+%BEGINCODE%
+import com.iciql.Iciql.IQColumn;
+import com.iciql.Iciql.IQIndex;
+import com.iciql.Iciql.IQTable;
+
+@IQTable
+@IQIndex(standard = {"productName", "category"})
+public class Product {
+
+ @IQColumn(primaryKey = true)
+ public Integer productId;
+
+ @IQColumn(maxLength = 200, trimString = true)
+ public String productName;
+
+ @IQColumn(maxLength = 50, trimString = true)
+ public String category;
+
+ @IQColumn
+ public Double unitPrice;
+
+ @IQColumn(name = "units")
+ public Integer unitsInStock;
+
+ @IQColumn
+ private Integer reorderQuantity;
+
+ public Product() {
+ // default constructor
+ }
+}
+%ENDCODE%
+
+## Interface Configuration (deprecated)
+Alternatively, you may map your model classes using the original JaQu interface approach by implementing the `com.iciql.Iciql` interface.
+
+This is a less verbose configuration style, but it comes at the expense of introducing a compile-time dependency on the logic of the iciql library. This might be a deterrent, for example, if you were serializing your model classes to another process that may not have the iciql library.
+
+The `com.iciql.Iciql` interface specifies a single method, *defineIQ()*. In your implementation of *defineIQ()* you would use static method calls to set:
+
+- the table name (if it's not the class name)
+- the column name (if it's not the field name)
+- the max length of a string field
+- the primaryKey (single field or compound)
+- any indexes (single field or compound)
+
+### advantages
+
+- less verbose model class
+- compile-time index definitions
+- compile-time compound primary key definitions
+
+### disadvantages
+
+- <u>only **public** fields of the model class are reflectively mapped as columns</u>. all other scoped fields and inherited fields are ignored.
+- model runtime dependency on entire iciql library
+- *defineIQ()* is called from a static synchronized block which may be a bottleneck for highly concurrent systems
+
+### Example Interface Model
+%BEGINCODE%
+import com.iciql.Iciql;
+
+public class Product implements Iciql {
+ public Integer productId;
+ public String productName;
+ public String category;
+ public Double unitPrice;
+ public Integer unitsInStock;
+
+ // this field is ignored because it is not public
+ Integer reorderQuantity;
+
+ public Product() {
+ }
+
+ @Override
+ public void defineIQ() {
+ com.iciql.Define.primaryKey(productId);
+ com.iciql.Define.columnName(unitsInStock, "units");
+ com.iciql.Define.maxLength(productName, 200);
+ com.iciql.Define.maxLength(category, 50);
+ com.iciql.Define.index(productName, category);
+ }
+}
+%ENDCODE%
\ No newline at end of file diff --git a/docs/02_table_versioning.mkd b/docs/02_table_versioning.mkd new file mode 100644 index 0000000..0c778cb --- /dev/null +++ b/docs/02_table_versioning.mkd @@ -0,0 +1,29 @@ +## Database & Table Versioning
+
+Iciql supports an optional, simple versioning mechanism. There are two parts to the mechanism.
+
+1. You must supply an implementation of `com.iciql.DbUpgrader` to your `com.iciql.Db` instance.
+2. One or more of your table model classes must set the *version* field of the `com.iciql.IQTable` annotation<br>
+AND/OR<br/>
+Your `com.iciql.DbUpgrader` implementation must set the *version* field of the `com.iciql.IQDatabase` annotation
+
+### How does it work?
+If you choose to use versioning, iciql will maintain a table within your database named *_iq_versions* which is defined as:
+
+ CREATE TABLE _IQ_VERSIONS(SCHEMANAME TEXT NOT NULL, TABLENAME TEXT NOT NULL, VERSION INT NOT NULL)
+
+This database table is automatically created if and only if at least one of your model classes specifies a *version* > 0.
+
+When you generate a statement, iciql will compare the annotated version field of your model class to its last known value in the *_iq_versions* table. If *_iq_versions* lags behind the model annotation, iciql will immediately call the registered `com.iciql.DbUpgrader` implementation before generating and executing the current statement.
+
+When an upgrade scenario is identified, the current version and the annotated version information is passed to either:
+
+- `DbUpgrader.upgradeDatabase(db, fromVersion, toVersion)`
+- `DbUpgrader.upgradeTable(db, schema, table, fromVersion, toVersion)`
+
+both of which allow for non-linear upgrades. If the upgrade method call is successful and returns *true*, iciql will update the *_iq_versions* table with the annotated version number.
+
+The actual upgrade procedure is beyond the scope of iciql and is your responsibility to implement. This is simply a mechanism to automatically identify when an upgrade is necessary.
+
+**NOTE:**<br/>
+The database entry of the *_iq_versions* table is specified as SCHEMANAME='' and TABLENAME=''.
\ No newline at end of file diff --git a/docs/02_usage.mkd b/docs/02_usage.mkd new file mode 100644 index 0000000..d872ee0 --- /dev/null +++ b/docs/02_usage.mkd @@ -0,0 +1,164 @@ +## Usage
+
+Aside from this brief usage guide, please consult the [examples](examples.html), the [javadoc](javadoc.html) and the [source code](https://code.google.com/p/iciql/source/browse).
+
+### Instantiating a Db
+
+Use one of the static utility methods to instantiate a Db instance:
+
+ Db.open(String url, String user, String password);
+ Db.open(String url, String user, char[] password);
+ Db.open(Connection conn);
+ Db.open(DataSource dataSource);
+
+### Compile-Time Statements
+
+You compose your statements using the builder pattern where each method call returns an object that is used to specify the next part of the statement. Through clever usage of generics, pioneered by the original JaQu project, compile-time safety flows through the statement.
+
+%BEGINCODE%
+Db db = Db.open("jdbc:h2:mem:", "sa", "sa");
+db.insertAll(Product.getList());
+db.insertAll(Customer.getList());
+
+List<Product> restock =
+ db.from(p).
+ where(p.unitsInStock).
+ is(0).orderBy(p.productId).select();
+
+for (Product product : restock) {
+ db.from(p).
+ set(p.unitsInStock).to(25).
+ where(p.productId).is(product.productId).update();
+}
+db.close();
+%ENDCODE%
+
+Please see the [examples](examples.html) page for more code samples.
+
+### Dynamic Runtime Queries
+
+Iciql gives you compile-time type-safety, but it becomes inconvenient if your design requires more dynamic statement generation. For these scenarios iciql offers some runtime query support through a hybrid approach or a pure JDBC approach.
+
+#### Where String Fragment Approach
+This approach is a mixture of iciql and jdbc. It uses the traditional prepared statement *field=?* tokens with iciql compile-time model class type checking. There is no field token type-safety checking.
+%BEGINCODE%
+List<Product> restock = db.from(p).where("unitsInStock=? and productName like ? order by productId", 0, "Chef%").select();
+%ENDCODE%
+
+#### Db.executeQuery Approaches
+There may be times when the hybrid approach is still too restrictive and you'd prefer to write straight SQL. You can do that too and use iciql to build objects from your ResultSet, but be careful:
+
+1. Make sure to _select *_ in your query otherwise db.bindResultSet() will throw a RuntimeException
+2. There is no model class type checking nor field type checking.
+
+%BEGINCODE%
+List<Product> allProducts = db.executeQuery(Product.class, "select * from products");
+List<Product> restock = db.executeQuery(Product.class, "select * from products where unitsInStock=?", 0);
+%ENDCODE%
+
+Or if you want access to the raw *ResultSet* before building your model object instances...
+
+%BEGINCODE%
+ResultSet rs = db.executeQuery("select * from products");
+List<Product> allProducts = db.buildObjects(Product.class, rs);
+// This method ensures the creating statement is closed
+JdbcUtils.closeSilently(rs, true);
+%ENDCODE%
+
+### JDBC Statements, ResultSets, and Exception Handling
+
+Iciql opens and closes all JDBC objects automatically. SQLExceptions thrown during execution of a statement (except for *close()* calls), will be caught, wrapped, and rethrown as an `IciqlException`, which is a RuntimeException.
+
+Iciql does not throw any [checked exceptions](http://en.wikipedia.org/wiki/Exception_handling#Checked_exceptions).
+
+### Statement Logging
+
+Iciql provides a mechanism to log generated statements to the console, to SLF4J, or to your own logging framework. Exceptions are not logged using this mechanism; exceptions are wrapped and rethrown as `IciqlException`, which is a RuntimeException.
+
+#### Console Logging
+%BEGINCODE%
+StatmentLogger.activeConsoleLogger();
+StatmentLogger.deactiveConsoleLogger();
+%ENDCODE%
+
+#### SLF4J Logging
+%BEGINCODE%
+Slf4jStatementListener slf4j = new Slf4jStatementListener();
+slf4j.setLevel(StatementType.CREATE, Level.WARN);
+slf4j.setLevel(StatementType.DELETE, Level.WARN);
+slf4j.setLevel(StatementType.MERGE, Level.OFF);
+StatmentLogger.registerListener(slf4j);
+StatmentLogger.unregisterListener(slf4j);
+%ENDCODE%
+
+#### Custom Logging
+%BEGINCODE%
+StatementListener custom = new StatementListener() {
+ public void logStatement(StatementType type, String statement) {
+ // do log
+ }
+};
+StatmentLogger.registerListener(custom);
+StatmentLogger.unregisterListener(custom);
+%ENDCODE%
+
+## Understanding Aliases and Model Classes
+Consider the following example:
+%BEGINCODE%
+Product p = new Product();
+List<Product> restock = db.from(p).where(p.unitsInStock).is(0).select();
+%ENDCODE%
+
+The Product model class instance named **p** is an *alias* object. An *alias* is simply an instance of your model class that is only used to build the compile-time/runtime representation of your table.
+
+1. *Alias* instances are **NOT** thread-safe and must not be used concurrently.
+2. *Alias* instances have no other purpose than to provide a compile-time/runtime map of your table.
+3. If you inspected an *alias* instance after using one you would find that it's fields have been assigned numeric values.<br/>These values have no meaning. They are assigned from a static counter in `com.iciql.Utils.newObject()` during execution of the *db.from()* method.
+
+If your statement is a query, like in the above example, iciql will generate new instances of your *alias* model class and return them as a list where each entry of the list represents a row from the JDBC `ResultSet`.
+
+### Why are Aliases not thread-safe?
+
+The _db.from(p)_ call reinstantiates each member field of p. Those reinstantiated fields are then subsequently used in clauses like _where(p.unitsInStock)_. If your *alias* instance is shared concurrently then its highly probable that when _queryA_ executes, _queryC_ has reinstantiated all the *alias* fields and broken _queryA's_ runtime field mapping.
+
+Depending on your design, you might consider using a [ThreadLocal](http://download.oracle.com/javase/6/docs/api/java/lang/ThreadLocal.html) variable if you do not want to keep instantiating *alias* instances. A utility function is included for easily creating ThreadLocal variables.
+
+%BEGINCODE%
+final ThreadLocal<Product> p = Utils.newThreadLocal(Product.class);
+db.from(p.get()).select();
+%ENDCODE%
+
+## Best Practices
+
+1. Close your *Db* instances when you are done with them, this closes the underlying connection or directs the pool to "close" the connection.
+2. Aliases instances are not thread-safe so DO NOT SHARE an alias!<br/>Consider using a *ThreadLocal* alias instance with the `com.iciql.Utils.newThreadLocal()` utility method.
+<table>
+<tr><th>Not Thread-Safe</th><th>Thread-Safe</th></tr>
+<tr><td>
+%BEGINCODE%
+final Product p = new Product();
+for (int i = 0; i < 5; i++) {
+ Thread thread = new Thread(new Runnable() {
+ public void run() {
+ // from(p) reinstantiates p's fields
+ db.from(p).select();
+ }
+ }, "Thread-" + i);
+ thread.start();
+}
+%ENDCODE%
+</td><td>
+%BEGINCODE%
+final ThreadLocal<Product> p = Utils.newThreadLocal(Product.class);
+for (int i = 0; i < 5; i++) {
+ Thread thread = new Thread(new Runnable() {
+ public void run() {
+ // p.get() returns a Product instance unique to this thread
+ db.from(p.get()).select();
+ }
+ }, "Thread-" + i);
+ thread.start();
+}
+%ENDCODE%
+</td></tr>
+</table>
\ No newline at end of file diff --git a/docs/03_natural_syntax.mkd b/docs/03_natural_syntax.mkd new file mode 100644 index 0000000..a91c5b8 --- /dev/null +++ b/docs/03_natural_syntax.mkd @@ -0,0 +1,23 @@ +## Natural Syntax
+
+**work-in-progress**
+
+The original JaQu source offers partial support for Java expressions in *where* clauses.
+
+This works by decompiling a Java expression, at runtime, to an SQL condition. The expression is written as an anonymous inner class implementation of the `com.iciql.Filter` interface.
+A proof-of-concept decompiler is included, but is incomplete.
+
+The proposed syntax is:
+%BEGINCODE%
+long count = db.from(co).
+ where(new Filter() { public boolean where() {
+ return co.id == x
+ && co.name.equals(name)
+ && co.value == new BigDecimal("1")
+ && co.amount == 1L
+ && co.birthday.before(new java.util.Date())
+ && co.created.before(java.sql.Timestamp.valueOf("2005-05-05 05:05:05"))
+ && co.time.before(java.sql.Time.valueOf("23:23:23"));
+ }
+ }).selectCount();
+%ENDCODE%
\ No newline at end of file diff --git a/docs/04_examples.mkd b/docs/04_examples.mkd new file mode 100644 index 0000000..d4f98da --- /dev/null +++ b/docs/04_examples.mkd @@ -0,0 +1,118 @@ +## Select Statements
+
+%BEGINCODE%
+// select * from products
+List<Product> allProducts = db.from(p).select();
+
+// select * from customers where region='WA'
+Customer c = new Customer();
+List<Customer> waCustomers = db.from(c). where(c.region).is("WA").select();
+
+// select with generation of new anonymous inner class
+List<ProductPrice> productPrices =
+ db.from(p).
+ orderBy(p.productId).
+ select(new ProductPrice() {{
+ productName = p.productName;
+ category = p.category;
+ price = p.unitPrice;
+ }});
+%ENDCODE%
+
+## Insert Statements
+
+%BEGINCODE%
+// single record insertion
+db.insert(singleProduct);
+
+// single record insertion with primary key retrieval
+Long key = db.insertAndGetKey(singleProduct);
+
+// batch record insertion
+db.insertAll(myProducts);
+
+// batch insertion with primary key retrieval
+List<Long> myKeys = db.insertAllAndGetKeys(list);
+%ENDCODE%
+
+## Update Statements
+
+%BEGINCODE%
+// single record update
+db.update(singleProduct);
+
+// batch record updates
+db.updateAll(myProducts);
+
+// update query
+db.from(p).set(p.productName).to("updated")
+ .increment(p.unitPrice).by(3.14)
+ .increment(p.unitsInStock).by(2)
+ .where(p.productId).is(1).update();
+%ENDCODE%
+
+## Merge Statements
+Merge statements currently generate the [H2 merge syntax](http://h2database.com/html/grammar.html#merge).
+
+%BEGINCODE%
+Product pChang = db.from(p).where(p.productName).is("Chang").selectFirst();
+pChang.unitPrice = 19.5;
+pChang.unitsInStock = 16;
+db.merge(pChang);
+%ENDCODE%
+
+## Delete Statements
+
+%BEGINCODE%
+// single record deletion
+db.delete(singleProduct);
+
+// batch record deletion
+db.deleteAll(myProducts);
+
+// delete query
+db.from(p).where(p.productId).atLeast(10).delete();
+
+%ENDCODE%
+
+## Inner Join Statements
+
+%BEGINCODE%
+final Customer c = new Customer();
+final Order o = new Order();
+List<CustOrder> orders =
+ db.from(c).
+ innerJoin(o).on(c.customerId).is(o.customerId).
+ where(o.total).lessThan(new BigDecimal("500.00")).
+ orderBy(1).
+ select(new CustOrder() {{
+ customerId = c.customerId;
+ orderId = o.orderId;
+ total = o.total;
+ }});
+%ENDCODE%
+
+## Dynamic Queries
+
+Dynamic queries skip all field type checking and, depending on which approach you use, may skip model class/table name checking too.
+
+%BEGINCODE%
+// where fragment with object parameters
+List<Product> restock = db.from(p).where("unitsInStock=? and productName like ? order by productId", 0, "Chef%").select();
+
+// statement with binding to your model class
+List<Product> allProducts = db.executeQuery(Product.class, "select * from products");
+
+// statement with object parameters and binding to your model class
+List<Product> restock = db.executeQuery(Product.class, "select * from products where unitsInStock=?", 0);
+
+/**
+ * If you want to process the intermediate ResultSet
+ * yourself make sure to use the <i>closeSilently()</i> method
+ * to ensure the parent statement is closed too.
+ */
+ResultSet rs = db.executeQuery("select * from products");
+List<Product> allProducts = db.buildObjects(Product.class, rs);
+JdbcUtils.closeSilently(rs, true);
+
+%ENDCODE%
\ No newline at end of file diff --git a/docs/04_tools.mkd b/docs/04_tools.mkd new file mode 100644 index 0000000..569689e --- /dev/null +++ b/docs/04_tools.mkd @@ -0,0 +1,95 @@ +## Model Generation
+If you do not have or do not want to annotate your existing model classes, you can use the included model generation tool to create iciql model classes.
+
+ java -jar iciql.jar <parameters>
+
+### Parameters
+<table>
+<tr><th>-url</th><td>JDBC url for the database</td><td>*REQUIRED*</td></tr>
+<tr><th>-username</th><td>username for JDBC connection</td><td>*optional*</td></tr>
+<tr><th>-password</th><td>password for JDBC connection</td><td>*optional*</td></tr>
+<tr><th>-schema</th><td>the target schema for model generation</td><td>*default:* all schemas</td></tr>
+<tr><th>-table</th><td>the target table for model generation</td><td>*default:* all tables</td></tr>
+<tr><th>-package</th><td>the destination package name for generated models</td><td>*default:* default package</td></tr>
+<tr><th>-folder</th><td>the output folder for .java files</td><td>*default:* current folder</td></tr>
+<tr><th>-annotateSchema</th><td>include the schema name in the class annotations</td><td>*default:* true</td></tr>
+<tr><th>-trimStrings</th><td>annotate trimStrings=true for any VARCHAR string mappings </td><td>*default:* false</td></tr>
+</table>
+
+## Model Validation
+Iciql can validate your model classes against your database to ensure that your models are optimally defined and are consistent with the current table and index definitions.
+
+Each `com.iciql.ValidationRemark` returned by the validation has an associated level from the following enum:
+%BEGINCODE%
+public static enum Level {
+ CONSIDER, WARN, ERROR;
+}
+%ENDCODE%
+
+A typical validation may output recommendations for adjusting a model field annotation such as setting the *maxLength* of a string to match the length of its linked VARCHAR column.
+
+### Sample Model Validation using JUnit 4
+%BEGINCODE%
+import static org.junit.Assert.assertTrue;
+
+import java.sql.SQLException;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ErrorCollector;
+
+import com.iciql.Db;
+import com.iciql.DbInspector;
+import com.iciql.ValidationRemark;
+import com.iciql.test.models.Product;
+import com.iciql.test.models.ProductAnnotationOnly;
+import com.iciql.test.models.ProductMixedAnnotation;
+
+public class ValidateModels {
+
+ /*
+ * The ErrorCollector Rule allows execution of a test to continue after the
+ * first problem is found and report them all at once
+ */
+ @Rule
+ public ErrorCollector errorCollector = new ErrorCollector();
+
+ private Db db;
+
+ @Before
+ public void setUp() {
+ db = Db.open("jdbc:h2:mem:", "sa", "sa");
+ }
+
+ @After
+ public void tearDown() {
+ db.close();
+ }
+
+ @Test
+ public void testValidateModels() {
+ DbInspector inspector = new DbInspector(db);
+ validateModel(inspector, new Product());
+ validateModel(inspector, new ProductAnnotationOnly());
+ validateModel(inspector, new ProductMixedAnnotation());
+ }
+
+ private void validateModel(DbInspector inspector, Object o) {
+ List<ValidationRemark> remarks = inspector.validateModel(o, false);
+ assertTrue("Validation remarks are null for " + o.getClass().getName(), remarks != null);
+ log("Validation remarks for " + o.getClass().getName());
+ for (ValidationRemark remark : remarks) {
+ log(remark.toString());
+ if (remark.isError()) {
+ errorCollector.addError(new SQLException(remark.toString()));
+ }
+ }
+ }
+
+ private void log(String message) {
+ System.out.println(message);
+ }
+}
+%ENDCODE%
\ No newline at end of file diff --git a/docs/05_building.mkd b/docs/05_building.mkd new file mode 100644 index 0000000..cb8381e --- /dev/null +++ b/docs/05_building.mkd @@ -0,0 +1,33 @@ +## Building from Source
+
+[Eclipse](http://eclipse.org) is recommended for development as the project settings are preconfigured.
+
+Additionally, [eclipse-cs](http://eclipse-cs.sourceforge.net), [FindBugs](http://findbugs.sourceforge.net), and [EclEmma](http://www.eclemma.org) are recommended development tools.
+
+### Build Dependencies (bundled)
+- [google-code-prettify](http://code.google.com/p/google-code-prettify) (Apache 2.0)
+
+### Build Dependencies (downloaded during build)
+- [H2 Database](http://h2database.com) (Eclipse Public License 1.0)
+- [JUnit](http://junit.org) (Common Public License)
+- [commons-net](http://commons.apache.org/net) (Apache 2.0)
+- [ant-googlecode](http://code.google.com/p/ant-googlecode) (New BSD)
+- [MarkdownPapers](http://markdown.tautua.org) (Apache 2.0)
+- [doclava](http://code.google.com/p/doclava) (Apache 2.0)
+- [SLF4J](http://www.slf4j.org) (MIT/X11)
+
+### Instructions
+1. Clone the git repository from [GoogleCode][iciqlsrc].
+2. Import the iciql project into your Eclipse workspace.<br/>
+*There will be some build errors.*
+3. Using Ant, execute the `build.xml` script in the project root.<br/>
+*This will download all necessary build dependencies.*
+4. Select your iciql project root and **Refresh** the project, this should correct all build problems.
+
+## Contributing
+Patches welcome in any form.
+
+Contributions must be your own original work and must licensed under the [Apache License, Version 2.0][apachelicense], the same license used by iciql.
+
+[iciqlsrc]: https://code.google.com/p/iciql/ "iciql git repository"
+[apachelicense]: http://www.apache.org/licenses/LICENSE-2.0 "Apache License, Version 2.0"
\ No newline at end of file diff --git a/docs/05_javadoc.mkd b/docs/05_javadoc.mkd new file mode 100644 index 0000000..c2e911d --- /dev/null +++ b/docs/05_javadoc.mkd @@ -0,0 +1,7 @@ +<div class="javadoc_nav">
+<a href="javadoc/overview-summary.html" target="javadoc">packages</a>
+ | <a href="javadoc/overview-tree.html" target="javadoc">tree</a>
+ | <a href="javadoc/deprecated-list.html" target="javadoc">deprecated</a>
+ | <a href="javadoc/index-all.html" target="javadoc">index</a>
+</div>
+<iframe name="javadoc" src="javadoc/overview-summary.html" width="100%" height="700" frameborder="0"></iframe>
diff --git a/docs/05_releases.mkd b/docs/05_releases.mkd new file mode 100644 index 0000000..9f19d24 --- /dev/null +++ b/docs/05_releases.mkd @@ -0,0 +1,38 @@ +## Release History
+
+### Current Release
+**%VERSION%** ([zip](http://code.google.com/p/iciql/downloads/detail?name=%ZIP%)|[jar](http://code.google.com/p/iciql/downloads/detail?name=%JAR%)) *released %BUILDDATE%*
+
+- initial release (API v1)
+
+*API changes compared to JaQu from H2 1.3.157 sources*
+
+- deprecated model class interface configuration
+- added *Db.open(Connection conn)* method, changed constructor to default scope
+- added *Db.registerDialect* static methods to register custom dialects
+- added *Query.where(String fragment, Object... args)* method to build a runtime query fragment when compile-time queries are too strict
+- added *Db.executeQuery(String query, Object... args)* to execute a complete sql query with optional arguments
+- added *Db.executeQuery(Class modelClass, String query, Object... args)* to execute a complete sql query, with optional arguments, and build objects from the result
+- added *Db.buildObjects(Class modelClass, ResultSet rs)* method to build objects from the ResultSet of a plain sql query
+- added *ThreadLocal<T> com.iciql.Utils.newThreadLocal(final Class<? extends T> clazz)* method
+- added optional console statement logger and SLF4J statement logger
+- throw *IciqlException* (which is a RuntimeException) instead of RuntimeException
+- synchronized *Db.classMap* for concurrent sharing of a Db instance
+- Database/table versioning uses the <b>_iq_versions </b> table, the <b>_ jq_versions</b> table, if present, is ignored
+- Changed the following class names:
+ - org.h2.jaqu.Table => com.iciql.Iciql
+ - org.h2.jaqu.JQSchema => com.iciql.IQSchema
+ - org.h2.jaqu.JQDatabase => com.iciql.IQDatabase
+ - org.h2.jaqu.JQIndex => com.iciql.IQIndex
+ - org.h2.jaqu.JQTable => com.iciql.IQTable
+ - org.h2.jaqu.JQColumn => com.iciql.IQColumn
+- Changed the following method names:
+ - org.h2.jaqu.Table.define() => com.iciql.Iciql.defineIQ()
+ - QueryConditon.bigger => QueryCondition.exceeds
+ - QueryConditon.biggerEqual => QueryCondition.atLeast
+ - QueryConditon.smaller => QueryCondition.lessThan
+ - QueryConditon.smallEqual => QueryCondition.atMost
+
+### Older Releases
+
+none
\ No newline at end of file diff --git a/docs/resources/iciql-favicon.png b/docs/resources/iciql-favicon.png Binary files differnew file mode 100644 index 0000000..dda916b --- /dev/null +++ b/docs/resources/iciql-favicon.png diff --git a/docs/resources/iciql.css b/docs/resources/iciql.css new file mode 100644 index 0000000..7f8a48b --- /dev/null +++ b/docs/resources/iciql.css @@ -0,0 +1,152 @@ +/*
+ iciql css.
+*/
+html, body, table, dl, dt, dd, ol, ul, li, form, a, span, tr, th, td, div, em {
+ font-family: verdana, sans-serif;
+ font-size: 12px;
+ line-height: 1.35em;
+ margin: 0;
+ padding: 0;
+ border: 0;
+ outline: 0;
+}
+
+body {
+ width: 980px;
+ margin: 5px;
+ background-color: #ffffff;
+ color: #000000;
+ margin-right: auto;
+ margin-left: auto;
+ padding: 0px;
+ background: url(background.png) repeat-x scroll 0 0 #FFFFFF;
+}
+
+iframe {
+ margin-top:5px;
+ /*border: 1px solid #ccc;*/
+}
+
+pre, code, pre.prettyprint {
+ color: black;
+ font-family: monospace;
+ font-size:12px;
+ border:0px;
+}
+
+pre.prettyprint {
+ background-color: #fdfdfd !important;
+ border: 1px solid #ccc !important;
+}
+
+pre, pre.prettyprint {
+ margin-left: 5px;
+ margin-right: 5px;
+}
+
+table {
+ border-collapse: collapse;
+ empty-cells: show;
+ font-size: 1em;
+}
+
+td, th {
+ background-color: inherit;
+ border: 1px solid #CCCCCC;
+ padding: 6px 12px;
+ text-align: left;
+ vertical-align: top;
+ margin: 0;
+}
+
+img.inlineIcon {
+ padding-left: 1px;
+ padding-right: 1px;
+}
+
+img.overview {
+ float:right;
+ border:1px solid #CCCCCC;
+}
+
+a {
+ color: #0000cc;
+}
+
+a:hover, a:visited, a:active {
+ color: #880000;
+}
+
+img.logo {
+ margin-top:-8px;
+ float: right;
+ border-width: 0px;
+}
+
+div.page_header {
+ height: 26px;
+ padding: 5px;
+ font-family: sans-serif;
+ font-weight: bold;
+ font-size: 200%;
+ color: #888;
+ background: transparent;
+}
+
+div.page_header span {
+ font-family: inherit;
+ font-size: inherit;
+}
+
+div.page_footer {
+ clear: both;
+ height: 17px;
+ color: black;
+ background-color: #ffffff;
+ padding: 5px;
+ border-top: 1px solid #bbb;
+ font-style: italic;
+}
+
+div.page_nav {
+ margin-top:10px;
+ padding: 5px;
+ border-radius: 3px;
+ background-color: #fdfdfd;
+ border: 1px solid #ccc;
+ color: #ccc;
+}
+
+div.page_nav a {
+ text-decoration: none;
+ color: blue;
+}
+
+div.page_nav a:hover {
+ text-decoration: underline;
+}
+
+div.page_nav em {
+ font-style: normal;
+}
+
+div.javadoc_nav {
+ text-align: center;
+ margin-top:0px;
+ padding: 5px;
+ border-bottom: 1px solid #ccc;
+ color: #ccc;
+}
+
+div.javadoc_nav a {
+ text-decoration: none;
+ color: blue;
+}
+
+div.javadoc_nav a:hover {
+ text-decoration: underline;
+}
+
+div.javadoc_nav em {
+ font-style: normal;
+}
\ No newline at end of file diff --git a/docs/resources/iciql.png b/docs/resources/iciql.png Binary files differnew file mode 100644 index 0000000..aa1da69 --- /dev/null +++ b/docs/resources/iciql.png diff --git a/docs/resources/iciql.xcf b/docs/resources/iciql.xcf Binary files differnew file mode 100644 index 0000000..1f9f501 --- /dev/null +++ b/docs/resources/iciql.xcf diff --git a/docs/resources/javadoc.css b/docs/resources/javadoc.css new file mode 100644 index 0000000..8a8b972 --- /dev/null +++ b/docs/resources/javadoc.css @@ -0,0 +1,52 @@ +/* Javadoc style sheet */
+
+/* Define colors, fonts and other style attributes here to override the defaults */
+
+/* Page background color */
+body { font-size:13px; background-color: #FFFFFF; color:#000000 }
+
+hr {
+ color: #ffffff;
+ background-color: #ffffff;
+ height: 1px; !important
+}
+
+/* Headings */
+h1 { font-size: 1.5em }
+h2 { font-size: 1.5em }
+
+table {
+ border: 1px solid #ccc; !important
+}
+
+table th {
+ border: 0px solid #ccc; !important
+ font-size: 1.0em; !important
+}
+
+table th font {
+ font-size: 1.3em; !important
+}
+
+table td {
+ border: 0px solid; !important
+}
+
+/* Table colors */
+.TableHeadingColor { background-color: #f0f0f0; } /* light gray */
+.TableSubHeadingColor { background-color: #f0f0f0; } /* light gray */
+.TableRowColor { }
+
+/* Font used in left-hand frame lists */
+.FrameTitleFont { }
+.FrameHeadingFont { }
+.FrameItemFont { }
+
+/* Navigation bar fonts and colors */
+.NavBarCell1 { background-color:#f0f0f0; } /* light gray */
+.NavBarCell1Rev { background-color:#00008B; color:#ffffff} /* Dark Blue */
+.NavBarFont1 { }
+.NavBarFont1Rev { color:#ffffff;}
+
+.NavBarCell2 { }
+.NavBarCell3 { }
\ No newline at end of file diff --git a/docs/resources/markdown.css b/docs/resources/markdown.css new file mode 100644 index 0000000..0caecd1 --- /dev/null +++ b/docs/resources/markdown.css @@ -0,0 +1,67 @@ +/*
+ * Git:Blit Markdown CSS definition.
+ */
+
+div.markdown {
+ line-height: 1.4em;
+}
+
+div.markdown h1,
+div.markdown h2,
+div.markdown h3,
+div.markdown h4,
+div.markdown h5,
+div.markdown h6 {
+ border: 0 none !important;
+}
+
+div.markdown h1 {
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+ padding-bottom: 0.5em;
+ border-bottom: 2px solid #000080 !important;
+}
+
+div.markdown h2 {
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+ padding-bottom: 0.5em;
+ border-bottom: 2px solid #000080 !important;
+}
+
+div.markdown pre {
+ background-color: #fdfdfd !important;
+ border: 1px solid #ccc !important;
+ border-radius: 3px;
+ overflow: auto;
+ padding: 5px;
+}
+
+div.markdown pre code {
+ background-color: inherit;
+ border: none;
+ padding: 0;
+}
+
+div.markdown code {
+ background-color: #ffffe0;
+ border: 1px solid orange;
+ border-radius: 3px;
+ padding: 0 0.2em;
+}
+
+div.markdown a {
+ text-decoration: underline;
+}
+
+div.markdown ul, div.markdown ol {
+ padding-left: 30px;
+}
+
+div.markdown li {
+ margin: 0.2em 0 0 0em; padding: 0px;
+}
+
+div.markdown em {
+ color: #b05000;
+}
\ No newline at end of file diff --git a/docs/resources/prettify.css b/docs/resources/prettify.css new file mode 100644 index 0000000..2925d13 --- /dev/null +++ b/docs/resources/prettify.css @@ -0,0 +1 @@ +.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun{color:#660}.pln{color:#000}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec{color:#606}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee}@media print{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun{color:#440}.pln{color:#000}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}
\ No newline at end of file diff --git a/docs/resources/prettify.js b/docs/resources/prettify.js new file mode 100644 index 0000000..c9161da --- /dev/null +++ b/docs/resources/prettify.js @@ -0,0 +1,33 @@ +window.PR_SHOULD_USE_CONTINUATION=true;window.PR_TAB_WIDTH=8;window.PR_normalizedHtml=window.PR=window.prettyPrintOne=window.prettyPrint=void 0;window._pr_isIE6=function(){var y=navigator&&navigator.userAgent&&navigator.userAgent.match(/\bMSIE ([678])\./);y=y?+y[1]:false;window._pr_isIE6=function(){return y};return y}; +(function(){function y(b){return b.replace(L,"&").replace(M,"<").replace(N,">")}function H(b,f,i){switch(b.nodeType){case 1:var o=b.tagName.toLowerCase();f.push("<",o);var l=b.attributes,n=l.length;if(n){if(i){for(var r=[],j=n;--j>=0;)r[j]=l[j];r.sort(function(q,m){return q.name<m.name?-1:q.name===m.name?0:1});l=r}for(j=0;j<n;++j){r=l[j];r.specified&&f.push(" ",r.name.toLowerCase(),'="',r.value.replace(L,"&").replace(M,"<").replace(N,">").replace(X,"""),'"')}}f.push(">"); +for(l=b.firstChild;l;l=l.nextSibling)H(l,f,i);if(b.firstChild||!/^(?:br|link|img)$/.test(o))f.push("</",o,">");break;case 3:case 4:f.push(y(b.nodeValue));break}}function O(b){function f(c){if(c.charAt(0)!=="\\")return c.charCodeAt(0);switch(c.charAt(1)){case "b":return 8;case "t":return 9;case "n":return 10;case "v":return 11;case "f":return 12;case "r":return 13;case "u":case "x":return parseInt(c.substring(2),16)||c.charCodeAt(1);case "0":case "1":case "2":case "3":case "4":case "5":case "6":case "7":return parseInt(c.substring(1), +8);default:return c.charCodeAt(1)}}function i(c){if(c<32)return(c<16?"\\x0":"\\x")+c.toString(16);c=String.fromCharCode(c);if(c==="\\"||c==="-"||c==="["||c==="]")c="\\"+c;return c}function o(c){var d=c.substring(1,c.length-1).match(RegExp("\\\\u[0-9A-Fa-f]{4}|\\\\x[0-9A-Fa-f]{2}|\\\\[0-3][0-7]{0,2}|\\\\[0-7]{1,2}|\\\\[\\s\\S]|-|[^-\\\\]","g"));c=[];for(var a=[],k=d[0]==="^",e=k?1:0,h=d.length;e<h;++e){var g=d[e];switch(g){case "\\B":case "\\b":case "\\D":case "\\d":case "\\S":case "\\s":case "\\W":case "\\w":c.push(g); +continue}g=f(g);var s;if(e+2<h&&"-"===d[e+1]){s=f(d[e+2]);e+=2}else s=g;a.push([g,s]);if(!(s<65||g>122)){s<65||g>90||a.push([Math.max(65,g)|32,Math.min(s,90)|32]);s<97||g>122||a.push([Math.max(97,g)&-33,Math.min(s,122)&-33])}}a.sort(function(v,w){return v[0]-w[0]||w[1]-v[1]});d=[];g=[NaN,NaN];for(e=0;e<a.length;++e){h=a[e];if(h[0]<=g[1]+1)g[1]=Math.max(g[1],h[1]);else d.push(g=h)}a=["["];k&&a.push("^");a.push.apply(a,c);for(e=0;e<d.length;++e){h=d[e];a.push(i(h[0]));if(h[1]>h[0]){h[1]+1>h[0]&&a.push("-"); +a.push(i(h[1]))}}a.push("]");return a.join("")}function l(c){for(var d=c.source.match(RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g")),a=d.length,k=[],e=0,h=0;e<a;++e){var g=d[e];if(g==="(")++h;else if("\\"===g.charAt(0))if((g=+g.substring(1))&&g<=h)k[g]=-1}for(e=1;e<k.length;++e)if(-1===k[e])k[e]=++n;for(h=e=0;e<a;++e){g=d[e];if(g==="("){++h;if(k[h]===undefined)d[e]="(?:"}else if("\\"=== +g.charAt(0))if((g=+g.substring(1))&&g<=h)d[e]="\\"+k[h]}for(h=e=0;e<a;++e)if("^"===d[e]&&"^"!==d[e+1])d[e]="";if(c.ignoreCase&&r)for(e=0;e<a;++e){g=d[e];c=g.charAt(0);if(g.length>=2&&c==="[")d[e]=o(g);else if(c!=="\\")d[e]=g.replace(/[a-zA-Z]/g,function(s){s=s.charCodeAt(0);return"["+String.fromCharCode(s&-33,s|32)+"]"})}return d.join("")}for(var n=0,r=false,j=false,q=0,m=b.length;q<m;++q){var t=b[q];if(t.ignoreCase)j=true;else if(/[a-z]/i.test(t.source.replace(/\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi, +""))){r=true;j=false;break}}var p=[];q=0;for(m=b.length;q<m;++q){t=b[q];if(t.global||t.multiline)throw Error(""+t);p.push("(?:"+l(t)+")")}return RegExp(p.join("|"),j?"gi":"g")}function Y(b){var f=0;return function(i){for(var o=null,l=0,n=0,r=i.length;n<r;++n)switch(i.charAt(n)){case "\t":o||(o=[]);o.push(i.substring(l,n));l=b-f%b;for(f+=l;l>=0;l-=16)o.push(" ".substring(0,l));l=n+1;break;case "\n":f=0;break;default:++f}if(!o)return i;o.push(i.substring(l));return o.join("")}}function I(b, +f,i,o){if(f){b={source:f,c:b};i(b);o.push.apply(o,b.d)}}function B(b,f){var i={},o;(function(){for(var r=b.concat(f),j=[],q={},m=0,t=r.length;m<t;++m){var p=r[m],c=p[3];if(c)for(var d=c.length;--d>=0;)i[c.charAt(d)]=p;p=p[1];c=""+p;if(!q.hasOwnProperty(c)){j.push(p);q[c]=null}}j.push(/[\0-\uffff]/);o=O(j)})();var l=f.length;function n(r){for(var j=r.c,q=[j,z],m=0,t=r.source.match(o)||[],p={},c=0,d=t.length;c<d;++c){var a=t[c],k=p[a],e=void 0,h;if(typeof k==="string")h=false;else{var g=i[a.charAt(0)]; +if(g){e=a.match(g[1]);k=g[0]}else{for(h=0;h<l;++h){g=f[h];if(e=a.match(g[1])){k=g[0];break}}e||(k=z)}if((h=k.length>=5&&"lang-"===k.substring(0,5))&&!(e&&typeof e[1]==="string")){h=false;k=P}h||(p[a]=k)}g=m;m+=a.length;if(h){h=e[1];var s=a.indexOf(h),v=s+h.length;if(e[2]){v=a.length-e[2].length;s=v-h.length}k=k.substring(5);I(j+g,a.substring(0,s),n,q);I(j+g+s,h,Q(k,h),q);I(j+g+v,a.substring(v),n,q)}else q.push(j+g,k)}r.d=q}return n}function x(b){var f=[],i=[];if(b.tripleQuotedStrings)f.push([A,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/, +null,"'\""]);else b.multiLineStrings?f.push([A,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"]):f.push([A,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"]);b.verbatimStrings&&i.push([A,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null]);if(b.hashComments)if(b.cStyleComments){f.push([C,/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"]);i.push([A,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/, +null])}else f.push([C,/^#[^\r\n]*/,null,"#"]);if(b.cStyleComments){i.push([C,/^\/\/[^\r\n]*/,null]);i.push([C,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}b.regexLiterals&&i.push(["lang-regex",RegExp("^"+Z+"(/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/)")]);b=b.keywords.replace(/^\s+|\s+$/g,"");b.length&&i.push([R,RegExp("^(?:"+b.replace(/\s+/g,"|")+")\\b"),null]);f.push([z,/^\s+/,null," \r\n\t\u00a0"]);i.push([J,/^@[a-z_$][a-z_$@0-9]*/i,null],[S,/^@?[A-Z]+[a-z][A-Za-z_$@0-9]*/, +null],[z,/^[a-z_$][a-z_$@0-9]*/i,null],[J,/^(?:0x[a-f0-9]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+\-]?\d+)?)[a-z]*/i,null,"0123456789"],[E,/^.[^\s\w\.$@\'\"\`\/\#]*/,null]);return B(f,i)}function $(b){function f(D){if(D>r){if(j&&j!==q){n.push("</span>");j=null}if(!j&&q){j=q;n.push('<span class="',j,'">')}var T=y(p(i.substring(r,D))).replace(e?d:c,"$1 ");e=k.test(T);n.push(T.replace(a,s));r=D}}var i=b.source,o=b.g,l=b.d,n=[],r=0,j=null,q=null,m=0,t=0,p=Y(window.PR_TAB_WIDTH),c=/([\r\n ]) /g, +d=/(^| ) /gm,a=/\r\n?|\n/g,k=/[ \r\n]$/,e=true,h=window._pr_isIE6();h=h?b.b.tagName==="PRE"?h===6?" \r\n":h===7?" <br>\r":" \r":" <br />":"<br />";var g=b.b.className.match(/\blinenums\b(?::(\d+))?/),s;if(g){for(var v=[],w=0;w<10;++w)v[w]=h+'</li><li class="L'+w+'">';var F=g[1]&&g[1].length?g[1]-1:0;n.push('<ol class="linenums"><li class="L',F%10,'"');F&&n.push(' value="',F+1,'"');n.push(">");s=function(){var D=v[++F%10];return j?"</span>"+D+'<span class="'+j+'">':D}}else s=h; +for(;;)if(m<o.length?t<l.length?o[m]<=l[t]:true:false){f(o[m]);if(j){n.push("</span>");j=null}n.push(o[m+1]);m+=2}else if(t<l.length){f(l[t]);q=l[t+1];t+=2}else break;f(i.length);j&&n.push("</span>");g&&n.push("</li></ol>");b.a=n.join("")}function u(b,f){for(var i=f.length;--i>=0;){var o=f[i];if(G.hasOwnProperty(o))"console"in window&&console.warn("cannot override language handler %s",o);else G[o]=b}}function Q(b,f){b&&G.hasOwnProperty(b)||(b=/^\s*</.test(f)?"default-markup":"default-code");return G[b]} +function U(b){var f=b.f,i=b.e;b.a=f;try{var o,l=f.match(aa);f=[];var n=0,r=[];if(l)for(var j=0,q=l.length;j<q;++j){var m=l[j];if(m.length>1&&m.charAt(0)==="<"){if(!ba.test(m))if(ca.test(m)){f.push(m.substring(9,m.length-3));n+=m.length-12}else if(da.test(m)){f.push("\n");++n}else if(m.indexOf(V)>=0&&m.replace(/\s(\w+)\s*=\s*(?:\"([^\"]*)\"|'([^\']*)'|(\S+))/g,' $1="$2$3$4"').match(/[cC][lL][aA][sS][sS]=\"[^\"]*\bnocode\b/)){var t=m.match(W)[2],p=1,c;c=j+1;a:for(;c<q;++c){var d=l[c].match(W);if(d&& +d[2]===t)if(d[1]==="/"){if(--p===0)break a}else++p}if(c<q){r.push(n,l.slice(j,c+1).join(""));j=c}else r.push(n,m)}else r.push(n,m)}else{var a;p=m;var k=p.indexOf("&");if(k<0)a=p;else{for(--k;(k=p.indexOf("&#",k+1))>=0;){var e=p.indexOf(";",k);if(e>=0){var h=p.substring(k+3,e),g=10;if(h&&h.charAt(0)==="x"){h=h.substring(1);g=16}var s=parseInt(h,g);isNaN(s)||(p=p.substring(0,k)+String.fromCharCode(s)+p.substring(e+1))}}a=p.replace(ea,"<").replace(fa,">").replace(ga,"'").replace(ha,'"').replace(ia," ").replace(ja, +"&")}f.push(a);n+=a.length}}o={source:f.join(""),h:r};var v=o.source;b.source=v;b.c=0;b.g=o.h;Q(i,v)(b);$(b)}catch(w){if("console"in window)console.log(w&&w.stack?w.stack:w)}}var A="str",R="kwd",C="com",S="typ",J="lit",E="pun",z="pln",P="src",V="nocode",Z=function(){for(var b=["!","!=","!==","#","%","%=","&","&&","&&=","&=","(","*","*=","+=",",","-=","->","/","/=",":","::",";","<","<<","<<=","<=","=","==","===",">",">=",">>",">>=",">>>",">>>=","?","@","[","^","^=","^^","^^=","{","|","|=","||","||=", +"~","break","case","continue","delete","do","else","finally","instanceof","return","throw","try","typeof"],f="(?:^^|[+-]",i=0;i<b.length;++i)f+="|"+b[i].replace(/([^=<>:&a-z])/g,"\\$1");f+=")\\s*";return f}(),L=/&/g,M=/</g,N=/>/g,X=/\"/g,ea=/</g,fa=/>/g,ga=/'/g,ha=/"/g,ja=/&/g,ia=/ /g,ka=/[\r\n]/g,K=null,aa=RegExp("[^<]+|<!--[\\s\\S]*?--\>|<!\\[CDATA\\[[\\s\\S]*?\\]\\]>|</?[a-zA-Z](?:[^>\"']|'[^']*'|\"[^\"]*\")*>|<","g"),ba=/^<\!--/,ca=/^<!\[CDATA\[/,da=/^<br\b/i,W=/^<(\/?)([a-zA-Z][a-zA-Z0-9]*)/, +la=x({keywords:"break continue do else for if return while auto case char const default double enum extern float goto int long register short signed sizeof static struct switch typedef union unsigned void volatile catch class delete false import new operator private protected public this throw true try typeof alignof align_union asm axiom bool concept concept_map const_cast constexpr decltype dynamic_cast explicit export friend inline late_check mutable namespace nullptr reinterpret_cast static_assert static_cast template typeid typename using virtual wchar_t where break continue do else for if return while auto case char const default double enum extern float goto int long register short signed sizeof static struct switch typedef union unsigned void volatile catch class delete false import new operator private protected public this throw true try typeof abstract boolean byte extends final finally implements import instanceof null native package strictfp super synchronized throws transient as base by checked decimal delegate descending event fixed foreach from group implicit in interface internal into is lock object out override orderby params partial readonly ref sbyte sealed stackalloc string select uint ulong unchecked unsafe ushort var break continue do else for if return while auto case char const default double enum extern float goto int long register short signed sizeof static struct switch typedef union unsigned void volatile catch class delete false import new operator private protected public this throw true try typeof debugger eval export function get null set undefined var with Infinity NaN caller delete die do dump elsif eval exit foreach for goto if import last local my next no our print package redo require sub undef unless until use wantarray while BEGIN END break continue do else for if return while and as assert class def del elif except exec finally from global import in is lambda nonlocal not or pass print raise try with yield False True None break continue do else for if return while alias and begin case class def defined elsif end ensure false in module next nil not or redo rescue retry self super then true undef unless until when yield BEGIN END break continue do else for if return while case done elif esac eval fi function in local set then until ", +hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true}),G={};u(la,["default-code"]);u(B([],[[z,/^[^<?]+/],["dec",/^<!\w[^>]*(?:>|$)/],[C,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[E,/^(?:<[%?]|[%?]>)/],["lang-",/^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup", +"htm","html","mxml","xhtml","xml","xsl"]);u(B([[z,/^[\s]+/,null," \t\r\n"],["atv",/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[E,/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i], +["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);u(B([],[["atv",/^[\s\S]+/]]),["uq.val"]);u(x({keywords:"break continue do else for if return while auto case char const default double enum extern float goto int long register short signed sizeof static struct switch typedef union unsigned void volatile catch class delete false import new operator private protected public this throw true try typeof alignof align_union asm axiom bool concept concept_map const_cast constexpr decltype dynamic_cast explicit export friend inline late_check mutable namespace nullptr reinterpret_cast static_assert static_cast template typeid typename using virtual wchar_t where ", +hashComments:true,cStyleComments:true}),["c","cc","cpp","cxx","cyc","m"]);u(x({keywords:"null true false"}),["json"]);u(x({keywords:"break continue do else for if return while auto case char const default double enum extern float goto int long register short signed sizeof static struct switch typedef union unsigned void volatile catch class delete false import new operator private protected public this throw true try typeof abstract boolean byte extends final finally implements import instanceof null native package strictfp super synchronized throws transient as base by checked decimal delegate descending event fixed foreach from group implicit in interface internal into is lock object out override orderby params partial readonly ref sbyte sealed stackalloc string select uint ulong unchecked unsafe ushort var ", +hashComments:true,cStyleComments:true,verbatimStrings:true}),["cs"]);u(x({keywords:"break continue do else for if return while auto case char const default double enum extern float goto int long register short signed sizeof static struct switch typedef union unsigned void volatile catch class delete false import new operator private protected public this throw true try typeof abstract boolean byte extends final finally implements import instanceof null native package strictfp super synchronized throws transient ", +cStyleComments:true}),["java"]);u(x({keywords:"break continue do else for if return while case done elif esac eval fi function in local set then until ",hashComments:true,multiLineStrings:true}),["bsh","csh","sh"]);u(x({keywords:"break continue do else for if return while and as assert class def del elif except exec finally from global import in is lambda nonlocal not or pass print raise try with yield False True None ",hashComments:true,multiLineStrings:true,tripleQuotedStrings:true}),["cv","py"]); +u(x({keywords:"caller delete die do dump elsif eval exit foreach for goto if import last local my next no our print package redo require sub undef unless until use wantarray while BEGIN END ",hashComments:true,multiLineStrings:true,regexLiterals:true}),["perl","pl","pm"]);u(x({keywords:"break continue do else for if return while alias and begin case class def defined elsif end ensure false in module next nil not or redo rescue retry self super then true undef unless until when yield BEGIN END ",hashComments:true, +multiLineStrings:true,regexLiterals:true}),["rb"]);u(x({keywords:"break continue do else for if return while auto case char const default double enum extern float goto int long register short signed sizeof static struct switch typedef union unsigned void volatile catch class delete false import new operator private protected public this throw true try typeof debugger eval export function get null set undefined var with Infinity NaN ",cStyleComments:true,regexLiterals:true}),["js"]);u(B([],[[A,/^[\s\S]+/]]), +["regex"]);window.PR_normalizedHtml=H;window.prettyPrintOne=function(b,f){var i={f:b,e:f};U(i);return i.a};window.prettyPrint=function(b){function f(){for(var t=window.PR_SHOULD_USE_CONTINUATION?j.now()+250:Infinity;q<o.length&&j.now()<t;q++){var p=o[q];if(p.className&&p.className.indexOf("prettyprint")>=0){var c=p.className.match(/\blang-(\w+)\b/);if(c)c=c[1];for(var d=false,a=p.parentNode;a;a=a.parentNode)if((a.tagName==="pre"||a.tagName==="code"||a.tagName==="xmp")&&a.className&&a.className.indexOf("prettyprint")>= +0){d=true;break}if(!d){a=p;if(null===K){d=document.createElement("PRE");d.appendChild(document.createTextNode('<!DOCTYPE foo PUBLIC "foo bar">\n<foo />'));K=!/</.test(d.innerHTML)}if(K){d=a.innerHTML;if("XMP"===a.tagName)d=y(d);else{a=a;if("PRE"===a.tagName)a=true;else if(ka.test(d)){var k="";if(a.currentStyle)k=a.currentStyle.whiteSpace;else if(window.getComputedStyle)k=window.getComputedStyle(a,null).whiteSpace;a=!k||k==="pre"}else a=true;a||(d=d.replace(/(<br\s*\/?>)[\r\n]+/g,"$1").replace(/(?:[\r\n]+[ \t]*)+/g, +" "))}d=d}else{d=[];for(a=a.firstChild;a;a=a.nextSibling)H(a,d);d=d.join("")}d=d.replace(/(?:\r\n?|\n)$/,"");m={f:d,e:c,b:p};U(m);if(p=m.a){c=m.b;if("XMP"===c.tagName){d=document.createElement("PRE");for(a=0;a<c.attributes.length;++a){k=c.attributes[a];if(k.specified)if(k.name.toLowerCase()==="class")d.className=k.value;else d.setAttribute(k.name,k.value)}d.innerHTML=p;c.parentNode.replaceChild(d,c)}else c.innerHTML=p}}}}if(q<o.length)setTimeout(f,250);else b&&b()}for(var i=[document.getElementsByTagName("pre"), +document.getElementsByTagName("code"),document.getElementsByTagName("xmp")],o=[],l=0;l<i.length;++l)for(var n=0,r=i[l].length;n<r;++n)o.push(i[l][n]);i=null;var j=Date;j.now||(j={now:function(){return(new Date).getTime()}});var q=0,m;f()};window.PR={combinePrefixPatterns:O,createSimpleLexer:B,registerLangHandler:u,sourceDecorator:x,PR_ATTRIB_NAME:"atn",PR_ATTRIB_VALUE:"atv",PR_COMMENT:C,PR_DECLARATION:"dec",PR_KEYWORD:R,PR_LITERAL:J,PR_NOCODE:V,PR_PLAIN:z,PR_PUNCTUATION:E,PR_SOURCE:P,PR_STRING:A, +PR_TAG:"tag",PR_TYPE:S}})()
\ No newline at end of file diff --git a/docs/resources/site_footer.html b/docs/resources/site_footer.html new file mode 100644 index 0000000..e1a5738 --- /dev/null +++ b/docs/resources/site_footer.html @@ -0,0 +1,7 @@ + </div>
+ <div style="margin-top:10px" class="page_footer">
+ <div style="float:right;">{0}</div>
+ The content of this page is licensed under the <a href="http://creativecommons.org/licenses/by/3.0">Creative Commons Attribution 3.0 License</a>.
+ </div>
+</body>
+</html>
\ No newline at end of file diff --git a/docs/resources/site_header.html b/docs/resources/site_header.html new file mode 100644 index 0000000..8ac117a --- /dev/null +++ b/docs/resources/site_header.html @@ -0,0 +1,32 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+ <head>
+ <title>iciql</title>
+ <link rel="stylesheet" type="text/css" href="./iciql.css"/>
+ <link rel="stylesheet" type="text/css" href="./markdown.css"/>
+ <link rel="shortcut icon" type="image/png" href="./iciql-favicon.png" />
+ <meta name="ROBOTS" content="INDEX">
+ <meta http-equiv="imagetoolbar" content="no" />
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <meta name="keywords" content="java sql query jaqu" />
+
+ <script type="text/javascript" src="prettify.js"></script>
+ <link href="prettify.css" type="text/css" rel="stylesheet" />
+
+ <!-- Place this tag in your head or just before your close body tag -->
+ <script type="text/javascript" src="https://apis.google.com/js/plusone.js"></script>
+
+ <!-- ANALYTICS -->
+ </head>
+ <body style="width:900px" onload="prettyPrint()">
+ <a href="http://github.com/iciql><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://d3nwyuy0nl342s.cloudfront.net/img/30f550e0d38ceb6ef5b81500c64d970b7fb0f028/687474703a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f6f72616e67655f6666373630302e706e67" alt="Fork me on GitHub"></a>
+ <div class="page_header">
+ <a title="iciql homepage" href="http://iciql.com/">
+ <img src="./iciql.png" width="76" height="48" alt="iciql" class="logo"/>
+ </a>
+ <span style="color:black;">{0}</span>
+ <!-- Google Plus One -->
+ <g:plusone></g:plusone>
+ </div>
+ <div class="page_nav">{1}</div>
+ <div class="markdown">
\ No newline at end of file |