From 5e29f19a31b41f9385aed2852879dbeec0ddef2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlio=20C=C3=A9zar?= Date: Fri, 17 Nov 2017 23:36:42 -0200 Subject: [PATCH] Add support to Foreign Key actions "ON UPDATE" and "ON DELETE" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Júlio Cézar --- .../annotation/ForeignKeyAction.java | 13 ++++ .../annotation/ForeignKeyConstraint.java | 9 +-- .../schematic/annotation/References.java | 4 + .../schematic/compiler/TableWriter.java | 73 +++++++++++++++---- .../schematic/sample/database/NoteColumns.kt | 9 +-- .../schematic/sample/database/TagColumns.kt | 11 +-- .../sample/database/NoteColumns.java | 5 +- .../schematic/sample/database/TagColumns.java | 4 +- 8 files changed, 90 insertions(+), 38 deletions(-) create mode 100755 schematic-annotations/src/main/java/net/simonvt/schematic/annotation/ForeignKeyAction.java mode change 100644 => 100755 schematic-annotations/src/main/java/net/simonvt/schematic/annotation/ForeignKeyConstraint.java mode change 100644 => 100755 schematic-annotations/src/main/java/net/simonvt/schematic/annotation/References.java mode change 100644 => 100755 schematic-compiler/src/main/java/net/simonvt/schematic/compiler/TableWriter.java mode change 100644 => 100755 schematic-sample-kotlin/src/main/java/net/simonvt/schematic/sample/database/NoteColumns.kt mode change 100644 => 100755 schematic-sample-kotlin/src/main/java/net/simonvt/schematic/sample/database/TagColumns.kt mode change 100644 => 100755 schematic-sample/src/main/java/net/simonvt/schematic/sample/database/NoteColumns.java mode change 100644 => 100755 schematic-sample/src/main/java/net/simonvt/schematic/sample/database/TagColumns.java diff --git a/schematic-annotations/src/main/java/net/simonvt/schematic/annotation/ForeignKeyAction.java b/schematic-annotations/src/main/java/net/simonvt/schematic/annotation/ForeignKeyAction.java new file mode 100755 index 0000000..f005331 --- /dev/null +++ b/schematic-annotations/src/main/java/net/simonvt/schematic/annotation/ForeignKeyAction.java @@ -0,0 +1,13 @@ +package net.simonvt.schematic.annotation; + +/** + * Action triggered with foreign key ON DELETE and ON UPDATE clauses. + */ +public enum ForeignKeyAction { + NONE, + NO_ACTION, + RESTRICT, + SET_NULL, + SET_DEFAULT, + CASCADE, +} diff --git a/schematic-annotations/src/main/java/net/simonvt/schematic/annotation/ForeignKeyConstraint.java b/schematic-annotations/src/main/java/net/simonvt/schematic/annotation/ForeignKeyConstraint.java old mode 100644 new mode 100755 index d9fa8bc..12309c9 --- a/schematic-annotations/src/main/java/net/simonvt/schematic/annotation/ForeignKeyConstraint.java +++ b/schematic-annotations/src/main/java/net/simonvt/schematic/annotation/ForeignKeyConstraint.java @@ -21,9 +21,8 @@ /** Column names in referenced table */ String[] referencedColumns(); - /** - * Defines conflict resolution algorithm. - * By default {@link ConflictResolutionType#NONE} is used. - * */ - ConflictResolutionType onConflict() default ConflictResolutionType.NONE; + + ForeignKeyAction onDelete() default ForeignKeyAction.NONE; + + ForeignKeyAction onUpdate() default ForeignKeyAction.NONE; } diff --git a/schematic-annotations/src/main/java/net/simonvt/schematic/annotation/References.java b/schematic-annotations/src/main/java/net/simonvt/schematic/annotation/References.java old mode 100644 new mode 100755 index 129d6ed..20a3ca2 --- a/schematic-annotations/src/main/java/net/simonvt/schematic/annotation/References.java +++ b/schematic-annotations/src/main/java/net/simonvt/schematic/annotation/References.java @@ -34,4 +34,8 @@ String table(); String column(); + + ForeignKeyAction onDelete() default ForeignKeyAction.NONE; + + ForeignKeyAction onUpdate() default ForeignKeyAction.NONE; } diff --git a/schematic-compiler/src/main/java/net/simonvt/schematic/compiler/TableWriter.java b/schematic-compiler/src/main/java/net/simonvt/schematic/compiler/TableWriter.java old mode 100644 new mode 100755 index 45171fa..65b3b1c --- a/schematic-compiler/src/main/java/net/simonvt/schematic/compiler/TableWriter.java +++ b/schematic-compiler/src/main/java/net/simonvt/schematic/compiler/TableWriter.java @@ -22,12 +22,31 @@ import com.squareup.javapoet.JavaFile; import com.squareup.javapoet.MethodSpec; import com.squareup.javapoet.TypeSpec; + +import net.simonvt.schematic.annotation.AutoIncrement; +import net.simonvt.schematic.annotation.Check; +import net.simonvt.schematic.annotation.ConflictResolutionType; +import net.simonvt.schematic.annotation.Constraints; +import net.simonvt.schematic.annotation.DataType; +import net.simonvt.schematic.annotation.DefaultValue; +import net.simonvt.schematic.annotation.ForeignKeyAction; +import net.simonvt.schematic.annotation.ForeignKeyConstraint; +import net.simonvt.schematic.annotation.IfNotExists; +import net.simonvt.schematic.annotation.NotNull; +import net.simonvt.schematic.annotation.PrimaryKey; +import net.simonvt.schematic.annotation.PrimaryKeyConstraint; +import net.simonvt.schematic.annotation.References; +import net.simonvt.schematic.annotation.Table; +import net.simonvt.schematic.annotation.Unique; +import net.simonvt.schematic.annotation.UniqueConstraint; + import java.io.IOException; import java.io.Writer; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Arrays; import java.util.List; + import javax.annotation.processing.Filer; import javax.annotation.processing.ProcessingEnvironment; import javax.lang.model.element.Element; @@ -38,21 +57,6 @@ import javax.lang.model.type.TypeMirror; import javax.tools.Diagnostic.Kind; import javax.tools.JavaFileObject; -import net.simonvt.schematic.annotation.AutoIncrement; -import net.simonvt.schematic.annotation.Check; -import net.simonvt.schematic.annotation.ConflictResolutionType; -import net.simonvt.schematic.annotation.Constraints; -import net.simonvt.schematic.annotation.DataType; -import net.simonvt.schematic.annotation.DefaultValue; -import net.simonvt.schematic.annotation.ForeignKeyConstraint; -import net.simonvt.schematic.annotation.IfNotExists; -import net.simonvt.schematic.annotation.NotNull; -import net.simonvt.schematic.annotation.PrimaryKey; -import net.simonvt.schematic.annotation.PrimaryKeyConstraint; -import net.simonvt.schematic.annotation.References; -import net.simonvt.schematic.annotation.Table; -import net.simonvt.schematic.annotation.Unique; -import net.simonvt.schematic.annotation.UniqueConstraint; public class TableWriter { @@ -251,6 +255,14 @@ public void createTable(TypeSpec.Builder databaseBuilder) .append("(") .append(references.column()) .append(")"); + if(references.onUpdate() != ForeignKeyAction.NONE) { + query.append(" ").append("ON UPDATE").append(" "); + writeOnActions(query, references.onUpdate()); + } + if(references.onDelete() != ForeignKeyAction.NONE) { + query.append(" ").append("ON DELETE").append(" "); + writeOnActions(query, references.onDelete()); + } } } @@ -310,7 +322,14 @@ private static void writeForeignKeyConstraint(StringBuilder query, ForeignKeyCon query.append(foreignKey.referencedColumns()[i]); } query.append(')'); - + if(foreignKey.onUpdate() != ForeignKeyAction.NONE) { + query.append(" ").append("ON UPDATE").append(" "); + writeOnActions(query, foreignKey.onUpdate()); + } + if(foreignKey.onDelete() != ForeignKeyAction.NONE) { + query.append(" ").append("ON DELETE").append(" "); + writeOnActions(query, foreignKey.onDelete()); + } } private static void writePrimaryOrUniqueConstraint( @@ -380,6 +399,28 @@ private static void writeOnConflict(StringBuilder query, } } + private static void writeOnActions(StringBuilder query, + ForeignKeyAction foreignKeyAction) { + switch (foreignKeyAction) { + case RESTRICT: + query.append("RESTRICT"); + break; + case SET_NULL: + query.append("SET NULL"); + break; + case SET_DEFAULT: + query.append("SET DEFAULT"); + break; + case CASCADE: + query.append("CASCADE"); + break; + case NO_ACTION: + default: + query.append("NO ACTION"); + break; + } + } + public void createValuesBuilder(Filer filer, String outPackage) throws IOException { String name = Character.toUpperCase(this.name.charAt(0)) + this.name.substring(1); String valuesPackage = outPackage + ".values"; diff --git a/schematic-sample-kotlin/src/main/java/net/simonvt/schematic/sample/database/NoteColumns.kt b/schematic-sample-kotlin/src/main/java/net/simonvt/schematic/sample/database/NoteColumns.kt old mode 100644 new mode 100755 index e83a7ab..3993a11 --- a/schematic-sample-kotlin/src/main/java/net/simonvt/schematic/sample/database/NoteColumns.kt +++ b/schematic-sample-kotlin/src/main/java/net/simonvt/schematic/sample/database/NoteColumns.kt @@ -16,13 +16,9 @@ package net.simonvt.schematic.sample.database -import net.simonvt.schematic.annotation.AutoIncrement -import net.simonvt.schematic.annotation.Check -import net.simonvt.schematic.annotation.DataType +import net.simonvt.schematic.annotation.* import net.simonvt.schematic.annotation.DataType.Type.INTEGER import net.simonvt.schematic.annotation.DataType.Type.TEXT -import net.simonvt.schematic.annotation.PrimaryKey -import net.simonvt.schematic.annotation.References import net.simonvt.schematic.sample.database.NotesDatabase.Tables interface NoteColumns { @@ -32,7 +28,8 @@ interface NoteColumns { @DataType(INTEGER) @PrimaryKey @AutoIncrement const val ID = "_id" - @DataType(INTEGER) @References(table = Tables.LISTS, column = ListColumns.ID) + @DataType(INTEGER) @References(table = Tables.LISTS, column = ListColumns.ID, + onDelete = ForeignKeyAction.CASCADE) const val LIST_ID = "listId" @DataType(TEXT) const val NOTE = "note" diff --git a/schematic-sample-kotlin/src/main/java/net/simonvt/schematic/sample/database/TagColumns.kt b/schematic-sample-kotlin/src/main/java/net/simonvt/schematic/sample/database/TagColumns.kt old mode 100644 new mode 100755 index ef0ae58..9e928e6 --- a/schematic-sample-kotlin/src/main/java/net/simonvt/schematic/sample/database/TagColumns.kt +++ b/schematic-sample-kotlin/src/main/java/net/simonvt/schematic/sample/database/TagColumns.kt @@ -1,14 +1,8 @@ package net.simonvt.schematic.sample.database -import net.simonvt.schematic.annotation.AutoIncrement +import net.simonvt.schematic.annotation.* import net.simonvt.schematic.annotation.ConflictResolutionType.REPLACE -import net.simonvt.schematic.annotation.Constraints -import net.simonvt.schematic.annotation.DataType import net.simonvt.schematic.annotation.DataType.Type -import net.simonvt.schematic.annotation.NotNull -import net.simonvt.schematic.annotation.PrimaryKey -import net.simonvt.schematic.annotation.References -import net.simonvt.schematic.annotation.UniqueConstraint @Constraints( unique = arrayOf( @@ -24,7 +18,8 @@ interface TagColumns { @DataType(Type.INTEGER) @PrimaryKey @AutoIncrement const val ID = "_id" @DataType(Type.INTEGER) @NotNull - @References(table = NotesDatabase.NOTES, column = NoteColumns.ID) + @References(table = NotesDatabase.NOTES, column = NoteColumns.ID, + onDelete = ForeignKeyAction.CASCADE) const val NOTE_ID = "note_id" @DataType(Type.TEXT) @NotNull diff --git a/schematic-sample/src/main/java/net/simonvt/schematic/sample/database/NoteColumns.java b/schematic-sample/src/main/java/net/simonvt/schematic/sample/database/NoteColumns.java old mode 100644 new mode 100755 index 90612d0..8ba2040 --- a/schematic-sample/src/main/java/net/simonvt/schematic/sample/database/NoteColumns.java +++ b/schematic-sample/src/main/java/net/simonvt/schematic/sample/database/NoteColumns.java @@ -20,6 +20,7 @@ import net.simonvt.schematic.annotation.Check; import net.simonvt.schematic.annotation.DataType; import net.simonvt.schematic.annotation.PrimaryKey; +import net.simonvt.schematic.annotation.ForeignKeyAction; import net.simonvt.schematic.annotation.References; import net.simonvt.schematic.sample.database.NotesDatabase.Tables; @@ -32,8 +33,8 @@ public interface NoteColumns { @DataType(INTEGER) @PrimaryKey @AutoIncrement String ID = "_id"; - @DataType(INTEGER) @References(table = Tables.LISTS, column = ListColumns.ID) String LIST_ID = - "listId"; + @DataType(INTEGER) @References(table = Tables.LISTS, column = ListColumns.ID, + onDelete = ForeignKeyAction.CASCADE) String LIST_ID = "listId"; @DataType(TEXT) String NOTE = "note"; diff --git a/schematic-sample/src/main/java/net/simonvt/schematic/sample/database/TagColumns.java b/schematic-sample/src/main/java/net/simonvt/schematic/sample/database/TagColumns.java old mode 100644 new mode 100755 index c300c74..59e0e1a --- a/schematic-sample/src/main/java/net/simonvt/schematic/sample/database/TagColumns.java +++ b/schematic-sample/src/main/java/net/simonvt/schematic/sample/database/TagColumns.java @@ -6,6 +6,7 @@ import net.simonvt.schematic.annotation.DataType.Type; import net.simonvt.schematic.annotation.NotNull; import net.simonvt.schematic.annotation.PrimaryKey; +import net.simonvt.schematic.annotation.ForeignKeyAction; import net.simonvt.schematic.annotation.References; import net.simonvt.schematic.annotation.UniqueConstraint; @@ -25,7 +26,8 @@ public interface TagColumns { @DataType(Type.INTEGER) @NotNull - @References(table = NotesDatabase.NOTES, column = NoteColumns.ID) + @References(table = NotesDatabase.NOTES, column = NoteColumns.ID, + onDelete = ForeignKeyAction.CASCADE) String NOTE_ID = "note_id"; @DataType(Type.TEXT)