Skip to content

Commit ad1c2d6

Browse files
authored
Merge pull request #26 from JavaWebStack/TimothyGillespie/lookAtOrderBy
Cast to snake cases and more
2 parents 54ad3d7 + 912bd78 commit ad1c2d6

File tree

9 files changed

+141
-39
lines changed

9 files changed

+141
-39
lines changed

src/main/java/org/javawebstack/orm/query/QueryOrderBy.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ public String toString() {
6464

6565
public String toString(TableInfo info) {
6666
return this.stream()
67-
.map(QueryOrderByElement::toString)
67+
.map(singleOrderByElement -> singleOrderByElement.toString(info))
6868
.collect(Collectors.joining(","));
6969
}
7070
}

src/main/java/org/javawebstack/orm/wrapper/builder/MySQLQueryStringBuilder.java

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import org.javawebstack.orm.TableInfo;
66
import org.javawebstack.orm.query.*;
77

8-
import java.lang.reflect.Field;
98
import java.sql.Timestamp;
109
import java.time.Instant;
1110
import java.util.*;
@@ -23,10 +22,10 @@ public SQLQueryString buildInsert(TableInfo info, Map<String, Object> values) {
2322
sb.append("` (");
2423
List<String> cols = new ArrayList<>();
2524
List<String> vals = new ArrayList<>();
26-
for (String columnName : values.keySet()) {
27-
cols.add("`" + columnName + "`");
25+
for (Map.Entry<String, Object> columnValueMapping : values.entrySet()) {
26+
cols.add("`" + columnValueMapping.getKey() + "`");
2827
vals.add("?");
29-
params.add(values.get(columnName));
28+
params.add(columnValueMapping.getValue());
3029
}
3130
sb.append(String.join(",", cols));
3231
sb.append(") VALUES (");
@@ -45,7 +44,7 @@ public SQLQueryString buildQuery(Query<?> query, boolean count) {
4544
.append('`');
4645
QueryGroup<?> where = query.getWhereGroup();
4746
checkWithDeleted(repo, query.isWithDeleted(), where);
48-
if (where.getQueryElements().size() > 0) {
47+
if (!where.getQueryElements().isEmpty()) {
4948
SQLQueryString qs = convertGroup(repo.getInfo(), where);
5049
sb.append(" WHERE ").append(qs.getQuery());
5150
parameters.addAll(qs.getParameters());
@@ -54,7 +53,7 @@ public SQLQueryString buildQuery(Query<?> query, boolean count) {
5453
QueryOrderBy orderBy = query.getOrder();
5554
if (!orderBy.isEmpty()) {
5655
sb.append(" ORDER BY ")
57-
.append(orderBy.toString());
56+
.append(orderBy.toString(repo.getInfo()));
5857
}
5958

6059
Integer offset = query.getOffset();
@@ -88,7 +87,7 @@ public SQLQueryString buildUpdate(Query<?> query, Map<String, Object> values) {
8887
.append(String.join(",", sets));
8988
QueryGroup<?> where = query.getWhereGroup();
9089
checkWithDeleted(repo, query.isWithDeleted(), where);
91-
if (where.getQueryElements().size() > 0) {
90+
if (!where.getQueryElements().isEmpty()) {
9291
SQLQueryString qs = convertGroup(repo.getInfo(), where);
9392
sb.append(" WHERE ").append(qs.getQuery());
9493
parameters.addAll(qs.getParameters());
@@ -104,7 +103,7 @@ public SQLQueryString buildDelete(Query<?> query) {
104103
StringBuilder sb = new StringBuilder("DELETE FROM `")
105104
.append(repo.getInfo().getTableName())
106105
.append('`');
107-
if (where.getQueryElements().size() > 0) {
106+
if (!where.getQueryElements().isEmpty()) {
108107
SQLQueryString qs = convertGroup(repo.getInfo(), where);
109108
sb.append(" WHERE ").append(qs.getQuery());
110109
parameters = qs.getParameters();
@@ -114,7 +113,7 @@ public SQLQueryString buildDelete(Query<?> query) {
114113

115114
private void checkWithDeleted(Repo<?> repo, boolean withDeleted, QueryGroup<?> where) {
116115
if (repo.getInfo().isSoftDelete() && !withDeleted) {
117-
if (where.getQueryElements().size() > 0)
116+
if (!where.getQueryElements().isEmpty())
118117
where.getQueryElements().add(0, QueryConjunction.AND);
119118
where.getQueryElements().add(0, new QueryCondition(new QueryColumn(repo.getInfo().getColumnName(repo.getInfo().getSoftDeleteField())), "IS NULL", null));
120119
}

src/test/java/org/javawebstack/orm/test/querybuilding/FromClauseTest.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package org.javawebstack.orm.test.querybuilding;
22

3-
import org.atteo.evo.inflector.English;
43
import org.javawebstack.orm.Model;
54
import org.javawebstack.orm.ORM;
65
import org.javawebstack.orm.Repo;
@@ -55,7 +54,7 @@ void testOneWordAlreadyInPluralDoesntWork() throws ORMConfigurationException {
5554

5655
@Test
5756
void testOverwrittenTableName() throws ORMConfigurationException {
58-
String query = getBaseQuery(OverwritteTableName.class);
57+
String query = getBaseQuery(OverwrittenTableName.class);
5958
assertTrue(query.contains("FROM `oVer_writtenValue`"));
6059
}
6160

src/test/java/org/javawebstack/orm/test/querybuilding/OrderByClauseTest.java

Lines changed: 35 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,67 +4,68 @@
44
import org.javawebstack.orm.query.Query;
55
import org.javawebstack.orm.test.exception.SectionIndexOutOfBoundException;
66
import org.javawebstack.orm.test.shared.models.Datatype;
7+
import org.javawebstack.orm.test.shared.models.columnnames.OverwrittenColumnName;
78
import org.javawebstack.orm.test.shared.verification.QueryVerification;
89
import org.junit.jupiter.api.Test;
9-
10-
import javax.xml.crypto.Data;
11-
1210
import java.util.*;
13-
import java.util.stream.Collectors;
14-
1511
import static org.javawebstack.orm.test.shared.setup.ModelSetup.setUpModel;
1612
import static org.junit.jupiter.api.Assertions.*;
1713

1814
// This class tests the query generation for order by statements an MySQL
19-
public class OrderByClauseTest {
15+
class OrderByClauseTest {
2016

2117
@Test
2218
void testOneExistingColumnDefaultOrderBy() {
2319
Query<Datatype> query = setUpModel(Datatype.class).query()
24-
.order("wrapper_integer");
20+
.order("wrapperInteger");
2521
new QueryVerification(query).assertSectionEquals("ORDER BY", "`wrapper_integer`");
2622
}
2723

2824
@Test
2925
void testOneNonExistingColumnDefaultOrderBy() {
3026
Query<Datatype> query = setUpModel(Datatype.class).query()
31-
.order("does_not_exist");
32-
new QueryVerification(query).assertSectionEquals("ORDER BY", "`does_not_exist`");
27+
.order("doesNotExist");
28+
29+
// Not in snake case as it is not in the mapping
30+
new QueryVerification(query).assertSectionEquals("ORDER BY", "`doesNotExist`");
3331
}
3432

3533
@Test
3634
void testOneExistingColumnASCOrderBy() {
3735
Query<Datatype> query = setUpModel(Datatype.class).query()
38-
.order("wrapper_integer", false);
36+
.order("wrapperInteger", false);
3937
new QueryVerification(query).assertSectionEquals("ORDER BY", "`wrapper_integer`");
4038
}
4139

4240
@Test
4341
void testOneNonExistingColumnASCOrderBy() {
4442
Query<Datatype> query = setUpModel(Datatype.class).query()
45-
.order("does_not_exist", false);
46-
new QueryVerification(query).assertSectionEquals("ORDER BY", "`does_not_exist`");
43+
.order("doesNotExist", false);
44+
45+
// Not in snake case as it is not in the mapping
46+
new QueryVerification(query).assertSectionEquals("ORDER BY", "`doesNotExist`");
4747
}
4848

4949
@Test
5050
void testOneExistingColumnDESCOrderBy() {
5151
Query<Datatype> query = setUpModel(Datatype.class).query()
52-
.order("wrapper_integer", true);
52+
.order("wrapperInteger", true);
5353
new QueryVerification(query).assertSectionEquals("ORDER BY", "`wrapper_integer` DESC");
5454
}
5555

5656
@Test
5757
void testOneNonExistingColumnDESCOrderBy() {
5858
Query<Datatype> query = setUpModel(Datatype.class).query()
59-
.order("does_not_exist", true);
60-
new QueryVerification(query).assertSectionEquals("ORDER BY", "`does_not_exist` DESC");
59+
.order("doesNotExist", true);
60+
// Not in snake case as it is not in the mapping
61+
new QueryVerification(query).assertSectionEquals("ORDER BY", "`doesNotExist` DESC");
6162
}
6263

6364
@Test
6465
void testMultipleOrderByClausesOfASCOrder() {
6566
Query<Datatype> query = setUpModel(Datatype.class).query()
66-
.order("wrapper_integer")
67-
.order("primitive_integer");
67+
.order("wrapperInteger")
68+
.order("primitiveInteger");
6869

6970
new QueryVerification(query)
7071
.assertSectionContains("ORDER BY", "`wrapper_integer`")
@@ -74,8 +75,8 @@ void testMultipleOrderByClausesOfASCOrder() {
7475
@Test
7576
void testMultipleOrderByClausesOfDESCOrder() {
7677
Query<Datatype> query = setUpModel(Datatype.class).query()
77-
.order("wrapper_integer", true)
78-
.order("primitive_integer", true);
78+
.order("wrapperInteger", true)
79+
.order("primitiveInteger", true);
7980

8081
new QueryVerification(query)
8182
.assertSectionContains("ORDER BY", "`wrapper_integer` DESC")
@@ -85,8 +86,8 @@ void testMultipleOrderByClausesOfDESCOrder() {
8586
@Test
8687
void testMultipleOrderByClausesOfMixedOrder() {
8788
Query<Datatype> query = setUpModel(Datatype.class).query()
88-
.order("wrapper_integer", false)
89-
.order("primitive_integer", true);
89+
.order("wrapperInteger", false)
90+
.order("primitiveInteger", true);
9091

9192
new QueryVerification(query)
9293
.assertSectionContains("ORDER BY", "`wrapper_integer`")
@@ -96,8 +97,8 @@ void testMultipleOrderByClausesOfMixedOrder() {
9697
@Test
9798
void testMultipleOrderByClausesOfMixedOrderReversed() {
9899
Query<Datatype> query = setUpModel(Datatype.class).query()
99-
.order("primitive_integer", true)
100-
.order("wrapper_integer", false);
100+
.order("primitiveInteger", true)
101+
.order("wrapperInteger", false);
101102

102103
new QueryVerification(query)
103104
.assertSectionContains("ORDER BY", "`primitive_integer` DESC")
@@ -108,6 +109,7 @@ void testMultipleOrderByClausesOfMixedOrderReversed() {
108109
@Test
109110
// This test is important because putting the order by statements in different order is relevant (they set priorities)
110111
void testMultipleOrderByClausesOfRandomOrderForCorrectOrder() throws SectionIndexOutOfBoundException {
112+
// This test does not use camel cases as input
111113
Query<Datatype> query = setUpModel(Datatype.class).query();
112114
ArrayList<String> columnNames = new ArrayList<>(Datatype.columnNames);
113115

@@ -121,7 +123,7 @@ void testMultipleOrderByClausesOfRandomOrderForCorrectOrder() throws SectionInde
121123

122124
String queryString = new QueryVerification(query).getSection("ORDER BY");
123125
int lastIndex = 0;
124-
int foundIndex = -1;
126+
int foundIndex;
125127
for (String nextInCallOrder : callOrder) {
126128
foundIndex = queryString.indexOf("`" + nextInCallOrder + "`");
127129
if(foundIndex < lastIndex) {
@@ -141,6 +143,13 @@ void testMultipleOrderByClausesOfRandomOrderForCorrectOrder() throws SectionInde
141143

142144
}
143145

146+
@Test
147+
void testWillUseOverwrittenColumnName() {
148+
Query<OverwrittenColumnName> query = setUpModel(OverwrittenColumnName.class).query()
149+
.order("dummyString");
150+
new QueryVerification(query).assertSectionEquals("ORDER BY", "`oVer_writtenColumn-name`");
151+
}
152+
144153
/*
145154
* Error Cases
146155
*/
@@ -149,8 +158,8 @@ void testMultipleOrderByClausesOfRandomOrderForCorrectOrder() throws SectionInde
149158
@Test
150159
void testCannotCallOrderOnSameColumnTwice() {
151160
Query<Datatype> query = setUpModel(Datatype.class).query()
152-
.order("primitive_integer", true);
161+
.order("primitiveInteger", true);
153162

154-
assertThrows(ORMQueryException.class, () -> query.order("primitive_integer"));
163+
assertThrows(ORMQueryException.class, () -> query.order("primitiveInteger"));
155164
}
156165
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package org.javawebstack.orm.test.queryexecution;
2+
3+
import org.javawebstack.orm.ORM;
4+
import org.javawebstack.orm.Repo;
5+
import org.javawebstack.orm.test.ORMTestCase;
6+
import org.javawebstack.orm.test.shared.models.OnlyIdModel;
7+
import org.javawebstack.orm.test.shared.setup.ModelSetup;
8+
import org.junit.jupiter.api.Test;
9+
10+
import java.util.List;
11+
12+
import static org.junit.jupiter.api.Assertions.*;
13+
14+
class OrderByTest extends ORMTestCase {
15+
16+
@Test
17+
void testOrderByCanPullResults() {
18+
ModelSetup.setUpModel(OnlyIdModel.class);
19+
ORM.autoMigrate(true);
20+
21+
new OnlyIdModel().save();
22+
new OnlyIdModel().save();
23+
new OnlyIdModel().save();
24+
25+
assertDoesNotThrow(() -> Repo.get(OnlyIdModel.class)
26+
.query()
27+
.order("id")
28+
.get()
29+
);
30+
}
31+
32+
@Test
33+
void testOrderByWorksWithAsc() {
34+
ModelSetup.setUpModel(OnlyIdModel.class);
35+
ORM.autoMigrate(true);
36+
37+
new OnlyIdModel().save();
38+
new OnlyIdModel().save();
39+
new OnlyIdModel().save();
40+
41+
List<OnlyIdModel> orderedList = Repo.get(OnlyIdModel.class)
42+
.query()
43+
.order("id", false)
44+
.get();
45+
46+
for(int i = 1; i <= 3; i++) {
47+
assertEquals(i, orderedList.get(i - 1).getId());
48+
}
49+
}
50+
51+
@Test
52+
void testOrderByWorksWithDesc() {
53+
ModelSetup.setUpModel(OnlyIdModel.class);
54+
ORM.autoMigrate(true);
55+
56+
new OnlyIdModel().save();
57+
new OnlyIdModel().save();
58+
new OnlyIdModel().save();
59+
60+
List<OnlyIdModel> orderedList = Repo.get(OnlyIdModel.class)
61+
.query()
62+
.order("id", true)
63+
.get();
64+
65+
for(int i = 3; i >= 1; i--) {
66+
assertEquals(i, orderedList.get(3 - i).getId());
67+
}
68+
}
69+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package org.javawebstack.orm.test.shared.models;
2+
3+
import lombok.Getter;
4+
import org.javawebstack.orm.Model;
5+
import org.javawebstack.orm.annotation.Column;
6+
7+
@Getter
8+
public class OnlyIdModel extends Model {
9+
10+
@Column
11+
int id;
12+
13+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package org.javawebstack.orm.test.shared.models.columnnames;
2+
3+
import org.javawebstack.orm.Model;
4+
import org.javawebstack.orm.annotation.Column;
5+
6+
public class OverwrittenColumnName extends Model {
7+
@Column
8+
int id;
9+
10+
@Column(name = "oVer_writtenColumn-name")
11+
String dummyString;
12+
}

src/test/java/org/javawebstack/orm/test/shared/models/tablenames/OverwritteTableName.java renamed to src/test/java/org/javawebstack/orm/test/shared/models/tablenames/OverwrittenTableName.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* This class overwrites the model name to a seemingly random word to test multiple cases at once.
99
*/
1010
@Table("oVer_writtenValue")
11-
public class OverwritteTableName extends Model {
11+
public class OverwrittenTableName extends Model {
1212
@Column
1313
int id;
1414
}

start_mariadb_test_server.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
docker run -p 3306:3306 -e MYSQL_DATABASE=ormtest -e MYSQL_ROOT_PASSWORD=testpassword -d mariadb:10.5.9

0 commit comments

Comments
 (0)