diff --git a/.idea/hydra.xml b/.idea/hydra.xml new file mode 100644 index 0000000000000000000000000000000000000000..66eeb9a09bd7413adc066eea7b10ad6a1f5cc95b --- /dev/null +++ b/.idea/hydra.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="HydraSettings"> + <option name="hydraStorePath" value="$PROJECT_DIR$/.hydra/idea" /> + <option name="noOfCores" value="2" /> + <option name="projectRoot" value="$PROJECT_DIR$" /> + <option name="sourcePartitioner" value="auto" /> + </component> +</project> \ No newline at end of file diff --git a/src/main/java/de/tobias/playpad/server/sql/ColumnName.java b/src/main/java/de/tobias/playpad/server/sql/ColumnName.java new file mode 100644 index 0000000000000000000000000000000000000000..733f758c76fd31b48fbe6c33ab60a6bbdefd6999 --- /dev/null +++ b/src/main/java/de/tobias/playpad/server/sql/ColumnName.java @@ -0,0 +1,19 @@ +package de.tobias.playpad.server.sql; + +import java.lang.annotation.*; + +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface ColumnName +{ + /** + * Name of the table column. + * + * @return name + */ + String value(); + + Class<? extends SqlResultHandler> handler() default StringSqlResultHandler.class; + +} diff --git a/src/main/java/de/tobias/playpad/server/sql/ForeignKey.java b/src/main/java/de/tobias/playpad/server/sql/ForeignKey.java new file mode 100644 index 0000000000000000000000000000000000000000..2cddd2cc44c9fa0829351925cc94825f2fb9a18e --- /dev/null +++ b/src/main/java/de/tobias/playpad/server/sql/ForeignKey.java @@ -0,0 +1,10 @@ +package de.tobias.playpad.server.sql; + +import java.lang.annotation.*; + +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface ForeignKey +{ +} diff --git a/src/main/java/de/tobias/playpad/server/sql/Id.java b/src/main/java/de/tobias/playpad/server/sql/Id.java new file mode 100644 index 0000000000000000000000000000000000000000..657f21485adf443b845e2db229cf228a87fe79e7 --- /dev/null +++ b/src/main/java/de/tobias/playpad/server/sql/Id.java @@ -0,0 +1,10 @@ +package de.tobias.playpad.server.sql; + +import java.lang.annotation.*; + +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface Id +{ +} diff --git a/src/main/java/de/tobias/playpad/server/sql/Table.java b/src/main/java/de/tobias/playpad/server/sql/Table.java new file mode 100644 index 0000000000000000000000000000000000000000..4430b4b97eb69ff741cd17e4c8f488bd82f79df1 --- /dev/null +++ b/src/main/java/de/tobias/playpad/server/sql/Table.java @@ -0,0 +1,11 @@ +package de.tobias.playpad.server.sql; + +import java.lang.annotation.*; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface Table +{ + String value(); +} diff --git a/src/main/scala/de/tobias/playpad/server/project/Pad.scala b/src/main/scala/de/tobias/playpad/server/project/Pad.scala index 79cdce53d657559aaed4e73f8d72e107b40191ad..490b58bc793c8d833bf975054d353542a5e91fb8 100644 --- a/src/main/scala/de/tobias/playpad/server/project/Pad.scala +++ b/src/main/scala/de/tobias/playpad/server/project/Pad.scala @@ -4,21 +4,28 @@ import java.util.UUID import de.tobias.playpad.server.json._ import de.tobias.playpad.server.project.settings.PadSettings +import de.tobias.playpad.server.sql.{ColumnName, ForeignKey, Id, Table} /** * Created by tobias on 17.02.17. */ +@Table("Pad") class Pad() { @JsonName(value = "id", handler = classOf[UUIDSerializerHandler]) + @Id + @ColumnName("id") var id: UUID = UUID.randomUUID() @JsonName("name") + @ColumnName("name") var name: String = _ @JsonName(value = "position", handler = classOf[IntSerializerHandler]) + @ColumnName("position") var position: Int = _ @JsonName("contentType") + @ColumnName("content_type") var contentType: String = _ @JsonCollection(value = "paths", `type` = classOf[Path]) var paths: List[Path] = List() @@ -27,5 +34,9 @@ class Pad() { var padSettings: PadSettings = _ @JsonParent + @ForeignKey var page: Page = _ + + + override def toString = s"Pad($id, $name, $position, $contentType, $paths, $padSettings, $page)" } diff --git a/src/main/scala/de/tobias/playpad/server/project/loader/sql/PadLoader.scala b/src/main/scala/de/tobias/playpad/server/project/loader/sql/PadLoader.scala index e89f571dd8582fc1b055ddff5c5c033416883030..aabfb7ad4a53480bddb0adfca450195ca4eadcfa 100644 --- a/src/main/scala/de/tobias/playpad/server/project/loader/sql/PadLoader.scala +++ b/src/main/scala/de/tobias/playpad/server/project/loader/sql/PadLoader.scala @@ -5,7 +5,7 @@ import java.util.UUID import de.tobias.playpad.server.project.utils.SqlDef._ import de.tobias.playpad.server.project.{Pad, Page} - +import de.tobias.playpad.server.sql.SqlSerializer /** * Created by tobias on 17.02.17. */ @@ -18,6 +18,10 @@ class PadLoader(val connection: Connection) { var pads: List[Pad] = List() + + val padss = new SqlSerializer().queryObj(classOf[Pad], connection) + println(padss) + while (result.next()) { val pad = new Pad() pad.id = UUID.fromString(result.getString(PAD_ID)) diff --git a/src/main/scala/de/tobias/playpad/server/sql/SqlResultHandler.scala b/src/main/scala/de/tobias/playpad/server/sql/SqlResultHandler.scala new file mode 100644 index 0000000000000000000000000000000000000000..cae028ee18c0e532ba23c041f8437429848292cb --- /dev/null +++ b/src/main/scala/de/tobias/playpad/server/sql/SqlResultHandler.scala @@ -0,0 +1,8 @@ +package de.tobias.playpad.server.sql + +trait SqlResultHandler { + + def fromResult(o: Any): Any + + def toQuery(o: Any): Any +} diff --git a/src/main/scala/de/tobias/playpad/server/sql/SqlSerializer.scala b/src/main/scala/de/tobias/playpad/server/sql/SqlSerializer.scala new file mode 100644 index 0000000000000000000000000000000000000000..f927f48526c3c566e23c0fa39cd642f7f6b63383 --- /dev/null +++ b/src/main/scala/de/tobias/playpad/server/sql/SqlSerializer.scala @@ -0,0 +1,107 @@ +package de.tobias.playpad.server.sql + +import java.sql.{Connection, ResultSet} +import java.util.UUID + +class SqlSerializer { + + def queryObj[T](clazz: Class[T], key: UUID, connection: Connection, keyName: String = null): T = { + val obj = clazz.newInstance() + if (clazz.isAnnotationPresent(classOf[Table])) { + val table = clazz.getAnnotation(classOf[Table]).value() + + val columnName = if (keyName != null) { + keyName + } else { + getKeyName(clazz) + } + + val stmt = connection.prepareStatement(s"SELECT * FROM $table WHERE $columnName = ?") + stmt.setString(1, key.toString) + val result = stmt.executeQuery() + + if (result.first()) { + clazz.getDeclaredFields + .filter(f => f.isAnnotationPresent(classOf[ColumnName])) + .foreach(f => { + f.setAccessible(true) + f.set(obj, result.getObject(f.getAnnotation(classOf[ColumnName]).value())) + }) + } + + result.close() + stmt.close() + } + obj + } + + private def getKeyName[T](clazz: Class[T]): String = { + val field = clazz.getDeclaredFields + .filter(f => f.isAnnotationPresent(classOf[ColumnName])) + .find(f => f.isAnnotationPresent(classOf[Id])) + + if (field.isDefined) { + field.get.getAnnotation(classOf[ColumnName]).value() + } else { + null + } + } + + // def queryObj[T](clazz: Class[T], key: UUID, connection: Connection, keyName: String): List[T] = { + // if (clazz.isAnnotationPresent(classOf[Table])) { + // val table = clazz.getAnnotation(classOf[Table]).value() + // + // val stmt = connection.prepareStatement(s"SELECT * FROM $table WHERE $keyName = ?") + // stmt.setString(1, key.toString) + // val result = stmt.executeQuery() + // + // val list = getResult(clazz, result) + // + // result.close() + // stmt.close() + // list + // } else { + // null + // } + // } + + def queryObj[T](clazz: Class[T], connection: Connection): List[T] = { + if (clazz.isAnnotationPresent(classOf[Table])) { + val table = clazz.getAnnotation(classOf[Table]).value() + + val stmt = connection.prepareStatement(s"SELECT * FROM $table") + val result = stmt.executeQuery() + + val list = getResult(clazz, result) + + result.close() + stmt.close() + list + } else { + null + } + } + + private def getResult[T](clazz: Class[T], result: ResultSet): List[T] = { + var list = List[T]() + while (result.next()) { + val obj = clazz.newInstance() + clazz.getDeclaredFields + .filter(f => f.isAnnotationPresent(classOf[ColumnName])) + .foreach(f => { + f.setAccessible(true) + + if (f.getType.equals(classOf[UUID])) { + f.set(obj, UUID.fromString(result.getString(f.getAnnotation(classOf[ColumnName]).value()))) + } else { + val column = f.getAnnotation(classOf[ColumnName]) + val columnName = column.value() + f.set(obj, column.handler().newInstance().fromResult(result.getObject(columnName))) + } + + }) + list = obj :: list + } + list + } +} diff --git a/src/main/scala/de/tobias/playpad/server/sql/StringSqlResultHandler.scala b/src/main/scala/de/tobias/playpad/server/sql/StringSqlResultHandler.scala new file mode 100644 index 0000000000000000000000000000000000000000..e1e501ff6d3fcaac452dfedfbfd44e6202898329 --- /dev/null +++ b/src/main/scala/de/tobias/playpad/server/sql/StringSqlResultHandler.scala @@ -0,0 +1,7 @@ +package de.tobias.playpad.server.sql + +class StringSqlResultHandler extends SqlResultHandler { + override def fromResult(o: Any): Any = o + + override def toQuery(o: Any): Any = o +} diff --git a/src/main/scala/de/tobias/playpad/server/sql/UUIDSqlResultHandler.scala b/src/main/scala/de/tobias/playpad/server/sql/UUIDSqlResultHandler.scala new file mode 100644 index 0000000000000000000000000000000000000000..2cc3788126d1cbbbc469af36949bacbe2cdf85eb --- /dev/null +++ b/src/main/scala/de/tobias/playpad/server/sql/UUIDSqlResultHandler.scala @@ -0,0 +1,19 @@ +package de.tobias.playpad.server.sql + +import java.util.UUID + +class UUIDSqlResultHandler extends SqlResultHandler { + override def fromResult(o: Any): Any = { + o match { + case string: String => UUID.fromString(string) + case _ => null + } + } + + override def toQuery(o: Any): Any = { + o match { + case uuid: UUID => uuid.toString + case _ => null + } + } +}