From fbb85ad4ba79c74544d6c804bbbf0a7ef350b113 Mon Sep 17 00:00:00 2001 From: Stewart Stewart Date: Fri, 22 Sep 2017 18:22:58 -0700 Subject: use Driver linting/formatting/style settings --- .scalafmt.conf | 29 ++++++++++ build.sbt | 4 ++ scalastyle-config.xml | 114 +++++++++++++++++++++++++++++++++++++ src/main/scala/CodegenPlugin.scala | 22 +++---- src/main/scala/Generators.scala | 89 ++++++++++++++--------------- src/main/scala/Main.scala | 44 +++++++------- src/main/scala/OutputHelpers.scala | 35 ++++-------- src/main/scala/SchemaParser.scala | 19 +++---- src/main/scala/TypedIdTable.scala | 34 +++++------ 9 files changed, 253 insertions(+), 137 deletions(-) create mode 100644 .scalafmt.conf create mode 100644 scalastyle-config.xml diff --git a/.scalafmt.conf b/.scalafmt.conf new file mode 100644 index 0000000..8a5d14f --- /dev/null +++ b/.scalafmt.conf @@ -0,0 +1,29 @@ +# scalafmt sbt plugin config +# refer to https://olafurpg.github.io/scalafmt/#Configuration for properties + +project.git = true + +style = defaultWithAlign +maxColumn = 120 + +docstrings = ScalaDoc + +continuationIndent.callSite = 2 +continuationIndent.defnSite = 8 + +rewriteTokens: { + "⇒" = "=>" + "←" = "<-" +} +danglingParentheses = false +align.arrowEnumeratorGenerator = true +align.openParenCallSite = true +spaces.afterTripleEquals = true +spaces.inImportCurlyBraces = false +newlines.alwaysBeforeCurlyBraceLambdaParams = false +newlines.sometimesBeforeColonInMethodReturnType = false +binPack.parentConstructors = true +assumeStandardLibraryStripMargin = true + +# align.openParenCallSite = +# align.openParenDefnSite = diff --git a/build.sbt b/build.sbt index 7cf3de0..81f7994 100644 --- a/build.sbt +++ b/build.sbt @@ -26,3 +26,7 @@ libraryDependencies ++= Seq( "com.typesafe.slick" %% "slick-codegen" % slickVersionValue, "com.typesafe.slick" %% "slick-hikaricp" % slickVersionValue ) + +lintingSettings + +formatSettings diff --git a/scalastyle-config.xml b/scalastyle-config.xml new file mode 100644 index 0000000..bbd85bc --- /dev/null +++ b/scalastyle-config.xml @@ -0,0 +1,114 @@ + + Scalastyle standard configuration + + + + + + + + + package + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + `.*` + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/scala/CodegenPlugin.scala b/src/main/scala/CodegenPlugin.scala index 6217695..94712c2 100644 --- a/src/main/scala/CodegenPlugin.scala +++ b/src/main/scala/CodegenPlugin.scala @@ -18,20 +18,19 @@ object CodegenPlugin extends AutoPlugin { * @param foreignKeys foreign key references to data models add manually */ case class CodegenDatabase( - databaseURI: String, - outputPackage: String, - outputPath: String, - schemaWhitelist: List[String] = List.empty, - foreignKeys: Map[TableColumn, TableColumn] = Map.empty + databaseURI: String, + outputPackage: String, + outputPath: String, + schemaWhitelist: List[String] = List.empty, + foreignKeys: Map[TableColumn, TableColumn] = Map.empty ) lazy val codegenDatabaseConfigs = SettingKey[List[CodegenDatabase]]( "codegen-database-configs", "configurations for each database and its generated code") - lazy val codegenSchemaBaseClassParts = SettingKey[List[String]]( - "codegen-schema-base-class-parts", - "parts inherited by each generated schema object") + lazy val codegenSchemaBaseClassParts = + SettingKey[List[String]]("codegen-schema-base-class-parts", "parts inherited by each generated schema object") lazy val codegenIdType = SettingKey[Option[String]]( "codegen-id-type", "The in-scope type `T` of kind `T[TableRow]` to apply in place T for id columns" @@ -76,10 +75,11 @@ object CodegenPlugin extends AutoPlugin { config.outputPath, config.foreignKeys, { val parts = - (if (codegenIdType.value.isEmpty) + (if (codegenIdType.value.isEmpty) { codegenSchemaBaseClassParts.value :+ "DefaultIdTypeMapper" - else - codegenSchemaBaseClassParts.value) + } else { + codegenSchemaBaseClassParts.value + }) Some(parts).filter(_.nonEmpty).map(_.mkString(" with ")) }, diff --git a/src/main/scala/Generators.scala b/src/main/scala/Generators.scala index b7b499e..ae410fb 100644 --- a/src/main/scala/Generators.scala +++ b/src/main/scala/Generators.scala @@ -1,21 +1,20 @@ 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)], - typeReplacements: Map[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)], + typeReplacements: Map[String, String] ) extends TypedIdSourceCodeGenerator( singleSchemaModel = model, databaseModel = fullDatabaseModel, idType, manualForeignKeys - ) - with RowOutputHelpers { + ) with RowOutputHelpers { override def Table = new TypedIdTable(_) { table => @@ -36,22 +35,20 @@ class RowSourceCodeGenerator( override def code = tables.map(_.code.mkString("\n")).mkString("\n\n") } -class TableSourceCodeGenerator( - 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)], - override val parentType: Option[String], - idType: Option[String], - typeReplacements: Map[String, String]) +class TableSourceCodeGenerator(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)], + override val parentType: Option[String], + idType: Option[String], + typeReplacements: Map[String, String]) extends TypedIdSourceCodeGenerator(singleSchemaModel = schemaOnlyModel, databaseModel = fullDatabaseModel, idType, - manualForeignKeys) - with TableOutputHelpers { + manualForeignKeys) with TableOutputHelpers { val defaultIdImplementation = """|final case class Id[T](v: Int) @@ -71,14 +68,14 @@ class TableSourceCodeGenerator( val tripleQuote = "\"\"\"" val namespaceDDL = s"""|val createNamespaceSchema = { - | implicit val GRUnit = slick.jdbc.GetResult(_ => ()) - | sql${tripleQuote}CREATE SCHEMA IF NOT EXISTS "$schemaName";${tripleQuote}.as[Unit] - |} - | - |val dropNamespaceSchema = { - | implicit val GRUnit = slick.jdbc.GetResult(_ => ()) - | sql${tripleQuote}DROP SCHEMA "$schemaName" CASCADE;${tripleQuote}.as[Unit] - |} """ + | implicit val GRUnit = slick.jdbc.GetResult(_ => ()) + | sql${tripleQuote}CREATE SCHEMA IF NOT EXISTS "$schemaName";${tripleQuote}.as[Unit] + |} + | + |val dropNamespaceSchema = { + | implicit val GRUnit = slick.jdbc.GetResult(_ => ()) + | sql${tripleQuote}DROP SCHEMA "$schemaName" CASCADE;${tripleQuote}.as[Unit] + |} """ tableCode + "\n\n" + namespaceDDL } @@ -99,21 +96,23 @@ class TableSourceCodeGenerator( override def factory: String = if (!hlistEnabled) super.factory else { - val args = columns.zipWithIndex.map("a" + _._2) + val args = columns.zipWithIndex.map("a" + _._2) val hlist = args.mkString("::") + ":: HNil" val hlistType = columns - .map(_.actualType) - .mkString("::") + ":: HNil.type" + .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 + 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 @@ -129,22 +128,22 @@ class TableSourceCodeGenerator( override def code = { val fkColumns = compoundValue(referencingColumns.map(_.name)) val qualifier = - if (referencedTable.model.name.schema == referencingTable.model.name.schema) + if (referencedTable.model.name.schema == referencingTable.model.name.schema) { "" - else - referencedTable.model.name.schema.fold("")(sname => - s"$pkg.$sname.") + } 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" + .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/Main.scala b/src/main/scala/Main.scala index 7f0374c..2a4624f 100644 --- a/src/main/scala/Main.scala +++ b/src/main/scala/Main.scala @@ -7,10 +7,7 @@ import slick.codegen.SourceCodeGenerator import slick.jdbc.JdbcProfile 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 => @@ -31,9 +28,7 @@ object Generator { folder: String, pkg: String, fileName = s"${camelSchemaName}Tables.scala") - rowGen.writeRowsToFile(folder: String, - pkg: String, - fileName = s"${camelSchemaName}Rows.scala") + rowGen.writeRowsToFile(folder: String, pkg: String, fileName = s"${camelSchemaName}Rows.scala") } def run(uri: URI, @@ -55,10 +50,8 @@ object Generator { def importStatements(imports: List[String]) = imports.map("import " + _).mkString("\n") try { - val dbModel: slick.model.Model = Await.result( - dc.db.run( - ModelTransformation.createModel(dc.profile, parsedSchemasOpt)), - Duration.Inf) + val dbModel: slick.model.Model = + Await.result(dc.db.run(ModelTransformation.createModel(dc.profile, parsedSchemasOpt)), Duration.Inf) parsedSchemasOpt.getOrElse(Map.empty).foreach { case (schemaName, tables) => @@ -66,10 +59,9 @@ object Generator { s"""slick.backend.DatabaseConfig.forConfig[slick.driver.JdbcProfile]("${uri .getFragment()}").driver""" - val schemaOnlyModel = Await.result( - dc.db.run(ModelTransformation - .createModel(dc.profile, Some(Map(schemaName -> tables)))), - Duration.Inf) + val schemaOnlyModel = Await.result(dc.db.run(ModelTransformation + .createModel(dc.profile, Some(Map(schemaName -> tables)))), + Duration.Inf) val rowGenerator = new RowSourceCodeGenerator( model = schemaOnlyModel, @@ -83,16 +75,18 @@ object Generator { ) val tableGenerator = - new TableSourceCodeGenerator(schemaOnlyModel = schemaOnlyModel, - headerComment = header, - imports = importStatements(tablesFileImports), - schemaName = schemaName, - fullDatabaseModel = dbModel, - pkg = pkg, - manualForeignKeys, - parentType = parentType, - idType, - typeReplacements) + new TableSourceCodeGenerator( + schemaOnlyModel = schemaOnlyModel, + headerComment = header, + imports = importStatements(tablesFileImports), + schemaName = schemaName, + fullDatabaseModel = dbModel, + pkg = pkg, + manualForeignKeys, + parentType = parentType, + idType, + typeReplacements + ) outputSchemaCode(schemaName = schemaName, profile = profile, diff --git a/src/main/scala/OutputHelpers.scala b/src/main/scala/OutputHelpers.scala index 97fb4e9..17c2019 100644 --- a/src/main/scala/OutputHelpers.scala +++ b/src/main/scala/OutputHelpers.scala @@ -1,7 +1,6 @@ import slick.codegen.{SourceCodeGenerator, OutputHelpers} -trait TableOutputHelpers extends TableFileGenerator with OutputHelpers { - self: SourceCodeGenerator => +trait TableOutputHelpers extends TableFileGenerator with OutputHelpers { self: SourceCodeGenerator => def headerComment: String def schemaName: String @@ -31,30 +30,21 @@ trait TableOutputHelpers extends TableFileGenerator with OutputHelpers { |} |""".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 @@ -67,10 +57,9 @@ trait RowOutputHelpers extends RowFileGenerator with OutputHelpers { 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/SchemaParser.scala b/src/main/scala/SchemaParser.scala index 85fffaf..bf555c3 100644 --- a/src/main/scala/SchemaParser.scala +++ b/src/main/scala/SchemaParser.scala @@ -14,14 +14,13 @@ object ModelTransformation { table.copy(columns = table.columns.map(column => if (column.options contains SqlType("citext")) { column.copy(options = column.options.filter { - case length: Length => false - case option => true + case _: Length => false + case _ => true }) } else column)))) def references(dbModel: m.Model, - tcMappings: Map[(String, String), (String, String)]) - : Map[(String, String), (m.Table, m.Column)] = { + 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 @@ -29,8 +28,7 @@ object ModelTransformation { .getOrElse(throw new RuntimeException("No table " + tableName)) val column = table.columns .find(_.name == columnName) - .getOrElse(throw new RuntimeException( - "No column " + columnName + " in table " + tableName)) + .getOrElse(throw new RuntimeException("No column " + columnName + " in table " + tableName)) (table, column) } @@ -39,16 +37,13 @@ object ModelTransformation { } } - def parseSchemaList( - schemaTableNames: List[String]): Map[String, List[String]] = + def parseSchemaList(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] = { + def createModel(jdbcProfile: JdbcProfile, mappedSchemasOpt: Option[Map[String, List[String]]]): DBIO[m.Model] = { import slick.jdbc.meta.MQName val filteredTables = mappedSchemasOpt.map { mappedSchemas => @@ -61,7 +56,7 @@ object ModelTransformation { .find(table => table.name match { case MQName(_, Some(`schemaName`), `tableName`) => true - case _ => false + case _ => false }) .getOrElse(throw new IllegalArgumentException( s"$schemaName.$tableName does not exist in the connected database."))) diff --git a/src/main/scala/TypedIdTable.scala b/src/main/scala/TypedIdTable.scala index ad62032..ead4a49 100644 --- a/src/main/scala/TypedIdTable.scala +++ b/src/main/scala/TypedIdTable.scala @@ -2,19 +2,19 @@ import slick.codegen.SourceCodeGenerator import slick.{model => m} class TypedIdSourceCodeGenerator( - singleSchemaModel: m.Model, - databaseModel: m.Model, - idType: Option[String], - manualForeignKeys: Map[(String, String), (String, String)] + singleSchemaModel: m.Model, + databaseModel: m.Model, + idType: Option[String], + manualForeignKeys: Map[(String, String), (String, String)] ) extends SourceCodeGenerator(singleSchemaModel) { val manualReferences = ModelTransformation.references(databaseModel, manualForeignKeys) val modelTypeToColumnMaper = Map( "java.util.UUID" -> "uuidKeyMapper", - "String" -> "naturalKeyMapper", - "Int" -> "serialKeyMapper", - "Long" -> "serialKeyMapper" + "String" -> "naturalKeyMapper", + "Int" -> "serialKeyMapper", + "Long" -> "serialKeyMapper" ) val keyReferences: Map[m.Column, m.Column] = { @@ -26,18 +26,15 @@ class TypedIdSourceCodeGenerator( val fks: Seq[(m.Column, m.Column)] = databaseModel.tables .flatMap(_.foreignKeys) .filter(_.referencedColumns.length == 1) - .filter(_.referencedColumns.forall( - _.options.contains(slick.ast.ColumnOption.PrimaryKey))) - .flatMap(fk => - fk.referencingColumns.flatMap(from => - fk.referencedColumns.headOption.map(to => (from -> to)))) + .filter(_.referencedColumns.forall(_.options.contains(slick.ast.ColumnOption.PrimaryKey))) + .flatMap(fk => fk.referencingColumns.flatMap(from => fk.referencedColumns.headOption.map(to => (from -> to)))) (pks ++ fks).toMap } def pKeyTypeTag(columnRef: m.Column): String = { val schemaName = columnRef.table.schema.getOrElse("`public`") - val tableName = entityName(columnRef.table.table) + val tableName = entityName(columnRef.table.table) s"$schemaName.$tableName" } @@ -47,11 +44,7 @@ class TypedIdSourceCodeGenerator( class TypedIdTable(model: m.Table) extends Table(model) { table => override def definitions = - Seq[Def](EntityType, - PlainSqlMapper, - TableClass, - TableValue, - PrimaryKeyMapper) + Seq[Def](EntityType, PlainSqlMapper, TableClass, TableValue, PrimaryKeyMapper) class TypedIdColumn(override val model: m.Column) extends Column(model) { override def rawType: String = { @@ -80,9 +73,8 @@ class TypedIdSourceCodeGenerator( override def code = primaryKeyColumn.fold("") { column => val tpe = s"BaseColumnType[${column.rawType}]" - s"""|implicit def $name: $tpe = - |${modelTypeToColumnMaper(column.model.tpe)}[${pKeyTypeTag( - column.model)}] + s"""|implicit def $name: $tpe = + |${modelTypeToColumnMaper(column.model.tpe)}[${pKeyTypeTag(column.model)}] |""".stripMargin.lines.mkString("").trim } } -- cgit v1.2.3