mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
Merge pull request #1697 from ebean-orm/feature/1695-binary
#1695 - For MySql like remove the binary keyword + Add caseSensitiveCollation configuration option
This commit is contained in:
@@ -227,9 +227,9 @@
|
||||
<!--</dependency>-->
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-docker-run</artifactId>
|
||||
<version>1.5.1</version>
|
||||
<groupId>io.ebean.test</groupId>
|
||||
<artifactId>ebean-test-docker</artifactId>
|
||||
<version>2.5.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -280,7 +280,7 @@
|
||||
<dependency>
|
||||
<groupId>com.microsoft.sqlserver</groupId>
|
||||
<artifactId>mssql-jdbc</artifactId>
|
||||
<version>7.2.0.jre8</version>
|
||||
<version>7.2.2.jre8</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
@@ -52,6 +52,8 @@ public class PlatformConfig {
|
||||
*/
|
||||
private boolean databaseInetAddressVarchar;
|
||||
|
||||
private boolean caseSensitiveCollation = true;
|
||||
|
||||
/**
|
||||
* Modify the default mapping of standard types such as default precision for DECIMAL etc.
|
||||
*/
|
||||
@@ -74,6 +76,7 @@ public class PlatformConfig {
|
||||
this.idType = platformConfig.idType;
|
||||
this.geometrySRID = platformConfig.geometrySRID;
|
||||
this.dbUuid = platformConfig.dbUuid;
|
||||
this.caseSensitiveCollation = platformConfig.caseSensitiveCollation;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -90,6 +93,20 @@ public class PlatformConfig {
|
||||
this.allQuotedIdentifiers = allQuotedIdentifiers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the collation is case sensitive.
|
||||
*/
|
||||
public boolean isCaseSensitiveCollation() {
|
||||
return caseSensitiveCollation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set to false to indicate that the collation is case insensitive.
|
||||
*/
|
||||
public void setCaseSensitiveCollation(boolean caseSensitiveCollation) {
|
||||
this.caseSensitiveCollation = caseSensitiveCollation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a value used to represent TRUE in the database.
|
||||
* <p>
|
||||
@@ -255,6 +272,7 @@ public class PlatformConfig {
|
||||
databaseBooleanTrue = p.get("databaseBooleanTrue", databaseBooleanTrue);
|
||||
databaseBooleanFalse = p.get("databaseBooleanFalse", databaseBooleanFalse);
|
||||
databaseInetAddressVarchar = p.getBoolean("databaseInetAddressVarchar", databaseInetAddressVarchar);
|
||||
caseSensitiveCollation = p.getBoolean("caseSensitiveCollation", caseSensitiveCollation);
|
||||
|
||||
DbUuid dbUuid = p.getEnum(DbUuid.class, "dbuuid", null);
|
||||
if (dbUuid != null) {
|
||||
|
||||
@@ -71,6 +71,8 @@ public class DatabasePlatform {
|
||||
*/
|
||||
protected boolean allQuotedIdentifiers;
|
||||
|
||||
protected boolean caseSensitiveCollation = true;
|
||||
|
||||
/**
|
||||
* For limit/offset, row_number etc limiting of SQL queries.
|
||||
*/
|
||||
@@ -226,6 +228,7 @@ public class DatabasePlatform {
|
||||
*/
|
||||
public void configure(PlatformConfig config) {
|
||||
this.sequenceBatchSize = config.getDatabaseSequenceBatchSize();
|
||||
this.caseSensitiveCollation = config.isCaseSensitiveCollation();
|
||||
configureIdType(config.getIdType());
|
||||
configure(config, config.isAllQuotedIdentifiers());
|
||||
}
|
||||
@@ -315,6 +318,16 @@ public class DatabasePlatform {
|
||||
return supportsDeleteTableAlias;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the collation is case sensitive.
|
||||
* <p>
|
||||
* This is expected to be used for testing only.
|
||||
* </p>
|
||||
*/
|
||||
public boolean isCaseSensitiveCollation() {
|
||||
return caseSensitiveCollation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the maximum table name length.
|
||||
* <p>
|
||||
|
||||
@@ -35,7 +35,7 @@ public class MySqlPlatform extends DatabasePlatform {
|
||||
this.dbIdentity.setSupportsGetGeneratedKeys(true);
|
||||
this.dbIdentity.setSupportsIdentity(true);
|
||||
this.dbIdentity.setSupportsSequence(false);
|
||||
|
||||
|
||||
this.dbDefaultValue.setNow("now(6)"); // must have same precision as TIMESTAMP
|
||||
this.dbDefaultValue.setFalse("0");
|
||||
this.dbDefaultValue.setTrue("1");
|
||||
@@ -51,8 +51,8 @@ public class MySqlPlatform extends DatabasePlatform {
|
||||
this.openQuote = "`";
|
||||
this.closeQuote = "`";
|
||||
// use pipe for escaping as it depends if mysql runs in no_backslash_escapes or not.
|
||||
this.likeClauseRaw = "like binary ? escape ''";
|
||||
this.likeClauseEscaped = "like binary ? escape '|'";
|
||||
this.likeClauseRaw = "like ? escape ''";
|
||||
this.likeClauseEscaped = "like ? escape '|'";
|
||||
|
||||
this.forwardOnlyHintOnFindIterate = true;
|
||||
this.booleanDbType = Types.BIT;
|
||||
|
||||
@@ -47,8 +47,8 @@ abstract class SqlServerBasePlatform extends DatabasePlatform {
|
||||
this.openQuote = "[";
|
||||
this.closeQuote = "]";
|
||||
this.likeSpecialCharacters = new char[]{'%', '_', '['};
|
||||
this.likeClauseRaw = "like ? collate Latin1_General_BIN";
|
||||
this.likeClauseEscaped = "like ? collate Latin1_General_BIN";
|
||||
this.likeClauseRaw = "like ?";
|
||||
this.likeClauseEscaped = "like ?";
|
||||
|
||||
booleanDbType = Types.INTEGER;
|
||||
this.dbDefaultValue.setFalse("0");
|
||||
|
||||
@@ -49,11 +49,11 @@ CREATE OR ALTER PROCEDURE usp_ebean_drop_default_constraint @tableName nvarchar(
|
||||
AS SET NOCOUNT ON
|
||||
declare @tmp nvarchar(1000)
|
||||
BEGIN
|
||||
select @Tmp = t1.name from sys.default_constraints t1
|
||||
select @tmp = t1.name from sys.default_constraints t1
|
||||
join sys.columns t2 on t1.object_id = t2.default_object_id
|
||||
where t1.parent_object_id = OBJECT_ID(@tableName) and t2.name = @columnName;
|
||||
|
||||
if @Tmp is not null EXEC('alter table ' + @tableName +' drop constraint ' + @tmp);
|
||||
if @tmp is not null EXEC('alter table ' + @tableName +' drop constraint ' + @tmp);
|
||||
END
|
||||
$$
|
||||
|
||||
@@ -171,13 +171,13 @@ AS
|
||||
BEGIN
|
||||
DECLARE foreign_key_names TABLE(CONSTRAINT_NAME NVARCHAR(256), TABLE_NAME NVARCHAR(256));
|
||||
DECLARE i INT;
|
||||
|
||||
|
||||
foreign_key_names = SELECT CONSTRAINT_NAME, TABLE_NAME FROM SYS.REFERENTIAL_CONSTRAINTS WHERE SCHEMA_NAME=CURRENT_SCHEMA AND TABLE_NAME=UPPER(:table_name) AND COLUMN_NAME=UPPER(:column_name);
|
||||
|
||||
|
||||
FOR I IN 1 .. RECORD_COUNT(:foreign_key_names) DO
|
||||
EXEC 'ALTER TABLE "' || ESCAPE_DOUBLE_QUOTES(:foreign_key_names.TABLE_NAME[i]) || '" DROP CONSTRAINT "' || ESCAPE_DOUBLE_QUOTES(:foreign_key_names.CONSTRAINT_NAME[i]) || '"';
|
||||
END FOR;
|
||||
|
||||
|
||||
END;
|
||||
$$
|
||||
|
||||
|
||||
@@ -126,6 +126,10 @@ public abstract class BaseTestCase {
|
||||
return sql;
|
||||
}
|
||||
|
||||
public boolean isPlatformCaseSensitive() {
|
||||
return spiEbeanServer().getDatabasePlatform().isCaseSensitiveCollation();
|
||||
}
|
||||
|
||||
/**
|
||||
* MS SQL Server does not allow setting explicit values on identity columns
|
||||
* so tests that do this need to be skipped for SQL Server.
|
||||
|
||||
@@ -132,10 +132,13 @@ public class EbeanServer_eqlTest extends BaseTestCase {
|
||||
Query<Customer> query = Ebean.createQuery(Customer.class);
|
||||
query.setMaxRows(10);
|
||||
query.setFirstRow(3);
|
||||
if (isSqlServer()) {
|
||||
query.orderBy("id");
|
||||
}
|
||||
query.findList();
|
||||
|
||||
if (isSqlServer()) {
|
||||
assertThat(query.getGeneratedSql()).endsWith("from o_customer t0 offset 3 rows fetch next 10 rows only");
|
||||
assertThat(query.getGeneratedSql()).endsWith("from o_customer t0 order by t0.id offset 3 rows fetch next 10 rows only");
|
||||
} else if (isOracle()) {
|
||||
assertThat(query.getGeneratedSql()).contains("where rownum <= 13");
|
||||
assertThat(query.getGeneratedSql()).contains("where rn_ > 3");
|
||||
|
||||
@@ -70,6 +70,7 @@ public class ServerConfigTest {
|
||||
props.setProperty("namingConvention", "io.ebean.config.MatchingNamingConvention");
|
||||
props.setProperty("idGeneratorAutomatic", "true");
|
||||
props.setProperty("enabledL2Regions", "r0,users,orgs");
|
||||
props.setProperty("caseSensitiveCollation", "false");
|
||||
|
||||
|
||||
serverConfig.loadFromProperties(props);
|
||||
@@ -79,6 +80,7 @@ public class ServerConfigTest {
|
||||
assertTrue(serverConfig.isDbOffline());
|
||||
assertTrue(serverConfig.isAutoReadOnlyDataSource());
|
||||
assertTrue(serverConfig.isIdGeneratorAutomatic());
|
||||
assertFalse(serverConfig.getPlatformConfig().isCaseSensitiveCollation());
|
||||
|
||||
assertThat(serverConfig.getNamingConvention()).isInstanceOf(MatchingNamingConvention.class);
|
||||
|
||||
@@ -131,6 +133,7 @@ public class ServerConfigTest {
|
||||
assertFalse(serverConfig.isIdGeneratorAutomatic());
|
||||
assertEquals(JsonConfig.DateTime.ISO8601, serverConfig.getJsonDateTime());
|
||||
assertEquals(JsonConfig.Date.ISO8601, serverConfig.getJsonDate());
|
||||
assertTrue(serverConfig.getPlatformConfig().isCaseSensitiveCollation());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -596,7 +596,7 @@ public class EqlParserTest extends BaseTestCase {
|
||||
|
||||
ResetBasicData.reset();
|
||||
|
||||
Query<Customer> query = parse("limit 10 offset 5");
|
||||
Query<Customer> query = parse("order by name limit 10 offset 5");
|
||||
query.findList();
|
||||
if (isH2()) {
|
||||
assertThat(query.getGeneratedSql()).contains(" limit 10 offset 5");
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package main;
|
||||
|
||||
import io.ebean.docker.commands.MySqlConfig;
|
||||
import io.ebean.docker.commands.MySqlContainer;
|
||||
|
||||
public class StartMyServer {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
MySqlConfig config = new MySqlConfig("5.7");
|
||||
config.setDbName("unit");
|
||||
config.setUser("unit");
|
||||
config.setPassword("unit");
|
||||
|
||||
// by default this mysql docker collation is case sensitive
|
||||
// using utf8mb4_bin
|
||||
//
|
||||
// when changing to a CI collation (e.g. utf8mb4_unicode_ci) we also set
|
||||
// ebean.<db>.caseSensitiveCollation=false
|
||||
// ... such that tests now take that into account
|
||||
// config.setCollation("default");
|
||||
// config.setCollation("utf8mb4_unicode_ci");
|
||||
// config.setCharacterSet("utf8mb4");
|
||||
|
||||
MySqlContainer container = new MySqlContainer(config);
|
||||
container.start();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package main;
|
||||
|
||||
import io.ebean.docker.commands.SqlServerConfig;
|
||||
import io.ebean.docker.commands.SqlServerContainer;
|
||||
|
||||
public class StartSqlServer {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
SqlServerConfig config = new SqlServerConfig("2017-CU4");
|
||||
config.setDbName("test_ebean");
|
||||
config.setUser("test_ebean");
|
||||
|
||||
// by default this sqlserver docker collation is case sensitive
|
||||
// using MSSQL_COLLATION=Latin1_General_100_BIN2
|
||||
//
|
||||
// when changing to a CI collation also use
|
||||
// ebean.sqlserver.caseSensitiveCollation=false
|
||||
// ... such that tests now take that into account
|
||||
|
||||
//config.setCollation("default");
|
||||
//config.setCollation("Latin1_General_100_CI");
|
||||
|
||||
SqlServerContainer container = new SqlServerContainer(config);
|
||||
container.start();
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,8 @@ package org.tests.basic;
|
||||
import io.ebean.BaseTestCase;
|
||||
import io.ebean.DB;
|
||||
import io.ebean.Transaction;
|
||||
import io.ebean.annotation.IgnorePlatform;
|
||||
import io.ebean.annotation.Platform;
|
||||
import org.junit.Test;
|
||||
import org.tests.model.basic.Country;
|
||||
import org.tests.model.basic.ResetBasicData;
|
||||
@@ -32,6 +34,7 @@ public class TestQueryUsingConnection extends BaseTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@IgnorePlatform(Platform.SQLSERVER)
|
||||
@Test
|
||||
public void usingTransaction() {
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ public class TestSecondaryQueries extends TransactionalTestCase {
|
||||
|
||||
assertThat(sql).hasSize(1);
|
||||
if (isSqlServer()) {
|
||||
assertThat(trimSql(sql.get(0), 2)).contains("select top 10 t0.id, t0.status, t0.kcustomer_id from o_order t0 order by t0.id");
|
||||
assertThat(trimSql(sql.get(0), 2)).contains("select top 10 t0.id, t0.status, t0.kcustomer_id from o_order t0");
|
||||
} else {
|
||||
assertThat(trimSql(sql.get(0), 2)).contains("select t0.id, t0.status, t0.kcustomer_id from o_order t0");
|
||||
}
|
||||
@@ -91,7 +91,7 @@ public class TestSecondaryQueries extends TransactionalTestCase {
|
||||
|
||||
assertThat(sql).hasSize(1);
|
||||
if (isSqlServer()) {
|
||||
assertThat(trimSql(sql.get(0), 2)).contains("select top 10 t0.id, t0.status from o_order t0 order by t0.id");
|
||||
assertThat(trimSql(sql.get(0), 2)).contains("select top 10 t0.id, t0.status from o_order t0");
|
||||
} else {
|
||||
assertThat(trimSql(sql.get(0), 2)).contains("select t0.id, t0.status from o_order t0");
|
||||
}
|
||||
|
||||
@@ -34,15 +34,20 @@ public class TestOneToManyJoinTableInheritance extends BaseTestCase {
|
||||
|
||||
List<String> sql = LoggedSqlCollector.current();
|
||||
|
||||
boolean hasSequence = isSqlServer(); // uses sequence
|
||||
assertThat(sql).hasSize(11);
|
||||
assertThat(sql.get(0)).contains("insert into class_super ");
|
||||
assertThat(sql.get(1)).contains("-- bind(ClassA)");
|
||||
assertThat(sql.get(2)).contains("-- bind(ClassB)");
|
||||
if (!hasSequence) {
|
||||
assertThat(sql.get(1)).contains("-- bind(ClassA)");
|
||||
assertThat(sql.get(2)).contains("-- bind(ClassB)");
|
||||
}
|
||||
assertThat(sql.get(3)).contains("insert into monkey ");
|
||||
assertThat(sql.get(4)).contains("-- bind(Sim");
|
||||
assertThat(sql.get(5)).contains("-- bind(Tim");
|
||||
assertThat(sql.get(6)).contains("-- bind(Uim");
|
||||
assertThat(sql.get(7)).contains("insert into class_super_monkey (class_super_sid, monkey_mid) values (?, ?)");
|
||||
if (!hasSequence) {
|
||||
assertThat(sql.get(4)).contains("-- bind(Sim");
|
||||
assertThat(sql.get(5)).contains("-- bind(Tim");
|
||||
assertThat(sql.get(6)).contains("-- bind(Uim");
|
||||
assertThat(sql.get(7)).contains("insert into class_super_monkey (class_super_sid, monkey_mid) values (?, ?)");
|
||||
}
|
||||
assertSqlBind(sql, 8, 10);
|
||||
|
||||
ClassA dbA = Ebean.find(ClassA.class, 1);
|
||||
|
||||
@@ -126,6 +126,7 @@ public class TestAddOrderByWithFirstRowsMaxRows extends BaseTestCase {
|
||||
Ebean.find(Order.class)
|
||||
.setFirstRow(10)
|
||||
.setMaxRows(10)
|
||||
.orderBy("id")
|
||||
.findPagedList()
|
||||
.getList();
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package org.tests.query;
|
||||
|
||||
import io.ebean.BaseTestCase;
|
||||
import io.ebean.Ebean;
|
||||
import io.ebean.DB;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.tests.model.basic.Customer;
|
||||
@@ -23,13 +23,17 @@ public class TestQueryFilterCaseInsensitive extends BaseTestCase {
|
||||
|
||||
// Note: this test uses only customer#1..#4
|
||||
|
||||
List<Customer> customers = Ebean.find(Customer.class).where()
|
||||
List<Customer> customers = DB.find(Customer.class).where()
|
||||
.eq("name", "ROB") // case match
|
||||
.le("id", 4).findList();
|
||||
|
||||
assertThat(customers).isEmpty();
|
||||
if (isPlatformCaseSensitive()) {
|
||||
assertThat(customers).isEmpty();
|
||||
} else {
|
||||
assertThat(customers).isNotEmpty();
|
||||
}
|
||||
|
||||
customers = Ebean.find(Customer.class).where()
|
||||
customers = DB.find(Customer.class).where()
|
||||
.ieq("name", "ROB") // case insensitive match
|
||||
.le("id", 4).findList();
|
||||
|
||||
@@ -38,13 +42,17 @@ public class TestQueryFilterCaseInsensitive extends BaseTestCase {
|
||||
|
||||
@Test
|
||||
public void testNe() {
|
||||
List<Customer> customers = Ebean.find(Customer.class).where()
|
||||
List<Customer> customers = DB.find(Customer.class).where()
|
||||
.ne("name", "ROB") // case match
|
||||
.le("id", 4).findList();
|
||||
|
||||
assertThat(customers).hasSize(4);
|
||||
if (isPlatformCaseSensitive()) {
|
||||
assertThat(customers).hasSize(4);
|
||||
} else {
|
||||
assertThat(customers).isNotEmpty();
|
||||
}
|
||||
|
||||
customers = Ebean.find(Customer.class).where()
|
||||
customers = DB.find(Customer.class).where()
|
||||
.ine("name", "ROB") // case insensitive match
|
||||
.le("id", 4).findList();
|
||||
|
||||
@@ -54,13 +62,17 @@ public class TestQueryFilterCaseInsensitive extends BaseTestCase {
|
||||
|
||||
@Test
|
||||
public void testLike() {
|
||||
List<Customer> customers = Ebean.find(Customer.class).where()
|
||||
List<Customer> customers = DB.find(Customer.class).where()
|
||||
.like("name", "%O%") // case match
|
||||
.le("id", 4).findList();
|
||||
|
||||
assertThat(customers).isEmpty();
|
||||
if (isPlatformCaseSensitive()) {
|
||||
assertThat(customers).isEmpty();
|
||||
} else {
|
||||
assertThat(customers).isNotEmpty();
|
||||
}
|
||||
|
||||
customers = Ebean.find(Customer.class).where()
|
||||
customers = DB.find(Customer.class).where()
|
||||
.ilike("name", "%O%") // case insensitive match
|
||||
.le("id", 4).findList();
|
||||
|
||||
@@ -69,29 +81,36 @@ public class TestQueryFilterCaseInsensitive extends BaseTestCase {
|
||||
|
||||
@Test
|
||||
public void testContains() {
|
||||
List<Customer> customers = Ebean.find(Customer.class).where()
|
||||
List<Customer> customers = DB.find(Customer.class).where()
|
||||
.contains("name", "O") // case match
|
||||
.le("id", 4).findList();
|
||||
|
||||
assertThat(customers).isEmpty();
|
||||
if (isPlatformCaseSensitive()) {
|
||||
assertThat(customers).isEmpty();
|
||||
} else {
|
||||
assertThat(customers).isNotEmpty();
|
||||
}
|
||||
|
||||
customers = Ebean.find(Customer.class).where()
|
||||
customers = DB.find(Customer.class).where()
|
||||
.icontains("name", "O") // case insensitive match
|
||||
.le("id", 4).findList();
|
||||
|
||||
assertThat(customers).hasSize(4); // Rob / Fiona / Cust No address / NocCust
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStartsWith() {
|
||||
List<Customer> customers = Ebean.find(Customer.class).where()
|
||||
List<Customer> customers = DB.find(Customer.class).where()
|
||||
.startsWith("name", "RO") // case match
|
||||
.le("id", 4).findList();
|
||||
|
||||
assertThat(customers).isEmpty();
|
||||
if (isPlatformCaseSensitive()) {
|
||||
assertThat(customers).isEmpty();
|
||||
} else {
|
||||
assertThat(customers).isNotEmpty();
|
||||
}
|
||||
|
||||
customers = Ebean.find(Customer.class).where()
|
||||
customers = DB.find(Customer.class).where()
|
||||
.istartsWith("name", "RO") // case insensitive match
|
||||
.le("id", 4).findList();
|
||||
|
||||
@@ -100,13 +119,17 @@ public class TestQueryFilterCaseInsensitive extends BaseTestCase {
|
||||
|
||||
@Test
|
||||
public void testEndsWith() {
|
||||
List<Customer> customers = Ebean.find(Customer.class).where()
|
||||
List<Customer> customers = DB.find(Customer.class).where()
|
||||
.endsWith("name", "OB") // case match
|
||||
.le("id", 4).findList();
|
||||
|
||||
assertThat(customers).isEmpty();
|
||||
if (isPlatformCaseSensitive()) {
|
||||
assertThat(customers).isEmpty();
|
||||
} else {
|
||||
assertThat(customers).isNotEmpty();
|
||||
}
|
||||
|
||||
customers = Ebean.find(Customer.class).where()
|
||||
customers = DB.find(Customer.class).where()
|
||||
.iendsWith("name", "OB") // case insensitive match
|
||||
.le("id", 4).findList();
|
||||
|
||||
|
||||
@@ -94,6 +94,7 @@ public class TestQueryFindPagedList extends BaseTestCase {
|
||||
PagedList<Order> pagedList2 = Ebean.find(Order.class)
|
||||
.setFirstRow(1)
|
||||
.setMaxRows(3)
|
||||
.orderBy("id")
|
||||
.findPagedList();
|
||||
|
||||
pagedList2.loadCount();
|
||||
@@ -109,6 +110,7 @@ public class TestQueryFindPagedList extends BaseTestCase {
|
||||
PagedList<Order> pagedList3 = Ebean.find(Order.class)
|
||||
.setFirstRow(2)
|
||||
.setMaxRows(150)
|
||||
.orderBy("id")
|
||||
.findPagedList();
|
||||
|
||||
assertFalse(pagedList3.hasNext());
|
||||
|
||||
@@ -15,11 +15,16 @@ public class TestQueryOrderById extends BaseTestCase {
|
||||
|
||||
Query<Customer> query = DB.find(Customer.class)
|
||||
.select("id,name")
|
||||
.orderBy("id")
|
||||
.setFirstRow(1)
|
||||
.setMaxRows(5);
|
||||
|
||||
query.findList();
|
||||
assertThat(sqlOf(query)).isEqualTo("select t0.id, t0.name from o_customer t0 limit 5 offset 1");
|
||||
if (isSqlServer()) {
|
||||
assertThat(sqlOf(query)).isEqualTo("select t0.id, t0.name from o_customer t0 order by t0.id offset 1 rows fetch next 5 rows only");
|
||||
} else {
|
||||
assertThat(sqlOf(query)).isEqualTo("select t0.id, t0.name from o_customer t0 order by t0.id limit 5 offset 1");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -32,6 +37,10 @@ public class TestQueryOrderById extends BaseTestCase {
|
||||
.orderById(true);
|
||||
|
||||
query.findList();
|
||||
assertThat(sqlOf(query)).isEqualTo("select t0.id, t0.name from o_customer t0 order by t0.id limit 5 offset 1");
|
||||
if (isSqlServer()) {
|
||||
assertThat(sqlOf(query)).isEqualTo("select t0.id, t0.name from o_customer t0 order by t0.id offset 1 rows fetch next 5 rows only");
|
||||
} else {
|
||||
assertThat(sqlOf(query)).isEqualTo("select t0.id, t0.name from o_customer t0 order by t0.id limit 5 offset 1");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package org.tests.query.other;
|
||||
|
||||
import io.ebean.Ebean;
|
||||
import io.ebean.DB;
|
||||
import io.ebean.TransactionalTestCase;
|
||||
|
||||
import org.tests.model.basic.Customer;
|
||||
@@ -16,76 +16,80 @@ public class TestLikeEscaping extends TransactionalTestCase {
|
||||
public void testLikeEscaping() {
|
||||
// Mysql, PgSql, H2 special chars: "_" "%"
|
||||
// MsSql special chars: "_" "%" "[" AND different Quoting!
|
||||
Ebean.save(ResetBasicData.createCustomer("Paul % Percentage", "*Star", "[none]", 0, null));
|
||||
Ebean.save(ResetBasicData.createCustomer("(none)", "More * Star", "[none]", 0, null));
|
||||
DB.save(ResetBasicData.createCustomer("Paul % Percentage", "*Star", "[none]", 0, null));
|
||||
DB.save(ResetBasicData.createCustomer("(none)", "More * Star", "[none]", 0, null));
|
||||
|
||||
Ebean.save(ResetBasicData.createCustomer("Paul %% Doublepercentage", "|Pipeway", "[other]", 1, null));
|
||||
Ebean.save(ResetBasicData.createCustomer("_Udo Underscore", "|Pipeway", "[other]", 1, null));
|
||||
DB.save(ResetBasicData.createCustomer("Paul %% Doublepercentage", "|Pipeway", "[other]", 1, null));
|
||||
DB.save(ResetBasicData.createCustomer("_Udo Underscore", "|Pipeway", "[other]", 1, null));
|
||||
|
||||
Ebean.save(ResetBasicData.createCustomer("Bodo \\ backslash", "\\BS", "[other]", 1, null));
|
||||
DB.save(ResetBasicData.createCustomer("Bodo \\ backslash", "\\BS", "[other]", 1, null));
|
||||
|
||||
assertThat(Ebean.find(Customer.class)
|
||||
assertThat(DB.find(Customer.class)
|
||||
.where().contains("name", "Paul %%").findCount()
|
||||
).isEqualTo(1);
|
||||
|
||||
assertThat(Ebean.find(Customer.class)
|
||||
assertThat(DB.find(Customer.class)
|
||||
.where().contains("name", "o \\ b").findCount()
|
||||
).isEqualTo(1);
|
||||
|
||||
assertThat(Ebean.find(Customer.class)
|
||||
assertThat(DB.find(Customer.class)
|
||||
.where().contains("name", "o \\\\ b").findCount()
|
||||
).isEqualTo(0);
|
||||
|
||||
assertThat(Ebean.find(Customer.class)
|
||||
assertThat(DB.find(Customer.class)
|
||||
.where().startsWith("name", "_").findCount()
|
||||
).isEqualTo(1);
|
||||
|
||||
assertThat(Ebean.find(Customer.class)
|
||||
if (isPlatformCaseSensitive()) {
|
||||
assertThat(DB.find(Customer.class)
|
||||
.where().startsWith("name", "_u").findCount()
|
||||
).isEqualTo(0);
|
||||
).isEqualTo(0);
|
||||
}
|
||||
|
||||
assertThat(Ebean.find(Customer.class)
|
||||
assertThat(DB.find(Customer.class)
|
||||
.where().istartsWith("name", "_U").findCount()
|
||||
).isEqualTo(1);
|
||||
|
||||
assertThat(Ebean.find(Customer.class)
|
||||
if (isPlatformCaseSensitive()) {
|
||||
assertThat(DB.find(Customer.class)
|
||||
.where().startsWith("shippingAddress.line1", "|p").findCount()
|
||||
).isEqualTo(0);
|
||||
).isEqualTo(0);
|
||||
}
|
||||
|
||||
assertThat(Ebean.find(Customer.class)
|
||||
assertThat(DB.find(Customer.class)
|
||||
.where().startsWith("shippingAddress.line1", "|P").findCount()
|
||||
).isEqualTo(2);
|
||||
|
||||
assertThat(Ebean.find(Customer.class)
|
||||
assertThat(DB.find(Customer.class)
|
||||
.where().startsWith("shippingAddress.line1", "\\B").findCount()
|
||||
).isEqualTo(1);
|
||||
|
||||
assertThat(Ebean.find(Customer.class)
|
||||
assertThat(DB.find(Customer.class)
|
||||
.where().endsWith("billingAddress.line1", "]").findCount()
|
||||
).isEqualTo(5);
|
||||
|
||||
assertThat(Ebean.find(Customer.class)
|
||||
assertThat(DB.find(Customer.class)
|
||||
.where().endsWith("billingAddress.line1", "[none]").findCount()
|
||||
).isEqualTo(2);
|
||||
|
||||
assertThat(Ebean.find(Customer.class)
|
||||
assertThat(DB.find(Customer.class)
|
||||
.where().startsWith("billingAddress.line1", "[none]").findCount()
|
||||
).isEqualTo(2);
|
||||
|
||||
assertThat(Ebean.find(Customer.class)
|
||||
assertThat(DB.find(Customer.class)
|
||||
.where().contains("billingAddress.line1", "[none]").findCount()
|
||||
).isEqualTo(2);
|
||||
|
||||
|
||||
assertThat(Ebean.find(Customer.class)
|
||||
assertThat(DB.find(Customer.class)
|
||||
.where().contains("shippingAddress.line1", "*").findCount()
|
||||
).isEqualTo(2);
|
||||
|
||||
assertThat(Ebean.find(Customer.class)
|
||||
assertThat(DB.find(Customer.class)
|
||||
.where().startsWith("shippingAddress.line1", "*").findCount()
|
||||
).isEqualTo(1);
|
||||
|
||||
assertThat(Ebean.find(Customer.class)
|
||||
assertThat(DB.find(Customer.class)
|
||||
.where().endsWith("shippingAddress.line1", "*").findCount()
|
||||
).isEqualTo(0);
|
||||
}
|
||||
|
||||
@@ -26,10 +26,11 @@ public class TestWhereLikeWithSlash extends BaseTestCase {
|
||||
Query<EBasic> query1 = Ebean.find(EBasic.class).where().like("name", "slash\\mon%").query();
|
||||
List<EBasic> list1 = query1.findList();
|
||||
|
||||
// This doesn't work in the latest version of H2 so disable for now.
|
||||
// Still good on Postgres which was the original issue
|
||||
assertEquals(1, list1.size());
|
||||
|
||||
if (!isMySql()) {
|
||||
// For mysql this assert depends on no_backslash_escapes setting so we won't assert here
|
||||
// Still good on Postgres which was the original issue
|
||||
assertEquals(1, list1.size());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -151,6 +151,7 @@ public class TestRawSqlOrmQuery extends BaseTestCase {
|
||||
|
||||
query.setFirstRow(1);
|
||||
query.setMaxRows(2);
|
||||
query.orderBy("id");
|
||||
|
||||
List<Customer> list = query.findList();
|
||||
|
||||
|
||||
@@ -75,17 +75,22 @@ public class TestBatchModelFlush extends BaseTestCase {
|
||||
assertThat(sql).hasSize(9);
|
||||
|
||||
// first saved to batch - (depth 100)
|
||||
boolean hasSequence = isSqlServer();
|
||||
assertThat(sql.get(0)).contains("insert into mny_b");
|
||||
assertThat(sql.get(1)).contains(" -- bind(BatchMultipleTop_0");
|
||||
assertThat(sql.get(2)).contains(" -- bind(BatchMultipleTop_1");
|
||||
if (!hasSequence) {
|
||||
assertThat(sql.get(1)).contains(" -- bind(BatchMultipleTop_0");
|
||||
assertThat(sql.get(2)).contains(" -- bind(BatchMultipleTop_1");
|
||||
}
|
||||
// second saved to batch - (depth 101)
|
||||
assertThat(sql.get(3)).contains("insert into mt_role");
|
||||
assertThat(sql.get(4)).contains(" -- bind(");
|
||||
assertThat(sql.get(5)).contains(" -- bind(");
|
||||
// third saved to batch - (depth 102)
|
||||
assertThat(sql.get(6)).contains("insert into mny_topic");
|
||||
assertThat(sql.get(7)).contains(" -- bind(MnyTopic_0");
|
||||
assertThat(sql.get(8)).contains(" -- bind(MnyTopic_1");
|
||||
if (!hasSequence) {
|
||||
assertThat(sql.get(7)).contains(" -- bind(MnyTopic_0");
|
||||
assertThat(sql.get(8)).contains(" -- bind(MnyTopic_1");
|
||||
}
|
||||
|
||||
DB.delete(t0);
|
||||
DB.delete(t1);
|
||||
|
||||
@@ -9,13 +9,13 @@ AS
|
||||
BEGIN
|
||||
DECLARE foreign_key_names TABLE(CONSTRAINT_NAME NVARCHAR(256), TABLE_NAME NVARCHAR(256));
|
||||
DECLARE i INT;
|
||||
|
||||
|
||||
foreign_key_names = SELECT CONSTRAINT_NAME, TABLE_NAME FROM SYS.REFERENTIAL_CONSTRAINTS WHERE SCHEMA_NAME=CURRENT_SCHEMA AND TABLE_NAME=UPPER(:table_name) AND COLUMN_NAME=UPPER(:column_name);
|
||||
|
||||
|
||||
FOR I IN 1 .. RECORD_COUNT(:foreign_key_names) DO
|
||||
EXEC 'ALTER TABLE "' || ESCAPE_DOUBLE_QUOTES(:foreign_key_names.TABLE_NAME[i]) || '" DROP CONSTRAINT "' || ESCAPE_DOUBLE_QUOTES(:foreign_key_names.CONSTRAINT_NAME[i]) || '"';
|
||||
END FOR;
|
||||
|
||||
|
||||
END;
|
||||
$$
|
||||
|
||||
|
||||
@@ -46,11 +46,11 @@ CREATE OR ALTER PROCEDURE usp_ebean_drop_default_constraint @tableName nvarchar(
|
||||
AS SET NOCOUNT ON
|
||||
declare @tmp nvarchar(1000)
|
||||
BEGIN
|
||||
select @Tmp = t1.name from sys.default_constraints t1
|
||||
select @tmp = t1.name from sys.default_constraints t1
|
||||
join sys.columns t2 on t1.object_id = t2.default_object_id
|
||||
where t1.parent_object_id = OBJECT_ID(@tableName) and t2.name = @columnName;
|
||||
|
||||
if @Tmp is not null EXEC('alter table ' + @tableName +' drop constraint ' + @tmp);
|
||||
if @tmp is not null EXEC('alter table ' + @tableName +' drop constraint ' + @tmp);
|
||||
END
|
||||
$$
|
||||
|
||||
|
||||
@@ -129,10 +129,12 @@ datasource.hsqldb.password=
|
||||
datasource.hsqldb.databaseUrl=jdbc:hsqldb:mem:tests
|
||||
datasource.hsqldb.databaseDriver=org.hsqldb.jdbcDriver
|
||||
|
||||
|
||||
# Set caseSensitiveCollation to false when using
|
||||
# MySql with case insenstive collation
|
||||
#ebean.mysql.caseSensitiveCollation=false
|
||||
datasource.mysql.username=unit
|
||||
datasource.mysql.password=unit
|
||||
datasource.mysql.databaseUrl=jdbc:mysql://127.0.0.1:3306/unit
|
||||
datasource.mysql.databaseUrl=jdbc:mysql://127.0.0.1:4306/unit
|
||||
#datasource.mysql.username=test_ebean
|
||||
#datasource.mysql.password=test
|
||||
#datasource.mysql.databaseUrl=jdbc:mysql://127.0.0.1:4306/test_ebean
|
||||
@@ -158,10 +160,13 @@ datasource.pg.maxStackTraceSize=50
|
||||
# Our main testing target for SqlServer is sqlserver17
|
||||
ebean.sqlserver.databasePlatformName=sqlserver17
|
||||
|
||||
# set caseSensitiveCollation=false when using a
|
||||
# case insenstive collation with sql server - See main.StartSqlServer
|
||||
#ebean.sqlserver.caseSensitiveCollation=false
|
||||
datasource.sqlserver.username=test_ebean
|
||||
datasource.sqlserver.password=SqlS3rv#r
|
||||
datasource.sqlserver.databaseUrl=jdbc:sqlserver://localhost:1433;databaseName=test_ebean
|
||||
datasource.sqlserver.databaseDriver=com.microsoft.sqlserver.jdbc.SQLServerDriver
|
||||
datasource.sqlserver.url=jdbc:sqlserver://localhost:1433;databaseName=test_ebean;sendTimeAsDateTime=false
|
||||
datasource.sqlserver.driver=com.microsoft.sqlserver.jdbc.SQLServerDriver
|
||||
|
||||
datasource.db2.username=db2admin
|
||||
datasource.db2.password=veryverysecret#1234
|
||||
|
||||
@@ -73,13 +73,10 @@
|
||||
</root>
|
||||
|
||||
|
||||
<logger name="io.ebeaninternal.dbmigration.DdlGenerator" level="TRACE"/>
|
||||
<logger name="org.avaje.dbmigration.ddl" level="TRACE"/>
|
||||
|
||||
<logger name="org.tests" level="INFO"/>
|
||||
<logger name="io.ebean" level="INFO"/>
|
||||
|
||||
<!--<logger name="org.avaje.docker" level="TRACE"/>-->
|
||||
<logger name="io.ebean.docker" level="TRACE"/>
|
||||
<!--<logger name="io.ebean.DDL" level="DEBUG"/>-->
|
||||
|
||||
<!-- <logger name="io.ebean.SQL" level="TRACE"/>-->
|
||||
|
||||
Reference in New Issue
Block a user