diff --git a/src/allographer/schema_builder/models/column.nim b/src/allographer/schema_builder/models/column.nim index ff99f923..fce185cc 100644 --- a/src/allographer/schema_builder/models/column.nim +++ b/src/allographer/schema_builder/models/column.nim @@ -20,6 +20,7 @@ type Column* = ref object defaultDatetime*: DefaultDateTime foreignOnDelete*: ForeignOnDelete commentContent*:string + isCommentNull*:bool info*: JsonNode checksum*:string # alter table @@ -51,6 +52,7 @@ proc toSchema*(self:Column):JsonNode = "defaultJson": self.defaultJson, "foreignOnDelete": self.foreignOnDelete, "comment": self.commentContent, + "isCommentNull": self.isCommentNull, "info": self.info, "previousName":self.previousName, "migrationType":self.migrationType, @@ -389,6 +391,10 @@ proc comment*(c: Column, value:string): Column = c.commentContent = value return c +proc comment*(c: Column, arg:type nil): Column = + c.isCommentNull = true + return c + # ============================================================================= # alter table diff --git a/src/allographer/schema_builder/queries/postgres/change_column.nim b/src/allographer/schema_builder/queries/postgres/change_column.nim index 1859e797..96dd2425 100644 --- a/src/allographer/schema_builder/queries/postgres/change_column.nim +++ b/src/allographer/schema_builder/queries/postgres/change_column.nim @@ -6,17 +6,13 @@ else: import std/json import ../../models/table import ../../models/column -import ../../enums import ./schema_utils import ./postgres_query_type import ./sub/change_column_query proc changeColumn*(self:PostgresSchema, isReset:bool) = - var queries = changeColumnString(self.table, self.column) - - if self.column.isIndex and self.column.typ != rdbIncrements: - queries.add(changeIndexString(self.table, self.column)) + let queries = changeColumnString(self.table, self.column) let schema = $self.column.toSchema() let checksum = $schema.secureHash() diff --git a/src/allographer/schema_builder/queries/postgres/sub/add_column_query.nim b/src/allographer/schema_builder/queries/postgres/sub/add_column_query.nim index 84a0cb24..37740417 100644 --- a/src/allographer/schema_builder/queries/postgres/sub/add_column_query.nim +++ b/src/allographer/schema_builder/queries/postgres/sub/add_column_query.nim @@ -421,6 +421,14 @@ proc addIndexColumn(column:Column, table:Table):string = return &"CREATE INDEX IF NOT EXISTS \"{table.name}_{column.name}_index\" ON \"{table.name}\"(\"{column.name}\")" +proc addCommentColumn(column:Column, table:Table):string = + return &"COMMENT ON COLUMN \"{table.name}\".\"{column.name}\" IS '{column.commentContent}'" + + +proc addNullCommentColumn(column:Column, table:Table):string = + return &"COMMENT ON COLUMN \"{table.name}\".\"{column.name}\" IS NULL" + + proc addColumnString*(table:Table, column:Column):seq[string] = var queries:seq[string] case column.typ: @@ -492,4 +500,9 @@ proc addColumnString*(table:Table, column:Column):seq[string] = if column.isUpdatedAt: queries.add(column.addUpdatedAtColumn(table)) + if column.commentContent.len > 0: + queries.add(column.addCommentColumn(table)) + elif column.isCommentNull: + queries.add(column.addNullCommentColumn(table)) + return queries diff --git a/src/allographer/schema_builder/queries/postgres/sub/change_column_query.nim b/src/allographer/schema_builder/queries/postgres/sub/change_column_query.nim index bb88730d..589b5875 100644 --- a/src/allographer/schema_builder/queries/postgres/sub/change_column_query.nim +++ b/src/allographer/schema_builder/queries/postgres/sub/change_column_query.nim @@ -347,68 +347,83 @@ proc indexColumn(column:Column, table:Table):string = return &"CREATE INDEX IF NOT EXISTS \"{table.name}_{column.name}_index\" ON \"{table.name}\"(\"{column.name}\")" +proc addCommentColumn(column:Column, table:Table):string = + return &"COMMENT ON COLUMN \"{table.name}\".\"{column.name}\" IS '{column.commentContent}'" + + +proc addNullCommentColumn(column:Column, table:Table):string = + return &"COMMENT ON COLUMN \"{table.name}\".\"{column.name}\" IS NULL" + + proc changeColumnString*(table:Table, column:Column):seq[string] = + var queries:seq[string] case column.typ: # int of rdbIncrements: - notAllowedType("increments") + queries = column.changeIntColumn(table) of rdbInteger: - return column.changeIntColumn(table) + queries = column.changeIntColumn(table) of rdbSmallInteger: - return column.changeSmallIntColumn(table) + queries = column.changeSmallIntColumn(table) of rdbMediumInteger: - return column.changeMediumIntColumn(table) + queries = column.changeMediumIntColumn(table) of rdbBigInteger: - return column.changeBigIntColumn(table) + queries = column.changeBigIntColumn(table) # float of rdbDecimal: - return column.changeDecimalColumn(table) + queries = column.changeDecimalColumn(table) of rdbDouble: - return column.changeDecimalColumn(table) + queries = column.changeDecimalColumn(table) of rdbFloat: - return column.changeFloatColumn(table) + queries = column.changeFloatColumn(table) # char of rdbUuid: - return column.changeStringColumn(table) + queries = column.changeStringColumn(table) of rdbChar: - return column.changeCharColumn(table) + queries = column.changeCharColumn(table) of rdbString: - return column.changeStringColumn(table) + queries = column.changeStringColumn(table) # text of rdbText: - return column.changeTextColumn(table) + queries = column.changeTextColumn(table) of rdbMediumText: - return column.changeTextColumn(table) + queries = column.changeTextColumn(table) of rdbLongText: - return column.changeTextColumn(table) + queries = column.changeTextColumn(table) # date of rdbDate: - return column.changeDateColumn(table) + queries = column.changeDateColumn(table) of rdbDatetime: - return column.changeDatetimeColumn(table) + queries = column.changeDatetimeColumn(table) of rdbTime: - return column.changeTimeColumn(table) + queries = column.changeTimeColumn(table) of rdbTimestamp: - return column.changeTimestampColumn(table) + queries = column.changeTimestampColumn(table) of rdbTimestamps: notAllowedType("timestamps") of rdbSoftDelete: notAllowedType("softDelete") # others of rdbBinary: - return column.changeBlobColumn(table) + queries = column.changeBlobColumn(table) of rdbBoolean: - return column.changeBoolColumn(table) + queries = column.changeBoolColumn(table) of rdbEnumField: - return column.changeEnumColumn(table) + queries = column.changeEnumColumn(table) of rdbJson: - return column.changeJsonColumn(table) + queries = column.changeJsonColumn(table) # foreign of rdbForeign: notAllowedType("foreign") of rdbStrForeign: notAllowedType("strForeign") + if column.isIndex and column.typ != rdbIncrements: + queries.add(indexColumn(column, table)) + + if column.commentContent.len > 0: + queries.add(column.addCommentColumn(table)) + elif column.isCommentNull: + queries.add(column.addNullCommentColumn(table)) -proc changeIndexString*(table:Table, column:Column):string = - return column.indexColumn(table) + return queries diff --git a/src/allographer/schema_builder/usecases/postgres/create_schema.nim b/src/allographer/schema_builder/usecases/postgres/create_schema.nim index de87355d..541ef696 100644 --- a/src/allographer/schema_builder/usecases/postgres/create_schema.nim +++ b/src/allographer/schema_builder/usecases/postgres/create_schema.nim @@ -77,9 +77,21 @@ proc generateSchemaCode(tablesInfo: Table[string, seq[tuple[name: string, typ: s proc createSchema*(rdb: PostgresConnections, schemaPath="") {.async.} = - ## create schema.nim - let tablesInfo = rdb.getTableInfo().await - let schemaCode = generateSchemaCode(tablesInfo) - - writeFile(schemaPath / "schema.nim", schemaCode) - echo "schema.nim generated successfully" + ## if schemaPath is not specified, the schema will be generated in the current directory + ## + ## Default schema file name is `getCurrentDir() / "schema.nim"` + try: + let tablesInfo = rdb.getTableInfo().await + let schemaCode = generateSchemaCode(tablesInfo) + + let schemaFilePath = + if schemaPath == "": + getCurrentDir() / "schema.nim" + else: + schemaPath + + writeFile(schemaFilePath, schemaCode) + echo "schema generated successfully in ", schemaFilePath + except Exception as e: + echo "Error generating schema: ", e.msg + raise diff --git a/src/allographer/schema_builder/usecases/sqlite/create_schema.nim b/src/allographer/schema_builder/usecases/sqlite/create_schema.nim index 813d5de1..3d5abc73 100644 --- a/src/allographer/schema_builder/usecases/sqlite/create_schema.nim +++ b/src/allographer/schema_builder/usecases/sqlite/create_schema.nim @@ -74,14 +74,21 @@ proc generateSchemaCode(tablesInfo: Table[string, seq[tuple[name: string, typ: s return code proc createSchema*(rdb: SqliteConnections, schemaPath="") {.async.} = - ## create schema.nim + ## if schemaPath is not specified, the schema will be generated in the current directory + ## + ## Default schema file name is `getCurrentDir() / "schema.nim"` try: let tablesInfo = await rdb.getTableInfo() let schemaCode = generateSchemaCode(tablesInfo) + + let schemaFilePath = + if schemaPath == "": + getCurrentDir() / "schema.nim" + else: + schemaPath - writeFile(schemaPath / "schema.nim", schemaCode) - echo "schema.nim generated successfully" - + writeFile(schemaFilePath, schemaCode) + echo "schema generated successfully in ", schemaFilePath except Exception as e: echo "Error generating schema: ", e.msg raise diff --git a/tests/clear_tables.nim b/tests/clear_tables.nim index b6ab6efb..a5d669a0 100644 --- a/tests/clear_tables.nim +++ b/tests/clear_tables.nim @@ -6,51 +6,66 @@ import ../src/allographer/query_builder proc clearTables*(rdb:PostgresConnections) {.async.} = - let tables = rdb.table("_allographer_migrations").orderBy("id", Desc) .get().await - for table in tables: - let tableName = table["name"].getStr() - if not tableName.startsWith("_"): - rdb.raw(&"DROP TABLE IF EXISTS \"{tableName}\"").exec().await + try: + let tables = rdb.table("_allographer_migrations").orderBy("id", Desc) .get().await + for table in tables: + let tableName = table["name"].getStr() + if not tableName.startsWith("_"): + rdb.raw(&"DROP TABLE IF EXISTS \"{tableName}\"").exec().await - rdb.raw("DROP TABLE IF EXISTS \"_allographer_migrations\"").exec().await + rdb.raw("DROP TABLE IF EXISTS \"_allographer_migrations\"").exec().await + except: + echo "error: ", getCurrentExceptionMsg() proc clearTables*(rdb:MariaDBConnections) {.async.} = - let tables = rdb.table("_allographer_migrations").orderBy("id", Desc) .get().await - for table in tables: - let tableName = table["name"].getStr() - if not tableName.startsWith("_"): - rdb.raw(&"DROP TABLE IF EXISTS `{tableName}`").exec().await - - rdb.raw("DROP TABLE IF EXISTS `_allographer_migrations`").exec().await + try: + let tables = rdb.table("_allographer_migrations").orderBy("id", Desc) .get().await + for table in tables: + let tableName = table["name"].getStr() + if not tableName.startsWith("_"): + rdb.raw(&"DROP TABLE IF EXISTS `{tableName}`").exec().await + + rdb.raw("DROP TABLE IF EXISTS `_allographer_migrations`").exec().await + except: + echo "error: ", getCurrentExceptionMsg() proc clearTables*(rdb:MySQLConnections) {.async.} = - let tables = rdb.table("_allographer_migrations").orderBy("id", Desc) .get().await - for table in tables: - let tableName = table["name"].getStr() - if not tableName.startsWith("_"): - rdb.raw(&"DROP TABLE IF EXISTS `{tableName}`").exec().await - - rdb.raw("DROP TABLE IF EXISTS `_allographer_migrations`").exec().await + try: + let tables = rdb.table("_allographer_migrations").orderBy("id", Desc) .get().await + for table in tables: + let tableName = table["name"].getStr() + if not tableName.startsWith("_"): + rdb.raw(&"DROP TABLE IF EXISTS `{tableName}`").exec().await + + rdb.raw("DROP TABLE IF EXISTS `_allographer_migrations`").exec().await + except: + echo "error: ", getCurrentExceptionMsg() proc clearTables*(rdb:SqliteConnections) {.async.} = - let tables = rdb.table("_allographer_migrations").orderBy("id", Desc) .get().await - for table in tables: - let tableName = table["name"].getStr() - if not tableName.startsWith("_"): - rdb.raw(&"DROP TABLE IF EXISTS \"{tableName}\"").exec().await + try: + let tables = rdb.table("_allographer_migrations").orderBy("id", Desc) .get().await + for table in tables: + let tableName = table["name"].getStr() + if not tableName.startsWith("_"): + rdb.raw(&"DROP TABLE IF EXISTS \"{tableName}\"").exec().await - rdb.raw("DROP TABLE IF EXISTS \"_allographer_migrations\"").exec().await + rdb.raw("DROP TABLE IF EXISTS \"_allographer_migrations\"").exec().await + except: + echo "error: ", getCurrentExceptionMsg() proc clearTables*(rdb:SurrealConnections) {.async.} = - let dbInfo = rdb.raw("INFO FOR DB").info().await - let tables = dbInfo[0]["result"]["tb"] - for (table, _) in tables.pairs: - if not table.startsWith("_"): - rdb.raw(&"REMOVE TABLE {table}").exec().await + try: + let dbInfo = rdb.raw("INFO FOR DB").info().await + let tables = dbInfo[0]["result"]["tb"] + for (table, _) in tables.pairs: + if not table.startsWith("_"): + rdb.raw(&"REMOVE TABLE {table}").exec().await - rdb.raw(&"REMOVE TABLE _allographer_migrations").exec().await - rdb.raw(&"REMOVE TABLE _autoincrement_sequences").exec().await + rdb.raw(&"REMOVE TABLE _allographer_migrations").exec().await + rdb.raw(&"REMOVE TABLE _autoincrement_sequences").exec().await + except: + echo "error: ", getCurrentExceptionMsg() diff --git a/tests/postgres/test_create_schema.nim b/tests/postgres/test_create_schema.nim index bb68e51c..8928917e 100644 --- a/tests/postgres/test_create_schema.nim +++ b/tests/postgres/test_create_schema.nim @@ -2,6 +2,8 @@ discard """ cmd: "nim c -d:reset $file" """ +# nim c -d:reset -r tests/postgres/test_create_schema.nim + import std/unittest import std/asyncdispatch import std/os @@ -61,7 +63,7 @@ suite "Schema output after migration": test "should generate schema.nim file": # スキーマ生成 - rdb.createSchema().waitFor() + rdb.createSchema(schemaFilePath).waitFor() # schema.nim ファイルの存在確認 check fileExists(schemaFilePath) diff --git a/tests/postgres/test_schema.nim b/tests/postgres/test_schema.nim index 69ade141..5b25b399 100644 --- a/tests/postgres/test_schema.nim +++ b/tests/postgres/test_schema.nim @@ -15,6 +15,7 @@ import ../clear_tables let rdb = postgres +clearTables(rdb).waitFor() suite("PostgreSQL create table"): test("create table"): @@ -298,7 +299,7 @@ suite($rdb & " primary"): suite("Comment"): - test("column comment"): + test("create table with column comment"): rdb.create( table("Comment", [ Column.integer("index1").comment("index1 comment"), @@ -306,5 +307,26 @@ suite("Comment"): ]) ) + test("alter table change column comment"): + rdb.alter( + table("Comment", [ + Column.integer("index1").comment("changed index1 comment").change() + ]) + ) + + test("alter table add column comment"): + rdb.alter( + table("Comment", [ + Column.string("string2").comment("string2 comment").add() + ]) + ) + + test("alter table add null comment"): + rdb.alter( + table("Comment", [ + Column.string("string").comment(nil).change() + ]) + ) + clearTables(rdb).waitFor() diff --git a/tests/sqlite/test_create_schema.nim b/tests/sqlite/test_create_schema.nim index 6fc0738d..d6b2ff7f 100644 --- a/tests/sqlite/test_create_schema.nim +++ b/tests/sqlite/test_create_schema.nim @@ -2,6 +2,8 @@ discard """ cmd: "nim c -d:reset $file" """ +# nim c -d:reset -r tests/sqlite/test_create_schema.nim + import std/unittest import std/asyncdispatch import std/os @@ -61,7 +63,7 @@ suite "Schema output after migration": test "should generate schema.nim file": # スキーマ生成 - rdb.createSchema().waitFor() + rdb.createSchema(schemaFilePath).waitFor() # schema.nim ファイルの存在確認 check fileExists(schemaFilePath)