velocious 1.0.4 → 1.0.6

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/index.mjs +1 -19
  2. package/package.json +6 -3
  3. package/spec/cli/commands/db/create-spec.mjs +1 -1
  4. package/spec/cli/commands/db/migrate-spec.mjs +2 -0
  5. package/spec/database/connection/drivers/mysql/query-parser-spec.mjs +6 -5
  6. package/spec/database/drivers/mysql/connection-spec.mjs +2 -3
  7. package/spec/database/record/create-spec.mjs +9 -0
  8. package/spec/database/record/find-spec.mjs +0 -1
  9. package/spec/database/record/query-spec.mjs +37 -0
  10. package/spec/dummy/index.mjs +14 -2
  11. package/spec/dummy/src/config/configuration.example.mjs +16 -1
  12. package/spec/dummy/src/config/configuration.peakflow.mjs +16 -1
  13. package/spec/dummy/src/database/migrations/20230728075328-create-projects.mjs +0 -1
  14. package/spec/dummy/src/database/migrations/20230728075329-create-tasks.mjs +0 -1
  15. package/spec/dummy/src/database/migrations/20250605133926-create-project-translations.mjs +16 -0
  16. package/spec/dummy/src/models/project.mjs +9 -0
  17. package/spec/dummy/src/models/task.mjs +6 -2
  18. package/src/big-brother.mjs +37 -0
  19. package/src/cli/commands/db/create.mjs +8 -6
  20. package/src/cli/commands/db/migrate.mjs +1 -2
  21. package/src/cli/commands/generate/migration.mjs +1 -1
  22. package/src/cli/commands/generate/model.mjs +1 -1
  23. package/src/configuration.mjs +39 -3
  24. package/src/database/drivers/base.mjs +60 -0
  25. package/src/database/drivers/mysql/column.mjs +8 -0
  26. package/src/database/drivers/mysql/index.mjs +34 -2
  27. package/src/database/drivers/mysql/options.mjs +1 -0
  28. package/src/database/drivers/mysql/query-parser.mjs +2 -23
  29. package/src/database/drivers/mysql/table.mjs +25 -0
  30. package/src/database/drivers/sqlite/base.mjs +108 -0
  31. package/src/database/drivers/sqlite/column.mjs +10 -0
  32. package/src/database/drivers/sqlite/index.native.mjs +22 -63
  33. package/src/database/drivers/sqlite/index.web.mjs +28 -37
  34. package/src/database/drivers/sqlite/options.mjs +2 -1
  35. package/src/database/drivers/sqlite/query-parser.mjs +2 -23
  36. package/src/database/drivers/sqlite/query.native.mjs +16 -1
  37. package/src/database/drivers/sqlite/query.web.mjs +27 -2
  38. package/src/database/drivers/sqlite/sql/create-index.mjs +4 -0
  39. package/src/database/drivers/sqlite/table.mjs +24 -0
  40. package/src/database/initializer-from-require-context.mjs +21 -0
  41. package/src/database/migrate-from-require-context.mjs +11 -2
  42. package/src/database/migration/index.mjs +34 -2
  43. package/src/database/migrator.mjs +75 -0
  44. package/src/database/pool/async-tracked-multi-connection.mjs +1 -1
  45. package/src/database/pool/base.mjs +19 -1
  46. package/src/database/pool/single-multi-use.mjs +1 -1
  47. package/src/database/query/base.mjs +2 -1
  48. package/src/database/query/create-index-base.mjs +50 -0
  49. package/src/database/query/create-table-base.mjs +40 -17
  50. package/src/database/query/index.mjs +83 -21
  51. package/src/database/query/insert-base.mjs +4 -0
  52. package/src/database/query/preloader/belongs-to.mjs +52 -0
  53. package/src/database/query/preloader/has-many.mjs +55 -0
  54. package/src/database/query/preloader.mjs +41 -0
  55. package/src/database/query/where-base.mjs +9 -0
  56. package/src/database/query/where-hash.mjs +35 -0
  57. package/src/database/query/where-plain.mjs +13 -0
  58. package/src/database/query-parser/base-query-parser.mjs +33 -0
  59. package/src/database/query-parser/group-parser.mjs +40 -0
  60. package/src/database/query-parser/joins-parser.mjs +48 -7
  61. package/src/database/query-parser/limit-parser.mjs +40 -0
  62. package/src/database/query-parser/options.mjs +4 -3
  63. package/src/database/query-parser/order-parser.mjs +39 -0
  64. package/src/database/query-parser/select-parser.mjs +5 -1
  65. package/src/database/query-parser/where-parser.mjs +39 -0
  66. package/src/database/record/index.mjs +464 -29
  67. package/src/database/record/instance-relationships/base.mjs +28 -0
  68. package/src/database/record/instance-relationships/belongs-to.mjs +20 -0
  69. package/src/database/record/instance-relationships/has-many.mjs +47 -0
  70. package/src/database/record/relationships/base.mjs +32 -0
  71. package/src/database/record/relationships/belongs-to.mjs +12 -0
  72. package/src/database/record/relationships/has-many.mjs +12 -0
  73. package/src/database/table-data/index.mjs +15 -25
  74. package/src/http-server/worker-handler/worker-thread.mjs +7 -4
  75. package/src/templates/generate-model.mjs +3 -1
  76. package/src/utils/rest-args-error.mjs +9 -0
  77. package/src/database/drivers/index.mjs +0 -5
  78. package/src/database/index.mjs +0 -15
  79. package/src/database/migrator/index.mjs +0 -15
@@ -0,0 +1,33 @@
1
+ import {digs} from "diggerize"
2
+ import FromParser from "./from-parser.mjs"
3
+ import GroupParser from "./group-parser.mjs"
4
+ import JoinsParser from "./joins-parser.mjs"
5
+ import LimitParser from "./limit-parser.mjs"
6
+ import OrderParser from "./order-parser.mjs"
7
+ import SelectParser from "./select-parser.mjs"
8
+ import WhereParser from "./where-parser.mjs"
9
+
10
+ export default class VelociousDatabaseBaseQueryParser {
11
+ constructor({pretty, query}) {
12
+ if (!query) throw new Error("No query given")
13
+
14
+ this.pretty = pretty
15
+ this.query = query
16
+ }
17
+
18
+ toSql() {
19
+ const {pretty, query} = digs(this, "pretty", "query")
20
+
21
+ let sql = ""
22
+
23
+ sql += new SelectParser({pretty, query}).toSql()
24
+ sql += new FromParser({pretty, query}).toSql()
25
+ sql += new JoinsParser({pretty, query}).toSql()
26
+ sql += new WhereParser({pretty, query}).toSql()
27
+ sql += new GroupParser({pretty, query}).toSql()
28
+ sql += new OrderParser({pretty, query}).toSql()
29
+ sql += new LimitParser({pretty, query}).toSql()
30
+
31
+ return sql
32
+ }
33
+ }
@@ -0,0 +1,40 @@
1
+ import {digs} from "diggerize"
2
+
3
+ export default class VelociousDatabaseQueryParserFromParser {
4
+ constructor({pretty, query}) {
5
+ this.pretty = pretty
6
+ this.query = query
7
+ }
8
+
9
+ toSql() {
10
+ const {pretty, query} = digs(this, "pretty", "query")
11
+
12
+ if (query._groups.length == 0) {
13
+ return ""
14
+ }
15
+
16
+ let sql = " GROUP BY"
17
+
18
+ for (const groupKey in query._groups) {
19
+ const group = query._groups[groupKey]
20
+
21
+ if (groupKey > 0) {
22
+ sql += ","
23
+ }
24
+
25
+ if (pretty) {
26
+ sql += "\n "
27
+ } else {
28
+ sql += " "
29
+ }
30
+
31
+ if (typeof group == "string") {
32
+ sql += group
33
+ } else {
34
+ sql += group.toSql()
35
+ }
36
+ }
37
+
38
+ return sql
39
+ }
40
+ }
@@ -1,28 +1,69 @@
1
1
  import {digs} from "diggerize"
2
+ import JoinPlain from "../query/join-plain.mjs"
2
3
 
3
4
  export default class VelocuiousDatabaseQueryParserJoinsParser {
4
5
  constructor({pretty, query}) {
5
6
  this.pretty = pretty
6
7
  this.query = query
8
+ this.conn = this.query.driver
7
9
  }
8
10
 
9
11
  toSql() {
10
12
  const {pretty, query} = digs(this, "pretty", "query")
11
-
12
13
  let sql = ""
13
14
 
14
15
  for (const joinKey in query._joins) {
15
16
  const join = query._joins[joinKey]
16
17
 
17
- if (joinKey == 0) {
18
- if (pretty) {
19
- sql += "\n\n"
20
- } else {
21
- sql += " "
18
+ if (join instanceof JoinPlain) {
19
+ if (joinKey == 0) {
20
+ if (pretty) {
21
+ sql += "\n\n"
22
+ } else {
23
+ sql += " "
24
+ }
22
25
  }
26
+
27
+ sql += join.toSql()
28
+ } else if (typeof join == "object") {
29
+ sql = this.joinObject({join, modelClass: query.modelClass, sql})
30
+ } else {
31
+ throw new Error(`Unknown join object: ${join.constructor.name}`)
32
+ }
33
+ }
34
+
35
+ return sql
36
+ }
37
+
38
+ joinObject({join, modelClass, sql}) {
39
+ const {conn, pretty} = this
40
+
41
+ for (const joinKey in join) {
42
+ const joinValue = join[joinKey]
43
+ const relationship = modelClass.getRelationshipByName(joinKey)
44
+ const targetModelClass = relationship.getTargetModelClass()
45
+
46
+ if (pretty) {
47
+ sql += "\n\n"
48
+ } else {
49
+ sql += " "
23
50
  }
24
51
 
25
- sql += join.toSql()
52
+ sql += `LEFT JOIN ${conn.quoteTable(targetModelClass.tableName())} ON `
53
+
54
+ if (relationship.getType() == "belongsTo") {
55
+ sql += `${conn.quoteTable(targetModelClass.tableName())}.${conn.quoteColumn(relationship.getPrimaryKey())} = `
56
+ sql += `${conn.quoteTable(modelClass.tableName())}.${conn.quoteColumn(relationship.getForeignKey())}`
57
+ } else if (relationship.getType() == "hasMany" || relationship.getType() == "hasOne") {
58
+ sql += `${conn.quoteTable(targetModelClass.tableName())}.${conn.quoteColumn(relationship.getForeignKey())} = `
59
+ sql += `${conn.quoteTable(modelClass.tableName())}.${conn.quoteColumn(relationship.getPrimaryKey())}`
60
+ } else {
61
+ throw new Error(`Unknown relationship type: ${relationship.getType()}`)
62
+ }
63
+
64
+ if (typeof joinValue == "object") {
65
+ sql = this.joinObject({join: joinValue, modelClass: targetModelClass, sql})
66
+ }
26
67
  }
27
68
 
28
69
  return sql
@@ -0,0 +1,40 @@
1
+ import {digs} from "diggerize"
2
+
3
+ export default class VelocuiousDatabaseQueryParserLimitParser {
4
+ constructor({pretty, query}) {
5
+ this.pretty = pretty
6
+ this.query = query
7
+ }
8
+
9
+ toSql() {
10
+ const {pretty, query} = digs(this, "pretty", "query")
11
+ let sql = ""
12
+
13
+ if (query._limits.length == 0) return sql
14
+ if (query._limits.length >= 2) throw new Error(`Multiple limits found: ${query._limits.join(", ")}`)
15
+
16
+ if (pretty) {
17
+ sql += "\n\n"
18
+ } else {
19
+ sql += " "
20
+ }
21
+
22
+ sql += "LIMIT"
23
+
24
+ for (const limitKey in query._limits) {
25
+ const limit = query._limits[limitKey]
26
+
27
+ if (limitKey > 0) sql += ","
28
+
29
+ if (pretty) {
30
+ sql += "\n "
31
+ } else {
32
+ sql += " "
33
+ }
34
+
35
+ sql += this.query.getOptions().quote(limit)
36
+ }
37
+
38
+ return sql
39
+ }
40
+ }
@@ -3,21 +3,22 @@ import {digg} from "diggerize"
3
3
  export default class VelociousDatabaseQueryParserOptions {
4
4
  constructor(options) {
5
5
  this.columnQuote = digg(options, "columnQuote")
6
+ this.indexQuote = digg(options, "indexQuote")
6
7
  this.driver = digg(options, "driver")
7
8
  this.tableQuote = digg(options, "tableQuote")
8
9
  this.stringQuote = digg(options, "stringQuote")
9
10
 
10
- if (!this.driver) throw new Error("No driver given")
11
+ if (!this.driver) throw new Error("No driver given to parser options")
11
12
  }
12
13
 
13
14
  quoteColumnName(columnName) {
14
- if (columnName.includes(this.columnQuote)) throw new Error(`Invalid column name: ${columnName}`)
15
+ if (!columnName || columnName.includes(this.columnQuote)) throw new Error(`Invalid column name: ${columnName}`)
15
16
 
16
17
  return `${this.columnQuote}${columnName}${this.columnQuote}`
17
18
  }
18
19
 
19
20
  quoteTableName(tableName) {
20
- if (tableName.includes(this.tableQuote)) throw new Error(`Invalid table name: ${tableName}`)
21
+ if (!tableName || tableName.includes(this.tableQuote)) throw new Error(`Invalid table name: ${tableName}`)
21
22
 
22
23
  return `${this.tableQuote}${tableName}${this.tableQuote}`
23
24
  }
@@ -0,0 +1,39 @@
1
+ import {digs} from "diggerize"
2
+
3
+ export default class VelocuiousDatabaseQueryParserOrderParser {
4
+ constructor({pretty, query}) {
5
+ this.pretty = pretty
6
+ this.query = query
7
+ }
8
+
9
+ toSql() {
10
+ const {pretty, query} = digs(this, "pretty", "query")
11
+ let sql = ""
12
+
13
+ if (query._orders.length == 0) return sql
14
+
15
+ if (pretty) {
16
+ sql += "\n\n"
17
+ } else {
18
+ sql += " "
19
+ }
20
+
21
+ sql += "ORDER BY"
22
+
23
+ for (const orderKey in query._orders) {
24
+ const order = query._orders[orderKey]
25
+
26
+ if (orderKey > 0) sql += " ,"
27
+
28
+ if (pretty) {
29
+ sql += "\n "
30
+ } else {
31
+ sql += " "
32
+ }
33
+
34
+ sql += order.toSql()
35
+ }
36
+
37
+ return sql
38
+ }
39
+ }
@@ -35,7 +35,11 @@ export default class VelociousDatabaseQueryParserSelectParser {
35
35
  }
36
36
 
37
37
  if (query._selects.length == 0) {
38
- sql += "*"
38
+ if (query.modelClass) {
39
+ sql += `${query.modelClass.connection().quoteTable(query.modelClass.tableName())}.*`
40
+ } else {
41
+ sql += "*"
42
+ }
39
43
  }
40
44
 
41
45
  return sql
@@ -0,0 +1,39 @@
1
+ import {digs} from "diggerize"
2
+
3
+ export default class VelocuiousDatabaseQueryParserWhereParser {
4
+ constructor({pretty, query}) {
5
+ this.pretty = pretty
6
+ this.query = query
7
+ }
8
+
9
+ toSql() {
10
+ const {pretty, query} = digs(this, "pretty", "query")
11
+ let sql = ""
12
+
13
+ if (query._wheres.length == 0) return sql
14
+
15
+ if (pretty) {
16
+ sql += "\n\n"
17
+ } else {
18
+ sql += " "
19
+ }
20
+
21
+ sql += "WHERE"
22
+
23
+ for (const whereKey in query._wheres) {
24
+ const where = query._wheres[whereKey]
25
+
26
+ if (whereKey > 0) sql += " &&"
27
+
28
+ if (pretty) {
29
+ sql += "\n "
30
+ } else {
31
+ sql += " "
32
+ }
33
+
34
+ sql += where.toSql()
35
+ }
36
+
37
+ return sql
38
+ }
39
+ }