Skip to content

Commit 8cca6bd

Browse files
committed
Merge branch 'master' into desku
# Conflicts: # core/src/main/java/com/osiris/jsqlgen/Main.java # src/main/java/com/osiris/jsqlgen/MainApplication.java
2 parents 70125ce + 3d648cc commit 8cca6bd

9 files changed

Lines changed: 264 additions & 92 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ even execute get/add/update/delete. Provided in the generated Database class.
128128
PRs for these issues are greatly appreciated (sorted from most important, to least important).
129129
- You need to know a bit of SQL, especially about definitions and defaults. This could be fixed by simplifying the GUI further.
130130
- Internally a `idCounter` is used for each table, meaning if rows are added by another program the counter won't be accurate anymore and thus further insert operations will fail.
131+
- Direct modifications of the database by a third-party program breaks stuff.
131132
- Java Code Generator: No support for `FOREIGN KEY` / references between tables. However note that the idea of references is supported (columns named tableNameId are refs).
132133
- Java Code Generator: No support for `VIEW, JOIN, UNION` / merged tables/results. This might never get fixed if its not possible to create a developer-friendly / simple API for this.
133134
- Since there is a global id counter for all tables and columns, in each application, collaboration and syncing changes might be difficult.

core/src/main/java/com/osiris/jsqlgen/Main.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import com.osiris.jsqlgen.model.Column;
88
import com.osiris.jsqlgen.model.Database;
99
import com.osiris.jsqlgen.model.Table;
10+
import com.osiris.jsqlgen.model.TableChange;
11+
import com.osiris.jsqlgen.generator.GetTableChange;
1012

1113
import java.io.File;
1214
import java.util.concurrent.atomic.AtomicInteger;
@@ -29,6 +31,36 @@ public static void main(String[] args) {
2931
}
3032
}
3133

34+
// If there are missing changes add them (which might happen when importing databases generated by older jSQL-Gen versions).
35+
// For example if the table contains a column, but there is no change referencing that column
36+
for (Table t : db.tables) {
37+
if(t.changes.isEmpty()){
38+
TableChange currentTableChange = GetTableChange.get(t, Data.instance.databases);
39+
t.changes.add(currentTableChange);
40+
}
41+
for (Column col : t.columns) {
42+
boolean isAddedOnce = false;
43+
for (TableChange c : t.changes) {
44+
if(c.addedColumnNames.contains(col.name)) {
45+
isAddedOnce = true;
46+
break;
47+
}
48+
}
49+
boolean isRenamedOnce = false;
50+
for (TableChange c : t.changes) {
51+
if(c.newColumnNames.contains(col.name)) {
52+
isRenamedOnce = true;
53+
break;
54+
}
55+
}
56+
if(!isAddedOnce && !isRenamedOnce){
57+
TableChange firstChange = t.changes.get(0);
58+
firstChange.addedColumnNames.add(col.name);
59+
firstChange.addedColumnDefinitions.add(col.definition);
60+
}
61+
}
62+
}
63+
3264
// Cache current data
3365
JavaCodeGenerator.oldDatabases.add(db.duplicate());
3466
}

core/src/main/java/com/osiris/jsqlgen/generator/GenCreateMethods.java

Lines changed: 38 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import com.osiris.jsqlgen.model.Table;
55

66
public class GenCreateMethods {
7-
public static String s(Table t, String tNameQuoted, JavaCodeGenerator.Constructor minimalConstructor, boolean hasMoreFields) {
7+
public static String s(Table t, String tNameQuoted, JavaCodeGenerator.Constructor constructor, JavaCodeGenerator.Constructor minimalConstructor, boolean hasMoreFields) {
88
StringBuilder sb = new StringBuilder();
99
sb.append("""
1010
/**
@@ -14,16 +14,31 @@ Increments the id (thread-safe) and sets it for this object (basically reserves
1414
Also note that this method will NOT add the object to the table.
1515
*/
1616
""");
17-
Column firstCol = t.columns.get(0);
18-
String idParam = firstCol.type.inJava + " " + firstCol.name + ",";
17+
Column idCol = t.columns.get(0); // always first
1918
sb.append(
20-
"public static " + t.name + " create(" + minimalConstructor.params.replace(idParam, "")
19+
"public static " + t.name + " create(" + minimalConstructor.paramsWithoutId
2120
+ ") {\n" +
22-
firstCol.type.inJava + " " + firstCol.name + " = idCounter.getAndIncrement();\n" + t.name + " obj = new " + t.name + "(" + minimalConstructor.paramsWithoutTypes + ");\n" +
21+
idCol.type.inJava + " " + idCol.name + " = idCounter.getAndIncrement();\n" + t.name + " obj = new " + t.name + "(" + minimalConstructor.paramsWithoutTypes + ");\n" +
2322
"onCreate.forEach(code -> code.accept(obj));\n" +
2423
"return obj;\n");
2524
sb.append("}\n\n"); // Close create method
2625

26+
27+
if (hasMoreFields) {
28+
sb.append("/**\n" +
29+
"Creates and returns an object that can be added to this table.\n" +
30+
"Increments the id (thread-safe) and sets it for this object (basically reserves a space in the database).\n" +
31+
"Note that this method will NOT add the object to the table.\n" +
32+
"*/\n");
33+
sb.append(
34+
"public static " + t.name + " create(" + constructor.paramsWithoutId
35+
+ ") " + (t.isNoExceptions ? "" : "throws Exception") + " {\n" +
36+
idCol.type.inJava + " " + idCol.name + " = idCounter.getAndIncrement();\n" + t.name + " obj = new " + t.name + "();\n" + JavaCodeGenerator.genFieldAssignments("obj", t.columns) + "\n" +
37+
"onCreate.forEach(code -> code.accept(obj));\n" +
38+
"return obj;\n");
39+
sb.append("}\n\n"); // Close create method
40+
}
41+
2742
sb.append("""
2843
/**
2944
Creates and returns an in-memory object with -1 as id, that can be added to this table
@@ -34,37 +49,41 @@ Increments the id (thread-safe) and sets it for this object (basically reserves
3449
*/
3550
""");
3651
sb.append(
37-
"public static " + t.name + " createInMem(" + minimalConstructor.params.replace(idParam, "")
52+
"public static " + t.name + " createInMem(" + minimalConstructor.paramsWithoutId
3853
+ ") {\n" +
39-
firstCol.type.inJava + " " + firstCol.name + " = -1;\n" + t.name + " obj = new " + t.name + "(" + minimalConstructor.paramsWithoutTypes + ");\n" +
54+
idCol.type.inJava + " " + idCol.name + " = -1;\n" + t.name + " obj = new " + t.name + "(" + minimalConstructor.paramsWithoutTypes + ");\n" +
4055
"onCreate.forEach(code -> code.accept(obj));\n" +
4156
"return obj;\n");
4257
sb.append("}\n\n"); // Close create method
4358

44-
4559
if (hasMoreFields) {
46-
sb.append("/**\n" +
47-
"Creates and returns an object that can be added to this table.\n" +
48-
"Increments the id (thread-safe) and sets it for this object (basically reserves a space in the database).\n" +
49-
"Note that this method will NOT add the object to the table.\n" +
50-
"*/\n");
60+
sb.append("""
61+
/**
62+
Creates and returns an in-memory object with -1 as id, that can be added to this table
63+
AFTER you manually did obj.id = idCounter.getAndIncrement().
64+
This is useful for objects that may never be added to the table.
65+
Note that the parameters of this method represent "NOT NULL" fields in the table and thus should not be null.
66+
Also note that this method will NOT add the object to the table.
67+
*/
68+
""");
5169
sb.append(
52-
"public static " + t.name + " create(" + JavaCodeGenerator.genParams(t.columns).replace(idParam, "")
70+
"public static " + t.name + " createInMem(" + constructor.paramsWithoutId
5371
+ ") " + (t.isNoExceptions ? "" : "throws Exception") + " {\n" +
54-
firstCol.type.inJava + " " + firstCol.name + " = idCounter.getAndIncrement();\n" + t.name + " obj = new " + t.name + "();\n" + JavaCodeGenerator.genFieldAssignments("obj", t.columns) + "\n" +
72+
idCol.type.inJava + " " + idCol.name + " = -1;\n" + t.name + " obj = new " + t.name + "();\n" + JavaCodeGenerator.genFieldAssignments("obj", t.columns) + "\n" +
5573
"onCreate.forEach(code -> code.accept(obj));\n" +
5674
"return obj;\n");
5775
sb.append("}\n\n"); // Close create method
5876
}
5977

78+
6079
sb.append("/**\n" +
6180
"Convenience method for creating and directly adding a new object to the table.\n" +
6281
"Note that the parameters of this method represent \"NOT NULL\" fields in the table and thus should not be null.\n" +
6382
"*/\n");
6483
sb.append(
65-
"public static " + t.name + " createAndAdd(" + minimalConstructor.params.replace(idParam, "")
84+
"public static " + t.name + " createAndAdd(" + minimalConstructor.paramsWithoutId
6685
+ ") " + (t.isNoExceptions ? "" : "throws Exception") + " {\n" +
67-
firstCol.type.inJava + " " + firstCol.name + " = idCounter.getAndIncrement();\n" + t.name + " obj = new " + t.name + "(" + minimalConstructor.paramsWithoutTypes + ");\n" +
86+
idCol.type.inJava + " " + idCol.name + " = idCounter.getAndIncrement();\n" + t.name + " obj = new " + t.name + "(" + minimalConstructor.paramsWithoutTypes + ");\n" +
6887
"onCreate.forEach(code -> code.accept(obj));\n" +
6988
"add(obj);\n" +
7089
"return obj;\n");
@@ -76,9 +95,9 @@ Increments the id (thread-safe) and sets it for this object (basically reserves
7695
"Convenience method for creating and directly adding a new object to the table.\n" +
7796
"*/\n");
7897
sb.append(
79-
"public static " + t.name + " createAndAdd(" + JavaCodeGenerator.genParams(t.columns).replace(idParam, "")
98+
"public static " + t.name + " createAndAdd(" + constructor.paramsWithoutId
8099
+ ") " + (t.isNoExceptions ? "" : "throws Exception") + " {\n" +
81-
firstCol.type.inJava + " " + firstCol.name + " = idCounter.getAndIncrement();\n" + t.name + " obj = new " + t.name + "();\n" + JavaCodeGenerator.genFieldAssignments("obj", t.columns) + "\n" +
100+
idCol.type.inJava + " " + idCol.name + " = idCounter.getAndIncrement();\n" + t.name + " obj = new " + t.name + "();\n" + JavaCodeGenerator.genFieldAssignments("obj", t.columns) + "\n" +
82101
"onCreate.forEach(code -> code.accept(obj));\n" +
83102
"add(obj);\n" +
84103
"return obj;\n");

core/src/main/java/com/osiris/jsqlgen/generator/GenDefBlobClass.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ public static String s(LinkedHashSet<String> imports) {
1010
imports.add("import java.sql.Blob;");
1111
imports.add("import java.sql.SQLException;");
1212

13-
return "class DefaultBlob implements Blob{\n" +
13+
return "public static class DefaultBlob implements Blob{\n" +
1414
" private byte[] data;\n" +
1515
"\n" +
1616
" // Constructor that accepts a byte array\n" +

core/src/main/java/com/osiris/jsqlgen/generator/GenRemoveMethods.java

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ public TreeNode(TreeNode parent) {
3737

3838
public static String s(Database db, Table t, String tNameQuoted) {
3939

40+
Column idCol = t.columns.get(0);
41+
4042
LinkedHashMap<Table, List<Column>> allRefs = getAllRefs(db, t);
4143
LinkedHashMap<Table, List<Column>> allDirectRefs = getAllDirectRefs(db, t);
4244

@@ -49,14 +51,14 @@ public static String s(Database db, Table t, String tNameQuoted) {
4951
StringBuilder sb = new StringBuilder();
5052
sb.append(
5153
"/**\n" +
52-
"Unsets its references (sets them to -1) and deletes the provided object from the database.\n" +
54+
"Unsets its references (sets them to -1/'') and deletes the provided object from the database.\n" +
5355
"*/\n" +
5456
"public static void remove(" + t.name + " obj) " + (t.isNoExceptions ? "" : "throws Exception") + " {\n" +
5557
"remove(obj, true, Database.isRemoveRefs);\n" +
5658
"}\n" +
5759
"/**\n" +
5860
" * Deletes the provided object from the database.\n" +
59-
" * @param unsetRefs If true, sets ids in other tables to -1.\n" +
61+
" * @param unsetRefs If true, sets ids in other tables to -1/''.\n" +
6062
" * @param removeRefs !!! EXTREME CAUTION REQUIRED, MAJOR DATA-LOSS POSSIBLE !!! If true removes the complete obj/row(s) in all tables that reference/contain this id.\n" +
6163
" * This is recursive. It's highly recommended to call removeRefs() before instead, which allows to explicitly exclude some tables.\n" +
6264
"*/\n" +
@@ -108,11 +110,16 @@ public static String s(Database db, Table t, String tNameQuoted) {
108110
" */\n" +
109111
"public static void unsetRefs("+paramsDirect+") " + (t.isNoExceptions ? "" : "throws Exception") + " {\n");
110112
allDirectRefs.forEach((t1, columns) -> {
111-
for (Column col : columns) {
112-
String param = getParamName(t1, col);
113-
sb.append("if (remove_"+ param + ") {"+t1.name+".getLazySync(results -> { \n" +
114-
" for("+t1.name+" obj1 : results) {obj1."+col.name+" = -1; obj1.update();};\n" +
115-
"}, totalCount -> {}, 100, "+t1.name+".where"+firstToUpperCase(col.name)+"().is(obj.id));}\n");
113+
for (Column refCol : columns) {
114+
String param = getParamName(t1, refCol);
115+
String s = "if (remove_"+ param + ") {"+t1.name+".getLazySync(results -> { \n" +
116+
" for("+t1.name+" refObj : results) {refObj."+refCol.name+" = " +
117+
(refCol.type.isText() ? "\"\"" : "-1") +
118+
"; refObj.update();};\n" +
119+
"}, totalCount -> {}, 100, "+t1.name+".where"+firstToUpperCase(refCol.name)+"().is(obj."+idCol.name+"));}";
120+
if(!refCol.type.equals(idCol.type)) s = "/* Possibly not a primary id, since types do not match, thus ignored! " +
121+
t1.name+"."+refCol.name+" "+refCol.type.inJava +" != "+t.name+"."+idCol.name+" "+idCol.type.inJava+" \n" + s + "*/";
122+
sb.append(s + "\n\n");
116123
}
117124
});
118125
sb.append(" }\n\n");
@@ -124,17 +131,20 @@ public static String s(Database db, Table t, String tNameQuoted) {
124131
"public static void removeRefs("+params+") " + (t.isNoExceptions ? "" : "throws Exception") + " {\n" +
125132
"// Take care of direct refs and indirect refs\n");
126133
allDirectRefs.forEach((t1, columns) -> {
127-
for (Column col : columns) {
128-
String param = getParamName(t1, col);
134+
for (Column refCol : columns) {
135+
String param = getParamName(t1, refCol);
129136
LinkedHashMap<Table, List<Column>> allRefs1 = getAllRefs(db, t1);
130137
String params1 = genRefParams(t1, allRefs1);
131138
params1 = params1.substring(params1.indexOf("obj"))
132-
.replaceFirst("(obj)", "obj1")
139+
.replaceFirst("(obj)", "refObj")
133140
.replaceAll("( boolean )", "");
134141
//String paramsInvoke1 = genRefParamsInvoke(t1, allRefs1).replaceFirst("(obj)", "obj1");
135-
sb.append("if (remove_"+ param + ") {"+t1.name+".getLazySync(results -> { \n" +
136-
" for("+t1.name+" obj1 : results) {"+t1.name+".removeRefs("+params1.replaceAll("Class<[^>]+>", "")+");obj1.remove();};\n" +
137-
"}, totalCount -> {}, 100, "+t1.name+".where"+firstToUpperCase(col.name)+"().is(obj.id));}\n\n");
142+
String s = "if (remove_"+ param + ") {"+t1.name+".getLazySync(results -> { \n" +
143+
" for("+t1.name+" refObj : results) {"+t1.name+".removeRefs("+params1.replaceAll("Class<[^>]+>", "")+");refObj.remove();};\n" +
144+
"}, totalCount -> {}, 100, "+t1.name+".where"+firstToUpperCase(refCol.name)+"().is(obj."+idCol.name+"));}\n\n";
145+
if(!refCol.type.equals(idCol.type)) s = "/* Possibly not a primary id, since types do not match, thus ignored! " +
146+
t1.name+"."+refCol.name+" "+refCol.type.inJava +" != "+t.name+"."+idCol.name+" "+idCol.type.inJava+" \n" + s + "*/";
147+
sb.append(s + "\n\n");
138148
//sb.append(t1.name+".remove(\"WHERE "+col.name+"=?\", obj.id);");
139149
}
140150
});

0 commit comments

Comments
 (0)