@@ -3,8 +3,10 @@ import knex, { Knex } from 'knex';
33
44export class KnexDriver implements Driver {
55 private knex : Knex ;
6+ private config : any ;
67
78 constructor ( config : any ) {
9+ this . config = config ;
810 this . knex = knex ( config ) ;
911 }
1012
@@ -167,5 +169,106 @@ export class KnexDriver implements Driver {
167169 if ( filters ) this . applyFilters ( builder , filters ) ;
168170 return await builder . delete ( ) ;
169171 }
172+
173+ async init ( objects : any [ ] ) : Promise < void > {
174+ await this . ensureDatabaseExists ( ) ;
175+
176+ for ( const obj of objects ) {
177+ const tableName = obj . name ;
178+ const exists = await this . knex . schema . hasTable ( tableName ) ;
179+
180+ if ( ! exists ) {
181+ await this . knex . schema . createTable ( tableName , ( table ) => {
182+ table . string ( 'id' ) . primary ( ) ;
183+ table . timestamp ( 'created_at' ) . defaultTo ( this . knex . fn . now ( ) ) ;
184+ table . timestamp ( 'updated_at' ) . defaultTo ( this . knex . fn . now ( ) ) ;
185+ if ( obj . fields ) {
186+ for ( const [ name , field ] of Object . entries ( obj . fields ) ) {
187+ this . createColumn ( table , name , field ) ;
188+ }
189+ }
190+ } ) ;
191+ console . log ( `[KnexDriver] Created table '${ tableName } '` ) ;
192+ } else {
193+ const columnInfo = await this . knex ( tableName ) . columnInfo ( ) ;
194+ const existingColumns = Object . keys ( columnInfo ) ;
195+
196+ await this . knex . schema . alterTable ( tableName , ( table ) => {
197+ if ( obj . fields ) {
198+ for ( const [ name , field ] of Object . entries ( obj . fields ) ) {
199+ if ( ! existingColumns . includes ( name ) ) {
200+ this . createColumn ( table , name , field ) ;
201+ console . log ( `[KnexDriver] Added column '${ name } ' to '${ tableName } '` ) ;
202+ }
203+ }
204+ }
205+ } ) ;
206+ }
207+ }
208+ }
209+
210+ private createColumn ( table : Knex . CreateTableBuilder , name : string , field : any ) {
211+ const type = field . type || 'string' ;
212+ let col ;
213+ switch ( type ) {
214+ case 'string' : col = table . string ( name ) ; break ;
215+ case 'text' : col = table . text ( name ) ; break ;
216+ case 'integer' :
217+ case 'int' : col = table . integer ( name ) ; break ;
218+ case 'float' :
219+ case 'number' : col = table . float ( name ) ; break ;
220+ case 'boolean' : col = table . boolean ( name ) ; break ;
221+ case 'date' : col = table . date ( name ) ; break ;
222+ case 'datetime' : col = table . timestamp ( name ) ; break ;
223+ case 'json' :
224+ case 'object' :
225+ case 'array' : col = table . json ( name ) ; break ;
226+ default : col = table . string ( name ) ;
227+ }
228+ }
229+
230+ private async ensureDatabaseExists ( ) {
231+ if ( this . config . client !== 'pg' && this . config . client !== 'postgresql' ) return ;
232+
233+ try {
234+ await this . knex . raw ( 'SELECT 1' ) ;
235+ } catch ( e : any ) {
236+ if ( e . code === '3D000' ) { // Database does not exist
237+ await this . createDatabase ( ) ;
238+ } else {
239+ throw e ;
240+ }
241+ }
242+ }
243+
244+ private async createDatabase ( ) {
245+ const config = this . config ;
246+ const connection = config . connection ;
247+ let dbName = '' ;
248+ let adminConfig = { ...config } ;
249+
250+ if ( typeof connection === 'string' ) {
251+ const url = new URL ( connection ) ;
252+ dbName = url . pathname . slice ( 1 ) ;
253+ url . pathname = '/postgres' ;
254+ adminConfig . connection = url . toString ( ) ;
255+ } else {
256+ dbName = connection . database ;
257+ adminConfig . connection = { ...connection , database : 'postgres' } ;
258+ }
259+
260+ console . log ( `[KnexDriver] Database '${ dbName } ' does not exist. Creating...` ) ;
261+
262+ const adminKnex = knex ( adminConfig ) ;
263+ try {
264+ await adminKnex . raw ( `CREATE DATABASE "${ dbName } "` ) ;
265+ console . log ( `[KnexDriver] Database '${ dbName } ' created successfully.` ) ;
266+ } catch ( e : any ) {
267+ console . error ( `[KnexDriver] Failed to create database '${ dbName } ':` , e . message ) ;
268+ throw e ;
269+ } finally {
270+ await adminKnex . destroy ( ) ;
271+ }
272+ }
170273}
171274
0 commit comments