velocious 1.0.9 → 1.0.10

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.9",
6
+ "version": "1.0.10",
7
7
  "main": "index.js",
8
8
  "scripts": {
9
9
  "test": "jasmine",
@@ -78,6 +78,22 @@ export default class VelociousDatabaseDriversBase {
78
78
  return false
79
79
  }
80
80
 
81
+ async transaction(callback) {
82
+ await this.query("BEGIN TRANSACTION")
83
+
84
+ let result
85
+
86
+ try {
87
+ result = await callback()
88
+ await this.query("COMMIT")
89
+ } catch (error) {
90
+ this.query("ROLLBACK")
91
+ throw error
92
+ }
93
+
94
+ return result
95
+ }
96
+
81
97
  async update(...args) {
82
98
  const sql = this.updateSql(...args)
83
99
 
@@ -93,8 +93,9 @@ export default class VelociousDatabaseDriversMysql extends Base{
93
93
  return deleteInstruction.toSql()
94
94
  }
95
95
 
96
- insertSql({tableName, data}) {
97
- const insert = new Insert({driver: this, tableName, data})
96
+ insertSql(args) {
97
+ const insertArgs = Object.assign({driver: this}, args)
98
+ const insert = new Insert(insertArgs)
98
99
 
99
100
  return insert.toSql()
100
101
  }
@@ -1,29 +1,4 @@
1
1
  import InsertBase from "../../../query/insert-base.js"
2
2
 
3
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
4
  }
@@ -34,8 +34,8 @@ export default class VelociousDatabaseDriversSqliteBase extends Base {
34
34
  return createTable.toSql()
35
35
  }
36
36
 
37
- deleteSql = ({tableName, conditions}) => new Delete({conditions, driver: this, tableName}).toSql()
38
- insertSql = ({tableName, data}) => new Insert({driver: this, tableName, data}).toSql()
37
+ deleteSql = (args) => new Delete(Object.assign({driver: this}, args)).toSql()
38
+ insertSql = (args) => new Insert(Object.assign({driver: this}, args)).toSql()
39
39
 
40
40
  async getTableByName(tableName) {
41
41
  const result = await this.query(`SELECT name FROM sqlite_master WHERE type = 'table' AND name = ${this.quote(tableName)} LIMIT 1`)
@@ -64,6 +64,53 @@ export default class VelociousDatabaseDriversSqliteBase extends Base {
64
64
  return tables
65
65
  }
66
66
 
67
+ async insertMultiple(...args) {
68
+ if (this.supportsMultipleInsertValues()) {
69
+ return await this.insertMultipleWithSingleInsert(...args)
70
+ } else {
71
+ return await this.insertMultipleWithTransaction(...args)
72
+ }
73
+ }
74
+
75
+ supportsMultipleInsertValues() {
76
+ if (this.versionMajor >= 4) return true
77
+ if (this.versionMajor == 3 && this.versionMinor >= 8) return true
78
+ if (this.versionMajor == 3 && this.versionMinor == 7 && this.versionPatch >= 11) return true
79
+
80
+ return false
81
+ }
82
+
83
+ async insertMultipleWithSingleInsert(tableName, columns, rows) {
84
+ const sql = new Insert({columns, driver: this, rows, tableName}).toSql()
85
+
86
+ return await this.query(sql)
87
+ }
88
+
89
+ async insertMultipleWithTransaction(tableName, columns, rows) {
90
+ const sqls = []
91
+
92
+ for (const row of rows) {
93
+ const data = []
94
+
95
+ for (const columnIndex in columns) {
96
+ const columnName = columns[columnIndex]
97
+ const value = row[columnIndex]
98
+
99
+ data[columnName] = value
100
+ }
101
+
102
+ const insertSql = this.insertSql({tableName, data})
103
+
104
+ sqls.push(insertSql)
105
+ }
106
+
107
+ await this.transaction(async () => {
108
+ for (const sql of sqls) {
109
+ await this.query(sql)
110
+ }
111
+ })
112
+ }
113
+
67
114
  async lastInsertID() {
68
115
  const result = await this.query("SELECT LAST_INSERT_ROWID() AS last_insert_id")
69
116
 
@@ -80,6 +127,18 @@ export default class VelociousDatabaseDriversSqliteBase extends Base {
80
127
 
81
128
  queryToSql = (query) => new QueryParser({query}).toSql()
82
129
 
130
+ async registerVersion() {
131
+ const versionResult = await this.query("SELECT sqlite_version() AS version")
132
+
133
+ this.version = versionResult[0].version
134
+
135
+ const versionParts = this.version.split(".")
136
+
137
+ this.versionMajor = versionParts[0]
138
+ this.versionMinor = versionParts[1]
139
+ this.versionPatch = versionParts[2]
140
+ }
141
+
83
142
  escape(value) {
84
143
  const type = typeof value
85
144
 
@@ -22,6 +22,7 @@ export default class VelociousDatabaseDriversSqliteNative extends Base {
22
22
  }
23
23
 
24
24
  this.connection = await SQLite.openDatabaseAsync(databaseName)
25
+ await this.registerVersion()
25
26
  }
26
27
 
27
28
  async disconnect() {
@@ -24,6 +24,7 @@ export default class VelociousDatabaseDriversSqliteWeb extends Base {
24
24
  const databaseContent = await this.betterLocaleStorage.get(this.localStorageName())
25
25
 
26
26
  this.connection = new SQL.Database(databaseContent)
27
+ await this.registerVersion()
27
28
  }
28
29
 
29
30
  localStorageName = () => `VelociousDatabaseDriversSqliteWeb---${digg(this.getArgs(), "name")}`
@@ -1,29 +1,4 @@
1
1
  import InsertBase from "../../../query/insert-base.js"
2
2
 
3
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
4
  }
@@ -1,11 +1,17 @@
1
+ import restArgsError from "../../utils/rest-args-error.js"
2
+
1
3
  export default class VelociousDatabaseQueryInsertBase {
2
- constructor({driver, tableName, data}) {
4
+ constructor({columns, data, driver, multiple, tableName, rows, ...restArgs}) {
3
5
  if (!driver) throw new Error("No driver given to insert base")
4
6
  if (!tableName) throw new Error(`Invalid table name given to insert base: ${tableName}`)
5
- if (!data) throw new Error("No data given to insert base")
6
7
 
8
+ restArgsError(restArgs)
9
+
10
+ this.columns = columns
7
11
  this.data = data
8
12
  this.driver = driver
13
+ this.multiple = multiple
14
+ this.rows = rows
9
15
  this.tableName = tableName
10
16
  }
11
17
 
@@ -14,6 +20,56 @@ export default class VelociousDatabaseQueryInsertBase {
14
20
  }
15
21
 
16
22
  toSql() {
17
- throw new Error("'toSql' wasn't implemented")
23
+ let sql = `INSERT INTO ${this.getOptions().quoteTableName(this.tableName)} (`
24
+ let count = 0
25
+ let columns
26
+
27
+ if (this.columns && this.rows) {
28
+ columns = this.columns
29
+ } else if (this.data) {
30
+ columns = Object.keys(this.data)
31
+ } else {
32
+ throw new Error("Neither 'column' and 'rows' or data was given")
33
+ }
34
+
35
+ for (const columnName of columns) {
36
+ if (count > 0) sql += ", "
37
+
38
+ sql += this.getOptions().quoteColumnName(columnName)
39
+ count++
40
+ }
41
+
42
+ sql += ") VALUES "
43
+
44
+ if (this.columns && this.rows) {
45
+ let count = 0
46
+
47
+ for (const row of this.rows) {
48
+ if (count >= 1) sql += ", "
49
+
50
+ count++
51
+ sql += this._valuesSql(row)
52
+ }
53
+ } else {
54
+ sql += this._valuesSql(Object.values(this.data))
55
+ }
56
+
57
+ return sql
58
+ }
59
+
60
+ _valuesSql(data) {
61
+ let count = 0
62
+ let sql = "("
63
+
64
+ for (const value of data) {
65
+ if (count > 0) sql += ", "
66
+
67
+ sql += this.getOptions().quote(value)
68
+ count++
69
+ }
70
+
71
+ sql += ")"
72
+
73
+ return sql
18
74
  }
19
75
  }
@@ -19,6 +19,7 @@ export default class VelociousDatabaseRecord {
19
19
  }
20
20
 
21
21
  static _defineRelationship(relationshipName, data) {
22
+ if (!relationshipName) throw new Error(`Invalid relationship name given: ${relationshipName}`)
22
23
  if (!this._relationships) this._relationships = {}
23
24
  if (this._relationshipExists(relationshipName)) throw new Error(`Relationship ${relationshipName} already exists`)
24
25
 
@@ -275,6 +276,10 @@ export default class VelociousDatabaseRecord {
275
276
  return this._table
276
277
  }
277
278
 
279
+ static async insertMultiple(columns, rows) {
280
+ return await this.connection().insertMultiple(this.tableName(), columns, rows)
281
+ }
282
+
278
283
  static async last() {
279
284
  const query = this._newQuery().order(this.primaryKey())
280
285
  const record = await query.last()
@@ -415,9 +420,11 @@ export default class VelociousDatabaseRecord {
415
420
  }
416
421
 
417
422
  _setTranslatedAttribute(name, locale, newValue) {
418
- let translation = this.translations().loaded()?.find((translation) =>translation.locale() == locale)
423
+ let translation = this.translations().loaded()?.find((translation) => translation.locale() == locale)
419
424
 
420
- if (!translation) translation = this.translations().build({locale})
425
+ if (!translation) {
426
+ translation = this.translations().build({locale})
427
+ }
421
428
 
422
429
  const assignments = {}
423
430
 
@@ -519,7 +526,7 @@ export default class VelociousDatabaseRecord {
519
526
  _hasChanges = () => Object.keys(this._changes).length > 0
520
527
 
521
528
  isChanged() {
522
- if (this.isNewRecord() || this._hasChanges()) {
529
+ if (this.isNewRecord() || this._hasChanges()){
523
530
  return true
524
531
  }
525
532
 
@@ -543,6 +550,18 @@ export default class VelociousDatabaseRecord {
543
550
  return false
544
551
  }
545
552
 
553
+ changes() {
554
+ const changes = {}
555
+
556
+ for (const changeKey in this._changes) {
557
+ const changeValue = this._changes[changeKey]
558
+
559
+ changes[changeKey] = [this._attributes[changeKey], changeValue]
560
+ }
561
+
562
+ return changes
563
+ }
564
+
546
565
  _tableName() {
547
566
  if (this.__tableName) return this.__tableName
548
567