Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support to Foreign Key actions "ON UPDATE" and "ON DELETE" #84

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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,
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
4 changes: 4 additions & 0 deletions schematic-annotations/src/main/java/net/simonvt/schematic/annotation/References.java
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,8 @@
String table();

String column();

ForeignKeyAction onDelete() default ForeignKeyAction.NONE;

ForeignKeyAction onUpdate() default ForeignKeyAction.NONE;
}
73 changes: 57 additions & 16 deletions schematic-compiler/src/main/java/net/simonvt/schematic/compiler/TableWriter.java
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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 {

Expand Down Expand Up @@ -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());
}
}
}

Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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"
Expand Down
11 changes: 3 additions & 8 deletions schematic-sample-kotlin/src/main/java/net/simonvt/schematic/sample/database/TagColumns.kt
100644 → 100755
Original file line number Diff line number Diff line change
@@ -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(
Expand All @@ -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
Expand Down
5 changes: 3 additions & 2 deletions schematic-sample/src/main/java/net/simonvt/schematic/sample/database/NoteColumns.java
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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";

Expand Down
4 changes: 3 additions & 1 deletion schematic-sample/src/main/java/net/simonvt/schematic/sample/database/TagColumns.java
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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)
Expand Down