Skip to content

Commit 134330d

Browse files
authored
Merge pull request #5 from ZorTik/development
Development
2 parents d8a4c9d + e465a7d commit 134330d

5 files changed

Lines changed: 97 additions & 15 deletions

File tree

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package me.zort.sqllib.internal.annotation;
2+
3+
import java.lang.annotation.ElementType;
4+
import java.lang.annotation.Retention;
5+
import java.lang.annotation.RetentionPolicy;
6+
import java.lang.annotation.Target;
7+
8+
/**
9+
* This annotation is used to mark whether a field in table mapping
10+
* entity represents nullable column.
11+
*
12+
* <pre>
13+
* public class TableEntity {
14+
* &#064;PrimaryKey(autoIncrement = true)
15+
* private Integer id;
16+
* &#064;NullableField(nullable = false)
17+
* &#064;Id
18+
* private String name;
19+
* }
20+
*
21+
* new SQLTableRepositoryBuilder<TableEntity, String>()
22+
* .withConnection(connection)
23+
* .withTableName(tableName)
24+
* .withTypeClass(TableEntity.class)
25+
* .build()
26+
* </pre>
27+
*/
28+
@Retention(RetentionPolicy.RUNTIME)
29+
@Target(ElementType.FIELD)
30+
public @interface NullableField {
31+
32+
boolean nullable() default true;
33+
34+
}

api/src/main/java/me/zort/sqllib/internal/query/part/LimitStatement.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public class LimitStatement<P extends QueryPart<?>> extends QueryPartQuery<P> {
1212
private final int limit;
1313

1414
public LimitStatement(@Nullable P parent, List<QueryPart<?>> initial, int limit) {
15-
super(parent, initial, QueryPriority.LAST);
15+
super(parent, initial, Integer.MAX_VALUE);
1616
this.limit = limit;
1717
}
1818

core/src/main/java/me/zort/sqllib/SQLDatabaseConnectionImpl.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,11 @@ private <T> T assignValues(Row row, Class<T> typeClass) {
224224
}
225225
}
226226
for(Field field : typeClass.getDeclaredFields()) {
227+
228+
if(Modifier.isTransient(field.getModifiers()) || Modifier.isStatic(field.getModifiers())) {
229+
continue;
230+
}
231+
227232
try {
228233
field.setAccessible(true);
229234
field.set(instance, buildElementValue(field, row));

core/src/main/java/me/zort/sqllib/SQLTableRepositoryBuilder.java

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
import me.zort.sqllib.api.SQLDatabaseConnection;
55
import me.zort.sqllib.api.repository.CachingSQLTableRepository;
66
import me.zort.sqllib.api.repository.SQLTableRepository;
7+
import me.zort.sqllib.internal.annotation.JsonField;
8+
import me.zort.sqllib.internal.annotation.NullableField;
9+
import me.zort.sqllib.internal.annotation.PrimaryKey;
710
import me.zort.sqllib.util.Arrays;
811
import me.zort.sqllib.util.Validator;
912
import org.jetbrains.annotations.ApiStatus;
@@ -69,31 +72,50 @@ private void buildDefsFromType() {
6972
if(!(connection instanceof SQLDatabaseConnectionImpl)) {
7073
throw new IllegalStateException("We can build defs only from SQLDatabaseConnectionImpl child-classes.");
7174
}
75+
debug("Building defs from type class: " + info.getTypeClass().getName());
7276

7377
SQLDatabaseOptions options = ((SQLDatabaseConnectionImpl) connection).getOptions();
7478
String[] defs = new String[0];
7579

76-
for (Field field : info.getTypeClass().getFields()) {
77-
if(Modifier.isTransient(field.getModifiers()))
80+
for (Field field : info.getTypeClass().getDeclaredFields()) {
81+
debug("Building def for field: " + field.getName() + " (" + field.getType().getName() + ")");
82+
if(Modifier.isTransient(field.getModifiers())) {
83+
debug(String.format("Field %s is transient, skipping.", field.getName()));
7884
continue;
85+
}
7986

8087
String colName = options.getNamingStrategy().fieldNameToColumn(field.getName());
8188
String colType = recognizeFieldTypeToDbType(field);
89+
90+
if(colType != null && !colType.contains("NOT NULL") && field.isAnnotationPresent(NullableField.class)) {
91+
if(!field.getAnnotation(NullableField.class).nullable()) {
92+
colType += " NOT NULL";
93+
}
94+
}
95+
8296
defs = Arrays.add(defs, colName + " " + colType);
97+
98+
debug("Added def: " + colName + " " + colType);
8399
}
84100

85101
info.setDefs(defs);
102+
debug("Built defs: " + java.util.Arrays.toString(defs));
86103
}
87104

88-
private static String recognizeFieldTypeToDbType(Field field) {
105+
private void debug(String message) {
106+
if(connection instanceof SQLDatabaseConnectionImpl && ((SQLDatabaseConnectionImpl) connection).getOptions().isDebug())
107+
((SQLDatabaseConnectionImpl) connection).debug(message);
108+
}
109+
110+
private String recognizeFieldTypeToDbType(Field field) {
89111
Class<?>[] supportedTypes = new Class<?>[] {
90112
Integer.class,
91113
Long.class,
92114
Float.class,
93115
Double.class,
94116
String.class
95117
};
96-
Class<?> fieldType = field.getType();
118+
Class<?> fieldType = Primitives.wrap(field.getType());
97119

98120
boolean isSupported = false;
99121
for (Class<?> aClass : supportedTypes) {
@@ -103,14 +125,18 @@ private static String recognizeFieldTypeToDbType(Field field) {
103125
}
104126
}
105127

128+
if(field.isAnnotationPresent(JsonField.class) && !isSupported) {
129+
return "TEXT";
130+
}
131+
106132
if(!isSupported)
107133
throw new RuntimeException(String.format("We don't support %s types in SQLTableRepositoryBuilder yet.", fieldType.getSimpleName()));
108134

109135
String dbType = null;
110136
if(fieldType.equals(String.class)) {
111137
dbType = "VARCHAR(255)";
112138
} else if(Primitives.wrap(fieldType).equals(Integer.class)) {
113-
dbType = "INT";
139+
dbType = "INTEGER";
114140
} else if(Primitives.wrap(fieldType).equals(Long.class)) {
115141
dbType = "BIGINT";
116142
} else if(Primitives.wrap(fieldType).equals(Double.class)) {
@@ -120,10 +146,13 @@ private static String recognizeFieldTypeToDbType(Field field) {
120146
}
121147

122148
if(Validator.validateAutoIncrement(field))
123-
dbType += " PRIMARY KEY AUTO_INCREMENT";
149+
dbType += " PRIMARY KEY " + (isSQLite() ? "AUTOINCREMENT" : "AUTO_INCREMENT");
150+
151+
return dbType;
152+
}
124153

125-
// Practically, it should not come here.
126-
return null;
154+
private boolean isSQLite() {
155+
return connection instanceof SQLiteDatabaseConnectionImpl;
127156
}
128157

129158
public interface RepoFactory<T, ID, R extends SQLTableRepository<T, ID>> {

core/src/main/java/me/zort/sqllib/SQLiteDatabaseConnectionImpl.java

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,29 +48,43 @@ public QueryResult save(String table, Object obj) {
4848
String[] defs = defsValsPair.getFirst();
4949
UnknownValueWrapper[] vals = defsValsPair.getSecond();
5050

51+
debug("Saving object into table " + table + " with definitions " + Arrays.toString(defs) + " and values " + Arrays.toString(vals));
52+
5153
PrimaryKey primaryKey = null;
5254
for(Field field : obj.getClass().getDeclaredFields()) {
5355
if(Modifier.isTransient(field.getModifiers())) {
5456
continue;
5557
}
5658
if(field.isAnnotationPresent(me.zort.sqllib.internal.annotation.PrimaryKey.class)) {
5759
String colName = getOptions().getNamingStrategy().fieldNameToColumn(field.getName());
58-
int index = Arrays.binarySearch(defs, colName);
60+
//int index = Arrays.binarySearch(defs, colName);
61+
int index = -1;
62+
int i = 0;
63+
for (String def : defs) {
64+
if(def.equals(colName)) {
65+
index = i;
66+
break;
67+
}
68+
i++;
69+
}
5970
if(index >= 0) {
6071
primaryKey = new PrimaryKey(colName, vals[index].getObject() instanceof String
6172
? (String)vals[index].getObject() : String.valueOf(vals[index].getObject()));
6273
break;
6374
}
6475
}
6576
}
66-
if(primaryKey == null) {
67-
debug("No primary key found for object: " + obj.getClass().getName());
68-
return new QueryResultImpl(false);
69-
}
7077
InsertQuery insert = insert().into(table, defs);
7178
for(UnknownValueWrapper val : vals) {
72-
insert.appendVal(val);
79+
insert.appendVal(val.getObject());
7380
}
81+
82+
if(primaryKey == null) {
83+
debug("No primary key found for object " + obj.getClass().getName() + ", so we can't build update condition.");
84+
debug("Performing insert query instead: " + insert.buildQuery());
85+
return insert.execute();
86+
}
87+
7488
SetStatement<UpdateQuery> setStmt = update().table(table).set();
7589
for(int i = 0; i < defs.length; i++) {
7690
setStmt.and(defs[i], vals[i].getObject());

0 commit comments

Comments
 (0)