#169 fixed UNION and date/time handling for SQLite

This commit is contained in:
Timo Westkämper 2012-06-17 12:15:44 +03:00
parent bc7685fbae
commit ed5fec9b65
15 changed files with 287 additions and 28 deletions

View File

@ -297,6 +297,7 @@ public class FilterFactory {
if (!target.equals(Target.DERBY)
&& !target.equals(Target.HSQLDB)
&& !target.equals(Target.H2)
&& !target.equals(Target.SQLITE)
&& !target.equals(Target.SQLSERVER)){
rv.add(expr.matches(knownValue.substring(0,1)+".*"));
rv.add(expr.matches(".*"+knownValue.substring(1)));

View File

@ -259,6 +259,7 @@ public class MatchingFiltersFactory {
|| (!target.equals(Target.HSQLDB)
&& !target.equals(Target.H2)
&& !target.equals(Target.DERBY)
&& !target.equals(Target.SQLITE)
&& !target.equals(Target.SQLSERVER))){
rv.add(expr.matches(other));

View File

@ -43,6 +43,7 @@ import com.mysema.query.types.ParamExpression;
import com.mysema.query.types.Path;
import com.mysema.query.types.Predicate;
import com.mysema.query.types.SubQueryExpression;
import com.mysema.query.types.TemplateExpression;
import com.mysema.query.types.TemplateExpressionImpl;
/**
@ -97,6 +98,8 @@ public class SQLSerializer extends SerializerBase<SQLSerializer> {
private final SQLTemplates templates;
private boolean inUnion = false;
public SQLSerializer(SQLTemplates templates) {
this(templates, false, false);
}
@ -457,7 +460,10 @@ public class SQLSerializer extends SerializerBase<SQLSerializer> {
@SuppressWarnings("unchecked")
public void serializeUnion(SubQueryExpression[] sqs, QueryMetadata metadata, boolean unionAll) {
// union
boolean oldInUnion = inUnion;
inUnion = true;
handle(unionAll ? templates.getUnionAll() : templates.getUnion(), Arrays.asList(sqs));
inUnion = oldInUnion;
// order by
if (!metadata.getOrderBy().isEmpty()) {
@ -547,9 +553,26 @@ public class SQLSerializer extends SerializerBase<SQLSerializer> {
@Override
public Void visit(SubQueryExpression<?> query, Void context) {
append("(");
serialize(query.getMetadata(), false);
append(")");
if (inUnion) {
serialize(query.getMetadata(), false);
} else {
append("(");
serialize(query.getMetadata(), false);
append(")");
}
return null;
}
@Override
public Void visit(TemplateExpression<?> expr, Void context) {
if (expr.getTemplate().toString().toLowerCase().contains("union")) {
boolean oldInUnion = inUnion;
inUnion = true;
super.visit(expr, context);
inUnion = oldInUnion;
} else {
super.visit(expr, context);
}
return null;
}

View File

@ -15,7 +15,6 @@ package com.mysema.query.sql;
import com.mysema.query.types.Ops;
//work in progress
/**
* @author tiwe
*
@ -38,17 +37,20 @@ public class SQLiteTemplates extends SQLTemplates {
add(Ops.INDEX_OF, "charindex({1},{0},1)-1");
add(Ops.INDEX_OF_2ARGS, "charindex({1},{0},{2s}+1)-1");
add(Ops.CONCAT, "{0} || {1}");
add(Ops.DateTimeOps.YEAR, "cast(strftime('%Y',{0},'unixepoch') as integer)");
add(Ops.DateTimeOps.YEAR_MONTH, "strftime('%Y',{0}) * 100 + strftime('%m',{0})");
add(Ops.DateTimeOps.MONTH, "cast(strftime('%m',{0},'unixepoch') as integer)");
add(Ops.DateTimeOps.WEEK, "cast(strftime('%W',{0},'unixepoch') as integer) + 1");
add(Ops.DateTimeOps.DAY_OF_MONTH, "cast(strftime('%d',{0}) as integer) + 1");
add(Ops.DateTimeOps.DAY_OF_WEEK, "cast(strftime('%w',{0}) as integer) ");
add(Ops.DateTimeOps.DAY_OF_YEAR, "cast(strftime('%j',{0}) as integer)");
add(Ops.DateTimeOps.HOUR, "cast(strftime('%H',{0}) as integer)");
add(Ops.DateTimeOps.MINUTE, "cast(strftime('%M',{0}) as integer)");
add(Ops.DateTimeOps.SECOND, "cast(strftime('%S',{0}) as integer)");
// TODO : optimize
add(Ops.DateTimeOps.YEAR, "cast(strftime('%Y',{0} / 1000, 'unixepoch', 'localtime') as integer)");
add(Ops.DateTimeOps.YEAR_MONTH, "strftime('%Y',{0} / 1000, 'unixepoch', 'localtime') * 100 + strftime('%m',{0} / 1000, 'unixepoch', 'localtime')");
add(Ops.DateTimeOps.MONTH, "cast(strftime('%m',{0} / 1000, 'unixepoch', 'localtime') as integer)");
add(Ops.DateTimeOps.WEEK, "cast(strftime('%W',{0} / 1000, 'unixepoch', 'localtime') as integer) + 1");
add(Ops.DateTimeOps.DAY_OF_MONTH, "cast(strftime('%d',{0} / 1000, 'unixepoch', 'localtime') as integer)");
add(Ops.DateTimeOps.DAY_OF_WEEK, "cast(strftime('%w',{0} / 1000, 'unixepoch', 'localtime') as integer) + 1");
add(Ops.DateTimeOps.DAY_OF_YEAR, "cast(strftime('%j',{0} / 1000, 'unixepoch', 'localtime') as integer)");
add(Ops.DateTimeOps.HOUR, "cast(strftime('%H',{0} / 1000, 'unixepoch', 'localtime') as integer)");
add(Ops.DateTimeOps.MINUTE, "cast(strftime('%M',{0} / 1000, 'unixepoch', 'localtime') as integer)");
add(Ops.DateTimeOps.SECOND, "cast(strftime('%S',{0} / 1000, 'unixepoch', 'localtime') as integer)");
}
}

View File

@ -129,9 +129,9 @@ public final class Connections {
}
private static Connection getSQLite() throws SQLException, ClassNotFoundException {
System.setProperty("sqlite.purejava", "true");
//System.setProperty("sqlite.purejava", "true");
Class.forName("org.sqlite.JDBC");
return DriverManager.getConnection("jdbc:sqlite:");
return DriverManager.getConnection("jdbc:sqlite:target/sample.db");
}
private static CreateTableClause createTable(SQLTemplates templates, String table){

View File

@ -0,0 +1,43 @@
/*
* Copyright 2011, Mysema Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mysema.query._sqlite;
import java.sql.SQLException;
import org.junit.Before;
import org.junit.BeforeClass;
import com.mysema.query.Connections;
import com.mysema.query.DeleteBaseTest;
import com.mysema.query.Target;
import com.mysema.query.sql.SQLiteTemplates;
import com.mysema.testutil.Label;
@Label(Target.SQLITE)
public class DeleteSQLiteTest extends DeleteBaseTest{
@BeforeClass
public static void setUpClass() throws Exception {
Connections.initSQLite();
}
@Before
public void setUp() throws SQLException {
templates = new SQLiteTemplates(){{
newLineToSingleSpace();
}};
super.setUp();
}
}

View File

@ -0,0 +1,43 @@
/*
* Copyright 2011, Mysema Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mysema.query._sqlite;
import java.sql.SQLException;
import org.junit.Before;
import org.junit.BeforeClass;
import com.mysema.query.Connections;
import com.mysema.query.InsertBaseTest;
import com.mysema.query.Target;
import com.mysema.query.sql.SQLiteTemplates;
import com.mysema.testutil.Label;
@Label(Target.SQLITE)
public class InsertSQLiteTest extends InsertBaseTest{
@BeforeClass
public static void setUpClass() throws Exception {
Connections.initSQLite();
}
@Before
public void setUp() throws SQLException {
templates = new SQLiteTemplates(){{
newLineToSingleSpace();
}};
super.setUp();
}
}

View File

@ -0,0 +1,43 @@
/*
* Copyright 2011, Mysema Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mysema.query._sqlite;
import java.sql.SQLException;
import org.junit.Before;
import org.junit.BeforeClass;
import com.mysema.query.Connections;
import com.mysema.query.LikeEscapeBaseTest;
import com.mysema.query.Target;
import com.mysema.query.sql.SQLiteTemplates;
import com.mysema.testutil.Label;
@Label(Target.SQLITE)
public class LikeEscapeSQLiteTest extends LikeEscapeBaseTest{
@BeforeClass
public static void setUpClass() throws Exception {
Connections.initSQLite();
}
@Before
public void setUp() throws SQLException {
templates = new SQLiteTemplates('!', false){{
newLineToSingleSpace();
}};
super.setUp();
}
}

View File

@ -0,0 +1,42 @@
/*
* Copyright 2011, Mysema Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mysema.query._sqlite;
import java.sql.SQLException;
import org.junit.Before;
import org.junit.BeforeClass;
import com.mysema.query.Connections;
import com.mysema.query.MergeBaseTest;
import com.mysema.query.Target;
import com.mysema.query.sql.SQLiteTemplates;
import com.mysema.testutil.Label;
@Label(Target.SQLITE)
public class MergeSQLiteTest extends MergeBaseTest{
@BeforeClass
public static void setUpClass() throws Exception {
Connections.initSQLite();
}
@Before
public void setUp() throws SQLException {
templates = new SQLiteTemplates(){{
newLineToSingleSpace();
}};
super.setUp();
}
}

View File

@ -17,7 +17,6 @@ import static com.mysema.query.Constants.employee;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import com.mysema.query.Connections;
@ -27,7 +26,6 @@ import com.mysema.query.sql.SQLQuery;
import com.mysema.query.sql.SQLiteTemplates;
import com.mysema.testutil.Label;
@Ignore // work in progress
@Label(Target.SQLITE)
public class SelectSQLiteTest extends SelectBaseTest {

View File

@ -0,0 +1,20 @@
package com.mysema.query._sqlite;
import org.junit.BeforeClass;
import com.mysema.query.Connections;
import com.mysema.query.Target;
import com.mysema.query.TypesBaseTest;
import com.mysema.testutil.Label;
@Label(Target.SQLITE)
public class TypesSQLiteTest extends TypesBaseTest {
// not supported
@BeforeClass
public static void setUpClass() throws Exception {
Connections.initSQLite();
}
}

View File

@ -0,0 +1,43 @@
/*
* Copyright 2011, Mysema Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mysema.query._sqlite;
import java.sql.SQLException;
import org.junit.Before;
import org.junit.BeforeClass;
import com.mysema.query.Connections;
import com.mysema.query.Target;
import com.mysema.query.UpdateBaseTest;
import com.mysema.query.sql.SQLiteTemplates;
import com.mysema.testutil.Label;
@Label(Target.SQLITE)
public class UpdateSQLiteTest extends UpdateBaseTest{
@BeforeClass
public static void setUpClass() throws Exception {
Connections.initSQLite();
}
@Before
public void setUp() throws SQLException {
templates = new SQLiteTemplates(){{
newLineToSingleSpace();
}};
super.setUp();
}
}

View File

@ -59,11 +59,11 @@ public abstract class AbstractSQLTemplatesTest {
sq().unique(two),
sq().unique(three));
assertEquals(
"(select 1 as col1 from dual) " +
"select 1 as col1 from dual " +
"union " +
"(select 2 from dual) " +
"select 2 from dual " +
"union " +
"(select 3 from dual)", union.toString());
"select 3 from dual", union.toString());
}
@Test

View File

@ -45,11 +45,11 @@ public class OracleTemplatesTest extends AbstractSQLTemplatesTest{
sq().unique(two),
sq().unique(three));
assertEquals(
"(select 1 col1 from dual) " +
"select 1 col1 from dual " +
"union " +
"(select 2 from dual) " +
"select 2 from dual " +
"union " +
"(select 3 from dual)", union.toString());
"select 3 from dual", union.toString());
}
@Test

View File

@ -53,11 +53,11 @@ public class SQLServerTemplatesTest extends AbstractSQLTemplatesTest{
sq().unique(two),
sq().unique(three));
assertEquals(
"(select 1 as col1) " +
"select 1 as col1 " +
"union " +
"(select 2) " +
"select 2 " +
"union " +
"(select 3)", union.toString());
"select 3", union.toString());
}
@Test