From 9d25f129826b4fced8726c27f1be8c3aa6387a4b Mon Sep 17 00:00:00 2001 From: Stewart Stewart Date: Wed, 22 Feb 2017 21:52:14 -0500 Subject: separate rows from table defs --- src/main/scala/NamespacedCodegen.scala | 111 ++++++++++++++++++++++++++++++--- src/main/scala/OutputHelpers.scala | 2 +- 2 files changed, 105 insertions(+), 8 deletions(-) diff --git a/src/main/scala/NamespacedCodegen.scala b/src/main/scala/NamespacedCodegen.scala index 85e21bf..7dd99cc 100644 --- a/src/main/scala/NamespacedCodegen.scala +++ b/src/main/scala/NamespacedCodegen.scala @@ -49,7 +49,7 @@ object Generator { Some(Map(schemaName -> tables)))), Duration.Inf) - val generator = new Generator(pkg, + val tableGenerator = new TableGenerator(pkg, dbModel, schemaOnlyModel, manualForeignKeys, @@ -57,12 +57,28 @@ object Generator { idType, header, schemaImports, - typeReplacements) - generator.writeToFile(profile = profile, + typeReplacements, + schemaName) + tableGenerator.writeToFile(profile = profile, folder = outputPath, pkg = pkg, container = schemaName, fileName = s"${schemaName}.scala") + + val rowGenerator = new RowGenerator(pkg, + dbModel, + schemaOnlyModel, + manualForeignKeys, + parentType, + idType, + header, + schemaImports, + typeReplacements) + rowGenerator.writeToFile( + schemaName = schemaName, + folder = outputPath, + pkg = pkg, + fileName = s"${schemaName.capitalize}Rows.scala") } } finally { dc.db.close() @@ -71,7 +87,7 @@ object Generator { } -class Generator(pkg: String, +abstract class Generator(pkg: String, fullDatabaseModel: Model, schemaOnlyModel: Model, manualForeignKeys: Map[(String, String), (String, String)], @@ -99,7 +115,9 @@ class Generator(pkg: String, // Alias to ForeignKeyAction is in profile.api // TODO: fix upstream - override def Table = new Table(_) { table => + override def Table = new TableO(_) + + class TableO(model: sModel.Table) extends this.Table(model) { table => override def TableClass = new TableClass() { // We disable the option mapping, as it is a bit more complex to support and we don't appear to need it @@ -138,10 +156,10 @@ class Generator(pkg: String, // But can't have the final case class inside the trait // TODO: Fix by putting case classes in package or object // TODO: Upstream default should be false. - (if (classEnabled) "sealed " else "") + super.code + (if (classEnabled) "final " else "") + super.code } - override def Column = new Column(_) { column => + override def Column = new this.Column(_) { column => // use fullDatabasemodel model here for cross-schema foreign keys val manualReferences = SchemaParser.references(fullDatabaseModel, manualForeignKeys) @@ -260,3 +278,82 @@ object SchemaParser { jdbcProfile.createModel(filteredTables) } } + +class RowGenerator(pkg: String, + fullDatabaseModel: Model, + schemaOnlyModel: Model, + manualForeignKeys: Map[(String, String), (String, String)], + override val parentType: Option[String], + idType: Option[String], + override val headerComment: String, + schemaImports: List[String], + typeReplacements: Map[String, String]) + extends Generator(pkg, + fullDatabaseModel, + schemaOnlyModel, + manualForeignKeys, + parentType, + idType, + headerComment, + schemaImports, + typeReplacements) { + + override def Table = new TableO(_) { + //override def Column = new IdColumn(_){ } + override def code = Seq[Def](EntityType).map(_.docWithCode) + } + + override def code = tables.map(_.code.mkString("\n")).mkString("\n\n") + + def writeToFile(schemaName: String, folder: String, pkg: String, fileName: String) = { + writeStringToFile(packageCode(pkg, schemaName), folder = folder, pkg = pkg, fileName = fileName) + } + + override val imports = schemaImports.map("import " + _).mkString("\n") + + def packageCode(pkg: String, schemaName: String) = { + s"""|package $pkg + |package $schemaName + | + |$imports + | + |$code + |""".stripMargin.trim() + } + + // disable helpers for Table schema generators + //override def packageCode(profile: String, pkg: String, container: String, parentType: Option[String]) = ??? + //override def writeToFile(profile: String, folder: String, pkg: String, container: String, fileName: String) = ??? +} + +class TableGenerator(pkg: String, + fullDatabaseModel: Model, + schemaOnlyModel: Model, + manualForeignKeys: Map[(String, String), (String, String)], + override val parentType: Option[String], + idType: Option[String], + override val headerComment: String, + schemaImports: List[String], + typeReplacements: Map[String, String], + schemaName: String +) + extends Generator(pkg, + fullDatabaseModel, + schemaOnlyModel, + manualForeignKeys, + parentType, + idType, + headerComment, + schemaImports, + typeReplacements) { + + override def Table = new TableO(_) { + override def EntityType = new EntityType { + override def enabled = false + } + override def TableClass = new TableClass { + override def elementType = s"$schemaName.${super.elementType}" + override def optionEnabled = false + } + } +} diff --git a/src/main/scala/OutputHelpers.scala b/src/main/scala/OutputHelpers.scala index ce22f2a..82eabd1 100644 --- a/src/main/scala/OutputHelpers.scala +++ b/src/main/scala/OutputHelpers.scala @@ -15,7 +15,7 @@ trait OutputHelpers extends slick.codegen.OutputHelpers { |$imports | |/** Stand-alone Slick data model for immediate use */ - |object $container extends { + |package object $container extends { | val profile = $profile |} with $traitName | -- cgit v1.2.3 From fc53279b51f4be08b4bed7dca7bf427b116874ea Mon Sep 17 00:00:00 2001 From: Stewart Stewart Date: Thu, 23 Feb 2017 13:58:00 -0500 Subject: scalafmt --- src/main/scala/NamespacedCodegen.scala | 158 +++++++++++++++++---------------- 1 file changed, 81 insertions(+), 77 deletions(-) diff --git a/src/main/scala/NamespacedCodegen.scala b/src/main/scala/NamespacedCodegen.scala index 7dd99cc..bdb9fc6 100644 --- a/src/main/scala/NamespacedCodegen.scala +++ b/src/main/scala/NamespacedCodegen.scala @@ -5,10 +5,7 @@ import scala.concurrent.Await import scala.concurrent.duration.Duration import scala.concurrent.ExecutionContext.Implicits.global import slick.backend.DatabaseConfig -import slick.codegen.{ - SourceCodeGenerator, - StringGeneratorHelpers -} +import slick.codegen.{SourceCodeGenerator, StringGeneratorHelpers} import slick.dbio.DBIO import slick.driver.JdbcProfile import slick.jdbc.meta.MTable @@ -50,35 +47,35 @@ object Generator { Duration.Inf) val tableGenerator = new TableGenerator(pkg, - dbModel, - schemaOnlyModel, - manualForeignKeys, - parentType, - idType, - header, - schemaImports, - typeReplacements, - schemaName) + dbModel, + schemaOnlyModel, + manualForeignKeys, + parentType, + idType, + header, + schemaImports, + typeReplacements, + schemaName) tableGenerator.writeToFile(profile = profile, - folder = outputPath, - pkg = pkg, - container = schemaName, - fileName = s"${schemaName}.scala") + folder = outputPath, + pkg = pkg, + container = schemaName, + fileName = s"${schemaName}.scala") val rowGenerator = new RowGenerator(pkg, - dbModel, - schemaOnlyModel, - manualForeignKeys, - parentType, - idType, - header, - schemaImports, - typeReplacements) - rowGenerator.writeToFile( - schemaName = schemaName, - folder = outputPath, - pkg = pkg, - fileName = s"${schemaName.capitalize}Rows.scala") + dbModel, + schemaOnlyModel, + manualForeignKeys, + parentType, + idType, + header, + schemaImports, + typeReplacements) + rowGenerator.writeToFile(schemaName = schemaName, + folder = outputPath, + pkg = pkg, + fileName = + s"${schemaName.capitalize}Rows.scala") } } finally { dc.db.close() @@ -87,15 +84,16 @@ object Generator { } -abstract class Generator(pkg: String, - fullDatabaseModel: Model, - schemaOnlyModel: Model, - manualForeignKeys: Map[(String, String), (String, String)], - override val parentType: Option[String], - idType: Option[String], - override val headerComment: String, - schemaImports: List[String], - typeReplacements: Map[String, String]) +abstract class Generator( + pkg: String, + fullDatabaseModel: Model, + schemaOnlyModel: Model, + manualForeignKeys: Map[(String, String), (String, String)], + override val parentType: Option[String], + idType: Option[String], + override val headerComment: String, + schemaImports: List[String], + typeReplacements: Map[String, String]) extends SourceCodeGenerator(schemaOnlyModel) with OutputHelpers { @@ -116,7 +114,7 @@ abstract class Generator(pkg: String, // TODO: fix upstream override def Table = new TableO(_) - + class TableO(model: sModel.Table) extends this.Table(model) { table => override def TableClass = new TableClass() { @@ -280,23 +278,23 @@ object SchemaParser { } class RowGenerator(pkg: String, - fullDatabaseModel: Model, - schemaOnlyModel: Model, - manualForeignKeys: Map[(String, String), (String, String)], - override val parentType: Option[String], - idType: Option[String], - override val headerComment: String, - schemaImports: List[String], - typeReplacements: Map[String, String]) + fullDatabaseModel: Model, + schemaOnlyModel: Model, + manualForeignKeys: Map[(String, String), (String, String)], + override val parentType: Option[String], + idType: Option[String], + override val headerComment: String, + schemaImports: List[String], + typeReplacements: Map[String, String]) extends Generator(pkg, - fullDatabaseModel, - schemaOnlyModel, - manualForeignKeys, - parentType, - idType, - headerComment, - schemaImports, - typeReplacements) { + fullDatabaseModel, + schemaOnlyModel, + manualForeignKeys, + parentType, + idType, + headerComment, + schemaImports, + typeReplacements) { override def Table = new TableO(_) { //override def Column = new IdColumn(_){ } @@ -305,8 +303,14 @@ class RowGenerator(pkg: String, override def code = tables.map(_.code.mkString("\n")).mkString("\n\n") - def writeToFile(schemaName: String, folder: String, pkg: String, fileName: String) = { - writeStringToFile(packageCode(pkg, schemaName), folder = folder, pkg = pkg, fileName = fileName) + def writeToFile(schemaName: String, + folder: String, + pkg: String, + fileName: String) = { + writeStringToFile(packageCode(pkg, schemaName), + folder = folder, + pkg = pkg, + fileName = fileName) } override val imports = schemaImports.map("import " + _).mkString("\n") @@ -326,26 +330,26 @@ class RowGenerator(pkg: String, //override def writeToFile(profile: String, folder: String, pkg: String, container: String, fileName: String) = ??? } -class TableGenerator(pkg: String, - fullDatabaseModel: Model, - schemaOnlyModel: Model, - manualForeignKeys: Map[(String, String), (String, String)], - override val parentType: Option[String], - idType: Option[String], - override val headerComment: String, - schemaImports: List[String], - typeReplacements: Map[String, String], - schemaName: String -) +class TableGenerator( + pkg: String, + fullDatabaseModel: Model, + schemaOnlyModel: Model, + manualForeignKeys: Map[(String, String), (String, String)], + override val parentType: Option[String], + idType: Option[String], + override val headerComment: String, + schemaImports: List[String], + typeReplacements: Map[String, String], + schemaName: String) extends Generator(pkg, - fullDatabaseModel, - schemaOnlyModel, - manualForeignKeys, - parentType, - idType, - headerComment, - schemaImports, - typeReplacements) { + fullDatabaseModel, + schemaOnlyModel, + manualForeignKeys, + parentType, + idType, + headerComment, + schemaImports, + typeReplacements) { override def Table = new TableO(_) { override def EntityType = new EntityType { -- cgit v1.2.3 From 8fb0784cf220f72bc5aca87566e620b2d935b33c Mon Sep 17 00:00:00 2001 From: Stewart Stewart Date: Fri, 24 Feb 2017 03:15:30 -0500 Subject: checkpoint --- src/main/scala/NamespacedCodegen.scala | 23 ++++++++++------------- src/main/scala/OutputHelpers.scala | 5 ++--- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/src/main/scala/NamespacedCodegen.scala b/src/main/scala/NamespacedCodegen.scala index bdb9fc6..f08bd6c 100644 --- a/src/main/scala/NamespacedCodegen.scala +++ b/src/main/scala/NamespacedCodegen.scala @@ -46,6 +46,9 @@ object Generator { Some(Map(schemaName -> tables)))), Duration.Inf) + val camelSchemaName = + schemaName.split('_').map(_.capitalize).mkString("") + val tableGenerator = new TableGenerator(pkg, dbModel, schemaOnlyModel, @@ -54,13 +57,13 @@ object Generator { idType, header, schemaImports, - typeReplacements, - schemaName) + typeReplacements) tableGenerator.writeToFile(profile = profile, folder = outputPath, - pkg = pkg, + pkg = s"$pkg.$schemaName", container = schemaName, - fileName = s"${schemaName}.scala") + fileName = + s"${camelSchemaName}Tables.scala") val rowGenerator = new RowGenerator(pkg, dbModel, @@ -73,9 +76,8 @@ object Generator { typeReplacements) rowGenerator.writeToFile(schemaName = schemaName, folder = outputPath, - pkg = pkg, - fileName = - s"${schemaName.capitalize}Rows.scala") + pkg = s"$pkg.$schemaName", + fileName = s"${camelSchemaName}Rows.scala") } } finally { dc.db.close() @@ -339,8 +341,7 @@ class TableGenerator( idType: Option[String], override val headerComment: String, schemaImports: List[String], - typeReplacements: Map[String, String], - schemaName: String) + typeReplacements: Map[String, String]) extends Generator(pkg, fullDatabaseModel, schemaOnlyModel, @@ -355,9 +356,5 @@ class TableGenerator( override def EntityType = new EntityType { override def enabled = false } - override def TableClass = new TableClass { - override def elementType = s"$schemaName.${super.elementType}" - override def optionEnabled = false - } } } diff --git a/src/main/scala/OutputHelpers.scala b/src/main/scala/OutputHelpers.scala index 82eabd1..3a184a4 100644 --- a/src/main/scala/OutputHelpers.scala +++ b/src/main/scala/OutputHelpers.scala @@ -8,7 +8,6 @@ trait OutputHelpers extends slick.codegen.OutputHelpers { pkg: String, container: String, parentType: Option[String]): String = { - val traitName = container.capitalize + "SchemaDef" s"""|${headerComment.trim().lines.map("// " + _).mkString("\n")} |package $pkg | @@ -17,10 +16,10 @@ trait OutputHelpers extends slick.codegen.OutputHelpers { |/** Stand-alone Slick data model for immediate use */ |package object $container extends { | val profile = $profile - |} with $traitName + |} with Tables | |/** Slick data model trait for extension, choice of backend or usage in the cake pattern. (Make sure to initialize this late.) */ - |trait $traitName${parentType.fold("")(" extends " + _)} { + |trait Tables${parentType.fold("")(" extends " + _)} { | import profile.api._ | ${indent(code)} |}""".stripMargin.trim() -- cgit v1.2.3 From 3a9d4366d7eda68145aaafc35619cf3e9c1a4d30 Mon Sep 17 00:00:00 2001 From: Stewart Stewart Date: Fri, 24 Feb 2017 04:12:50 -0500 Subject: stub out row/table OutputHelpers --- src/main/scala/NamespacedCodegen.scala | 2 +- src/main/scala/OutputHelpers.scala | 57 +++++++++++++++++++++++++++++++++- 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/src/main/scala/NamespacedCodegen.scala b/src/main/scala/NamespacedCodegen.scala index f08bd6c..08c0efd 100644 --- a/src/main/scala/NamespacedCodegen.scala +++ b/src/main/scala/NamespacedCodegen.scala @@ -97,7 +97,7 @@ abstract class Generator( schemaImports: List[String], typeReplacements: Map[String, String]) extends SourceCodeGenerator(schemaOnlyModel) - with OutputHelpers { + with OOutputHelpers { override val imports = schemaImports.map("import " + _).mkString("\n") diff --git a/src/main/scala/OutputHelpers.scala b/src/main/scala/OutputHelpers.scala index 3a184a4..2a3641e 100644 --- a/src/main/scala/OutputHelpers.scala +++ b/src/main/scala/OutputHelpers.scala @@ -1,4 +1,4 @@ -trait OutputHelpers extends slick.codegen.OutputHelpers { +trait OOutputHelpers extends slick.codegen.OutputHelpers { def imports: String @@ -25,3 +25,58 @@ trait OutputHelpers extends slick.codegen.OutputHelpers { |}""".stripMargin.trim() } } + +import slick.codegen.{SourceCodeGenerator, OutputHelpers} + +trait TableFileGenerator { self: SourceCodeGenerator => + def writeTablesToFile(folder:String, pkg: String, fileName: String): Unit +} + +trait RowFileGenerator { self: SourceCodeGenerator => + def writeRowsToFile(folder:String, pkg: String, fileName: String): Unit +} + +// Dirty work to hide OutputHelpers +trait TableOutputHelpers extends TableFileGenerator with OutputHelpers { self: SourceCodeGenerator => + + def packageTableCode: String = + """|${headerComment.trim().lines.map("// " + _).mkString("\n")} + |package $pkg + |package $schemaName + | + |$imports + | + |/** Stand-alone Slick data model for immediate use */ + |// TODO: change this to `object tables` + |package object $schemaName extends { + | val profile = $profile + |} with Tables + | + |/** Slick data model trait for extension, choice of backend or usage in the cake pattern. (Make sure to initialize this late.) */ + |trait Tables${parentType.fold("")(" extends " + _)} { + | import profile.api._ + | ${indent(code)} | + |""".stripMargin.trim() + + def writeTablesToFile(folder:String, pkg: String, fileName: String): Unit = { + writeStringToFile(content = packageTableCode, folder = folder, pkg = pkg, fileName = fileName) + } +} + +trait RowOutputHelpers extends RowFileGenerator with OutputHelpers { self: SourceCodeGenerator => + + def packageRowCode: String = + """|${headerComment.trim().lines.map("// " + _).mkString("\n")} + |/** Definitions for table rows types of database schema $schemaName */ + |package $pkg + |package $schemaName + | + |$imports + | + |$code + |""".stripMargin.trim() + + def writeRowsToFile(folder:String, pkg: String, fileName: String): Unit = { + writeStringToFile(content = packageRowCode, folder = folder, pkg = pkg, fileName = fileName) + } +} -- cgit v1.2.3 From 4458e2e22b2a170dc92e7315224020562a60e2ee Mon Sep 17 00:00:00 2001 From: Stewart Stewart Date: Fri, 24 Feb 2017 04:27:42 -0500 Subject: flesh out OutputHelper structure --- src/main/scala/OutputHelpers.scala | 73 +++++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 32 deletions(-) diff --git a/src/main/scala/OutputHelpers.scala b/src/main/scala/OutputHelpers.scala index 2a3641e..c3c5e0d 100644 --- a/src/main/scala/OutputHelpers.scala +++ b/src/main/scala/OutputHelpers.scala @@ -29,7 +29,7 @@ trait OOutputHelpers extends slick.codegen.OutputHelpers { import slick.codegen.{SourceCodeGenerator, OutputHelpers} trait TableFileGenerator { self: SourceCodeGenerator => - def writeTablesToFile(folder:String, pkg: String, fileName: String): Unit + def writeTablesToFile(profile: String, folder:String, pkg: String, fileName: String): Unit } trait RowFileGenerator { self: SourceCodeGenerator => @@ -39,44 +39,53 @@ trait RowFileGenerator { self: SourceCodeGenerator => // Dirty work to hide OutputHelpers trait TableOutputHelpers extends TableFileGenerator with OutputHelpers { self: SourceCodeGenerator => - def packageTableCode: String = - """|${headerComment.trim().lines.map("// " + _).mkString("\n")} - |package $pkg - |package $schemaName - | - |$imports - | - |/** Stand-alone Slick data model for immediate use */ - |// TODO: change this to `object tables` - |package object $schemaName extends { - | val profile = $profile - |} with Tables - | - |/** Slick data model trait for extension, choice of backend or usage in the cake pattern. (Make sure to initialize this late.) */ - |trait Tables${parentType.fold("")(" extends " + _)} { - | import profile.api._ - | ${indent(code)} | - |""".stripMargin.trim() + def headerComment: String + def schemaName: String + def imports: String + + def packageTableCode(headerComment: String, pkg: String, schemaName: String, imports: String, profile: String): String = + s"""|${headerComment.trim().lines.map("// " + _).mkString("\n")} + |package $pkg + |package $schemaName + | + |$imports + | + |/** Stand-alone Slick data model for immediate use */ + |// TODO: change this to `object tables` + |package object $schemaName extends { + | val profile = $profile + |} with Tables + | + |/** Slick data model trait for extension, choice of backend or usage in the cake pattern. (Make sure to initialize this late.) */ + |trait Tables${parentType.fold("")(" extends " + _)} { + | import profile.api._ + | ${indent(code)} | + |""".stripMargin.trim() - def writeTablesToFile(folder:String, pkg: String, fileName: String): Unit = { - writeStringToFile(content = packageTableCode, folder = folder, pkg = pkg, fileName = fileName) + def writeTablesToFile(profile: String, folder:String, pkg: String, fileName: String): Unit = { + writeStringToFile(content = packageTableCode(headerComment, pkg, schemaName, imports, profile), folder = folder, pkg = s"$pkg.$schemaName", fileName = fileName) } } trait RowOutputHelpers extends RowFileGenerator with OutputHelpers { self: SourceCodeGenerator => - def packageRowCode: String = - """|${headerComment.trim().lines.map("// " + _).mkString("\n")} - |/** Definitions for table rows types of database schema $schemaName */ - |package $pkg - |package $schemaName - | - |$imports - | - |$code - |""".stripMargin.trim() + def headerComment: String + def schemaName: String + def imports: String + + def packageRowCode(headerComment: String, schemaName: String, pkg: String, imports: String): String = + s"""|${headerComment.trim().lines.map("// " + _).mkString("\n")} + |/** Definitions for table rows types of database schema $schemaName */ + |package $pkg + |package $schemaName + | + |$imports + | + |$code + |""".stripMargin.trim() def writeRowsToFile(folder:String, pkg: String, fileName: String): Unit = { - writeStringToFile(content = packageRowCode, folder = folder, pkg = pkg, fileName = fileName) + + writeStringToFile(content = packageRowCode(headerComment, schemaName, pkg, imports), folder = folder, pkg = s"$pkg.$schemaName", fileName = fileName) } } -- cgit v1.2.3 From a05801a3045e8137a419ebaade56d4be70c423e4 Mon Sep 17 00:00:00 2001 From: Stewart Stewart Date: Fri, 24 Feb 2017 04:32:44 -0500 Subject: flesh out generator usage --- src/main/scala/NamespacedCodegen.scala | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/scala/NamespacedCodegen.scala b/src/main/scala/NamespacedCodegen.scala index 08c0efd..dd3d0f2 100644 --- a/src/main/scala/NamespacedCodegen.scala +++ b/src/main/scala/NamespacedCodegen.scala @@ -14,6 +14,13 @@ import slick.model.{Column, Model, Table, QualifiedName} object Generator { + def outputSchemaCode(schemaName: String, profile: String, folder: String, pkg: String, tableGen: TableFileGenerator, rowGen: RowFileGenerator): Unit = { + val camelSchemaName = schemaName.split('_').map(_.capitalize).mkString("") + + tableGen.writeTablesToFile(profile: String, folder: String, pkg: String, fileName = s"${camelSchemaName}Tables.scala") + rowGen.writeRowsToFile(folder: String, pkg: String, fileName = s"{camelSchemaName}Rows.scala") + } + def run(uri: URI, pkg: String, schemaNames: Option[List[String]], -- cgit v1.2.3 From e800f430a3437c5b4b3dfc61740e211ee74a8abf Mon Sep 17 00:00:00 2001 From: Stewart Stewart Date: Fri, 24 Feb 2017 04:51:06 -0500 Subject: stub out RowSourceCodeGenerator --- src/main/scala/Generators.scala | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/main/scala/Generators.scala diff --git a/src/main/scala/Generators.scala b/src/main/scala/Generators.scala new file mode 100644 index 0000000..345baa4 --- /dev/null +++ b/src/main/scala/Generators.scala @@ -0,0 +1,21 @@ +import slick.codegen.SourceCodeGenerator +import slick.{model => m} + +class RowSourceCodeGenerator( + model: m.Model, + override val headerComment: String, + override val imports: String, + override val schemaName: String +) extends SourceCodeGenerator(model) with RowOutputHelpers { + + override def Table = new Table(_) { table => + override def EntityType = new EntityType { + override def code: String = + (if (classEnabled) "final " else "") + super.code + } + + override def code = Seq[Def](EntityType).map(_.docWithCode) + } + + override def code = tables.map(_.code.mkString("\n")).mkString("\n\n") +} -- cgit v1.2.3 From 55e374669634dd8a7d5b7c2abd549081c71b21f8 Mon Sep 17 00:00:00 2001 From: Stewart Stewart Date: Fri, 24 Feb 2017 05:48:00 -0500 Subject: separate typed key implementation --- src/main/scala/TypedIdTable.scala | 48 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 src/main/scala/TypedIdTable.scala diff --git a/src/main/scala/TypedIdTable.scala b/src/main/scala/TypedIdTable.scala new file mode 100644 index 0000000..b5c6056 --- /dev/null +++ b/src/main/scala/TypedIdTable.scala @@ -0,0 +1,48 @@ +import slick.codegen.SourceCodeGenerator +import slick.{model => m} + +class TypedIdSourceCodeGenerator( + model: m.Model, + idType: Option[String], + manualForeignKeys: Map[(String, String), (String, String)] +) extends SourceCodeGenerator(model) { + val manualReferences = SchemaParser.references(model, manualForeignKeys) + + def derefColumn(table: m.Table, + column: m.Column): (m.Table, m.Column) = { + val referencedColumn: Seq[(m.Table, m.Column)] = + table.foreignKeys + .filter(tableFk => tableFk.referencingColumns.forall(_ == column)) + .filter(columnFk => columnFk.referencedColumns.length == 1) + .flatMap(_.referencedColumns.map(c => + (model.tablesByName(c.table), c))) + assert(referencedColumn.distinct.length <= 1, referencedColumn) + + referencedColumn.headOption + .orElse(manualReferences.get((table.name.asString, column.name))) + .map((derefColumn _).tupled) + .getOrElse((table, column)) + } + + override def Table = new Table(_){ table => + override def Column = new Column(_) { column => + + def tableReferenceName(tableName: m.QualifiedName) = { + val schemaObjectName = tableName.schema.getOrElse("`public`") + val rowTypeName = entityName(tableName.table) + val idTypeName = idType.getOrElse("Id") + s"$idTypeName[$schemaObjectName.$rowTypeName]" + } + + override def rawType: String = { + // write key columns as Id types + val (referencedTable, referencedColumn) = + derefColumn(table.model, column.model) + if (referencedColumn.options.contains( + slick.ast.ColumnOption.PrimaryKey)) + tableReferenceName(referencedTable.name) + else super.rawType + } + } + } +} -- cgit v1.2.3 From 3edcb26eb91993a59b712c92e6f2d1ba67bdf111 Mon Sep 17 00:00:00 2001 From: Stewart Stewart Date: Fri, 24 Feb 2017 07:11:42 -0500 Subject: replace inline type replacement with modularized --- src/main/scala/NamespacedCodegen.scala | 44 ++++------------------------------ src/main/scala/TypedIdTable.scala | 4 ++-- 2 files changed, 7 insertions(+), 41 deletions(-) diff --git a/src/main/scala/NamespacedCodegen.scala b/src/main/scala/NamespacedCodegen.scala index dd3d0f2..f498923 100644 --- a/src/main/scala/NamespacedCodegen.scala +++ b/src/main/scala/NamespacedCodegen.scala @@ -103,7 +103,7 @@ abstract class Generator( override val headerComment: String, schemaImports: List[String], typeReplacements: Map[String, String]) - extends SourceCodeGenerator(schemaOnlyModel) + extends TypedIdSourceCodeGenerator(fullDatabaseModel, idType, manualForeignKeys) with OOutputHelpers { override val imports = schemaImports.map("import " + _).mkString("\n") @@ -124,7 +124,7 @@ abstract class Generator( override def Table = new TableO(_) - class TableO(model: sModel.Table) extends this.Table(model) { table => + class TableO(model: sModel.Table) extends this.TypedIdTable(model) { table => override def TableClass = new TableClass() { // We disable the option mapping, as it is a bit more complex to support and we don't appear to need it @@ -166,43 +166,9 @@ abstract class Generator( (if (classEnabled) "final " else "") + super.code } - override def Column = new this.Column(_) { column => - // use fullDatabasemodel model here for cross-schema foreign keys - val manualReferences = - SchemaParser.references(fullDatabaseModel, manualForeignKeys) - - // work out the destination of the foreign key - def derefColumn(table: sModel.Table, - column: sModel.Column): (sModel.Table, sModel.Column) = { - val referencedColumn: Seq[(sModel.Table, sModel.Column)] = - table.foreignKeys - .filter(tableFk => tableFk.referencingColumns.forall(_ == column)) - .filter(columnFk => columnFk.referencedColumns.length == 1) - .flatMap(_.referencedColumns.map(c => - (fullDatabaseModel.tablesByName(c.table), c))) - assert(referencedColumn.distinct.length <= 1, referencedColumn) - - referencedColumn.headOption - .orElse(manualReferences.get((table.name.asString, column.name))) - .map((derefColumn _).tupled) - .getOrElse((table, column)) - } - - def tableReferenceName(tableName: QualifiedName) = { - val schemaObjectName = tableName.schema.getOrElse("`public`") - val rowTypeName = entityName(tableName.table) - val idTypeName = idType.getOrElse("Id") - s"$idTypeName[$schemaObjectName.$rowTypeName]" - } - - // re-write ids other custom types - override def rawType: String = { - val (referencedTable, referencedColumn) = - derefColumn(table.model, column.model) - if (referencedColumn.options.contains( - slick.ast.ColumnOption.PrimaryKey)) - tableReferenceName(referencedTable.name) - else typeReplacements.getOrElse(model.tpe, model.tpe) + override def Column = new TypedIdColumn(_) { + override def rawType: String = { + typeReplacements.getOrElse(model.tpe, super.rawType) } } diff --git a/src/main/scala/TypedIdTable.scala b/src/main/scala/TypedIdTable.scala index b5c6056..bcfc065 100644 --- a/src/main/scala/TypedIdTable.scala +++ b/src/main/scala/TypedIdTable.scala @@ -24,8 +24,8 @@ class TypedIdSourceCodeGenerator( .getOrElse((table, column)) } - override def Table = new Table(_){ table => - override def Column = new Column(_) { column => + class TypedIdTable(model: m.Table) extends Table(model) { table => + class TypedIdColumn(override val model: m.Column) extends Column(model) { column => def tableReferenceName(tableName: m.QualifiedName) = { val schemaObjectName = tableName.schema.getOrElse("`public`") -- cgit v1.2.3 From 2e96fdd23a18cd12ea6705f1e04b4824ca479dbc Mon Sep 17 00:00:00 2001 From: Stewart Stewart Date: Fri, 24 Feb 2017 07:34:47 -0500 Subject: stub out usage of row generator --- src/main/scala/NamespacedCodegen.scala | 49 ++++++++++++---------------------- 1 file changed, 17 insertions(+), 32 deletions(-) diff --git a/src/main/scala/NamespacedCodegen.scala b/src/main/scala/NamespacedCodegen.scala index f498923..ea6fcdf 100644 --- a/src/main/scala/NamespacedCodegen.scala +++ b/src/main/scala/NamespacedCodegen.scala @@ -53,38 +53,23 @@ object Generator { Some(Map(schemaName -> tables)))), Duration.Inf) - val camelSchemaName = - schemaName.split('_').map(_.capitalize).mkString("") - - val tableGenerator = new TableGenerator(pkg, - dbModel, - schemaOnlyModel, - manualForeignKeys, - parentType, - idType, - header, - schemaImports, - typeReplacements) - tableGenerator.writeToFile(profile = profile, - folder = outputPath, - pkg = s"$pkg.$schemaName", - container = schemaName, - fileName = - s"${camelSchemaName}Tables.scala") - - val rowGenerator = new RowGenerator(pkg, - dbModel, - schemaOnlyModel, - manualForeignKeys, - parentType, - idType, - header, - schemaImports, - typeReplacements) - rowGenerator.writeToFile(schemaName = schemaName, - folder = outputPath, - pkg = s"$pkg.$schemaName", - fileName = s"${camelSchemaName}Rows.scala") + val rowGenerator = new RowSourceCodeGenerator( + schemaOnlyModel, + headerComment = header, + imports = schemaImports.map("import " + _).mkString("\n"), + schemaName = schemaName + ) + /* + val tableGenerator: TableFileGenerator = ??? + + outputSchemaCode( + schemaName = schemaName, + profile = profile, + folder = outputPath, + pkg = pkg, + tableGen = tableGenerator, + rowGen = rowGenerator) + */ } } finally { dc.db.close() -- cgit v1.2.3 From 8be11dc3a5920d7a97831c688c06999dd09bfd1b Mon Sep 17 00:00:00 2001 From: Stewart Stewart Date: Fri, 24 Feb 2017 07:46:40 -0500 Subject: use typed id columns in row generators and remove old implementation --- src/main/scala/Generators.scala | 14 ++++++-- src/main/scala/NamespacedCodegen.scala | 58 +++------------------------------- 2 files changed, 15 insertions(+), 57 deletions(-) diff --git a/src/main/scala/Generators.scala b/src/main/scala/Generators.scala index 345baa4..402f87f 100644 --- a/src/main/scala/Generators.scala +++ b/src/main/scala/Generators.scala @@ -5,10 +5,18 @@ class RowSourceCodeGenerator( model: m.Model, override val headerComment: String, override val imports: String, - override val schemaName: String -) extends SourceCodeGenerator(model) with RowOutputHelpers { + override val schemaName: String, + fullDatabaseModel: m.Model, + idType: Option[String], + manualForeignKeys: Map[(String, String), (String, String)] +) extends TypedIdSourceCodeGenerator( + fullDatabaseModel, + idType, + manualForeignKeys +) with RowOutputHelpers { - override def Table = new Table(_) { table => + override def Table = new TypedIdTable(_) { table => + override def Column = new TypedIdColumn(_) { } override def EntityType = new EntityType { override def code: String = (if (classEnabled) "final " else "") + super.code diff --git a/src/main/scala/NamespacedCodegen.scala b/src/main/scala/NamespacedCodegen.scala index ea6fcdf..16ab383 100644 --- a/src/main/scala/NamespacedCodegen.scala +++ b/src/main/scala/NamespacedCodegen.scala @@ -57,7 +57,10 @@ object Generator { schemaOnlyModel, headerComment = header, imports = schemaImports.map("import " + _).mkString("\n"), - schemaName = schemaName + schemaName = schemaName, + dbModel, + idType, + manualForeignKeys ) /* val tableGenerator: TableFileGenerator = ??? @@ -237,59 +240,6 @@ object SchemaParser { } } -class RowGenerator(pkg: String, - fullDatabaseModel: Model, - schemaOnlyModel: Model, - manualForeignKeys: Map[(String, String), (String, String)], - override val parentType: Option[String], - idType: Option[String], - override val headerComment: String, - schemaImports: List[String], - typeReplacements: Map[String, String]) - extends Generator(pkg, - fullDatabaseModel, - schemaOnlyModel, - manualForeignKeys, - parentType, - idType, - headerComment, - schemaImports, - typeReplacements) { - - override def Table = new TableO(_) { - //override def Column = new IdColumn(_){ } - override def code = Seq[Def](EntityType).map(_.docWithCode) - } - - override def code = tables.map(_.code.mkString("\n")).mkString("\n\n") - - def writeToFile(schemaName: String, - folder: String, - pkg: String, - fileName: String) = { - writeStringToFile(packageCode(pkg, schemaName), - folder = folder, - pkg = pkg, - fileName = fileName) - } - - override val imports = schemaImports.map("import " + _).mkString("\n") - - def packageCode(pkg: String, schemaName: String) = { - s"""|package $pkg - |package $schemaName - | - |$imports - | - |$code - |""".stripMargin.trim() - } - - // disable helpers for Table schema generators - //override def packageCode(profile: String, pkg: String, container: String, parentType: Option[String]) = ??? - //override def writeToFile(profile: String, folder: String, pkg: String, container: String, fileName: String) = ??? -} - class TableGenerator( pkg: String, fullDatabaseModel: Model, -- cgit v1.2.3 From 73ff2c2e532436d691d7ba169be0482e3dae5851 Mon Sep 17 00:00:00 2001 From: Stewart Stewart Date: Fri, 24 Feb 2017 08:13:45 -0500 Subject: strip out unnecessary parts of table generator --- src/main/scala/NamespacedCodegen.scala | 52 ++++------------------------------ src/main/scala/OutputHelpers.scala | 29 ------------------- 2 files changed, 6 insertions(+), 75 deletions(-) diff --git a/src/main/scala/NamespacedCodegen.scala b/src/main/scala/NamespacedCodegen.scala index 16ab383..3f8034e 100644 --- a/src/main/scala/NamespacedCodegen.scala +++ b/src/main/scala/NamespacedCodegen.scala @@ -81,20 +81,15 @@ object Generator { } -abstract class Generator( +class TableSourceCodeGenerator( pkg: String, fullDatabaseModel: Model, schemaOnlyModel: Model, manualForeignKeys: Map[(String, String), (String, String)], - override val parentType: Option[String], + parentType: Option[String], idType: Option[String], - override val headerComment: String, - schemaImports: List[String], typeReplacements: Map[String, String]) - extends TypedIdSourceCodeGenerator(fullDatabaseModel, idType, manualForeignKeys) - with OOutputHelpers { - - override val imports = schemaImports.map("import " + _).mkString("\n") + extends TypedIdSourceCodeGenerator(fullDatabaseModel, idType, manualForeignKeys) { val defaultIdImplementation = """|final case class Id[T](v: Int) @@ -110,10 +105,7 @@ abstract class Generator( // Alias to ForeignKeyAction is in profile.api // TODO: fix upstream - override def Table = new TableO(_) - - class TableO(model: sModel.Table) extends this.TypedIdTable(model) { table => - + override def Table = new this.TypedIdTable(_) { table => override def TableClass = new TableClass() { // We disable the option mapping, as it is a bit more complex to support and we don't appear to need it override def optionEnabled = false @@ -145,13 +137,8 @@ abstract class Generator( .map("a." + _.name) .mkString("::") + ":: HNil)" - override def EntityType = new EntityTypeDef { - override def code: String = - // Wartremover wants `final` - // But can't have the final case class inside the trait - // TODO: Fix by putting case classes in package or object - // TODO: Upstream default should be false. - (if (classEnabled) "final " else "") + super.code + override def EntityType = new EntityType { + override def enabled = false } override def Column = new TypedIdColumn(_) { @@ -239,30 +226,3 @@ object SchemaParser { jdbcProfile.createModel(filteredTables) } } - -class TableGenerator( - pkg: String, - fullDatabaseModel: Model, - schemaOnlyModel: Model, - manualForeignKeys: Map[(String, String), (String, String)], - override val parentType: Option[String], - idType: Option[String], - override val headerComment: String, - schemaImports: List[String], - typeReplacements: Map[String, String]) - extends Generator(pkg, - fullDatabaseModel, - schemaOnlyModel, - manualForeignKeys, - parentType, - idType, - headerComment, - schemaImports, - typeReplacements) { - - override def Table = new TableO(_) { - override def EntityType = new EntityType { - override def enabled = false - } - } -} diff --git a/src/main/scala/OutputHelpers.scala b/src/main/scala/OutputHelpers.scala index c3c5e0d..9e6dd0f 100644 --- a/src/main/scala/OutputHelpers.scala +++ b/src/main/scala/OutputHelpers.scala @@ -1,31 +1,3 @@ -trait OOutputHelpers extends slick.codegen.OutputHelpers { - - def imports: String - - def headerComment: String = "" - - override def packageCode(profile: String, - pkg: String, - container: String, - parentType: Option[String]): String = { - s"""|${headerComment.trim().lines.map("// " + _).mkString("\n")} - |package $pkg - | - |$imports - | - |/** Stand-alone Slick data model for immediate use */ - |package object $container extends { - | val profile = $profile - |} with Tables - | - |/** Slick data model trait for extension, choice of backend or usage in the cake pattern. (Make sure to initialize this late.) */ - |trait Tables${parentType.fold("")(" extends " + _)} { - | import profile.api._ - | ${indent(code)} - |}""".stripMargin.trim() - } -} - import slick.codegen.{SourceCodeGenerator, OutputHelpers} trait TableFileGenerator { self: SourceCodeGenerator => @@ -36,7 +8,6 @@ trait RowFileGenerator { self: SourceCodeGenerator => def writeRowsToFile(folder:String, pkg: String, fileName: String): Unit } -// Dirty work to hide OutputHelpers trait TableOutputHelpers extends TableFileGenerator with OutputHelpers { self: SourceCodeGenerator => def headerComment: String -- cgit v1.2.3 From 102aa93a791e9941d15d78caead93e8bf8d58bdc Mon Sep 17 00:00:00 2001 From: Stewart Stewart Date: Fri, 24 Feb 2017 08:18:21 -0500 Subject: move schema parser to separate file --- src/main/scala/NamespacedCodegen.scala | 56 ------------------------------- src/main/scala/SchemaParser.scala | 60 ++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 56 deletions(-) create mode 100644 src/main/scala/SchemaParser.scala diff --git a/src/main/scala/NamespacedCodegen.scala b/src/main/scala/NamespacedCodegen.scala index 3f8034e..364dcab 100644 --- a/src/main/scala/NamespacedCodegen.scala +++ b/src/main/scala/NamespacedCodegen.scala @@ -6,9 +6,7 @@ import scala.concurrent.duration.Duration import scala.concurrent.ExecutionContext.Implicits.global import slick.backend.DatabaseConfig import slick.codegen.{SourceCodeGenerator, StringGeneratorHelpers} -import slick.dbio.DBIO import slick.driver.JdbcProfile -import slick.jdbc.meta.MTable import slick.{model => sModel} import slick.model.{Column, Model, Table, QualifiedName} @@ -172,57 +170,3 @@ class TableSourceCodeGenerator( } } } - -object SchemaParser { - def references(dbModel: Model, - tcMappings: Map[(String, String), (String, String)]) - : Map[(String, String), (Table, Column)] = { - def getTableColumn(tc: (String, String)): (Table, Column) = { - val (tableName, columnName) = tc - val table = dbModel.tables - .find(_.name.asString == tableName) - .getOrElse(throw new RuntimeException("No table " + tableName)) - val column = table.columns - .find(_.name == columnName) - .getOrElse(throw new RuntimeException( - "No column " + columnName + " in table " + tableName)) - (table, column) - } - - tcMappings.map { - case (from, to) => ({ getTableColumn(from); from }, getTableColumn(to)) - } - } - - def parse(schemaTableNames: List[String]): Map[String, List[String]] = - schemaTableNames - .map(_.split('.')) - .groupBy(_.head) - .mapValues(_.flatMap(_.tail)) - - def createModel( - jdbcProfile: JdbcProfile, - mappedSchemasOpt: Option[Map[String, List[String]]]): DBIO[Model] = { - import slick.jdbc.meta.MQName - - val filteredTables = mappedSchemasOpt.map { mappedSchemas => - MTable.getTables.map { (tables: Vector[MTable]) => - mappedSchemas.flatMap { - case (schemaName, tableNames) => - tableNames.map( - tableName => - tables - .find(table => - table.name match { - case MQName(_, Some(`schemaName`), `tableName`) => true - case _ => false - }) - .getOrElse(throw new IllegalArgumentException( - s"$schemaName.$tableName does not exist in the connected database."))) - }.toList - } - } - - jdbcProfile.createModel(filteredTables) - } -} diff --git a/src/main/scala/SchemaParser.scala b/src/main/scala/SchemaParser.scala new file mode 100644 index 0000000..1186f11 --- /dev/null +++ b/src/main/scala/SchemaParser.scala @@ -0,0 +1,60 @@ +import scala.concurrent.ExecutionContext.Implicits.global + +import slick.dbio.DBIO +import slick.driver.JdbcProfile +import slick.jdbc.meta.MTable +import slick.{model => m} + +object SchemaParser { + def references(dbModel: m.Model, + tcMappings: Map[(String, String), (String, String)]) + : Map[(String, String), (m.Table, m.Column)] = { + def getTableColumn(tc: (String, String)): (m.Table, m.Column) = { + val (tableName, columnName) = tc + val table = dbModel.tables + .find(_.name.asString == tableName) + .getOrElse(throw new RuntimeException("No table " + tableName)) + val column = table.columns + .find(_.name == columnName) + .getOrElse(throw new RuntimeException( + "No column " + columnName + " in table " + tableName)) + (table, column) + } + + tcMappings.map { + case (from, to) => ({ getTableColumn(from); from }, getTableColumn(to)) + } + } + + def parse(schemaTableNames: List[String]): Map[String, List[String]] = + schemaTableNames + .map(_.split('.')) + .groupBy(_.head) + .mapValues(_.flatMap(_.tail)) + + def createModel( + jdbcProfile: JdbcProfile, + mappedSchemasOpt: Option[Map[String, List[String]]]): DBIO[m.Model] = { + import slick.jdbc.meta.MQName + + val filteredTables = mappedSchemasOpt.map { mappedSchemas => + MTable.getTables.map { (tables: Vector[MTable]) => + mappedSchemas.flatMap { + case (schemaName, tableNames) => + tableNames.map( + tableName => + tables + .find(table => + table.name match { + case MQName(_, Some(`schemaName`), `tableName`) => true + case _ => false + }) + .getOrElse(throw new IllegalArgumentException( + s"$schemaName.$tableName does not exist in the connected database."))) + }.toList + } + } + + jdbcProfile.createModel(filteredTables) + } +} -- cgit v1.2.3 From 2ff0ebe6b09774b59b2ae29e5413ec9b671554fb Mon Sep 17 00:00:00 2001 From: Stewart Stewart Date: Fri, 24 Feb 2017 08:23:07 -0500 Subject: Move table generator class to generators file --- src/main/scala/Generators.scala | 92 +++++++++++++++++++++++++++++++++ src/main/scala/NamespacedCodegen.scala | 93 ---------------------------------- 2 files changed, 92 insertions(+), 93 deletions(-) diff --git a/src/main/scala/Generators.scala b/src/main/scala/Generators.scala index 402f87f..20314b5 100644 --- a/src/main/scala/Generators.scala +++ b/src/main/scala/Generators.scala @@ -27,3 +27,95 @@ class RowSourceCodeGenerator( override def code = tables.map(_.code.mkString("\n")).mkString("\n\n") } + +class TableSourceCodeGenerator( + pkg: String, + fullDatabaseModel: m.Model, + schemaOnlyModel: m.Model, + manualForeignKeys: Map[(String, String), (String, String)], + parentType: Option[String], + idType: Option[String], + typeReplacements: Map[String, String]) + extends TypedIdSourceCodeGenerator(fullDatabaseModel, idType, manualForeignKeys) { + + val defaultIdImplementation = + """|final case class Id[T](v: Int) + |trait DefaultIdTypeMapper { + | val profile: slick.driver.JdbcProfile + | import profile.api._ + | implicit def idTypeMapper[A]: BaseColumnType[Id[A]] = MappedColumnType.base[Id[A], Int](_.v, Id(_)) + |} + |""".stripMargin + + override def code = super.code.lines.drop(1).mkString("\n") + // Drops needless import: `"import slick.model.ForeignKeyAction\n"`. + // Alias to ForeignKeyAction is in profile.api + // TODO: fix upstream + + override def Table = new this.TypedIdTable(_) { table => + override def TableClass = new TableClass() { + // We disable the option mapping, as it is a bit more complex to support and we don't appear to need it + override def optionEnabled = false + } + + // use hlists all the time + override def hlistEnabled: Boolean = true + + // if false rows are type aliases to hlists, if true rows are case classes + override def mappingEnabled: Boolean = true + + // create case class from colums + override def factory: String = + if (!hlistEnabled) super.factory + else { + val args = columns.zipWithIndex.map("a" + _._2) + val hlist = args.mkString("::") + ":: HNil" + val hlistType = columns + .map(_.actualType) + .mkString("::") + ":: HNil.type" + s"((h : $hlistType) => h match {case $hlist => ${TableClass.elementType}(${args.mkString(",")})})" + } + + // from case class create columns + override def extractor: String = + if (!hlistEnabled) super.extractor + else + s"(a : ${TableClass.elementType}) => Some(" + columns + .map("a." + _.name) + .mkString("::") + ":: HNil)" + + override def EntityType = new EntityType { + override def enabled = false + } + + override def Column = new TypedIdColumn(_) { + override def rawType: String = { + typeReplacements.getOrElse(model.tpe, super.rawType) + } + } + + override def ForeignKey = new ForeignKey(_) { + override def code = { + val fkColumns = compoundValue(referencingColumns.map(_.name)) + val qualifier = + if (referencedTable.model.name.schema == referencingTable.model.name.schema) + "" + else + referencedTable.model.name.schema.fold("")(sname => + s"$pkg.$sname.") + + val qualifiedName = qualifier + referencedTable.TableValue.name + val pkColumns = compoundValue(referencedColumns.map(c => + s"r.${c.name}${if (!c.model.nullable && referencingColumns.forall(_.model.nullable)) ".?" + else ""}")) + val fkName = referencingColumns + .map(_.name) + .flatMap(_.split("_")) + .map(_.capitalize) + .mkString + .uncapitalize + "Fk" + s"""lazy val $fkName = foreignKey("$dbName", $fkColumns, $qualifiedName)(r => $pkColumns, onUpdate=$onUpdate, onDelete=$onDelete)""" + } + } + } +} diff --git a/src/main/scala/NamespacedCodegen.scala b/src/main/scala/NamespacedCodegen.scala index 364dcab..fd6ad3e 100644 --- a/src/main/scala/NamespacedCodegen.scala +++ b/src/main/scala/NamespacedCodegen.scala @@ -76,97 +76,4 @@ object Generator { dc.db.close() } } - -} - -class TableSourceCodeGenerator( - pkg: String, - fullDatabaseModel: Model, - schemaOnlyModel: Model, - manualForeignKeys: Map[(String, String), (String, String)], - parentType: Option[String], - idType: Option[String], - typeReplacements: Map[String, String]) - extends TypedIdSourceCodeGenerator(fullDatabaseModel, idType, manualForeignKeys) { - - val defaultIdImplementation = - """|final case class Id[T](v: Int) - |trait DefaultIdTypeMapper { - | val profile: slick.driver.JdbcProfile - | import profile.api._ - | implicit def idTypeMapper[A]: BaseColumnType[Id[A]] = MappedColumnType.base[Id[A], Int](_.v, Id(_)) - |} - |""".stripMargin - - override def code = super.code.lines.drop(1).mkString("\n") - // Drops needless import: `"import slick.model.ForeignKeyAction\n"`. - // Alias to ForeignKeyAction is in profile.api - // TODO: fix upstream - - override def Table = new this.TypedIdTable(_) { table => - override def TableClass = new TableClass() { - // We disable the option mapping, as it is a bit more complex to support and we don't appear to need it - override def optionEnabled = false - } - - // use hlists all the time - override def hlistEnabled: Boolean = true - - // if false rows are type aliases to hlists, if true rows are case classes - override def mappingEnabled: Boolean = true - - // create case class from colums - override def factory: String = - if (!hlistEnabled) super.factory - else { - val args = columns.zipWithIndex.map("a" + _._2) - val hlist = args.mkString("::") + ":: HNil" - val hlistType = columns - .map(_.actualType) - .mkString("::") + ":: HNil.type" - s"((h : $hlistType) => h match {case $hlist => ${TableClass.elementType}(${args.mkString(",")})})" - } - - // from case class create columns - override def extractor: String = - if (!hlistEnabled) super.extractor - else - s"(a : ${TableClass.elementType}) => Some(" + columns - .map("a." + _.name) - .mkString("::") + ":: HNil)" - - override def EntityType = new EntityType { - override def enabled = false - } - - override def Column = new TypedIdColumn(_) { - override def rawType: String = { - typeReplacements.getOrElse(model.tpe, super.rawType) - } - } - - override def ForeignKey = new ForeignKey(_) { - override def code = { - val fkColumns = compoundValue(referencingColumns.map(_.name)) - val qualifier = - if (referencedTable.model.name.schema == referencingTable.model.name.schema) - "" - else - referencedTable.model.name.schema.fold("")(sname => - s"$pkg.$sname.") - - val qualifiedName = qualifier + referencedTable.TableValue.name - val pkColumns = compoundValue(referencedColumns.map(c => - s"r.${c.name}${if (!c.model.nullable && referencingColumns.forall(_.model.nullable)) ".?" - else ""}")) - val fkName = referencingColumns - .map(_.name) - .flatMap(_.split("_")) - .map(_.capitalize) - .mkString - .uncapitalize + "Fk" - s"""lazy val $fkName = foreignKey("$dbName", $fkColumns, $qualifiedName)(r => $pkColumns, onUpdate=$onUpdate, onDelete=$onDelete)""" - } - } - } } -- cgit v1.2.3 From 42f846add5a7b82f64a09f526d8817cb12b8ca86 Mon Sep 17 00:00:00 2001 From: Stewart Stewart Date: Fri, 24 Feb 2017 08:50:31 -0500 Subject: extend use table output helpers --- src/main/scala/Generators.scala | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/scala/Generators.scala b/src/main/scala/Generators.scala index 20314b5..741fe6b 100644 --- a/src/main/scala/Generators.scala +++ b/src/main/scala/Generators.scala @@ -29,14 +29,19 @@ class RowSourceCodeGenerator( } class TableSourceCodeGenerator( - pkg: String, - fullDatabaseModel: m.Model, schemaOnlyModel: m.Model, + override val headerComment: String, + override val imports: String, + override val schemaName: String, + fullDatabaseModel: m.Model, + pkg: String, manualForeignKeys: Map[(String, String), (String, String)], parentType: Option[String], idType: Option[String], typeReplacements: Map[String, String]) - extends TypedIdSourceCodeGenerator(fullDatabaseModel, idType, manualForeignKeys) { + extends TypedIdSourceCodeGenerator(fullDatabaseModel, idType, manualForeignKeys) + with TableOutputHelpers +{ val defaultIdImplementation = """|final case class Id[T](v: Int) -- cgit v1.2.3 From bb4be989a15f250741ab771e7ed78f512e74632d Mon Sep 17 00:00:00 2001 From: Stewart Stewart Date: Fri, 24 Feb 2017 08:50:52 -0500 Subject: scalafmt --- src/main/scala/Generators.scala | 34 +++++++++++++------------- src/main/scala/NamespacedCodegen.scala | 20 ++++++++++++---- src/main/scala/OutputHelpers.scala | 44 ++++++++++++++++++++++++++-------- src/main/scala/TypedIdTable.scala | 12 +++++----- 4 files changed, 73 insertions(+), 37 deletions(-) diff --git a/src/main/scala/Generators.scala b/src/main/scala/Generators.scala index 741fe6b..51e02ce 100644 --- a/src/main/scala/Generators.scala +++ b/src/main/scala/Generators.scala @@ -2,21 +2,22 @@ import slick.codegen.SourceCodeGenerator import slick.{model => m} class RowSourceCodeGenerator( - model: m.Model, - override val headerComment: String, - override val imports: String, - override val schemaName: String, - fullDatabaseModel: m.Model, - idType: Option[String], - manualForeignKeys: Map[(String, String), (String, String)] + model: m.Model, + override val headerComment: String, + override val imports: String, + override val schemaName: String, + fullDatabaseModel: m.Model, + idType: Option[String], + manualForeignKeys: Map[(String, String), (String, String)] ) extends TypedIdSourceCodeGenerator( - fullDatabaseModel, - idType, - manualForeignKeys -) with RowOutputHelpers { + fullDatabaseModel, + idType, + manualForeignKeys + ) + with RowOutputHelpers { override def Table = new TypedIdTable(_) { table => - override def Column = new TypedIdColumn(_) { } + override def Column = new TypedIdColumn(_) {} override def EntityType = new EntityType { override def code: String = (if (classEnabled) "final " else "") + super.code @@ -39,9 +40,10 @@ class TableSourceCodeGenerator( parentType: Option[String], idType: Option[String], typeReplacements: Map[String, String]) - extends TypedIdSourceCodeGenerator(fullDatabaseModel, idType, manualForeignKeys) - with TableOutputHelpers -{ + extends TypedIdSourceCodeGenerator(fullDatabaseModel, + idType, + manualForeignKeys) + with TableOutputHelpers { val defaultIdImplementation = """|final case class Id[T](v: Int) @@ -94,7 +96,7 @@ class TableSourceCodeGenerator( } override def Column = new TypedIdColumn(_) { - override def rawType: String = { + override def rawType: String = { typeReplacements.getOrElse(model.tpe, super.rawType) } } diff --git a/src/main/scala/NamespacedCodegen.scala b/src/main/scala/NamespacedCodegen.scala index fd6ad3e..05b1c35 100644 --- a/src/main/scala/NamespacedCodegen.scala +++ b/src/main/scala/NamespacedCodegen.scala @@ -12,11 +12,21 @@ import slick.model.{Column, Model, Table, QualifiedName} object Generator { - def outputSchemaCode(schemaName: String, profile: String, folder: String, pkg: String, tableGen: TableFileGenerator, rowGen: RowFileGenerator): Unit = { + def outputSchemaCode(schemaName: String, + profile: String, + folder: String, + pkg: String, + tableGen: TableFileGenerator, + rowGen: RowFileGenerator): Unit = { val camelSchemaName = schemaName.split('_').map(_.capitalize).mkString("") - tableGen.writeTablesToFile(profile: String, folder: String, pkg: String, fileName = s"${camelSchemaName}Tables.scala") - rowGen.writeRowsToFile(folder: String, pkg: String, fileName = s"{camelSchemaName}Rows.scala") + tableGen.writeTablesToFile(profile: String, + folder: String, + pkg: String, + fileName = s"${camelSchemaName}Tables.scala") + rowGen.writeRowsToFile(folder: String, + pkg: String, + fileName = s"{camelSchemaName}Rows.scala") } def run(uri: URI, @@ -60,7 +70,7 @@ object Generator { idType, manualForeignKeys ) - /* + /* val tableGenerator: TableFileGenerator = ??? outputSchemaCode( @@ -70,7 +80,7 @@ object Generator { pkg = pkg, tableGen = tableGenerator, rowGen = rowGenerator) - */ + */ } } finally { dc.db.close() diff --git a/src/main/scala/OutputHelpers.scala b/src/main/scala/OutputHelpers.scala index 9e6dd0f..ce71a44 100644 --- a/src/main/scala/OutputHelpers.scala +++ b/src/main/scala/OutputHelpers.scala @@ -1,20 +1,28 @@ import slick.codegen.{SourceCodeGenerator, OutputHelpers} trait TableFileGenerator { self: SourceCodeGenerator => - def writeTablesToFile(profile: String, folder:String, pkg: String, fileName: String): Unit + def writeTablesToFile(profile: String, + folder: String, + pkg: String, + fileName: String): Unit } trait RowFileGenerator { self: SourceCodeGenerator => - def writeRowsToFile(folder:String, pkg: String, fileName: String): Unit + def writeRowsToFile(folder: String, pkg: String, fileName: String): Unit } -trait TableOutputHelpers extends TableFileGenerator with OutputHelpers { self: SourceCodeGenerator => +trait TableOutputHelpers extends TableFileGenerator with OutputHelpers { + self: SourceCodeGenerator => def headerComment: String def schemaName: String def imports: String - def packageTableCode(headerComment: String, pkg: String, schemaName: String, imports: String, profile: String): String = + def packageTableCode(headerComment: String, + pkg: String, + schemaName: String, + imports: String, + profile: String): String = s"""|${headerComment.trim().lines.map("// " + _).mkString("\n")} |package $pkg |package $schemaName @@ -33,18 +41,30 @@ trait TableOutputHelpers extends TableFileGenerator with OutputHelpers { self: S | ${indent(code)} | |""".stripMargin.trim() - def writeTablesToFile(profile: String, folder:String, pkg: String, fileName: String): Unit = { - writeStringToFile(content = packageTableCode(headerComment, pkg, schemaName, imports, profile), folder = folder, pkg = s"$pkg.$schemaName", fileName = fileName) + def writeTablesToFile(profile: String, + folder: String, + pkg: String, + fileName: String): Unit = { + writeStringToFile( + content = + packageTableCode(headerComment, pkg, schemaName, imports, profile), + folder = folder, + pkg = s"$pkg.$schemaName", + fileName = fileName) } } -trait RowOutputHelpers extends RowFileGenerator with OutputHelpers { self: SourceCodeGenerator => +trait RowOutputHelpers extends RowFileGenerator with OutputHelpers { + self: SourceCodeGenerator => def headerComment: String def schemaName: String def imports: String - def packageRowCode(headerComment: String, schemaName: String, pkg: String, imports: String): String = + def packageRowCode(headerComment: String, + schemaName: String, + pkg: String, + imports: String): String = s"""|${headerComment.trim().lines.map("// " + _).mkString("\n")} |/** Definitions for table rows types of database schema $schemaName */ |package $pkg @@ -55,8 +75,12 @@ trait RowOutputHelpers extends RowFileGenerator with OutputHelpers { self: Sourc |$code |""".stripMargin.trim() - def writeRowsToFile(folder:String, pkg: String, fileName: String): Unit = { + def writeRowsToFile(folder: String, pkg: String, fileName: String): Unit = { - writeStringToFile(content = packageRowCode(headerComment, schemaName, pkg, imports), folder = folder, pkg = s"$pkg.$schemaName", fileName = fileName) + writeStringToFile( + content = packageRowCode(headerComment, schemaName, pkg, imports), + folder = folder, + pkg = s"$pkg.$schemaName", + fileName = fileName) } } diff --git a/src/main/scala/TypedIdTable.scala b/src/main/scala/TypedIdTable.scala index bcfc065..c7f0151 100644 --- a/src/main/scala/TypedIdTable.scala +++ b/src/main/scala/TypedIdTable.scala @@ -2,14 +2,13 @@ import slick.codegen.SourceCodeGenerator import slick.{model => m} class TypedIdSourceCodeGenerator( - model: m.Model, - idType: Option[String], - manualForeignKeys: Map[(String, String), (String, String)] + model: m.Model, + idType: Option[String], + manualForeignKeys: Map[(String, String), (String, String)] ) extends SourceCodeGenerator(model) { val manualReferences = SchemaParser.references(model, manualForeignKeys) - def derefColumn(table: m.Table, - column: m.Column): (m.Table, m.Column) = { + def derefColumn(table: m.Table, column: m.Column): (m.Table, m.Column) = { val referencedColumn: Seq[(m.Table, m.Column)] = table.foreignKeys .filter(tableFk => tableFk.referencingColumns.forall(_ == column)) @@ -25,7 +24,8 @@ class TypedIdSourceCodeGenerator( } class TypedIdTable(model: m.Table) extends Table(model) { table => - class TypedIdColumn(override val model: m.Column) extends Column(model) { column => + class TypedIdColumn(override val model: m.Column) extends Column(model) { + column => def tableReferenceName(tableName: m.QualifiedName) = { val schemaObjectName = tableName.schema.getOrElse("`public`") -- cgit v1.2.3 From ca9dde318c7bc7b780cf5745cdee71e8430d9f6e Mon Sep 17 00:00:00 2001 From: Stewart Stewart Date: Fri, 24 Feb 2017 09:06:40 -0500 Subject: remember to generate code only for a schema --- src/main/scala/Generators.scala | 4 +++- src/main/scala/TypedIdTable.scala | 10 ++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/main/scala/Generators.scala b/src/main/scala/Generators.scala index 51e02ce..59c9d9f 100644 --- a/src/main/scala/Generators.scala +++ b/src/main/scala/Generators.scala @@ -10,6 +10,7 @@ class RowSourceCodeGenerator( idType: Option[String], manualForeignKeys: Map[(String, String), (String, String)] ) extends TypedIdSourceCodeGenerator( + model, fullDatabaseModel, idType, manualForeignKeys @@ -40,7 +41,8 @@ class TableSourceCodeGenerator( parentType: Option[String], idType: Option[String], typeReplacements: Map[String, String]) - extends TypedIdSourceCodeGenerator(fullDatabaseModel, + extends TypedIdSourceCodeGenerator(schemaOnlyModel, + fullDatabaseModel, idType, manualForeignKeys) with TableOutputHelpers { diff --git a/src/main/scala/TypedIdTable.scala b/src/main/scala/TypedIdTable.scala index c7f0151..1a8f986 100644 --- a/src/main/scala/TypedIdTable.scala +++ b/src/main/scala/TypedIdTable.scala @@ -2,11 +2,13 @@ import slick.codegen.SourceCodeGenerator import slick.{model => m} class TypedIdSourceCodeGenerator( - model: m.Model, + singleSchemaModel: m.Model, + databaseModel: m.Model, idType: Option[String], manualForeignKeys: Map[(String, String), (String, String)] -) extends SourceCodeGenerator(model) { - val manualReferences = SchemaParser.references(model, manualForeignKeys) +) extends SourceCodeGenerator(singleSchemaModel) { + val manualReferences = + SchemaParser.references(databaseModel, manualForeignKeys) def derefColumn(table: m.Table, column: m.Column): (m.Table, m.Column) = { val referencedColumn: Seq[(m.Table, m.Column)] = @@ -14,7 +16,7 @@ class TypedIdSourceCodeGenerator( .filter(tableFk => tableFk.referencingColumns.forall(_ == column)) .filter(columnFk => columnFk.referencedColumns.length == 1) .flatMap(_.referencedColumns.map(c => - (model.tablesByName(c.table), c))) + (databaseModel.tablesByName(c.table), c))) assert(referencedColumn.distinct.length <= 1, referencedColumn) referencedColumn.headOption -- cgit v1.2.3 From a76870feabe6b132e67c576d08dc92a15c241b8e Mon Sep 17 00:00:00 2001 From: Stewart Stewart Date: Fri, 24 Feb 2017 09:14:22 -0500 Subject: use concrete tableGenerator --- src/main/scala/NamespacedCodegen.scala | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/main/scala/NamespacedCodegen.scala b/src/main/scala/NamespacedCodegen.scala index 05b1c35..ca32641 100644 --- a/src/main/scala/NamespacedCodegen.scala +++ b/src/main/scala/NamespacedCodegen.scala @@ -43,6 +43,7 @@ object Generator { DatabaseConfig.forURI[JdbcProfile](uri) val parsedSchemasOpt: Option[Map[String, List[String]]] = schemaNames.map(SchemaParser.parse) + val imports = schemaImports.map("import " + _).mkString("\n") try { val dbModel: Model = Await.result( @@ -64,14 +65,24 @@ object Generator { val rowGenerator = new RowSourceCodeGenerator( schemaOnlyModel, headerComment = header, - imports = schemaImports.map("import " + _).mkString("\n"), + imports = imports, schemaName = schemaName, dbModel, idType, manualForeignKeys ) - /* - val tableGenerator: TableFileGenerator = ??? + + val tableGenerator = new TableSourceCodeGenerator( + schemaOnlyModel = schemaOnlyModel, + headerComment = header, + imports = imports, + schemaName = schemaName, + fullDatabaseModel = dbModel, + pkg = pkg, + manualForeignKeys, + parentType = parentType, + idType, + typeReplacements) outputSchemaCode( schemaName = schemaName, @@ -80,7 +91,6 @@ object Generator { pkg = pkg, tableGen = tableGenerator, rowGen = rowGenerator) - */ } } finally { dc.db.close() -- cgit v1.2.3 From 73eb214f539913acf8af8e06a37cb3c0328cf891 Mon Sep 17 00:00:00 2001 From: Stewart Stewart Date: Fri, 24 Feb 2017 09:15:38 -0500 Subject: missing interpolator --- src/main/scala/NamespacedCodegen.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/NamespacedCodegen.scala b/src/main/scala/NamespacedCodegen.scala index ca32641..c3bf89c 100644 --- a/src/main/scala/NamespacedCodegen.scala +++ b/src/main/scala/NamespacedCodegen.scala @@ -26,7 +26,7 @@ object Generator { fileName = s"${camelSchemaName}Tables.scala") rowGen.writeRowsToFile(folder: String, pkg: String, - fileName = s"{camelSchemaName}Rows.scala") + fileName = s"${camelSchemaName}Rows.scala") } def run(uri: URI, -- cgit v1.2.3 From 80a0363548bf9ab7be4126ee357d3bba47f13c1e Mon Sep 17 00:00:00 2001 From: Stewart Stewart Date: Fri, 24 Feb 2017 09:39:11 -0500 Subject: use type replacements in row generator --- src/main/scala/Generators.scala | 11 +++++++++-- src/main/scala/NamespacedCodegen.scala | 3 ++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/main/scala/Generators.scala b/src/main/scala/Generators.scala index 59c9d9f..b3bfeab 100644 --- a/src/main/scala/Generators.scala +++ b/src/main/scala/Generators.scala @@ -8,7 +8,8 @@ class RowSourceCodeGenerator( override val schemaName: String, fullDatabaseModel: m.Model, idType: Option[String], - manualForeignKeys: Map[(String, String), (String, String)] + manualForeignKeys: Map[(String, String), (String, String)], + typeReplacements: Map[String, String] ) extends TypedIdSourceCodeGenerator( model, fullDatabaseModel, @@ -18,7 +19,13 @@ class RowSourceCodeGenerator( with RowOutputHelpers { override def Table = new TypedIdTable(_) { table => - override def Column = new TypedIdColumn(_) {} + + override def Column = new TypedIdColumn(_) { + override def rawType: String = { + typeReplacements.getOrElse(model.tpe, super.rawType) + } + } + override def EntityType = new EntityType { override def code: String = (if (classEnabled) "final " else "") + super.code diff --git a/src/main/scala/NamespacedCodegen.scala b/src/main/scala/NamespacedCodegen.scala index c3bf89c..7ae4ac0 100644 --- a/src/main/scala/NamespacedCodegen.scala +++ b/src/main/scala/NamespacedCodegen.scala @@ -69,7 +69,8 @@ object Generator { schemaName = schemaName, dbModel, idType, - manualForeignKeys + manualForeignKeys, + typeReplacements ) val tableGenerator = new TableSourceCodeGenerator( -- cgit v1.2.3 From d628c535f658cc8af9b9f280b5222eb3364e8c30 Mon Sep 17 00:00:00 2001 From: Stewart Stewart Date: Fri, 24 Feb 2017 10:22:05 -0500 Subject: stray character --- src/main/scala/OutputHelpers.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/OutputHelpers.scala b/src/main/scala/OutputHelpers.scala index ce71a44..b68af8c 100644 --- a/src/main/scala/OutputHelpers.scala +++ b/src/main/scala/OutputHelpers.scala @@ -38,7 +38,7 @@ trait TableOutputHelpers extends TableFileGenerator with OutputHelpers { |/** Slick data model trait for extension, choice of backend or usage in the cake pattern. (Make sure to initialize this late.) */ |trait Tables${parentType.fold("")(" extends " + _)} { | import profile.api._ - | ${indent(code)} | + | ${indent(code)} |""".stripMargin.trim() def writeTablesToFile(profile: String, -- cgit v1.2.3 From e3023da0727520129d744607a0c60979b5f21fc1 Mon Sep 17 00:00:00 2001 From: Stewart Stewart Date: Fri, 24 Feb 2017 10:24:48 -0500 Subject: clean up main file --- src/main/scala/Main.scala | 108 +++++++++++++++++++++++++++++++++ src/main/scala/NamespacedCodegen.scala | 100 ------------------------------ src/main/scala/OutputHelpers.scala | 11 ---- 3 files changed, 108 insertions(+), 111 deletions(-) create mode 100644 src/main/scala/Main.scala delete mode 100644 src/main/scala/NamespacedCodegen.scala diff --git a/src/main/scala/Main.scala b/src/main/scala/Main.scala new file mode 100644 index 0000000..55275a3 --- /dev/null +++ b/src/main/scala/Main.scala @@ -0,0 +1,108 @@ +import java.net.URI +import java.nio.file.Paths + +import scala.concurrent.Await +import scala.concurrent.duration.Duration +import scala.concurrent.ExecutionContext.Implicits.global +import slick.backend.DatabaseConfig +import slick.codegen.SourceCodeGenerator +import slick.driver.JdbcProfile + +trait TableFileGenerator { self: SourceCodeGenerator => + def writeTablesToFile(profile: String, + folder: String, + pkg: String, + fileName: String): Unit +} + +trait RowFileGenerator { self: SourceCodeGenerator => + def writeRowsToFile(folder: String, pkg: String, fileName: String): Unit +} + +object Generator { + + private def outputSchemaCode(schemaName: String, + profile: String, + folder: String, + pkg: String, + tableGen: TableFileGenerator, + rowGen: RowFileGenerator): Unit = { + val camelSchemaName = schemaName.split('_').map(_.capitalize).mkString("") + + tableGen.writeTablesToFile(profile: String, + folder: String, + pkg: String, + fileName = s"${camelSchemaName}Tables.scala") + rowGen.writeRowsToFile(folder: String, + pkg: String, + fileName = s"${camelSchemaName}Rows.scala") + } + + def run(uri: URI, + pkg: String, + schemaNames: Option[List[String]], + outputPath: String, + manualForeignKeys: Map[(String, String), (String, String)], + parentType: Option[String], + idType: Option[String], + header: String, + schemaImports: List[String], + typeReplacements: Map[String, String]) = { + val dc: DatabaseConfig[JdbcProfile] = + DatabaseConfig.forURI[JdbcProfile](uri) + val parsedSchemasOpt: Option[Map[String, List[String]]] = + schemaNames.map(SchemaParser.parse) + val imports = schemaImports.map("import " + _).mkString("\n") + + try { + val dbModel: slick.model.Model = Await.result( + dc.db.run(SchemaParser.createModel(dc.driver, parsedSchemasOpt)), + Duration.Inf) + + parsedSchemasOpt.getOrElse(Map.empty).foreach { + case (schemaName, tables) => + val profile = + s"""slick.backend.DatabaseConfig.forConfig[slick.driver.JdbcProfile]("${uri + .getFragment()}").driver""" + + val schemaOnlyModel = Await.result( + dc.db.run( + SchemaParser.createModel(dc.driver, + Some(Map(schemaName -> tables)))), + Duration.Inf) + + val rowGenerator = new RowSourceCodeGenerator( + schemaOnlyModel, + headerComment = header, + imports = imports, + schemaName = schemaName, + dbModel, + idType, + manualForeignKeys, + typeReplacements + ) + + val tableGenerator = + new TableSourceCodeGenerator(schemaOnlyModel = schemaOnlyModel, + headerComment = header, + imports = imports, + schemaName = schemaName, + fullDatabaseModel = dbModel, + pkg = pkg, + manualForeignKeys, + parentType = parentType, + idType, + typeReplacements) + + outputSchemaCode(schemaName = schemaName, + profile = profile, + folder = outputPath, + pkg = pkg, + tableGen = tableGenerator, + rowGen = rowGenerator) + } + } finally { + dc.db.close() + } + } +} diff --git a/src/main/scala/NamespacedCodegen.scala b/src/main/scala/NamespacedCodegen.scala deleted file mode 100644 index 7ae4ac0..0000000 --- a/src/main/scala/NamespacedCodegen.scala +++ /dev/null @@ -1,100 +0,0 @@ -import java.net.URI -import java.nio.file.Paths - -import scala.concurrent.Await -import scala.concurrent.duration.Duration -import scala.concurrent.ExecutionContext.Implicits.global -import slick.backend.DatabaseConfig -import slick.codegen.{SourceCodeGenerator, StringGeneratorHelpers} -import slick.driver.JdbcProfile -import slick.{model => sModel} -import slick.model.{Column, Model, Table, QualifiedName} - -object Generator { - - def outputSchemaCode(schemaName: String, - profile: String, - folder: String, - pkg: String, - tableGen: TableFileGenerator, - rowGen: RowFileGenerator): Unit = { - val camelSchemaName = schemaName.split('_').map(_.capitalize).mkString("") - - tableGen.writeTablesToFile(profile: String, - folder: String, - pkg: String, - fileName = s"${camelSchemaName}Tables.scala") - rowGen.writeRowsToFile(folder: String, - pkg: String, - fileName = s"${camelSchemaName}Rows.scala") - } - - def run(uri: URI, - pkg: String, - schemaNames: Option[List[String]], - outputPath: String, - manualForeignKeys: Map[(String, String), (String, String)], - parentType: Option[String], - idType: Option[String], - header: String, - schemaImports: List[String], - typeReplacements: Map[String, String]) = { - val dc: DatabaseConfig[JdbcProfile] = - DatabaseConfig.forURI[JdbcProfile](uri) - val parsedSchemasOpt: Option[Map[String, List[String]]] = - schemaNames.map(SchemaParser.parse) - val imports = schemaImports.map("import " + _).mkString("\n") - - try { - val dbModel: Model = Await.result( - dc.db.run(SchemaParser.createModel(dc.driver, parsedSchemasOpt)), - Duration.Inf) - - parsedSchemasOpt.getOrElse(Map.empty).foreach { - case (schemaName, tables) => - val profile = - s"""slick.backend.DatabaseConfig.forConfig[slick.driver.JdbcProfile]("${uri - .getFragment()}").driver""" - - val schemaOnlyModel = Await.result( - dc.db.run( - SchemaParser.createModel(dc.driver, - Some(Map(schemaName -> tables)))), - Duration.Inf) - - val rowGenerator = new RowSourceCodeGenerator( - schemaOnlyModel, - headerComment = header, - imports = imports, - schemaName = schemaName, - dbModel, - idType, - manualForeignKeys, - typeReplacements - ) - - val tableGenerator = new TableSourceCodeGenerator( - schemaOnlyModel = schemaOnlyModel, - headerComment = header, - imports = imports, - schemaName = schemaName, - fullDatabaseModel = dbModel, - pkg = pkg, - manualForeignKeys, - parentType = parentType, - idType, - typeReplacements) - - outputSchemaCode( - schemaName = schemaName, - profile = profile, - folder = outputPath, - pkg = pkg, - tableGen = tableGenerator, - rowGen = rowGenerator) - } - } finally { - dc.db.close() - } - } -} diff --git a/src/main/scala/OutputHelpers.scala b/src/main/scala/OutputHelpers.scala index b68af8c..852c2ff 100644 --- a/src/main/scala/OutputHelpers.scala +++ b/src/main/scala/OutputHelpers.scala @@ -1,16 +1,5 @@ import slick.codegen.{SourceCodeGenerator, OutputHelpers} -trait TableFileGenerator { self: SourceCodeGenerator => - def writeTablesToFile(profile: String, - folder: String, - pkg: String, - fileName: String): Unit -} - -trait RowFileGenerator { self: SourceCodeGenerator => - def writeRowsToFile(folder: String, pkg: String, fileName: String): Unit -} - trait TableOutputHelpers extends TableFileGenerator with OutputHelpers { self: SourceCodeGenerator => -- cgit v1.2.3 From 5545a29838803802382be8556ad35a9e5cb69130 Mon Sep 17 00:00:00 2001 From: Stewart Stewart Date: Fri, 24 Feb 2017 10:28:18 -0500 Subject: add closing bracket --- src/main/scala/OutputHelpers.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/scala/OutputHelpers.scala b/src/main/scala/OutputHelpers.scala index 852c2ff..9a5ca53 100644 --- a/src/main/scala/OutputHelpers.scala +++ b/src/main/scala/OutputHelpers.scala @@ -28,6 +28,7 @@ trait TableOutputHelpers extends TableFileGenerator with OutputHelpers { |trait Tables${parentType.fold("")(" extends " + _)} { | import profile.api._ | ${indent(code)} + |} |""".stripMargin.trim() def writeTablesToFile(profile: String, -- cgit v1.2.3 From a8b637c87d8d6b11793f175e4b6ce00199eaec58 Mon Sep 17 00:00:00 2001 From: Stewart Stewart Date: Fri, 24 Feb 2017 10:31:11 -0500 Subject: expose package object --- src/main/scala/OutputHelpers.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/OutputHelpers.scala b/src/main/scala/OutputHelpers.scala index 9a5ca53..97fb4e9 100644 --- a/src/main/scala/OutputHelpers.scala +++ b/src/main/scala/OutputHelpers.scala @@ -20,7 +20,7 @@ trait TableOutputHelpers extends TableFileGenerator with OutputHelpers { | |/** Stand-alone Slick data model for immediate use */ |// TODO: change this to `object tables` - |package object $schemaName extends { + |object `package` extends { | val profile = $profile |} with Tables | -- cgit v1.2.3 From 36339f501c5dfb59deb70d1bcfa0c6270894cf38 Mon Sep 17 00:00:00 2001 From: Stewart Stewart Date: Fri, 24 Feb 2017 11:19:57 -0500 Subject: pass along parentType --- src/main/scala/Generators.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/Generators.scala b/src/main/scala/Generators.scala index b3bfeab..fb75cc1 100644 --- a/src/main/scala/Generators.scala +++ b/src/main/scala/Generators.scala @@ -45,7 +45,7 @@ class TableSourceCodeGenerator( fullDatabaseModel: m.Model, pkg: String, manualForeignKeys: Map[(String, String), (String, String)], - parentType: Option[String], + override val parentType: Option[String], idType: Option[String], typeReplacements: Map[String, String]) extends TypedIdSourceCodeGenerator(schemaOnlyModel, -- cgit v1.2.3