klesh commented on code in PR #3473:
URL: 
https://github.com/apache/incubator-devlake/pull/3473#discussion_r1003284378


##########
helpers/migrationhelper/migrationhelper.go:
##########
@@ -42,6 +43,138 @@ func AutoMigrateTables(basicRes core.BasicRes, dst 
...interface{}) errors.Error
        return nil
 }
 
+// ChangeColumnsType change the type of specified columns for the table
+func ChangeColumnsType[D any](
+       basicRes core.BasicRes,
+       script core.MigrationScript,
+       tableName string,
+       columns []string,
+       update func(tmpColumnParams []interface{}) errors.Error,
+) (err errors.Error) {
+       db := basicRes.GetDal()
+       tmpColumnsNames := make([]string, len(columns))
+       for i, v := range columns {
+               tmpColumnsNames[i] = fmt.Sprintf("%s_%s", v, hashScript(script))
+               err = db.RenameColumn(tableName, v, tmpColumnsNames[i])
+               if err != nil {
+                       return err
+               }
+
+               defer func(tmpColumnName string, ColumnsName string) {
+                       if err != nil {
+                               err1 := db.RenameColumn(tableName, 
tmpColumnName, ColumnsName)
+                               if err1 != nil {
+                                       err = errors.Default.Wrap(err, 
fmt.Sprintf("RollBack by RenameColum failed.Relevant data needs to be repaired 
manually.%s", err1.Error()))
+                               }
+                       }
+               }(tmpColumnsNames[i], v)
+       }
+
+       err = db.AutoMigrate(new(D), dal.From(tableName))
+       if err != nil {
+               return errors.Default.Wrap(err, "AutoMigrate for Add Colume 
Error")
+       }
+
+       defer func() {
+               if err != nil {
+                       err1 := db.DropColumns(tableName, columns...)
+                       if err1 != nil {
+                               err = errors.Default.Wrap(err, 
fmt.Sprintf("RollBack by DropColume failed.Relevant data needs to be repaired 
manually.%s", err1.Error()))
+                       }
+               }
+       }()
+
+       if update == nil {
+               params := make([]interface{}, 0, len(columns)*2+1)
+               params = append(params, clause.Table{Name: tableName})
+               updateStr := "UPDATE ? SET "
+               for i, v := range columns {
+                       if i > 0 {
+                               updateStr += " AND "
+                       }
+                       updateStr += "? = ?"
+                       params = append(params, clause.Column{Name: v})
+                       params = append(params, clause.Column{Name: 
tmpColumnsNames[i]})
+               }
+               err = db.Exec(updateStr, params...)
+       } else {
+               params := make([]interface{}, 0, len(tmpColumnsNames))
+               for _, v := range tmpColumnsNames {
+                       params = append(params, clause.Column{Name: v})
+               }
+               err = update(params)
+       }
+       if err != nil {
+               return err
+       }
+
+       err = db.DropColumns(tableName, tmpColumnsNames...)
+       if err != nil {
+               return err
+       }
+
+       return nil
+}
+
+// TransformColumns change the type of specified columns for the table and 
transform data one by one
+func TransformColumns[S any, D any](
+       basicRes core.BasicRes,
+       script core.MigrationScript,
+       tableName string,
+       columns []string,
+       transform func(src *S) (*D, errors.Error),
+) (err errors.Error) {
+       db := basicRes.GetDal()
+       return ChangeColumnsType[D](
+               basicRes,
+               script,
+               tableName,
+               columns,
+               func(tmpColumnParams []interface{}) errors.Error {
+                       // create selectStr for transform tmpColumnsNames
+                       params := make([]interface{}, 0, len(columns)*2+1)
+                       selectStr := "SELECT * "
+                       for i, v := range columns {
+                               selectStr += ",? as ?"
+                               params = append(params, tmpColumnParams[i])
+                               params = append(params, clause.Column{Name: v})
+                       }
+                       selectStr += " FROM ? "
+                       params = append(params, clause.Table{Name: tableName})
+
+                       cursor, err := db.RawCursor(selectStr, params...)

Review Comment:
   I think we could use `db.Cursor` rather than `db.RawCursor`.
   It would be better to use `db.Cursor` because it is strong-typed



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to