@strapi/database 4.2.0-alpha.9 → 4.2.0-beta.1

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.
@@ -0,0 +1,64 @@
1
+ /* eslint-disable node/no-missing-require */
2
+ /* eslint-disable node/no-extraneous-require */
3
+ 'use strict';
4
+
5
+ const knex = require('knex');
6
+
7
+ const SqliteClient = require('knex/lib/dialects/sqlite3/index');
8
+
9
+ const trySqlitePackage = packageName => {
10
+ try {
11
+ require.resolve(packageName);
12
+ return packageName;
13
+ } catch (error) {
14
+ if (error.code === 'MODULE_NOT_FOUND') {
15
+ return false;
16
+ }
17
+ throw error;
18
+ }
19
+ };
20
+ class LegacySqliteClient extends SqliteClient {
21
+ _driver() {
22
+ return require('sqlite3');
23
+ }
24
+ }
25
+
26
+ const clientMap = {
27
+ 'better-sqlite3': 'better-sqlite3',
28
+ '@vscode/sqlite3': 'sqlite',
29
+ sqlite3: LegacySqliteClient,
30
+ };
31
+
32
+ const getSqlitePackageName = () => {
33
+ // NOTE: allow forcing the package to use (mostly used for testing purposes)
34
+ if (typeof process.env.SQLITE_PKG !== 'undefined') {
35
+ return process.env.SQLITE_PKG;
36
+ }
37
+
38
+ // NOTE: this tries to find the best sqlite module possible to use
39
+ // while keeping retro compatibility
40
+ return (
41
+ trySqlitePackage('better-sqlite3') ||
42
+ trySqlitePackage('@vscode/sqlite3') ||
43
+ trySqlitePackage('sqlite3')
44
+ );
45
+ };
46
+
47
+ const createConnection = config => {
48
+ const knexConfig = { ...config };
49
+ if (knexConfig.client === 'sqlite') {
50
+ const sqlitePackageName = getSqlitePackageName();
51
+
52
+ knexConfig.client = clientMap[sqlitePackageName];
53
+ }
54
+
55
+ const knexInstance = knex(knexConfig);
56
+
57
+ return Object.assign(knexInstance, {
58
+ getSchemaName() {
59
+ return this.client.connectionSettings.schema;
60
+ },
61
+ });
62
+ };
63
+
64
+ module.exports = createConnection;
@@ -48,7 +48,7 @@ const toStrapiType = column => {
48
48
  switch (rootType) {
49
49
  case 'int': {
50
50
  if (column.column_key === 'PRI') {
51
- return { type: 'increments', args: [{ primary: true }], unsigned: false };
51
+ return { type: 'increments', args: [{ primary: true, primaryKey: true }], unsigned: false };
52
52
  }
53
53
 
54
54
  return { type: 'integer' };
@@ -16,7 +16,7 @@ const toStrapiType = column => {
16
16
  switch (rootType) {
17
17
  case 'integer': {
18
18
  if (column.pk) {
19
- return { type: 'increments', args: [{ primary: true }] };
19
+ return { type: 'increments', args: [{ primary: true, primaryKey: true }] };
20
20
  }
21
21
 
22
22
  return { type: 'integer' };
@@ -166,10 +166,12 @@ const createEntityManager = db => {
166
166
 
167
167
  const dataToInsert = processData(metadata, data, { withDefaults: true });
168
168
 
169
- const [id] = await this.createQueryBuilder(uid)
169
+ const res = await this.createQueryBuilder(uid)
170
170
  .insert(dataToInsert)
171
171
  .execute();
172
172
 
173
+ const id = res[0].id || res[0];
174
+
173
175
  await this.attachRelations(uid, id, data);
174
176
 
175
177
  // TODO: in case there is no select or populate specified return the inserted data ?
package/lib/index.js CHANGED
@@ -1,28 +1,17 @@
1
1
  'use strict';
2
2
 
3
- const knex = require('knex');
4
-
5
3
  const { getDialect } = require('./dialects');
6
4
  const createSchemaProvider = require('./schema');
7
5
  const createMetadata = require('./metadata');
8
6
  const { createEntityManager } = require('./entity-manager');
9
7
  const { createMigrationsProvider } = require('./migrations');
10
8
  const { createLifecyclesProvider } = require('./lifecycles');
9
+ const createConnection = require('./connection');
11
10
  const errors = require('./errors');
12
11
 
13
12
  // TODO: move back into strapi
14
13
  const { transformContentTypes } = require('./utils/content-types');
15
14
 
16
- const createConnection = config => {
17
- const knexInstance = knex(config);
18
-
19
- return Object.assign(knexInstance, {
20
- getSchemaName() {
21
- return this.client.connectionSettings.schema;
22
- },
23
- });
24
- };
25
-
26
15
  class Database {
27
16
  constructor(config) {
28
17
  this.metadata = createMetadata(config.models);
@@ -105,7 +105,7 @@ const getColumnType = attribute => {
105
105
  case 'increments': {
106
106
  return {
107
107
  type: 'increments',
108
- args: [{ primary: true }],
108
+ args: [{ primary: true, primaryKey: true }],
109
109
  notNullable: true,
110
110
  };
111
111
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@strapi/database",
3
- "version": "4.2.0-alpha.9",
3
+ "version": "4.2.0-beta.1",
4
4
  "description": "Strapi's database layer",
5
5
  "homepage": "https://strapi.io",
6
6
  "bugs": {
@@ -34,7 +34,7 @@
34
34
  "date-fns": "2.22.1",
35
35
  "debug": "4.3.1",
36
36
  "fs-extra": "10.0.0",
37
- "knex": "0.95.6",
37
+ "knex": "1.0.4",
38
38
  "lodash": "4.17.21",
39
39
  "umzug": "2.3.0"
40
40
  },
@@ -42,5 +42,5 @@
42
42
  "node": ">=12.22.0 <=16.x.x",
43
43
  "npm": ">=6.0.0"
44
44
  },
45
- "gitHead": "db70f0de7cc73fb469c8a076b89530729cf14142"
45
+ "gitHead": "4fa2804f35e15ed72dfd309fb5bb1c4dba18932f"
46
46
  }
@@ -1,36 +0,0 @@
1
- 'use strict';
2
-
3
- const postgres = {
4
- client: 'postgres',
5
- connection: {
6
- database: 'strapi',
7
- user: 'strapi',
8
- password: 'strapi',
9
- },
10
- // debug: true,
11
- };
12
-
13
- const mysql = {
14
- client: 'mysql',
15
- connection: {
16
- database: 'strapi',
17
- user: 'strapi',
18
- password: 'strapi',
19
- },
20
- // debug: true,
21
- };
22
-
23
- const sqlite = {
24
- client: 'sqlite',
25
- connection: {
26
- filename: 'data.sqlite',
27
- },
28
- useNullAsDefault: true,
29
- // debug: true,
30
- };
31
-
32
- module.exports = {
33
- sqlite,
34
- postgres,
35
- mysql,
36
- };
@@ -1,29 +0,0 @@
1
- version: '3'
2
-
3
- services:
4
- postgres:
5
- image: postgres
6
- restart: always
7
- volumes:
8
- - ./data/postgresql:/var/lib/postgresql/data
9
- environment:
10
- POSTGRES_USER: strapi
11
- POSTGRES_PASSWORD: strapi
12
- POSTGRES_DB: strapi
13
- ports:
14
- - '5432:5432'
15
-
16
- mysql:
17
- image: mysql
18
- restart: always
19
- command: --default-authentication-plugin=mysql_native_password
20
- environment:
21
- MYSQL_DATABASE: strapi
22
- MYSQL_USER: strapi
23
- MYSQL_PASSWORD: strapi
24
- MYSQL_ROOT_HOST: '%'
25
- MYSQL_ROOT_PASSWORD: strapi
26
- volumes:
27
- - ./data/mysql:/var/lib/mysql
28
- ports:
29
- - '3306:3306'
package/examples/index.js DELETED
@@ -1,73 +0,0 @@
1
- 'use strict';
2
-
3
- const util = require('util');
4
-
5
- const { Database } = require('../lib/index');
6
- const models = require('./models');
7
- const connections = require('./connections');
8
-
9
- async function main(connection) {
10
- const orm = await Database.init({
11
- connection,
12
- models: Database.transformContentTypes(models),
13
- });
14
-
15
- try {
16
- // await orm.schema.drop();
17
- // await orm.schema.create();
18
-
19
- await orm.schema.reset();
20
-
21
- let res;
22
-
23
- const c1 = await orm.query('comment').create({
24
- data: {
25
- title: 'coucou',
26
- },
27
- });
28
-
29
- const c2 = await orm.query('video-comment').create({
30
- data: {
31
- title: 'coucou',
32
- },
33
- });
34
-
35
- res = await orm.query('article').create({
36
- data: {
37
- dz: [
38
- {
39
- __type: 'comment',
40
- id: c1.id,
41
- },
42
- {
43
- __type: 'video-comment',
44
- id: c2.id,
45
- },
46
- ],
47
- },
48
- populate: {
49
- dz: true,
50
- },
51
- });
52
-
53
- log(res);
54
-
55
- res = await orm.query('article').findMany({
56
- populate: {
57
- dz: true,
58
- },
59
- });
60
-
61
- log(res);
62
-
63
- // await tests(orm);
64
- } finally {
65
- orm.destroy();
66
- }
67
- }
68
-
69
- function log(res) {
70
- console.log(util.inspect(res, null, null, true));
71
- }
72
-
73
- main(connections.sqlite);
@@ -1,341 +0,0 @@
1
- 'use strict';
2
-
3
- const category = {
4
- modelName: 'category',
5
- uid: 'category',
6
- collectionName: 'categories',
7
- attributes: {
8
- title: {
9
- type: 'string',
10
- },
11
- price: {
12
- type: 'integer',
13
- required: true,
14
- default: 12,
15
-
16
- column: {
17
- unique: true,
18
- nonNullable: true,
19
- unsigned: true,
20
- defaultTo: 12,
21
- },
22
- },
23
- articles: {
24
- type: 'relation',
25
- relation: 'oneToMany',
26
- target: 'article',
27
- mappedBy: 'category',
28
- },
29
- compo: {
30
- type: 'component',
31
- component: 'compo',
32
- },
33
- },
34
- };
35
-
36
- const article = {
37
- modelName: 'article',
38
- uid: 'article',
39
- collectionName: 'articles',
40
- attributes: {
41
- title: {
42
- type: 'string',
43
- },
44
- category: {
45
- type: 'relation',
46
- relation: 'manyToOne',
47
- target: 'category',
48
- inversedBy: 'articles',
49
- // useJoinTable: false,
50
- },
51
- // tags: {
52
- // type: 'relation',
53
- // relation: 'manyToMany',
54
- // target: 'tag',
55
- // inversedBy: 'articles',
56
- // },
57
- // compo: {
58
- // type: 'component',
59
- // component: 'compo',
60
- // // repeatable: true,
61
- // },
62
- // cover: {
63
- // type: 'media',
64
- // single: true,
65
- // },
66
- // gallery: {
67
- // type: 'media',
68
- // multiple: true,
69
- // },
70
- },
71
- };
72
-
73
- const tags = {
74
- modelName: 'tag',
75
- uid: 'tag',
76
- collectionName: 'tags',
77
- attributes: {
78
- name: {
79
- type: 'string',
80
- },
81
- articles: {
82
- type: 'relation',
83
- relation: 'manyToMany',
84
- target: 'article',
85
- mappedBy: 'tag',
86
- },
87
- },
88
- };
89
-
90
- const compo = {
91
- modelName: 'compo',
92
- uid: 'compo',
93
- collectionName: 'compos',
94
- attributes: {
95
- key: {
96
- type: 'string',
97
- },
98
- value: {
99
- type: 'string',
100
- },
101
- },
102
- };
103
-
104
- const user = {
105
- modelName: 'user',
106
- uid: 'user',
107
- collectionName: 'users',
108
- attributes: {
109
- address: {
110
- type: 'relation',
111
- relation: 'oneToOne',
112
- target: 'address',
113
- inversedBy: 'user',
114
- // useJoinTable: false,
115
- },
116
- },
117
- };
118
-
119
- const address = {
120
- modelName: 'address',
121
- uid: 'address',
122
- collectionName: 'addresses',
123
- attributes: {
124
- name: {
125
- type: 'string',
126
- },
127
- user: {
128
- type: 'relation',
129
- relation: 'oneToOne',
130
- target: 'user',
131
- mappedBy: 'address',
132
- },
133
- },
134
- };
135
-
136
- const file = {
137
- modelName: 'file',
138
- uid: 'file',
139
- collectionName: 'files',
140
- attributes: {
141
- name: {
142
- type: 'string',
143
- },
144
- alternativeText: {
145
- type: 'string',
146
- },
147
- caption: {
148
- type: 'string',
149
- },
150
- width: {
151
- type: 'integer',
152
- },
153
- height: {
154
- type: 'integer',
155
- },
156
- formats: {
157
- type: 'json',
158
- },
159
- hash: {
160
- type: 'string',
161
- },
162
- ext: {
163
- type: 'string',
164
- },
165
- mime: {
166
- type: 'string',
167
- },
168
- size: {
169
- type: 'decimal',
170
- },
171
- url: {
172
- type: 'string',
173
- },
174
- previewUrl: {
175
- type: 'string',
176
- },
177
- provider: {
178
- type: 'string',
179
- },
180
- provider_metadata: {
181
- type: 'json',
182
- },
183
- // related: {
184
- // type: 'relation',
185
- // relation: 'oneToMany',
186
- // target: 'file_morph',
187
- // mappedBy: 'file',
188
- // },
189
- // related: {
190
- // type: 'relation',
191
- // realtion: 'morphTo',
192
- // },
193
- },
194
- };
195
-
196
- const fileMorph = {
197
- modelName: 'file-morph',
198
- uid: 'file-morph',
199
- collectionName: 'file_morphs',
200
- attributes: {
201
- // file: {
202
- // type: 'relation',
203
- // relation: 'manyToOne',
204
- // target: 'file',
205
- // inversedBy: 'related',
206
- // useJoinTable: false,
207
- // },
208
- },
209
- };
210
-
211
- const blogPost = {
212
- modelName: 'blogPost',
213
- uid: 'blogPost',
214
- collectionName: 'blog_posts',
215
- attributes: {
216
- passwordField: {
217
- type: 'password',
218
- },
219
- emailField: {
220
- type: 'email',
221
- },
222
- stringField: {
223
- type: 'string',
224
- },
225
- uidField: {
226
- type: 'uid',
227
- },
228
- richtextField: {
229
- type: 'richtext',
230
- },
231
- textField: {
232
- type: 'text',
233
- },
234
- enumerationField: {
235
- type: 'enumeration',
236
- enum: ['A', 'B'],
237
- },
238
- jsonField: {
239
- type: 'json',
240
- },
241
- bigintegerField: {
242
- type: 'biginteger',
243
- },
244
- integerField: {
245
- type: 'integer',
246
- },
247
- floatField: {
248
- type: 'float',
249
- },
250
- decimalField: {
251
- type: 'decimal',
252
- },
253
- dateField: {
254
- type: 'date',
255
- },
256
- timeField: {
257
- type: 'time',
258
- },
259
- datetimeField: {
260
- type: 'datetime',
261
- },
262
- timestampField: {
263
- type: 'timestamp',
264
- },
265
- booleanField: {
266
- type: 'boolean',
267
- },
268
- },
269
- };
270
-
271
- module.exports = [category, article, tags, compo, user, address, file, fileMorph, blogPost];
272
-
273
- // const article = {
274
- // modelName: 'article',
275
- // uid: 'article',
276
- // collectionName: 'articles',
277
- // attributes: {
278
- // commentable: {
279
- // type: 'relation',
280
- // relation: 'morphToOne',
281
- // },
282
- // reportables: {
283
- // type: 'relation',
284
- // relation: 'morphToMany',
285
- // },
286
- // dz: {
287
- // type: 'dynamiczone',
288
- // components: ['comment', 'video-comment'],
289
- // },
290
- // },
291
- // };
292
-
293
- // const comment = {
294
- // modelName: 'comment',
295
- // uid: 'comment',
296
- // collectionName: 'comments',
297
- // attributes: {
298
- // article: {
299
- // type: 'relation',
300
- // relation: 'morphOne',
301
- // target: 'article',
302
- // morphBy: 'commentable',
303
- // },
304
- // title: {
305
- // type: 'string',
306
- // },
307
- // },
308
- // };
309
-
310
- // const videoComment = {
311
- // modelName: 'video-comment',
312
- // uid: 'video-comment',
313
- // collectionName: 'video_comments',
314
- // attributes: {
315
- // articles: {
316
- // type: 'relation',
317
- // relation: 'morphMany',
318
- // target: 'article',
319
- // morphBy: 'commentable',
320
- // },
321
- // title: {
322
- // type: 'string',
323
- // },
324
- // },
325
- // };
326
-
327
- // const folder = {
328
- // modelName: 'folder',
329
- // uid: 'folder',
330
- // collectionName: 'folders',
331
- // attributes: {
332
- // articles: {
333
- // type: 'relation',
334
- // relation: 'morphMany',
335
- // target: 'article',
336
- // morphBy: 'reportables',
337
- // },
338
- // },
339
- // };
340
-
341
- // module.exports = [article, comment, videoComment, folder];
@@ -1,17 +0,0 @@
1
- type ID = number | string;
2
-
3
- interface Category {
4
- id: ID;
5
- title: string;
6
- }
7
-
8
- interface Article {
9
- id: ID;
10
- title: string;
11
- category: Category | ID;
12
- }
13
-
14
- interface AllTypes {
15
- article: Article;
16
- category: Category;
17
- }