@@ -228,7 +228,7 @@ func (session *Session) Sync2(beans ...interface{}) error {
228228defer session .Close ()
229229}
230230
231- tables , err := engine .DBMetas ()
231+ tables , err := engine .dialect . GetTables ()
232232if err != nil {
233233return err
234234}
@@ -239,15 +239,12 @@ func (session *Session) Sync2(beans ...interface{}) error {
239239session .resetStatement ()
240240}()
241241
242- var structTables []* core.Table
243-
244242for _ , bean := range beans {
245243v := rValue (bean )
246244table , err := engine .mapType (v )
247245if err != nil {
248246return err
249247}
250- structTables = append (structTables , table )
251248tbName := engine .TableName (bean )
252249tbNameWithSchema := engine .TableName (tbName , true )
253250
@@ -259,6 +256,7 @@ func (session *Session) Sync2(beans ...interface{}) error {
259256}
260257}
261258
259+ // this is a new table
262260if oriTable == nil {
263261err = session .StoreEngine (session .statement .StoreEngine ).createTable (bean )
264262if err != nil {
@@ -274,148 +272,148 @@ func (session *Session) Sync2(beans ...interface{}) error {
274272if err != nil {
275273return err
276274}
277- } else {
278- for _ , col := range table .Columns () {
279- var oriCol * core.Column
280- for _ , col2 := range oriTable .Columns () {
281- if strings .EqualFold (col .Name , col2 .Name ) {
282- oriCol = col2
283- break
284- }
285- }
275+ continue
276+ }
286277
287- if oriCol != nil {
288- expectedType := engine .dialect .SqlType (col )
289- curType := engine .dialect .SqlType (oriCol )
290- if expectedType != curType {
291- if expectedType == core .Text &&
292- strings .HasPrefix (curType , core .Varchar ) {
293- // currently only support mysql & postgres
294- if engine .dialect .DBType () == core .MYSQL ||
295- engine .dialect .DBType () == core .POSTGRES {
296- engine .logger .Infof ("Table %s column %s change type from %s to %s\n " ,
297- tbNameWithSchema , col .Name , curType , expectedType )
298- _ , err = session .exec (engine .dialect .ModifyColumnSql (tbNameWithSchema , col ))
299- } else {
300- engine .logger .Warnf ("Table %s column %s db type is %s, struct type is %s\n " ,
301- tbNameWithSchema , col .Name , curType , expectedType )
302- }
303- } else if strings .HasPrefix (curType , core .Varchar ) && strings .HasPrefix (expectedType , core .Varchar ) {
304- if engine .dialect .DBType () == core .MYSQL {
305- if oriCol .Length < col .Length {
306- engine .logger .Infof ("Table %s column %s change type from varchar(%d) to varchar(%d)\n " ,
307- tbNameWithSchema , col .Name , oriCol .Length , col .Length )
308- _ , err = session .exec (engine .dialect .ModifyColumnSql (tbNameWithSchema , col ))
309- }
310- }
311- } else {
312- if ! (strings .HasPrefix (curType , expectedType ) && curType [len (expectedType )] == '(' ) {
313- engine .logger .Warnf ("Table %s column %s db type is %s, struct type is %s" ,
314- tbNameWithSchema , col .Name , curType , expectedType )
315- }
316- }
317- } else if expectedType == core .Varchar {
318- if engine .dialect .DBType () == core .MYSQL {
319- if oriCol .Length < col .Length {
320- engine .logger .Infof ("Table %s column %s change type from varchar(%d) to varchar(%d)\n " ,
321- tbNameWithSchema , col .Name , oriCol .Length , col .Length )
322- _ , err = session .exec (engine .dialect .ModifyColumnSql (tbNameWithSchema , col ))
323- }
324- }
325- }
326- if col .Default != oriCol .Default {
327- engine .logger .Warnf ("Table %s Column %s db default is %s, struct default is %s" ,
328- tbName , col .Name , oriCol .Default , col .Default )
329- }
330- if col .Nullable != oriCol .Nullable {
331- engine .logger .Warnf ("Table %s Column %s db nullable is %v, struct nullable is %v" ,
332- tbName , col .Name , oriCol .Nullable , col .Nullable )
333- }
334- } else {
335- session .statement .RefTable = table
336- session .statement .tableName = tbNameWithSchema
337- err = session .addColumn (col .Name )
278+ // this will modify an old table
279+ if err = engine .loadTableInfo (oriTable ); err != nil {
280+ return err
281+ }
282+
283+ // check columns
284+ for _ , col := range table .Columns () {
285+ var oriCol * core.Column
286+ for _ , col2 := range oriTable .Columns () {
287+ if strings .EqualFold (col .Name , col2 .Name ) {
288+ oriCol = col2
289+ break
338290}
339- if err != nil {
291+ }
292+
293+ // column is not exist on table
294+ if oriCol == nil {
295+ session .statement .RefTable = table
296+ session .statement .tableName = tbNameWithSchema
297+ if err = session .addColumn (col .Name ); err != nil {
340298return err
341299}
300+ continue
342301}
343302
344- var foundIndexNames = make (map [string ]bool )
345- var addedNames = make (map [string ]* core.Index )
346-
347- for name , index := range table .Indexes {
348- var oriIndex * core.Index
349- for name2 , index2 := range oriTable .Indexes {
350- if index .Equal (index2 ) {
351- oriIndex = index2
352- foundIndexNames [name2 ] = true
353- break
303+ err = nil
304+ expectedType := engine .dialect .SqlType (col )
305+ curType := engine .dialect .SqlType (oriCol )
306+ if expectedType != curType {
307+ if expectedType == core .Text &&
308+ strings .HasPrefix (curType , core .Varchar ) {
309+ // currently only support mysql & postgres
310+ if engine .dialect .DBType () == core .MYSQL ||
311+ engine .dialect .DBType () == core .POSTGRES {
312+ engine .logger .Infof ("Table %s column %s change type from %s to %s\n " ,
313+ tbNameWithSchema , col .Name , curType , expectedType )
314+ _ , err = session .exec (engine .dialect .ModifyColumnSql (tbNameWithSchema , col ))
315+ } else {
316+ engine .logger .Warnf ("Table %s column %s db type is %s, struct type is %s\n " ,
317+ tbNameWithSchema , col .Name , curType , expectedType )
354318}
355- }
356-
357- if oriIndex != nil {
358- if oriIndex .Type != index .Type {
359- sql := engine .dialect .DropIndexSql (tbNameWithSchema , oriIndex )
360- _ , err = session .exec (sql )
361- if err != nil {
362- return err
319+ } else if strings .HasPrefix (curType , core .Varchar ) && strings .HasPrefix (expectedType , core .Varchar ) {
320+ if engine .dialect .DBType () == core .MYSQL {
321+ if oriCol .Length < col .Length {
322+ engine .logger .Infof ("Table %s column %s change type from varchar(%d) to varchar(%d)\n " ,
323+ tbNameWithSchema , col .Name , oriCol .Length , col .Length )
324+ _ , err = session .exec (engine .dialect .ModifyColumnSql (tbNameWithSchema , col ))
363325}
364- oriIndex = nil
326+ }
327+ } else {
328+ if ! (strings .HasPrefix (curType , expectedType ) && curType [len (expectedType )] == '(' ) {
329+ engine .logger .Warnf ("Table %s column %s db type is %s, struct type is %s" ,
330+ tbNameWithSchema , col .Name , curType , expectedType )
365331}
366332}
367-
368- if oriIndex == nil {
369- addedNames [name ] = index
333+ } else if expectedType == core .Varchar {
334+ if engine .dialect .DBType () == core .MYSQL {
335+ if oriCol .Length < col .Length {
336+ engine .logger .Infof ("Table %s column %s change type from varchar(%d) to varchar(%d)\n " ,
337+ tbNameWithSchema , col .Name , oriCol .Length , col .Length )
338+ _ , err = session .exec (engine .dialect .ModifyColumnSql (tbNameWithSchema , col ))
339+ }
370340}
371341}
342+ if col .Default != oriCol .Default {
343+ engine .logger .Warnf ("Table %s Column %s db default is %s, struct default is %s" ,
344+ tbName , col .Name , oriCol .Default , col .Default )
345+ }
346+ if col .Nullable != oriCol .Nullable {
347+ engine .logger .Warnf ("Table %s Column %s db nullable is %v, struct nullable is %v" ,
348+ tbName , col .Name , oriCol .Nullable , col .Nullable )
349+ }
350+
351+ if err != nil {
352+ return err
353+ }
354+ }
355+
356+ var foundIndexNames = make (map [string ]bool )
357+ var addedNames = make (map [string ]* core.Index )
372358
359+ for name , index := range table .Indexes {
360+ var oriIndex * core.Index
373361for name2 , index2 := range oriTable .Indexes {
374- if _ , ok := foundIndexNames [name2 ]; ! ok {
375- sql := engine .dialect .DropIndexSql (tbNameWithSchema , index2 )
362+ if index .Equal (index2 ) {
363+ oriIndex = index2
364+ foundIndexNames [name2 ] = true
365+ break
366+ }
367+ }
368+
369+ if oriIndex != nil {
370+ if oriIndex .Type != index .Type {
371+ sql := engine .dialect .DropIndexSql (tbNameWithSchema , oriIndex )
376372_ , err = session .exec (sql )
377373if err != nil {
378374return err
379375}
376+ oriIndex = nil
380377}
381378}
382379
383- for name , index := range addedNames {
384- if index .Type == core .UniqueType {
385- session .statement .RefTable = table
386- session .statement .tableName = tbNameWithSchema
387- err = session .addUnique (tbNameWithSchema , name )
388- } else if index .Type == core .IndexType {
389- session .statement .RefTable = table
390- session .statement .tableName = tbNameWithSchema
391- err = session .addIndex (tbNameWithSchema , name )
392- }
380+ if oriIndex == nil {
381+ addedNames [name ] = index
382+ }
383+ }
384+
385+ for name2 , index2 := range oriTable .Indexes {
386+ if _ , ok := foundIndexNames [name2 ]; ! ok {
387+ sql := engine .dialect .DropIndexSql (tbNameWithSchema , index2 )
388+ _ , err = session .exec (sql )
393389if err != nil {
394390return err
395391}
396392}
397393}
398- }
399394
400- for _ , table := range tables {
401- var oriTable * core.Table
402- for _ , structTable := range structTables {
403- if strings .EqualFold (table .Name , session .tbNameNoSchema (structTable )) {
404- oriTable = structTable
405- break
395+ for name , index := range addedNames {
396+ if index .Type == core .UniqueType {
397+ session .statement .RefTable = table
398+ session .statement .tableName = tbNameWithSchema
399+ err = session .addUnique (tbNameWithSchema , name )
400+ } else if index .Type == core .IndexType {
401+ session .statement .RefTable = table
402+ session .statement .tableName = tbNameWithSchema
403+ err = session .addIndex (tbNameWithSchema , name )
404+ }
405+ if err != nil {
406+ return err
406407}
407408}
408409
409- if oriTable == nil {
410- //engine.LogWarnf("Table %s has no struct to mapping it", table.Name)
411- continue
412- }
413-
414- for _ , colName := range table .ColumnsSeq () {
415- if oriTable .GetColumn (colName ) == nil {
416- engine .logger .Warnf ("Table %s has column %s but struct has not related field" , engine .TableName (table .Name , true ), colName )
410+ // check all the columns which removed from struct fields but left on database tables.
411+ for _ , colName := range oriTable .ColumnsSeq () {
412+ if table .GetColumn (colName ) == nil {
413+ engine .logger .Warnf ("Table %s has column %s but struct has not related field" , engine .TableName (oriTable .Name , true ), colName )
417414}
418415}
419416}
417+
420418return nil
421419}
0 commit comments