mirror of
				https://github.com/strapi/strapi.git
				synced 2025-10-31 18:08:11 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			202 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			202 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 'use strict';
 | |
| 
 | |
| const types = require('../types');
 | |
| 
 | |
| const createColumn = (name, attribute) => {
 | |
|   const { type, args = [], ...opts } = getColumnType(attribute);
 | |
| 
 | |
|   return {
 | |
|     name,
 | |
|     type,
 | |
|     args,
 | |
|     defaultTo: null,
 | |
|     notNullable: false,
 | |
|     unsigned: false,
 | |
|     ...opts,
 | |
|     ...(attribute.column || {}),
 | |
|   };
 | |
| };
 | |
| 
 | |
| const createTable = meta => {
 | |
|   const table = {
 | |
|     name: meta.tableName,
 | |
|     indexes: meta.indexes || [],
 | |
|     foreignKeys: meta.foreignKeys || [],
 | |
|     columns: [],
 | |
|   };
 | |
| 
 | |
|   for (const key in meta.attributes) {
 | |
|     const attribute = meta.attributes[key];
 | |
| 
 | |
|     if (types.isRelation(attribute.type)) {
 | |
|       if (attribute.morphColumn && attribute.owner) {
 | |
|         const { idColumn, typeColumn } = attribute.morphColumn;
 | |
| 
 | |
|         table.columns.push(
 | |
|           createColumn(idColumn.name, {
 | |
|             type: 'integer',
 | |
|             column: {
 | |
|               unsigned: true,
 | |
|             },
 | |
|           })
 | |
|         );
 | |
| 
 | |
|         table.columns.push(createColumn(typeColumn.name, { type: 'string' }));
 | |
|       } else if (attribute.joinColumn && attribute.owner) {
 | |
|         // NOTE: we could pass uniquness for oneToOne to avoid creating more than one to one
 | |
| 
 | |
|         const { name: columnName, referencedColumn, referencedTable } = attribute.joinColumn;
 | |
| 
 | |
|         const column = createColumn(columnName, {
 | |
|           type: 'integer',
 | |
|           column: {
 | |
|             unsigned: true,
 | |
|           },
 | |
|         });
 | |
| 
 | |
|         table.columns.push(column);
 | |
| 
 | |
|         table.foreignKeys.push({
 | |
|           name: `${table.name}_${columnName}_fk`,
 | |
|           columns: [columnName],
 | |
|           referencedTable,
 | |
|           referencedColumns: [referencedColumn],
 | |
|           // NOTE: could allow configuration
 | |
|           onDelete: 'SET NULL',
 | |
|         });
 | |
| 
 | |
|         table.indexes.push({
 | |
|           name: `${table.name}_${columnName}_fk`,
 | |
|           columns: [columnName],
 | |
|         });
 | |
|       }
 | |
|     } else if (types.isScalar(attribute.type)) {
 | |
|       const column = createColumn(attribute.columnName || key, attribute);
 | |
| 
 | |
|       if (column.unique) {
 | |
|         table.indexes.push({
 | |
|           type: 'unique',
 | |
|           name: `${table.name}_${column.name}_unique`,
 | |
|           columns: [column.name],
 | |
|         });
 | |
|       }
 | |
| 
 | |
|       if (column.primary) {
 | |
|         table.indexes.push({
 | |
|           type: 'primary',
 | |
|           name: `${table.name}_${column.name}_primary`,
 | |
|           columns: [column.name],
 | |
|         });
 | |
|       }
 | |
| 
 | |
|       table.columns.push(column);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return table;
 | |
| };
 | |
| 
 | |
| const getColumnType = attribute => {
 | |
|   if (attribute.columnType) {
 | |
|     return attribute.columnType;
 | |
|   }
 | |
| 
 | |
|   switch (attribute.type) {
 | |
|     case 'increments': {
 | |
|       return {
 | |
|         type: 'increments',
 | |
|         args: [{ primary: true, primaryKey: true }],
 | |
|         notNullable: true,
 | |
|       };
 | |
|     }
 | |
| 
 | |
|     // We might want to convert email/password to string types before going into the orm with specific validators & transformers
 | |
|     case 'password':
 | |
|     case 'email':
 | |
|     case 'string':
 | |
|     case 'enumeration': {
 | |
|       return { type: 'string' };
 | |
|     }
 | |
|     case 'uid': {
 | |
|       return {
 | |
|         type: 'string',
 | |
|         unique: true,
 | |
|       };
 | |
|     }
 | |
|     case 'richtext':
 | |
|     case 'text': {
 | |
|       return {
 | |
|         type: 'text',
 | |
|         args: ['longtext'],
 | |
|       };
 | |
|     }
 | |
|     case 'json': {
 | |
|       return { type: 'jsonb' };
 | |
|     }
 | |
|     case 'integer': {
 | |
|       return { type: 'integer' };
 | |
|     }
 | |
|     case 'biginteger': {
 | |
|       return { type: 'bigInteger' };
 | |
|     }
 | |
|     case 'float': {
 | |
|       return { type: 'double' };
 | |
|     }
 | |
|     case 'decimal': {
 | |
|       return { type: 'decimal', args: [10, 2] };
 | |
|     }
 | |
|     case 'date': {
 | |
|       return { type: 'date' };
 | |
|     }
 | |
|     case 'time': {
 | |
|       return { type: 'time', args: [{ precision: 3 }] };
 | |
|     }
 | |
|     case 'datetime': {
 | |
|       return {
 | |
|         type: 'datetime',
 | |
|         args: [
 | |
|           {
 | |
|             useTz: false,
 | |
|             precision: 6,
 | |
|           },
 | |
|         ],
 | |
|       };
 | |
|     }
 | |
|     case 'timestamp': {
 | |
|       return {
 | |
|         type: 'timestamp',
 | |
|         args: [
 | |
|           {
 | |
|             useTz: false,
 | |
|             precision: 6,
 | |
|           },
 | |
|         ],
 | |
|       };
 | |
|     }
 | |
|     case 'boolean': {
 | |
|       return { type: 'boolean' };
 | |
|     }
 | |
|     default: {
 | |
|       throw new Error(`Unknown type ${attribute.type}`);
 | |
|     }
 | |
|   }
 | |
| };
 | |
| 
 | |
| const metadataToSchema = metadata => {
 | |
|   const schema = {
 | |
|     tables: [],
 | |
|     addTable(table) {
 | |
|       this.tables.push(table);
 | |
|       return this;
 | |
|     },
 | |
|   };
 | |
| 
 | |
|   metadata.forEach(metadata => {
 | |
|     schema.addTable(createTable(metadata));
 | |
|   });
 | |
| 
 | |
|   return schema;
 | |
| };
 | |
| 
 | |
| module.exports = { metadataToSchema, createTable };
 | 
