velocious 1.0.78 → 1.0.80

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.
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "velocious": "bin/velocious.js"
4
4
  },
5
5
  "name": "velocious",
6
- "version": "1.0.78",
6
+ "version": "1.0.80",
7
7
  "main": "index.js",
8
8
  "scripts": {
9
9
  "test": "VELOCIOUS_TEST_DIR=../ cd spec/dummy && npx velocious test",
@@ -40,7 +40,7 @@
40
40
  "strftime": "^0.10.2"
41
41
  },
42
42
  "devDependencies": {
43
- "mssql": "^11.0.1",
43
+ "mssql": "^12.0.0",
44
44
  "mysql": "^2.18.1",
45
45
  "node-fetch": "^3.3.1",
46
46
  "pg": "^8.16.3",
@@ -0,0 +1,29 @@
1
+ import Dummy from "../../dummy/index.js"
2
+ import Project from "../../dummy/src/models/project.js"
3
+ import Task from "../../dummy/src/models/task.js"
4
+
5
+ describe("Record - last", () => {
6
+ it("finds the last record", async () => {
7
+ await Dummy.run(async () => {
8
+ const project1 = await Project.create()
9
+
10
+ await Task.create({name: "Test task 1", project: project1})
11
+ await Task.create({name: "Test task 2", project: project1})
12
+ await Task.create({name: "Test task 3", project: project1})
13
+
14
+ const project2 = await Project.create()
15
+
16
+ await Task.create({name: "Test task 4", project: project2})
17
+ await Task.create({name: "Test task 5", project: project2})
18
+ await Task.create({name: "Test task 6", project: project2})
19
+
20
+ const foundTask = await Task.last()
21
+
22
+ expect(foundTask.name()).toEqual("Test task 6")
23
+
24
+ const foundTaskWithFilter = await Task.where({project_id: project1.id()}).last()
25
+
26
+ expect(foundTaskWithFilter.name()).toEqual("Test task 3")
27
+ })
28
+ })
29
+ })
@@ -174,7 +174,7 @@ export default class VelociousDatabaseQuery {
174
174
  }
175
175
 
176
176
  async first() {
177
- const newQuery = this.clone().limit(1).reorder(this.modelClass.orderableColumn())
177
+ const newQuery = this.clone().limit(1).reorder(`${this.driver.quoteTable(this.modelClass.tableName())}.${this.driver.quoteColumn(this.modelClass.orderableColumn())}`)
178
178
  const results = await newQuery.toArray()
179
179
 
180
180
  return results[0]
@@ -16,19 +16,18 @@ export default class VelociousDatabaseQueryWhereHash extends WhereBase {
16
16
  return sql
17
17
  }
18
18
 
19
- _whereSQLFromHash(hash, tableName) {
19
+ _whereSQLFromHash(hash, tableName, index = 0) {
20
20
  const options = this.getOptions()
21
21
  let sql = ""
22
- let index = 0
23
22
 
24
23
  for (const whereKey in hash) {
25
24
  const whereValue = hash[whereKey]
26
25
 
27
- if (index > 0) sql += " AND "
28
-
29
- if (!Array.isArray(whereValue) && typeof whereValue == "object") {
30
- sql += this._whereSQLFromHash(whereValue, whereKey)
26
+ if (!Array.isArray(whereValue) && whereValue !== null && typeof whereValue == "object") {
27
+ sql += this._whereSQLFromHash(whereValue, whereKey, index)
31
28
  } else {
29
+ if (index > 0) sql += " AND "
30
+
32
31
  if (tableName) {
33
32
  sql += `${options.quoteTableName(tableName)}.`
34
33
  }
@@ -37,6 +36,8 @@ export default class VelociousDatabaseQueryWhereHash extends WhereBase {
37
36
 
38
37
  if (Array.isArray(whereValue)) {
39
38
  sql += ` IN (${whereValue.map((value) => options.quote(value)).join(", ")})`
39
+ } else if (whereValue === null) {
40
+ sql += " IS NULL"
40
41
  } else {
41
42
  sql += ` = ${options.quote(whereValue)}`
42
43
  }
@@ -290,15 +290,7 @@ class VelociousDatabaseRecord {
290
290
  this.prototype[`has${camelizedColumnNameBigFirst}`] = function() {
291
291
  let value = this[camelizedColumnName]()
292
292
 
293
- if (typeof value == "string") {
294
- value = value.trim()
295
- }
296
-
297
- if (value) {
298
- return true
299
- }
300
-
301
- return false
293
+ return this._hasAttribute(value)
302
294
  }
303
295
  }
304
296
 
@@ -306,6 +298,18 @@ class VelociousDatabaseRecord {
306
298
  this._initialized = true
307
299
  }
308
300
 
301
+ _hasAttribute(value) {
302
+ if (typeof value == "string") {
303
+ value = value.trim()
304
+ }
305
+
306
+ if (value) {
307
+ return true
308
+ }
309
+
310
+ return false
311
+ }
312
+
309
313
  static isInitialized() {
310
314
  if (this._initialized) return true
311
315
 
@@ -324,13 +328,19 @@ class VelociousDatabaseRecord {
324
328
  const nameCamelized = inflection.camelize(name)
325
329
  const setterMethodName = `set${nameCamelized}`
326
330
 
327
- this.prototype[name] = function() {
331
+ this.prototype[name] = function getTranslatedAttribute() {
328
332
  const locale = this._getConfiguration().getLocale()
329
333
 
330
334
  return this._getTranslatedAttributeWithFallback(name, locale)
331
335
  }
332
336
 
333
- this.prototype[setterMethodName] = function(newValue) {
337
+ this.prototype[`has${nameCamelized}`] = function hasTranslatedAttribute() {
338
+ const value = this[name]()
339
+
340
+ return this._hasAttribute(value)
341
+ }
342
+
343
+ this.prototype[setterMethodName] = function setTranslatedAttribute(newValue) {
334
344
  const locale = this._getConfiguration().getLocale()
335
345
 
336
346
  return this._setTranslatedAttribute(name, locale, newValue)
@@ -341,11 +351,11 @@ class VelociousDatabaseRecord {
341
351
  const getterMethodNameLocalized = `${name}${localeCamelized}`
342
352
  const setterMethodNameLocalized = `${setterMethodName}${localeCamelized}`
343
353
 
344
- this.prototype[getterMethodNameLocalized] = function() {
354
+ this.prototype[getterMethodNameLocalized] = function getTranslatedAttributeWithLocale() {
345
355
  return this._getTranslatedAttribute(name, locale)
346
356
  }
347
357
 
348
- this.prototype[setterMethodNameLocalized] = function(newValue) {
358
+ this.prototype[setterMethodNameLocalized] = function setTranslatedAttributeWithLocale(newValue) {
349
359
  return this._setTranslatedAttribute(name, locale, newValue)
350
360
  }
351
361
  }
@@ -416,13 +426,6 @@ class VelociousDatabaseRecord {
416
426
  return await this.connection().insertMultiple(this.tableName(), columns, rows)
417
427
  }
418
428
 
419
- static async last() {
420
- const query = this._newQuery().order(this.primaryKey())
421
- const record = await query.last()
422
-
423
- return record
424
- }
425
-
426
429
  static async nextPrimaryKey() {
427
430
  const primaryKey = this.primaryKey()
428
431
  const tableName = this.tableName()
@@ -758,6 +761,10 @@ class VelociousDatabaseRecord {
758
761
  return this._newQuery().joins(...args)
759
762
  }
760
763
 
764
+ static async last(...args) {
765
+ return await this._newQuery().last(...args)
766
+ }
767
+
761
768
  static limit(...args) {
762
769
  return this._newQuery().limit(...args)
763
770
  }
@@ -930,7 +937,7 @@ class VelociousDatabaseRecord {
930
937
  }
931
938
 
932
939
  if (column && this.constructor.getDatabaseType() == "sqlite") {
933
- if (column.getType() == "date" || column.getType() == "datetime") {
940
+ if (result && (column.getType() == "date" || column.getType() == "datetime")) {
934
941
  result = new Date(Date.parse(result))
935
942
  }
936
943
  }
@@ -1021,7 +1028,17 @@ class VelociousDatabaseRecord {
1021
1028
  }
1022
1029
  }
1023
1030
 
1024
- id() { return this.readAttribute(this.constructor._columnNameToAttributeName[this.constructor.primaryKey()]) }
1031
+ id() {
1032
+ const primaryKey = this.constructor.primaryKey()
1033
+ const attributeName = this.constructor._columnNameToAttributeName[primaryKey]
1034
+
1035
+ if (attributeName === undefined) {
1036
+ throw new Error(`Primary key ${primaryKey} doesn't exist in columns: ${Object.keys(this.constructor._columnNameToAttributeName).join(", ")}`)
1037
+ }
1038
+
1039
+ return this.readAttribute(attributeName)
1040
+ }
1041
+
1025
1042
  isPersisted() { return !this._isNewRecord }
1026
1043
  isNewRecord() { return this._isNewRecord }
1027
1044