| 
									
										
										
										
											2021-05-18 10:16:03 +02:00
										 |  |  | 'use strict'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-17 12:00:14 +02:00
										 |  |  | const debug = require('debug')('strapi::database'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-02 15:53:22 +02:00
										 |  |  | const createSchemaBuilder = require('./builder'); | 
					
						
							| 
									
										
										
										
											2021-09-17 12:00:14 +02:00
										 |  |  | const createSchemaDiff = require('./diff'); | 
					
						
							|  |  |  | const createSchemaStorage = require('./storage'); | 
					
						
							| 
									
										
										
										
											2021-09-16 11:44:43 +02:00
										 |  |  | const { metadataToSchema } = require('./schema'); | 
					
						
							| 
									
										
										
										
											2021-05-18 10:16:03 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-20 19:15:50 +02:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @type {import('.').default} | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2021-05-18 10:16:03 +02:00
										 |  |  | const createSchemaProvider = db => { | 
					
						
							| 
									
										
										
										
											2021-09-16 11:44:43 +02:00
										 |  |  |   const schema = metadataToSchema(db.metadata); | 
					
						
							| 
									
										
										
										
											2021-05-18 10:16:03 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-02 15:53:22 +02:00
										 |  |  |   return { | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |     builder: createSchemaBuilder(db), | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  |     schemaDiff: createSchemaDiff(db), | 
					
						
							| 
									
										
										
										
											2021-09-17 12:00:14 +02:00
										 |  |  |     schemaStorage: createSchemaStorage(db), | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Drops the database schema | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     async drop() { | 
					
						
							| 
									
										
										
										
											2021-09-17 12:00:14 +02:00
										 |  |  |       debug('Dropping database schema'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-16 11:44:43 +02:00
										 |  |  |       const DBSchema = await db.dialect.schemaInspector.getSchema(); | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |       await this.builder.dropSchema(DBSchema); | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Creates the database schema | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     async create() { | 
					
						
							| 
									
										
										
										
											2021-09-17 12:00:14 +02:00
										 |  |  |       debug('Created database schema'); | 
					
						
							| 
									
										
										
										
											2021-09-16 11:44:43 +02:00
										 |  |  |       await this.builder.createSchema(schema); | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Resets the database schema | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     async reset() { | 
					
						
							| 
									
										
										
										
											2021-09-17 12:00:14 +02:00
										 |  |  |       debug('Resetting database schema'); | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |       await this.drop(); | 
					
						
							|  |  |  |       await this.create(); | 
					
						
							| 
									
										
										
										
											2021-06-02 15:53:22 +02:00
										 |  |  |     }, | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-17 12:00:14 +02:00
										 |  |  |     async syncSchema() { | 
					
						
							|  |  |  |       debug('Synchronizing database schema'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const DBSchema = await db.dialect.schemaInspector.getSchema(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const { status, diff } = this.schemaDiff.diff(DBSchema, schema); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (status === 'CHANGED') { | 
					
						
							|  |  |  |         await this.builder.updateSchema(diff); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       await this.schemaStorage.add(schema); | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |     // TODO: support options to migrate softly or forcefully
 | 
					
						
							|  |  |  |     // TODO: support option to disable auto migration & run a CLI command instead to avoid doing it at startup
 | 
					
						
							| 
									
										
										
										
											2021-09-16 11:44:43 +02:00
										 |  |  |     // TODO: Allow keeping extra indexes / extra tables / extra columns (globally or on a per table basis)
 | 
					
						
							| 
									
										
										
										
											2021-06-02 15:53:22 +02:00
										 |  |  |     async sync() { | 
					
						
							| 
									
										
										
										
											2021-09-20 19:15:50 +02:00
										 |  |  |       if (await db.migrations.shouldRun()) { | 
					
						
							| 
									
										
										
										
											2021-09-17 12:00:14 +02:00
										 |  |  |         debug('Found migrations to run'); | 
					
						
							| 
									
										
										
										
											2021-09-20 19:15:50 +02:00
										 |  |  |         await db.migrations.up(); | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-17 12:00:14 +02:00
										 |  |  |         return this.syncSchema(); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-09-16 13:37:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-17 12:00:14 +02:00
										 |  |  |       const oldSchema = await this.schemaStorage.read(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (!oldSchema) { | 
					
						
							|  |  |  |         debug('Schema not persisted yet'); | 
					
						
							|  |  |  |         return this.syncSchema(); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const { hash: oldHash } = oldSchema; | 
					
						
							|  |  |  |       const hash = await this.schemaStorage.hashSchema(schema); | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-17 12:00:14 +02:00
										 |  |  |       if (oldHash !== hash) { | 
					
						
							|  |  |  |         debug('Schema changed'); | 
					
						
							| 
									
										
										
										
											2021-09-20 09:12:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-17 12:00:14 +02:00
										 |  |  |         return this.syncSchema(); | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-17 12:00:14 +02:00
										 |  |  |       debug('Schema unchanged'); | 
					
						
							|  |  |  |       return; | 
					
						
							| 
									
										
										
										
											2021-06-02 15:53:22 +02:00
										 |  |  |     }, | 
					
						
							|  |  |  |   }; | 
					
						
							| 
									
										
										
										
											2021-05-18 10:16:03 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module.exports = createSchemaProvider; |