<classpathentry kind="lib" path="ext/derby-10.11.1.1.jar" />
<classpathentry kind="lib" path="ext/mysql-connector-java-5.1.33.jar" />
<classpathentry kind="lib" path="ext/postgresql-9.3-1102-jdbc4.jar" sourcepath="ext/src/postgresql-9.3-1102-jdbc4.jar" />
+ <classpathentry kind="lib" path="ext/sqlite-jdbc-3.8.7.jar" sourcepath="ext/src/sqlite-jdbc-3.8.7.jar" />
<classpathentry kind="lib" path="ext/slf4j-api-1.6.1.jar" sourcepath="ext/src/slf4j-api-1.6.1.jar" />
<classpathentry kind="lib" path="ext/commons-pool-1.5.6.jar" sourcepath="ext/src/commons-pool-1.5.6.jar" />
<classpathentry kind="lib" path="ext/commons-dbcp-1.4.jar" sourcepath="ext/src/commons-dbcp-1.4.jar" />
iciql **is not**...\r
\r
- a complete alternative to JDBC\r
-- designed to compete with more powerful database query tools like [jOOQ](http://jooq.sourceforge.net) or [Querydsl](http://source.mysema.com/display/querydsl/Querydsl)\r
+- designed to compete with more powerful database query tools like [jOOQ](http://jooq.sourceforge.net) or [QueryDSL](http://source.mysema.com/display/querydsl/Querydsl)\r
- designed to compete with enterprise ORM tools like [Hibernate](http://www.hibernate.org) or [mybatis](http://www.mybatis.org)\r
\r
Supported Databases (Unit-Tested)\r
- [Derby](http://db.apache.org/derby) 10.11\r
- [MySQL](http://mysql.com) 5.6\r
- [PostgreSQL](http://postgresql.org) 9.3\r
+- [SQLite](http://www.sqlite.org) 3.8\r
\r
Support for others is possible and may only require creating a simple "dialect" class.\r
\r
Getting help\r
-------\r
Read the online documentation available at the [iciql website](http://iciql.com)<br/>\r
-Issues, binaries, & sources @ [Google Code](http://code.google.com/p/iciql)\r
+Issues & sources @ [GitHub](http://github.com/gitblit/iciql)\r
+Binaries @ [Iciql Maven Repository](http://gitblit.github.io/iciql/maven/)\r
\r
Building iciql\r
----------------\r
derby.version : 10.11.1.1
mysql.version : 5.6
postgresql.version : 9.3
+ sqlite.version : 3.8.7
}
dependencies:
- provided 'org.apache.derby:derby:${derby.version}'
- provided 'mysql:mysql-connector-java:5.1.33'
- provided 'org.postgresql:postgresql:9.3-1102-jdbc4'
+- provided 'org.xerial:sqlite-jdbc:${sqlite.version}'
- provided 'org.slf4j:slf4j-api:1.6.1'
- provided 'commons-pool:commons-pool:1.5.6'
- provided 'commons-dbcp:commons-dbcp:1.4'
DIALECTS.put("MySQL", SQLDialectMySQL.class);\r
DIALECTS.put("PostgreSQL", SQLDialectPostgreSQL.class);\r
DIALECTS.put("Microsoft SQL Server", SQLDialectMSSQL.class);\r
+ DIALECTS.put("SQLite", SQLDialectSQLite.class);\r
}\r
\r
private Db(Connection conn) {\r
// MySQL duplicate primary key on insert\r
iciqlCode = CODE_DUPLICATE_KEY;\r
if (s.getErrorCode() == 1217) {\r
- iciqlCode = CODE_CONSTRAINT_VIOLATION; \r
+ iciqlCode = CODE_CONSTRAINT_VIOLATION;\r
}\r
} else if ("23505".equals(state)) {\r
// Derby duplicate primary key on insert\r
} else if ("X0Y25".equals(state)) {\r
// Derby constraint violation\r
iciqlCode = CODE_CONSTRAINT_VIOLATION;\r
+ } else if (s.getMessage().startsWith("[SQLITE")) {\r
+ // SQLite error codes\r
+ final String msg = s.getMessage();\r
+ switch (s.getErrorCode()) {\r
+ case 1:\r
+ iciqlCode = CODE_OBJECT_NOT_FOUND;\r
+ break;\r
+ case 19:\r
+ if (msg.contains("UNIQUE")) {\r
+ iciqlCode = CODE_DUPLICATE_KEY;\r
+ } else {\r
+ iciqlCode = CODE_CONSTRAINT_VIOLATION;\r
+ }\r
+ break;\r
+ default:\r
+ iciqlCode = s.getErrorCode();\r
+ break;\r
+ }\r
} else {\r
// uncharacterized SQL code, we can always rely on iciqlCode != 0 in IciqlException\r
iciqlCode = s.getErrorCode() == 0 ? CODE_UNCHARACTERIZED : s.getErrorCode();\r
--- /dev/null
+/*\r
+ * Copyright 2014 James Moger.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package com.iciql;\r
+\r
+import com.iciql.TableDefinition.FieldDefinition;\r
+import com.iciql.TableDefinition.IndexDefinition;\r
+import com.iciql.util.IciqlLogger;\r
+import com.iciql.util.StatementBuilder;\r
+\r
+\r
+/**\r
+ * SQLite database dialect.\r
+ */\r
+public class SQLDialectSQLite extends SQLDialectDefault {\r
+\r
+ @Override\r
+ public boolean supportsSavePoints() {\r
+ return false;\r
+ }\r
+\r
+ @Override\r
+ public void configureDialect(Db db) {\r
+ super.configureDialect(db);\r
+ // enable foreign key constraint enforcement\r
+ db.executeUpdate("PRAGMA foreign_keys = ON;");\r
+ }\r
+\r
+ @Override\r
+ protected <T> String prepareCreateTable(TableDefinition<T> def) {\r
+ return "CREATE TABLE IF NOT EXISTS";\r
+ }\r
+\r
+ @Override\r
+ protected <T> String prepareCreateView(TableDefinition<T> def) {\r
+ return "CREATE VIEW IF NOT EXISTS";\r
+ }\r
+\r
+ @Override\r
+ public <T> void prepareDropView(SQLStatement stat, TableDefinition<T> def) {\r
+ StatementBuilder buff = new StatementBuilder("DROP VIEW IF EXISTS "\r
+ + prepareTableName(def.schemaName, def.tableName));\r
+ stat.setSQL(buff.toString());\r
+ return;\r
+ }\r
+\r
+ @Override\r
+ public void prepareCreateIndex(SQLStatement stat, String schemaName, String tableName,\r
+ IndexDefinition index) {\r
+ StatementBuilder buff = new StatementBuilder();\r
+ buff.append("CREATE ");\r
+ switch (index.type) {\r
+ case UNIQUE:\r
+ buff.append("UNIQUE ");\r
+ break;\r
+ case UNIQUE_HASH:\r
+ buff.append("UNIQUE ");\r
+ break;\r
+ default:\r
+ IciqlLogger.warn("{0} does not support hash indexes", getClass().getSimpleName());\r
+ }\r
+ buff.append("INDEX IF NOT EXISTS ");\r
+ buff.append(index.indexName);\r
+ buff.append(" ON ");\r
+ // FIXME maybe we can use schemaName ?\r
+ // buff.append(prepareTableName(schemaName, tableName));\r
+ buff.append(tableName);\r
+ buff.append("(");\r
+ for (String col : index.columnNames) {\r
+ buff.appendExceptFirst(", ");\r
+ buff.append(prepareColumnName(col));\r
+ }\r
+ buff.append(") ");\r
+\r
+ stat.setSQL(buff.toString().trim());\r
+ }\r
+\r
+ @Override\r
+ public <T> void prepareMerge(SQLStatement stat, String schemaName, String tableName,\r
+ TableDefinition<T> def, Object obj) {\r
+ StatementBuilder buff = new StatementBuilder("INSERT OR REPLACE INTO ");\r
+ buff.append(prepareTableName(schemaName, tableName)).append(" (");\r
+ buff.resetCount();\r
+ for (FieldDefinition field : def.fields) {\r
+ buff.appendExceptFirst(", ");\r
+ buff.append(field.columnName);\r
+ }\r
+ buff.append(") ");\r
+ buff.resetCount();\r
+ buff.append("VALUES (");\r
+ for (FieldDefinition field : def.fields) {\r
+ buff.appendExceptFirst(", ");\r
+ buff.append('?');\r
+ Object value = def.getValue(obj, field);\r
+ Object parameter = serialize(value, field.typeAdapter);\r
+ stat.addParameter(parameter);\r
+ }\r
+ buff.append(')');\r
+ stat.setSQL(buff.toString());\r
+ }\r
+\r
+}
\ No newline at end of file
iciql **is not**...\r
\r
- a complete alternative to JDBC\r
-- designed to compete with more powerful database query tools like [jOOQ][jooq] or [Querydsl][querydsl]\r
+- designed to compete with more powerful database query tools like [jOOQ][jooq] or [QueryDSL][querydsl]\r
- designed to compete with enterprise [ORM][orm] tools like [Hibernate][hibernate] or [mybatis][mybatis]\r
\r
### Example Usage\r
- [Derby](http://db.apache.org/derby) ${derby.version}\r
- [MySQL](http://mysql.com) ${mysql.version}\r
- [PostgreSQL](http://postgresql.org) ${postgresql.version}\r
+- [SQLite](http://www.sqlite.org) ${sqlite.version}\r
\r
Support for others is possible and may only require creating a simple "dialect" class.\r
\r
[hibernate]: http://www.hibernate.org "Hibernate"\r
[mybatis]: http://www.mybatis.org "mybatis"\r
[github]: http://github.com/gitblit/iciql "iciql git repository"\r
-[googlecode]: http://code.google.com/p/iciql "iciql project management"\r
[apachelicense]: http://www.apache.org/licenses/LICENSE-2.0 "Apache License, Version 2.0"
\ No newline at end of file
<tr><th></th><th>Iciql</th><th>JaQu</th></tr>\r
<tr><th colspan="3">core</th></tr>\r
<tr><td>deployment</td><td>small, discrete library</td><td>depends on H2 database jar file</td></tr>\r
-<tr><td>databases</td><td>H2, HSQL, Derby, MySQL, and PostreSQL</td><td>H2 only</td></tr>\r
+<tr><td>databases</td><td>H2, HSQL, Derby, MySQL, PostreSQL, and SQLite</td><td>H2 only</td></tr>\r
<tr><td>logging</td><td>console, SLF4J, or custom logging</td><td>console logging</td></tr>\r
<tr><td>exceptions</td><td>always includes generated statement in exception, when available</td><td>--</td></tr>\r
<tr><td>column mappings</td><td>wildcard queries index result sets by column name</td><td>all result sets built by field index<br/>this can fail for wildcard queries</td></tr>\r
new TestDb("Derby", true, true, "jdbc:derby:memory:iciql;create=true"),\r
new TestDb("Derby", true, false, "jdbc:derby:directory:testdbs/derby/iciql;create=true"),\r
new TestDb("MySQL", false, false, "jdbc:mysql://localhost:3306/iciql", "sa", "sa"),\r
- new TestDb("PostgreSQL", false, false, "jdbc:postgresql://localhost:5432/iciql", "sa", "sa") };\r
+ new TestDb("PostgreSQL", false, false, "jdbc:postgresql://localhost:5432/iciql", "sa", "sa"),\r
+ new TestDb("SQLite", true, true, "jdbc:sqlite:file:iciql?mode=memory&cache=shared"),\r
+ new TestDb("SQLite", true, false, "jdbc:sqlite:"\r
+ + new File(baseFolder, "/sqlite/iciql.db").getAbsolutePath())\r
+ };\r
\r
private static final TestDb DEFAULT_TEST_DB = TEST_DBS[0];\r
\r
return IciqlSuite.getDatabaseEngineName(db).equals("MySQL");\r
}\r
\r
+ /**\r
+ * Returns true if the underlying database engine is SQLite.\r
+ *\r
+ * @param db\r
+ * @return true if underlying database engine is SQLite\r
+ */\r
+ public static boolean isSQLite(Db db) {\r
+ return IciqlSuite.getDatabaseEngineName(db).equals("SQLite");\r
+ }\r
+\r
/**\r
* Gets the default schema of the underlying database engine.\r
*\r
}\r
\r
deleteRecursively(baseFolder);\r
+ new File(baseFolder, "/sqlite").mkdirs();\r
\r
// Start the HSQL and H2 servers in-process\r
org.hsqldb.Server hsql = startHSQL();\r
out.println(dividerMajor);\r
out.println(MessageFormat.format("{0} {1} ({2}) test suite performance results", Constants.NAME,\r
Constants.VERSION, Constants.VERSION_DATE));\r
+\r
+ StringBuilder compressedSystem = new StringBuilder();\r
+ compressedSystem.append(" on ");\r
+ compressedSystem.append(System.getProperty("java.vendor"));\r
+ compressedSystem.append(' ');\r
+ compressedSystem.append(System.getProperty("java.runtime.version"));\r
+ compressedSystem.append(", ");\r
+ compressedSystem.append(System.getProperty("os.name"));\r
+ compressedSystem.append(' ');\r
+ compressedSystem.append(System.getProperty("os.version"));\r
+ compressedSystem.append(", ");\r
+ compressedSystem.append(System.getProperty("os.arch"));\r
+ out.println(compressedSystem.toString());\r
+\r
out.println(dividerMajor);\r
List<TestDb> dbs = Arrays.asList(TEST_DBS);\r
Collections.sort(dbs);\r
\r
/**\r
* Tests the database and table upgrade functions.\r
- * \r
+ *\r
*/\r
public class UpgradesTest {\r
\r
\r
// open a second connection to the database\r
// and then apply the v2 upgrade.\r
- // For H2 its important to keep the first connection\r
+ // For an in-memory db its important to keep the first connection\r
// alive so that the database is not destroyed.\r
Db db2 = IciqlSuite.openCurrentDb();\r
\r
db.close();\r
db2.close();\r
}\r
- \r
+\r
@Test\r
public void testDatabaseInheritedUpgrade() {\r
Db db = IciqlSuite.openNewDb();\r
\r
// open a second connection to the database\r
// and then apply the v2 upgrade.\r
- // For H2 its important to keep the first connection\r
+ // For an in-memory db its important to keep the first connection\r
// alive so that the database is not destroyed.\r
Db db2 = IciqlSuite.openCurrentDb();\r
\r
final AtomicInteger oldVersion = new AtomicInteger(0);\r
final AtomicInteger newVersion = new AtomicInteger(0);\r
\r
+ @Override\r
public boolean upgradeTable(Db db, String schema, String table, int fromVersion, int toVersion) {\r
// just claims success on upgrade request\r
oldVersion.set(fromVersion);\r
return true;\r
}\r
\r
+ @Override\r
public boolean upgradeDatabase(Db db, int fromVersion, int toVersion) {\r
// just claims success on upgrade request\r
oldVersion.set(fromVersion);\r
class V2DbUpgrader extends BaseDbUpgrader {\r
}\r
\r
- \r
+\r
/**\r
* A sample V2 database upgrader class which inherits its\r
* version from the parent class.\r