@@ -29,20 +29,24 @@ export function parseColumnType(type: DataTypeValue): [type: ParsedColumnType, i
2929 return [ dataType , isIncrements ]
3030}
3131
32+ export function asArray < T > ( arr : Arrayable < T > ) : T [ ] {
33+ return Array . isArray ( arr ) ? arr : [ arr ]
34+ }
35+
3236/**
3337 * Merge array with `_` and prepend `_`
3438 *
3539 * Return merged string and parsed array
3640 */
37- function parseArray ( arr : Arrayable < any > ) : [ columnListStr : string , key : string ] {
38- const columns = Array . isArray ( arr ) ? arr : [ arr ]
41+ function parseArray ( arr : Arrayable < any > ) : [ columnListStr : string , key : string , first : string ] {
42+ const columns = asArray ( arr )
3943 let key = ''
4044 let columnList = ''
4145 for ( const c of columns ) {
4246 key += `_${ c } `
4347 columnList += `"${ c } ",`
4448 }
45- return [ columnList . slice ( 0 , - 1 ) , key ]
49+ return [ columnList . slice ( 0 , - 1 ) , key , columns [ 0 ] ]
4650}
4751
4852/**
@@ -79,9 +83,9 @@ export function createTableWithIndexAndTrigger(
7983) : string [ ] {
8084 const { index, ...props } = table
8185 const result : string [ ] = [ ]
82- const { updateColumn, sql } = createTable ( trx , tableName , props )
86+ const [ sql , updateColumn , triggerColumn ] = createTable ( trx , tableName , props )
8387 result . push ( sql , ...createTableIndex ( tableName , index ) )
84- const triggerSql = createTimeTrigger ( tableName , updateColumn )
88+ const triggerSql = createTimeTrigger ( tableName , updateColumn , triggerColumn )
8589 if ( triggerSql ) {
8690 result . push ( triggerSql )
8791 }
@@ -102,9 +106,9 @@ export function createTable(
102106 trx : Kysely < any > | Transaction < any > ,
103107 tableName : string ,
104108 { columns, primary, unique, withoutRowId } : Omit < Table , 'index' > ,
105- ) : { updateColumn ?: string , sql : string } {
109+ ) : [ sql : string , updateColumn ?: string , triggerColumn ? : string ] {
106110 let updateColumn
107- let autoIncrementColumn
111+ let triggerColumn
108112
109113 const columnList : string [ ] = [ ]
110114
@@ -114,10 +118,13 @@ export function createTable(
114118 const [ dataType , isIncrements ] = parseColumnType ( type )
115119
116120 if ( isIncrements ) {
117- if ( autoIncrementColumn ) {
118- throw new Error ( `Multiple AUTOINCREMENT columns ( ${ autoIncrementColumn } , ${ columnName } ) in table ${ tableName } ` )
121+ if ( withoutRowId ) {
122+ throw new Error ( `Cannot setup AUTOINCREMENT column " ${ columnName } " in table " ${ tableName } " without rowid ` )
119123 }
120- autoIncrementColumn = columnName
124+ if ( triggerColumn ) {
125+ throw new Error ( `Multiple AUTOINCREMENT columns (${ triggerColumn } , ${ columnName } ) in table ${ tableName } ` )
126+ }
127+ triggerColumn = columnName
121128 columnList . push ( `"${ columnName } " ${ dataType } PRIMARY KEY AUTOINCREMENT` )
122129 } else {
123130 // update trigger column is not null
@@ -131,12 +138,15 @@ export function createTable(
131138
132139 // primary/unique key is jointable, so can not be set as trigger key
133140 if ( primary ) {
134- const [ targetColumns , key ] = parseArray ( primary )
135- if ( ! autoIncrementColumn ) {
141+ const [ targetColumns , key , first ] = parseArray ( primary )
142+ if ( ! triggerColumn ) {
136143 columnList . push ( `PRIMARY KEY (${ targetColumns } )` )
137- } else if ( autoIncrementColumn !== key . substring ( 1 ) ) {
138- throw new Error ( `Exists AUTOINCREMENT column "${ autoIncrementColumn } " in table "${ tableName } ", cannot setup extra primary key (${ targetColumns } )` )
144+ triggerColumn = first
145+ } else if ( triggerColumn !== key . substring ( 1 ) ) {
146+ throw new Error ( `Exists AUTOINCREMENT column "${ triggerColumn } " in table "${ tableName } ", cannot setup extra primary key (${ targetColumns } )` )
139147 }
148+ } else if ( withoutRowId ) {
149+ throw new Error ( `No primary key in table "${ tableName } " and "withoutRowId" setup` )
140150 }
141151
142152 if ( unique ) {
@@ -147,18 +157,19 @@ export function createTable(
147157
148158 const rowIdClause = withoutRowId ? ' WITHOUT ROWID' : ''
149159
150- return {
151- sql : `CREATE TABLE IF NOT EXISTS "${ tableName } " (${ columnList } )${ rowIdClause } ;` ,
160+ return [
161+ `CREATE TABLE IF NOT EXISTS "${ tableName } " (${ columnList } )${ rowIdClause } ;` ,
152162 updateColumn ,
153- }
163+ triggerColumn || 'rowid' ,
164+ ]
154165}
155166
156- export function createTimeTrigger ( tableName : string , updateColumn ? : string ) : string | undefined {
157- if ( ! updateColumn ) {
167+ export function createTimeTrigger ( tableName : string , updateColumn : string | undefined , triggerColumn : string | undefined ) : string | undefined {
168+ if ( ! updateColumn || ! triggerColumn ) {
158169 return
159170 }
160171 const triggerName = `tgr_${ tableName } _${ updateColumn } `
161- return `CREATE TRIGGER IF NOT EXISTS "${ triggerName } " AFTER UPDATE ON "${ tableName } " BEGIN UPDATE "${ tableName } " SET "${ updateColumn } " = CURRENT_TIMESTAMP WHERE "rowid " = NEW."rowid "; END;`
172+ return `CREATE TRIGGER IF NOT EXISTS "${ triggerName } " AFTER UPDATE ON "${ tableName } " BEGIN UPDATE "${ tableName } " SET "${ updateColumn } " = CURRENT_TIMESTAMP WHERE "${ triggerColumn } " = NEW."${ triggerColumn } "; END;`
162173}
163174
164175export function renameTable ( tableName : string , newTableName : string ) : string {
@@ -213,7 +224,7 @@ export function migrateWholeTable(
213224 const tempTableName = `_temp_${ tableName } `
214225
215226 // 1. create target table with temp name
216- const { updateColumn, sql } = createTable ( trx , tempTableName , targetTable )
227+ const [ sql , updateColumn , triggerColumn ] = createTable ( trx , tempTableName , targetTable )
217228 result . push ( sql )
218229
219230 // 2. diff and restore data from source table to target table
@@ -235,7 +246,7 @@ export function migrateWholeTable(
235246
236247 // 5. restore indexes and triggers
237248 result . push ( ...createTableIndex ( tableName , targetTable . index ) )
238- const triggerSql = createTimeTrigger ( tableName , updateColumn )
249+ const triggerSql = createTimeTrigger ( tableName , updateColumn , triggerColumn )
239250 if ( triggerSql ) {
240251 result . push ( triggerSql )
241252 }
0 commit comments