velocious 1.0.5 → 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 (69) hide show
  1. package/package.json +5 -3
  2. package/spec/cli/commands/db/create-spec.mjs +1 -1
  3. package/spec/cli/commands/db/migrate-spec.mjs +2 -0
  4. package/spec/database/record/create-spec.mjs +9 -0
  5. package/spec/database/record/find-spec.mjs +0 -1
  6. package/spec/database/record/query-spec.mjs +37 -0
  7. package/spec/dummy/index.mjs +14 -2
  8. package/spec/dummy/src/config/configuration.example.mjs +16 -1
  9. package/spec/dummy/src/config/configuration.peakflow.mjs +16 -1
  10. package/spec/dummy/src/database/migrations/20230728075328-create-projects.mjs +0 -1
  11. package/spec/dummy/src/database/migrations/20230728075329-create-tasks.mjs +0 -1
  12. package/spec/dummy/src/database/migrations/20250605133926-create-project-translations.mjs +16 -0
  13. package/spec/dummy/src/models/project.mjs +9 -0
  14. package/spec/dummy/src/models/task.mjs +5 -1
  15. package/src/big-brother.mjs +37 -0
  16. package/src/cli/commands/db/create.mjs +8 -6
  17. package/src/cli/commands/db/migrate.mjs +1 -2
  18. package/src/cli/commands/generate/migration.mjs +1 -1
  19. package/src/cli/commands/generate/model.mjs +1 -1
  20. package/src/configuration.mjs +39 -3
  21. package/src/database/drivers/base.mjs +21 -2
  22. package/src/database/drivers/mysql/column.mjs +8 -0
  23. package/src/database/drivers/mysql/index.mjs +34 -2
  24. package/src/database/drivers/mysql/options.mjs +1 -0
  25. package/src/database/drivers/mysql/query-parser.mjs +2 -23
  26. package/src/database/drivers/mysql/table.mjs +25 -0
  27. package/src/database/drivers/sqlite/base.mjs +76 -4
  28. package/src/database/drivers/sqlite/column.mjs +10 -0
  29. package/src/database/drivers/sqlite/index.native.mjs +19 -22
  30. package/src/database/drivers/sqlite/index.web.mjs +27 -17
  31. package/src/database/drivers/sqlite/options.mjs +2 -1
  32. package/src/database/drivers/sqlite/query-parser.mjs +2 -23
  33. package/src/database/drivers/sqlite/query.native.mjs +16 -1
  34. package/src/database/drivers/sqlite/query.web.mjs +27 -2
  35. package/src/database/drivers/sqlite/sql/create-index.mjs +4 -0
  36. package/src/database/drivers/sqlite/table.mjs +16 -1
  37. package/src/database/initializer-from-require-context.mjs +21 -0
  38. package/src/database/migration/index.mjs +34 -2
  39. package/src/database/migrator.mjs +4 -2
  40. package/src/database/pool/base.mjs +5 -0
  41. package/src/database/query/base.mjs +2 -1
  42. package/src/database/query/create-index-base.mjs +50 -0
  43. package/src/database/query/create-table-base.mjs +40 -17
  44. package/src/database/query/index.mjs +83 -21
  45. package/src/database/query/preloader/belongs-to.mjs +52 -0
  46. package/src/database/query/preloader/has-many.mjs +55 -0
  47. package/src/database/query/preloader.mjs +41 -0
  48. package/src/database/query/where-base.mjs +9 -0
  49. package/src/database/query/where-hash.mjs +35 -0
  50. package/src/database/query/where-plain.mjs +13 -0
  51. package/src/database/query-parser/base-query-parser.mjs +33 -0
  52. package/src/database/query-parser/group-parser.mjs +40 -0
  53. package/src/database/query-parser/joins-parser.mjs +48 -7
  54. package/src/database/query-parser/limit-parser.mjs +40 -0
  55. package/src/database/query-parser/options.mjs +2 -1
  56. package/src/database/query-parser/order-parser.mjs +39 -0
  57. package/src/database/query-parser/select-parser.mjs +5 -1
  58. package/src/database/query-parser/where-parser.mjs +39 -0
  59. package/src/database/record/index.mjs +464 -29
  60. package/src/database/record/instance-relationships/base.mjs +28 -0
  61. package/src/database/record/instance-relationships/belongs-to.mjs +20 -0
  62. package/src/database/record/instance-relationships/has-many.mjs +47 -0
  63. package/src/database/record/relationships/base.mjs +32 -0
  64. package/src/database/record/relationships/belongs-to.mjs +12 -0
  65. package/src/database/record/relationships/has-many.mjs +12 -0
  66. package/src/database/table-data/index.mjs +15 -25
  67. package/src/http-server/worker-handler/worker-thread.mjs +7 -4
  68. package/src/templates/generate-model.mjs +3 -1
  69. package/src/utils/rest-args-error.mjs +9 -0
@@ -1,20 +1,27 @@
1
1
  import FromPlain from "./from-plain.mjs"
2
+ import {incorporate} from "incorporator"
3
+ import * as inflection from "inflection"
2
4
  import JoinPlain from "./join-plain.mjs"
3
5
  import OrderPlain from "./order-plain.mjs"
6
+ import Preloader from "./preloader.mjs"
4
7
  import SelectPlain from "./select-plain.mjs"
8
+ import WhereHash from "./where-hash.mjs"
9
+ import WherePlain from "./where-plain.mjs"
5
10
 
6
11
  export default class VelociousDatabaseQuery {
7
- constructor({driver, froms = [], joins = [], handler, limits = [], modelClass, orders = [], selects = [], wheres = []}) {
8
- if (!driver) throw new Error("No driver given")
9
- if (!handler) throw new Error("No handler given")
12
+ constructor({driver, froms = [], groups = [], joins = [], handler, limits = [], modelClass, orders = [], preload = {}, selects = [], wheres = []}) {
13
+ if (!driver) throw new Error("No driver given to query")
14
+ if (!handler) throw new Error("No handler given to query")
10
15
 
11
16
  this.driver = driver
12
17
  this.handler = handler
13
18
  this.modelClass = modelClass
14
19
  this._froms = froms
20
+ this._groups = groups
15
21
  this._joins = joins
16
22
  this._limits = limits
17
23
  this._orders = orders
24
+ this._preload = preload
18
25
  this._selects = selects
19
26
  this._wheres = wheres
20
27
  }
@@ -24,10 +31,12 @@ export default class VelociousDatabaseQuery {
24
31
  driver: this.driver,
25
32
  froms: [...this._froms],
26
33
  handler: this.handler.clone(),
34
+ groups: [...this._groups],
27
35
  joins: [...this._joins],
28
36
  limits: [...this._limits],
29
37
  modelClass: this.modelClass,
30
38
  orders: [...this._orders],
39
+ preload: {...this._preload},
31
40
  selects: [...this._selects],
32
41
  wheres: [...this._wheres]
33
42
  })
@@ -35,8 +44,38 @@ export default class VelociousDatabaseQuery {
35
44
  return newQuery
36
45
  }
37
46
 
38
- getOptions() {
39
- return this.driver.options()
47
+ getOptions = () => this.driver.options()
48
+
49
+ async findBy(conditions) {
50
+ const newConditions = {}
51
+
52
+ for (const key in conditions) {
53
+ const keyUnderscore = inflection.underscore(key)
54
+
55
+ newConditions[keyUnderscore] = conditions[key]
56
+ }
57
+
58
+ return await this.clone().where(newConditions).first()
59
+ }
60
+
61
+ async findOrCreateBy(conditions) {
62
+ const record = await this.findOrInitializeBy(conditions)
63
+
64
+ if (record.isNewRecord()) {
65
+ await record.save()
66
+ }
67
+
68
+ return record
69
+ }
70
+
71
+ async findOrInitializeBy(conditions) {
72
+ const record = await this.findBy(conditions)
73
+
74
+ if (record) return record
75
+
76
+ const newRecord = new this.modelClass(conditions)
77
+
78
+ return newRecord
40
79
  }
41
80
 
42
81
  async first() {
@@ -55,24 +94,31 @@ export default class VelociousDatabaseQuery {
55
94
  return this
56
95
  }
57
96
 
58
- async last() {
59
- return await this.clone().reverseOrder().first()
60
- }
61
-
62
- limit(value) {
63
- this._limits.push(value)
97
+ group(group) {
98
+ this._groups.push(group)
64
99
  return this
65
100
  }
66
101
 
67
102
  joins(join) {
68
- if (typeof join == "string") join = new JoinPlain({plain: join, query: this})
69
-
70
- join.query = this
103
+ if (typeof join == "string") {
104
+ join = new JoinPlain({plain: join, query: this})
105
+ } else if (typeof join == "object") {
106
+ // Do nothing
107
+ } else {
108
+ throw new Error(`Unknown type of join: ${typeof join}`)
109
+ }
71
110
 
72
111
  this._joins.push(join)
73
112
  return this
74
113
  }
75
114
 
115
+ last = async () => await this.clone().reverseOrder().first()
116
+
117
+ limit(value) {
118
+ this._limits.push(value)
119
+ return this
120
+ }
121
+
76
122
  order(order) {
77
123
  if (typeof order == "number" || typeof order == "string") order = new OrderPlain({plain: order, query: this})
78
124
 
@@ -82,6 +128,11 @@ export default class VelociousDatabaseQuery {
82
128
  return this
83
129
  }
84
130
 
131
+ preload(data) {
132
+ incorporate(this._preload, data)
133
+ return this
134
+ }
135
+
85
136
  reorder(order) {
86
137
  this._orders = []
87
138
  this.order(order)
@@ -119,23 +170,34 @@ export default class VelociousDatabaseQuery {
119
170
  const models = []
120
171
 
121
172
  for (const result of results) {
122
- const model = new this.modelClass(result)
173
+ const model = new this.modelClass()
123
174
 
175
+ model.loadExistingRecord(result)
124
176
  models.push(model)
125
177
  }
126
178
 
179
+ if (Object.keys(this._preload).length > 0 && models.length > 0) {
180
+ const preloader = new Preloader({
181
+ modelClass: this.modelClass,
182
+ models,
183
+ preload: this._preload
184
+ })
185
+
186
+ await preloader.run()
187
+ }
188
+
127
189
  return models
128
190
  }
129
191
 
130
- toSql() {
131
- return this.driver.queryToSql(this)
132
- }
192
+ toSql = () => this.driver.queryToSql(this)
133
193
 
134
194
  where(where) {
135
195
  if (typeof where == "string") {
136
- where = new WherePlain({plain: where})
137
- } else if (typeof where == "object" && where.constructor.name == "object") {
138
- where = new WhereHash({hash: where})
196
+ where = new WherePlain(this, where)
197
+ } else if (typeof where == "object" && (where.constructor.name == "object" || where.constructor.name == "Object")) {
198
+ where = new WhereHash(this, where)
199
+ } else {
200
+ throw new Error(`Invalid type of where: ${typeof where} (${where.constructor.name})`)
139
201
  }
140
202
 
141
203
  this._wheres.push(where)
@@ -0,0 +1,52 @@
1
+ import * as inflection from "inflection"
2
+ import restArgsError from "../../../utils/rest-args-error.mjs"
3
+
4
+ export default class VelociousDatabaseQueryPreloaderBelongsTo {
5
+ constructor({models, relationship, ...restArgs}) {
6
+ restArgsError(restArgs)
7
+
8
+ this.models = models
9
+ this.relationship = relationship
10
+ }
11
+
12
+ async run() {
13
+ const foreignKeyValues = []
14
+ const modelsById = {}
15
+ const foreignKey = this.relationship.getForeignKey()
16
+ const foreignKeyCamelized = inflection.camelize(foreignKey, true)
17
+ const preloadCollections = {}
18
+
19
+ for (const model of this.models) {
20
+ const foreignKeyValue = model[foreignKeyCamelized]()
21
+
22
+ preloadCollections[model.id()] = []
23
+ foreignKeyValues.push(foreignKeyValue)
24
+ modelsById[model.id()] = model
25
+ }
26
+
27
+ const whereArgs = {}
28
+ const primaryKey = this.relationship.getPrimaryKey()
29
+
30
+ whereArgs[primaryKey] = foreignKeyValues
31
+
32
+ // Load target models to be preloaded on the given models
33
+ const targetModels = await this.relationship.getTargetModelClass().where(whereArgs).toArray()
34
+ const targetModelsById = {}
35
+
36
+ for (const targetModel of targetModels) {
37
+ targetModelsById[targetModel.id()] = targetModel
38
+ }
39
+
40
+ // Set the target preloaded models on the given models
41
+ for (const model of this.models) {
42
+ const foreignKeyValue = model[foreignKeyCamelized]()
43
+ const targetModel = targetModelsById[foreignKeyValue]
44
+ const modelRelationship = model.getRelationshipByName(this.relationship.getRelationshipName())
45
+
46
+ modelRelationship.setPreloaded(true)
47
+ modelRelationship.setLoaded(targetModel)
48
+ }
49
+
50
+ return targetModels
51
+ }
52
+ }
@@ -0,0 +1,55 @@
1
+ import * as inflection from "inflection"
2
+ import restArgsError from "../../../utils/rest-args-error.mjs"
3
+
4
+ export default class VelociousDatabaseQueryPreloaderHasMany {
5
+ constructor({models, relationship, ...restArgs}) {
6
+ restArgsError(restArgs)
7
+
8
+ this.models = models
9
+ this.relationship = relationship
10
+ }
11
+
12
+ async run() {
13
+ const modelIds = []
14
+ const modelsById = {}
15
+ const foreignKey = this.relationship.getForeignKey()
16
+ const foreignKeyCamelized = inflection.camelize(foreignKey, true)
17
+ const preloadCollections = {}
18
+
19
+ for (const model of this.models) {
20
+ preloadCollections[model.id()] = []
21
+ modelIds.push(model.id())
22
+
23
+ if (!(model.id in modelsById)) modelsById[model.id()] = []
24
+
25
+ modelsById[model.id()].push(model)
26
+ }
27
+
28
+ const whereArgs = {}
29
+
30
+ whereArgs[foreignKey] = modelIds
31
+
32
+ // Load target models to be preloaded on the given models
33
+ const targetModels = await this.relationship.getTargetModelClass().where(whereArgs).toArray()
34
+
35
+ for (const targetModel of targetModels) {
36
+ const foreignKeyValue = targetModel[foreignKeyCamelized]()
37
+
38
+ preloadCollections[foreignKeyValue].push(targetModel)
39
+ }
40
+
41
+ // Set the target preloaded models on the given models
42
+ for (const modelId in preloadCollections) {
43
+ const preloadedCollection = preloadCollections[modelId]
44
+
45
+ for (const model of modelsById[modelId]) {
46
+ const modelRelationship = model.getRelationshipByName(this.relationship.getRelationshipName())
47
+
48
+ modelRelationship.setPreloaded(true)
49
+ modelRelationship.addToLoaded(preloadedCollection)
50
+ }
51
+ }
52
+
53
+ return targetModels
54
+ }
55
+ }
@@ -0,0 +1,41 @@
1
+ import BelongsToPreloader from "./preloader/belongs-to.mjs"
2
+ import HasManyPreloader from "./preloader/has-many.mjs"
3
+ import restArgsError from "../../utils/rest-args-error.mjs"
4
+
5
+ export default class VelociousDatabaseQueryPreloader {
6
+ constructor({modelClass, models, preload, ...restArgs}) {
7
+ restArgsError(restArgs)
8
+
9
+ this.modelClass = modelClass
10
+ this.models = models
11
+ this.preload = preload
12
+ }
13
+
14
+ async run() {
15
+ for (const preloadRelationshipName in this.preload) {
16
+ const relationship = this.modelClass.getRelationshipByName(preloadRelationshipName)
17
+ let targetModels
18
+
19
+ if (relationship.getType() == "belongsTo") {
20
+ const hasManyPreloader = new BelongsToPreloader({models: this.models, relationship: relationship})
21
+
22
+ targetModels = await hasManyPreloader.run()
23
+ } else if (relationship.getType() == "hasMany") {
24
+ const hasManyPreloader = new HasManyPreloader({models: this.models, relationship: relationship})
25
+
26
+ targetModels = await hasManyPreloader.run()
27
+ } else {
28
+ throw new Error(`Unknown relationship type: ${relationship.getType()}`)
29
+ }
30
+
31
+ // Handle any further preloads in the tree
32
+ const newPreload = this.preload[preloadRelationshipName]
33
+
34
+ if (typeof newPreload == "object" && targetModels.length > 0) {
35
+ const preloader = new VelociousDatabaseQueryPreloader({modelClass: relationship.getTargetModelClass(), models: targetModels, preload: newPreload})
36
+
37
+ await preloader.run()
38
+ }
39
+ }
40
+ }
41
+ }
@@ -0,0 +1,9 @@
1
+ export default class VelociousDatabaseQueryWhereBase {
2
+ getOptions() {
3
+ return this.query.getOptions()
4
+ }
5
+
6
+ toSql() {
7
+ throw new Error("'toSql' wasn't implemented")
8
+ }
9
+ }
@@ -0,0 +1,35 @@
1
+ import WhereBase from "./where-base.mjs"
2
+
3
+ export default class VelociousDatabaseQueryWhereHash extends WhereBase {
4
+ constructor(query, hash) {
5
+ super()
6
+ this.hash = hash
7
+ this.query = query
8
+ }
9
+
10
+ toSql() {
11
+ const options = this.getOptions()
12
+ let sql = "("
13
+ let index = 0
14
+
15
+ for (const whereKey in this.hash) {
16
+ const whereValue = this.hash[whereKey]
17
+
18
+ if (index > 0) sql += " AND "
19
+
20
+ sql += `${options.quoteColumnName(whereKey)}`
21
+
22
+ if (Array.isArray(whereValue)) {
23
+ sql += ` IN (${whereValue.map((value) => options.quote(value)).join(", ")})`
24
+ } else {
25
+ sql += ` = ${options.quote(whereValue)}`
26
+ }
27
+
28
+ index++
29
+ }
30
+
31
+ sql += ")"
32
+
33
+ return sql
34
+ }
35
+ }
@@ -0,0 +1,13 @@
1
+ import WhereBase from "./where-base.mjs"
2
+
3
+ export default class VelociousDatabaseQueryWhereHash extends WhereBase {
4
+ constructor(query, plain) {
5
+ super()
6
+ this.plain = plain
7
+ this.query = query
8
+ }
9
+
10
+ toSql() {
11
+ return this.plain
12
+ }
13
+ }
@@ -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,11 +3,12 @@ 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) {
@@ -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
+ }