velocious 1.0.2 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/.github/dependabot.yml +1 -1
  2. package/README.md +19 -3
  3. package/bin/velocious.mjs +4 -4
  4. package/index.mjs +5 -3
  5. package/package.json +5 -3
  6. package/peak_flow.yml +5 -2
  7. package/spec/cli/commands/db/create-spec.mjs +25 -0
  8. package/spec/cli/commands/db/migrate-spec.mjs +37 -0
  9. package/spec/cli/commands/destroy/migration-spec.mjs +15 -0
  10. package/spec/cli/commands/generate/migration-spec.mjs +18 -0
  11. package/spec/cli/commands/init-spec.mjs +19 -0
  12. package/spec/cli/commands/test/test-files-finder-spec.mjs +12 -0
  13. package/spec/database/drivers/mysql/connection-spec.mjs +2 -2
  14. package/spec/dummy/dummy-directory.mjs +11 -0
  15. package/spec/dummy/index.mjs +22 -26
  16. package/spec/dummy/src/config/configuration.example.mjs +21 -0
  17. package/spec/dummy/src/config/configuration.peakflow.mjs +22 -0
  18. package/spec/dummy/src/database/migrations/20230728075328-create-projects.mjs +11 -0
  19. package/spec/dummy/src/database/migrations/20230728075329-create-tasks.mjs +13 -0
  20. package/spec/http-server/client-spec.mjs +7 -12
  21. package/src/application.mjs +10 -11
  22. package/src/cli/base-command.mjs +11 -0
  23. package/src/cli/commands/db/create.mjs +44 -8
  24. package/src/cli/commands/db/migrate.mjs +105 -0
  25. package/src/cli/commands/destroy/migration.mjs +35 -0
  26. package/src/cli/commands/generate/migration.mjs +31 -7
  27. package/src/cli/commands/generate/model.mjs +36 -0
  28. package/src/cli/commands/init.mjs +60 -0
  29. package/src/cli/commands/server.mjs +15 -0
  30. package/src/cli/commands/test/index.mjs +14 -0
  31. package/src/cli/commands/test/test-files-finder.mjs +99 -0
  32. package/src/cli/commands/test/test-runner.mjs +19 -0
  33. package/src/cli/index.mjs +37 -16
  34. package/src/configuration-resolver.mjs +26 -0
  35. package/src/configuration.mjs +51 -13
  36. package/src/controller.mjs +1 -1
  37. package/src/database/drivers/base.mjs +8 -0
  38. package/src/database/drivers/mysql/index.mjs +25 -0
  39. package/src/database/drivers/mysql/sql/create-database.mjs +4 -0
  40. package/src/database/drivers/mysql/sql/create-table.mjs +4 -0
  41. package/src/database/drivers/sqlite/index.native.mjs +92 -0
  42. package/src/database/drivers/sqlite/index.web.mjs +64 -0
  43. package/src/database/drivers/sqlite/options.mjs +17 -0
  44. package/src/database/drivers/sqlite/query-parser.mjs +25 -0
  45. package/src/database/drivers/sqlite/query.native.mjs +9 -0
  46. package/src/database/drivers/sqlite/query.web.mjs +9 -0
  47. package/src/database/drivers/sqlite/sql/create-table.mjs +4 -0
  48. package/src/database/drivers/sqlite/sql/delete.mjs +19 -0
  49. package/src/database/drivers/sqlite/sql/insert.mjs +29 -0
  50. package/src/database/drivers/sqlite/sql/update.mjs +31 -0
  51. package/src/database/handler.mjs +0 -4
  52. package/src/database/migrate-from-require-context.mjs +53 -0
  53. package/src/database/migration/index.mjs +15 -2
  54. package/src/database/pool/async-tracked-multi-connection.mjs +81 -0
  55. package/src/database/pool/base.mjs +47 -0
  56. package/src/database/pool/single-multi-use.mjs +40 -0
  57. package/src/database/query/base.mjs +11 -0
  58. package/src/database/query/create-database-base.mjs +22 -0
  59. package/src/database/query/create-table-base.mjs +69 -0
  60. package/src/database/query/delete-base.mjs +4 -10
  61. package/src/database/query/from-plain.mjs +3 -5
  62. package/src/database/query/from-table.mjs +2 -2
  63. package/src/database/record/index.mjs +2 -2
  64. package/src/database/table-data/index.mjs +83 -0
  65. package/src/http-server/worker-handler/index.mjs +2 -1
  66. package/src/http-server/worker-handler/worker-thread.mjs +17 -9
  67. package/src/routes/app-routes.mjs +10 -0
  68. package/src/routes/resolver.mjs +4 -2
  69. package/src/spec/index.mjs +5 -0
  70. package/src/templates/configuration.mjs +19 -0
  71. package/src/templates/generate-migration.mjs +11 -0
  72. package/src/templates/generate-model.mjs +4 -0
  73. package/src/templates/routes.mjs +11 -0
  74. package/src/utils/file-exists.mjs +13 -0
  75. package/spec/cli/generate/migration-spec.mjs +0 -9
  76. package/spec/dummy/src/config/database.example.mjs +0 -15
  77. package/spec/dummy/src/config/database.peakflow.mjs +0 -15
  78. package/spec/dummy/src/database/migrations/001-create-tasks.mjs +0 -12
  79. package/src/database/pool/index.mjs +0 -43
@@ -0,0 +1,4 @@
1
+ import CreateDatabaseBase from "../../../query/create-database-base.mjs"
2
+
3
+ export default class VelociousDatabaseConnectionDriversMysqlSqlCreateDatabase extends CreateDatabaseBase {
4
+ }
@@ -0,0 +1,4 @@
1
+ import CreateTableBase from "../../../query/create-table-base.mjs"
2
+
3
+ export default class VelociousDatabaseConnectionDriversMysqlSqlCreateTable extends CreateTableBase {
4
+ }
@@ -0,0 +1,92 @@
1
+ import Base from "../base.mjs"
2
+ import CreateTable from "../sqlite/sql/create-table.mjs"
3
+ import Delete from "../sqlite/sql/delete.mjs"
4
+ import {digg} from "diggerize"
5
+ import Insert from "../sqlite/sql/insert.mjs"
6
+ import Options from "../sqlite/options.mjs"
7
+ import query from "./query.mjs"
8
+ import QueryParser from "../sqlite/query-parser.mjs"
9
+ import * as SQLite from "expo-sqlite"
10
+ import Update from "../sqlite/sql/update.mjs"
11
+
12
+ export default class VelociousDatabaseDriversSqliteNative extends Base{
13
+ async connect() {
14
+ const connection = await SQLite.openDatabaseAsync(digg(this.connectArgs(), "name"))
15
+
16
+ this.connection = connection
17
+ }
18
+
19
+ disconnect() {
20
+ this.connection.end()
21
+ }
22
+
23
+ connectArgs() {
24
+ const args = this.getArgs()
25
+ const connectArgs = []
26
+ const forward = ["database", "host", "password"]
27
+
28
+ for (const forwardValue of forward) {
29
+ if (forwardValue in args) connectArgs[forwardValue] = digg(args, forwardValue)
30
+ }
31
+
32
+ if ("username" in args) connectArgs["user"] = args["username"]
33
+
34
+ return connectArgs
35
+ }
36
+
37
+ async close() {
38
+ await this.connection.end()
39
+ this.connection = undefined
40
+ }
41
+
42
+ createTableSql(tableData) {
43
+ const createArgs = Object.assign({tableData, driver: this})
44
+ const createTable = new CreateTable(createArgs)
45
+
46
+ return createTable.toSql()
47
+ }
48
+
49
+ async query(sql) {
50
+ return await query(this.connection, sql)
51
+ }
52
+
53
+ queryToSql(query) {
54
+ return new QueryParser({query}).toSql()
55
+ }
56
+
57
+ quote(string) {
58
+ if (!this.connection) throw new Error("Can't escape before connected")
59
+
60
+ return this.connection.escape(string)
61
+ }
62
+
63
+ quoteColumn(string) {
64
+ return `\`${string}\``
65
+ }
66
+
67
+ deleteSql({tableName, conditions}) {
68
+ const deleteInstruction = new Delete({conditions, driver: this, tableName})
69
+
70
+ return deleteInstruction.toSql()
71
+ }
72
+
73
+ insertSql({tableName, data}) {
74
+ const insert = new Insert({driver: this, tableName, data})
75
+
76
+ return insert.toSql()
77
+ }
78
+
79
+ options() {
80
+ if (!this._options) {
81
+ this._options = new Options({driver: this})
82
+ }
83
+
84
+ return this._options
85
+ }
86
+
87
+ updateSql({conditions, data, tableName}) {
88
+ const update = new Update({conditions, data, driver: this, tableName})
89
+
90
+ return update.toSql()
91
+ }
92
+ }
@@ -0,0 +1,64 @@
1
+ import Base from "../base.mjs"
2
+ import CreateTable from "../sqlite/sql/create-table.mjs"
3
+ import Delete from "../sqlite/sql/delete.mjs"
4
+ import {digg} from "diggerize"
5
+ import Insert from "../sqlite/sql/insert.mjs"
6
+ import Options from "../sqlite/options.mjs"
7
+ import query from "./query"
8
+ import QueryParser from "../sqlite/query-parser.mjs"
9
+ import Update from "../sqlite/sql/update.mjs"
10
+
11
+ import initSqlJs from "sql.js"
12
+
13
+ export default class VelociousDatabaseDriversSqliteWeb extends Base{
14
+ async connect() {
15
+ const SQL = await initSqlJs({
16
+ // Required to load the wasm binary asynchronously. Of course, you can host it wherever you want you can omit locateFile completely when running in Node.
17
+ locateFile: (file) => `https://sql.js.org/dist/${file}`
18
+ })
19
+
20
+ const databaseContent = localStorage.getItem(this.localStorageName())
21
+
22
+ this.connection = new SQL.Database(databaseContent)
23
+ }
24
+
25
+ localStorageName = () => `VelociousDatabaseDriversSqliteWeb---${digg(this.getArgs(), "name")}`
26
+ disconnect = () => this.saveDatabase()
27
+ saveDatabase = () => localStorage.setItem(this.localStorageName(), this.connection.export())
28
+
29
+ async close() {
30
+ this.saveDatabase()
31
+ await this.connection.end()
32
+ this.connection = undefined
33
+ }
34
+
35
+ createTableSql(tableData) {
36
+ const createArgs = Object.assign({tableData, driver: this})
37
+ const createTable = new CreateTable(createArgs)
38
+
39
+ return createTable.toSql()
40
+ }
41
+
42
+ query = async (sql) => await query(this.connection, sql)
43
+ queryToSql = (query) => new QueryParser({query}).toSql()
44
+
45
+ quote(string) {
46
+ if (!this.connection) throw new Error("Can't escape before connected")
47
+
48
+ return this.connection.escape(string)
49
+ }
50
+
51
+ quoteColumn = (string) => `\`${string}\``
52
+ deleteSql = ({tableName, conditions}) => new Delete({conditions, driver: this, tableName}).toSql()
53
+ insertSql = ({tableName, data}) => new Insert({driver: this, tableName, data}).toSql()
54
+
55
+ options() {
56
+ if (!this._options) {
57
+ this._options = new Options({driver: this})
58
+ }
59
+
60
+ return this._options
61
+ }
62
+
63
+ updateSql = ({conditions, data, tableName}) => new Update({conditions, data, driver: this, tableName}).toSql()
64
+ }
@@ -0,0 +1,17 @@
1
+ import QueryParserOptions from "../../query-parser/options.mjs"
2
+
3
+ export default class VelociousDatabaseDriversMysqlOptions extends QueryParserOptions {
4
+ constructor(options) {
5
+ options.columnQuote = "`"
6
+ options.stringQuote = "'"
7
+ options.tableQuote = "`"
8
+
9
+ super(options)
10
+ }
11
+
12
+ quote(string) {
13
+ if (!this.driver) throw new Error("Driver not set")
14
+
15
+ return this.driver.quote(string)
16
+ }
17
+ }
@@ -0,0 +1,25 @@
1
+ import {digs} from "diggerize"
2
+ import FromParser from "../../query-parser/from-parser.mjs"
3
+ import JoinsParser from "../../query-parser/joins-parser.mjs"
4
+ import SelectParser from "../../query-parser/select-parser.mjs"
5
+
6
+ export default class VelociousDatabaseConnectionDriversMysqlQueryParser {
7
+ constructor({pretty, query}) {
8
+ if (!query) throw new Error("No query given")
9
+
10
+ this.pretty = pretty
11
+ this.query = query
12
+ }
13
+
14
+ toSql() {
15
+ const {pretty, query} = digs(this, "pretty", "query")
16
+
17
+ let sql = ""
18
+
19
+ sql += new SelectParser({pretty, query}).toSql()
20
+ sql += new FromParser({pretty, query}).toSql()
21
+ sql += new JoinsParser({pretty, query}).toSql()
22
+
23
+ return sql
24
+ }
25
+ }
@@ -0,0 +1,9 @@
1
+ export default async function query(connection, sql) {
2
+ const rows = []
3
+
4
+ for await (const entry of connection.getEachAsync(sql)) {
5
+ rows.push(entry)
6
+ }
7
+
8
+ return rows
9
+ }
@@ -0,0 +1,9 @@
1
+ export default async function query(connection, sql) {
2
+ const rows = []
3
+
4
+ for await (const entry of connection.exec(sql)) {
5
+ rows.push(entry)
6
+ }
7
+
8
+ return rows
9
+ }
@@ -0,0 +1,4 @@
1
+ import CreateTableBase from "../../../query/create-table-base.mjs"
2
+
3
+ export default class VelociousDatabaseConnectionDriversMysqlSqlCreateTable extends CreateTableBase {
4
+ }
@@ -0,0 +1,19 @@
1
+ import DeleteBase from "../../../query/delete-base.mjs"
2
+
3
+ export default class VelociousDatabaseConnectionDriversMysqlSqlDelete extends DeleteBase {
4
+ toSql() {
5
+ let sql = `DELETE FROM ${this.getOptions().quoteTableName(this.tableName)} WHERE `
6
+ let count = 0
7
+
8
+ for (let columnName in this.conditions) {
9
+ if (count > 0) sql += " AND "
10
+
11
+ sql += this.getOptions().quoteColumnName(columnName)
12
+ sql += " = "
13
+ sql += this.getOptions().quote(this.conditions[columnName])
14
+ count++
15
+ }
16
+
17
+ return sql
18
+ }
19
+ }
@@ -0,0 +1,29 @@
1
+ import InsertBase from "../../../query/insert-base.mjs"
2
+
3
+ export default class VelociousDatabaseConnectionDriversMysqlSqlInsert extends InsertBase {
4
+ toSql() {
5
+ let sql = `INSERT INTO ${this.getOptions().quoteTableName(this.tableName)} (`
6
+ let count = 0
7
+
8
+ for (let columnName in this.data) {
9
+ if (count > 0) sql += ", "
10
+
11
+ sql += this.getOptions().quoteColumnName(columnName)
12
+ count++
13
+ }
14
+
15
+ sql += ") VALUES ("
16
+ count = 0
17
+
18
+ for (let columnName in this.data) {
19
+ if (count > 0) sql += ", "
20
+
21
+ sql += this.getOptions().quote(this.data[columnName])
22
+ count++
23
+ }
24
+
25
+ sql += ")"
26
+
27
+ return sql
28
+ }
29
+ }
@@ -0,0 +1,31 @@
1
+ import UpdateBase from "../../../query/update-base.mjs"
2
+
3
+ export default class VelociousDatabaseConnectionDriversMysqlSqlUpdate extends UpdateBase {
4
+ toSql() {
5
+ let sql = `UPDATE ${this.getOptions().quoteTableName(this.tableName)} SET `
6
+ let count = 0
7
+
8
+ for (let columnName in this.data) {
9
+ if (count > 0) sql += ", "
10
+
11
+ sql += this.getOptions().quoteColumnName(columnName)
12
+ sql += " = "
13
+ sql += this.getOptions().quote(this.data[columnName])
14
+ count++
15
+ }
16
+
17
+ sql += " WHERE "
18
+ count = 0
19
+
20
+ for (let columnName in this.conditions) {
21
+ if (count > 0) sql += " AND "
22
+
23
+ sql += this.getOptions().quoteColumnName(columnName)
24
+ sql += " = "
25
+ sql += this.getOptions().quote(this.conditions[columnName])
26
+ count++
27
+ }
28
+
29
+ return sql
30
+ }
31
+ }
@@ -1,8 +1,4 @@
1
1
  export default class VelociousDatabaseHandler {
2
- constructor() {
3
- console.log("stub")
4
- }
5
-
6
2
  clone() {
7
3
  const newHandler = new VelociousDatabaseHandler()
8
4
 
@@ -0,0 +1,53 @@
1
+ import Configuration from "../configuration.mjs"
2
+ import * as inflection from "inflection"
3
+
4
+ export default class VelociousDatabaseMigrateFromRequireContext {
5
+ constructor(configuration) {
6
+ this.configuration = configuration || Configuration.current()
7
+ }
8
+
9
+ async execute(requireContext) {
10
+ const files = requireContext.keys()
11
+ .map((file) => {
12
+ const match = file.match(/^\.\/(\d{14})-(.+)\.mjs$/)
13
+
14
+ if (!match) return null
15
+
16
+ const date = parseInt(match[1])
17
+ const migrationName = match[2]
18
+ const migrationClassName = inflection.camelize(migrationName)
19
+
20
+ return {
21
+ file,
22
+ date,
23
+ migrationClassName
24
+ }
25
+ })
26
+ .filter((migration) => Boolean(migration))
27
+ .sort((migration1, migration2) => migration1.date - migration2.date)
28
+
29
+ for (const migration of files) {
30
+ await this.runMigrationFile(migration, requireContext)
31
+ }
32
+ }
33
+
34
+ async runMigrationFile(migration, requireContext) {
35
+ if (!this.configuration) throw new Error("No configuration set")
36
+ if (!this.configuration.isDatabasePoolInitialized()) await this.configuration.initializeDatabasePool()
37
+
38
+ await this.configuration.getDatabasePool().withConnection(async () => {
39
+ const MigrationClass = requireContext(migration.file).default
40
+ const migrationInstance = new MigrationClass({
41
+ configuration: this.configuration
42
+ })
43
+
44
+ if (migrationInstance.change) {
45
+ await migrationInstance.change()
46
+ } else if (migrationInstance.up) {
47
+ await migrationInstance.up()
48
+ } else {
49
+ throw new Error(`'change' or 'up' didn't exist on migration: ${migration.file}`)
50
+ }
51
+ })
52
+ }
53
+ }
@@ -1,5 +1,18 @@
1
+ import TableData from "../table-data/index.mjs"
2
+
1
3
  export default class VelociousDatabaseMigration {
2
- createTable(tableName, callback) {
3
- throw new Error("stub")
4
+ constructor({configuration}) {
5
+ this.configuration = configuration
6
+ }
7
+
8
+ async createTable(tableName, callback) {
9
+ const tableData = new TableData(tableName)
10
+
11
+ callback(tableData)
12
+
13
+ const databasePool = this.configuration.getDatabasePool()
14
+ const sql = databasePool.createTableSql(tableData)
15
+
16
+ await databasePool.query(sql)
4
17
  }
5
18
  }
@@ -0,0 +1,81 @@
1
+ import {AsyncLocalStorage} from "async_hooks"
2
+ import BasePool from "./base.mjs"
3
+
4
+ let idSeq = 0
5
+
6
+ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends BasePool {
7
+ static current() {
8
+ if (!this.velociousDatabasePoolAsyncTrackedMultiConnection) {
9
+ this.velociousDatabasePoolAsyncTrackedMultiConnection = new VelociousDatabasePoolAsyncTrackedMultiConnection()
10
+ }
11
+
12
+ return this.velociousDatabasePoolAsyncTrackedMultiConnection
13
+ }
14
+
15
+ constructor(args = {}) {
16
+ super(args)
17
+ this.connections = []
18
+ this.connectionsInUse = {}
19
+ this.asyncLocalStorage = new AsyncLocalStorage()
20
+ }
21
+
22
+ checkin = (connection) => {
23
+ const id = connection.getIdSeq()
24
+
25
+ if (id in this.connectionsInUse) {
26
+ delete this.connectionsInUse[id]
27
+ }
28
+
29
+ connection.setIdSeq(undefined)
30
+
31
+ this.connections.push(connection)
32
+ }
33
+
34
+ async checkout() {
35
+ let connection = this.connections.shift()
36
+
37
+ if (!connection) {
38
+ connection = await this.spawnConnection()
39
+ }
40
+
41
+ if (connection.getIdSeq() !== undefined) throw new Error(`Connection already has an ID-seq - is it in use? ${connection.getIdSeq()}`)
42
+
43
+ const id = idSeq++
44
+
45
+ connection.setIdSeq(id)
46
+ this.connectionsInUse[id] = connection
47
+
48
+ return connection
49
+ }
50
+
51
+ setCurrent() {
52
+ this.constructor.velociousDatabasePoolAsyncTrackedMultiConnection = this
53
+ }
54
+
55
+ async withConnection(callback) {
56
+ const connection = await this.checkout()
57
+ const id = connection.getIdSeq()
58
+
59
+ await this.asyncLocalStorage.run(id, async () => {
60
+ try {
61
+ await callback()
62
+ } finally {
63
+ this.checkin(connection)
64
+ }
65
+ })
66
+ }
67
+
68
+ getCurrentConnection() {
69
+ const id = this.asyncLocalStorage.getStore()
70
+
71
+ if (id === undefined) {
72
+ throw new Error("ID hasn't been set for this async context")
73
+ }
74
+
75
+ if (!(id in this.connectionsInUse)) {
76
+ throw new Error(`Connection ${id} doesn't exist any more - has it been checked in again?`)
77
+ }
78
+
79
+ return this.connectionsInUse[id]
80
+ }
81
+ }
@@ -0,0 +1,47 @@
1
+ import Configuration from "../../configuration.mjs"
2
+ import {digg} from "diggerize"
3
+
4
+ class VelociousDatabasePoolBase {
5
+ constructor(args = {}) {
6
+ this.configuration = args.configuration || Configuration.current()
7
+ this.connections = []
8
+ this.connectionsInUse = {}
9
+ }
10
+
11
+ getConfiguration = () => digg(this, "configuration", "database", "default", "master")
12
+
13
+ setDriverClass(driverClass) {
14
+ this.driverClass = driverClass
15
+ }
16
+
17
+ async spawnConnection() {
18
+ const defaultConfig = this.getConfiguration()
19
+ const connection = await this.spawnConnectionWithConfiguration(defaultConfig)
20
+
21
+ return connection
22
+ }
23
+
24
+ async spawnConnectionWithConfiguration(config) {
25
+ const DriverClass = config.driver || this.driverClass
26
+
27
+ if (!DriverClass) throw new Error("No driver class set in database pool or in given config")
28
+
29
+ const connection = new DriverClass(config)
30
+
31
+ await connection.connect()
32
+
33
+ return connection
34
+ }
35
+ }
36
+
37
+ const forwardMethods = ["createTableSql", "deleteSql", "insertSql", "query", "quote", "updateSql"]
38
+
39
+ for (const forwardMethod of forwardMethods) {
40
+ VelociousDatabasePoolBase.prototype[forwardMethod] = function(...args) {
41
+ const connection = this.getCurrentConnection()
42
+
43
+ return connection[forwardMethod](...args)
44
+ }
45
+ }
46
+
47
+ export default VelociousDatabasePoolBase
@@ -0,0 +1,40 @@
1
+ import BasePool from "./base.mjs"
2
+
3
+ export default class VelociousDatabasePoolSingleMultiUser extends BasePool {
4
+ static current() {
5
+ if (!this.velociousDatabasePoolSingleMultiUser) {
6
+ this.velociousDatabasePoolSingleMultiUser = new VelociousDatabasePoolSingleMultiUser()
7
+ }
8
+
9
+ return this.velociousDatabasePoolSingleMultiUser
10
+ }
11
+
12
+ checkin = (connection) => {
13
+ // Do nothing
14
+ }
15
+
16
+ async checkout() {
17
+ if (!this.connection) {
18
+ this.connection = await this.spawnConnection()
19
+ }
20
+
21
+ return this.connection
22
+ }
23
+
24
+ setCurrent() {
25
+ this.constructor.velociousDatabasePoolSingleMultiUser = this
26
+ }
27
+
28
+ async withConnection(callback) {
29
+ await this.checkout() // Ensure a connection is present
30
+ await callback()
31
+ }
32
+
33
+ getCurrentConnection() {
34
+ if (!this.connection) {
35
+ throw new Error("A connection hasn't been made yet")
36
+ }
37
+
38
+ return this.connection
39
+ }
40
+ }
@@ -0,0 +1,11 @@
1
+ export default class VelociousDatabaseQueryBase {
2
+ constructor({driver}) {
3
+ this.driver = driver
4
+ }
5
+
6
+ getOptions = () => this.driver?.options()
7
+
8
+ toSql() {
9
+ throw new Error("'toSql' wasn't implemented")
10
+ }
11
+ }
@@ -0,0 +1,22 @@
1
+ import {digs} from "diggerize"
2
+ import QueryBase from "./base.mjs"
3
+
4
+ export default class VelociousDatabaseQueryCreateDatabaseBase extends QueryBase {
5
+ constructor({driver, databaseName, ifNotExists}) {
6
+ super({driver})
7
+ this.databaseName = databaseName
8
+ this.ifNotExists = ifNotExists
9
+ }
10
+
11
+ toSql() {
12
+ const {databaseName} = this
13
+ const {tableQuote} = digs(this.getOptions(), "tableQuote")
14
+ let sql = "CREATE DATABASE"
15
+
16
+ if (this.ifNotExists) sql += " IF NOT EXISTS"
17
+
18
+ sql += ` ${tableQuote}${databaseName}${tableQuote}`
19
+
20
+ return sql
21
+ }
22
+ }
@@ -0,0 +1,69 @@
1
+ import QueryBase from "./base.mjs"
2
+
3
+ export default class VelociousDatabaseQueryCreateTableBase extends QueryBase {
4
+ constructor({driver, ifNotExists, tableData}) {
5
+ super({driver})
6
+ this.ifNotExists = ifNotExists
7
+ this.tableData = tableData
8
+ }
9
+
10
+ toSql() {
11
+ const {tableData} = this
12
+ let sql = "CREATE TABLE"
13
+
14
+ if (this.ifNotExists || tableData.getIfNotExists()) sql += " IF NOT EXISTS"
15
+
16
+ sql += ` ${tableData.getName()} (`
17
+
18
+ let columnCount = 0
19
+
20
+ for (const column of tableData.getColumns()) {
21
+ columnCount++
22
+
23
+ let maxlength = column.args.maxlength
24
+ let type = column.args.type
25
+
26
+ if (type == "string") {
27
+ type = "varchar"
28
+ maxlength ||= 255
29
+ }
30
+
31
+ if (columnCount > 1) sql += ", "
32
+
33
+ sql += `${this.driver.quoteColumn(column.name)} ${type}`
34
+
35
+ if (maxlength !== undefined) sql += `(${maxlength})`
36
+
37
+ if (column.args.autoIncrement) sql += " AUTO_INCREMENT"
38
+ if (column.args.primaryKey) sql += " PRIMARY KEY"
39
+ }
40
+
41
+ for (const index of tableData.getIndexes()) {
42
+ sql += ","
43
+
44
+ if (index.getUnique()) {
45
+ sql += " UNIQUE"
46
+ }
47
+
48
+ sql += " INDEX"
49
+
50
+ if (index.getName()) {
51
+ sql += ` ${index.getName()}`
52
+ }
53
+
54
+ sql += " ("
55
+
56
+ index.getColumns().forEach((column, columnIndex) => {
57
+ if (columnIndex > 0) sql += ", "
58
+
59
+ sql += this.driver.quoteColumn(column.name)
60
+ })
61
+
62
+ sql += ")"
63
+ }
64
+
65
+ sql += ")"
66
+
67
+ return sql
68
+ }
69
+ }