@@ -530,3 +530,171 @@ func BuildDMLUpdateQuery(databaseName, tableName string, tableColumns, sharedCol
530530 )
531531 return result , sharedArgs , uniqueKeyArgs , nil
532532}
533+
534+ type DMLDeleteQueryBuilder struct {
535+ tableColumns , uniqueKeyColumns * ColumnList
536+ preparedStatement string
537+ }
538+
539+ func NewDMLDeleteQueryBuilder (databaseName , tableName string , tableColumns , uniqueKeyColumns * ColumnList ) (* DMLDeleteQueryBuilder , error ) {
540+ if uniqueKeyColumns .Len () == 0 {
541+ return nil , fmt .Errorf ("no unique key columns found in NewDMLDeleteQueryBuilder" )
542+ }
543+ databaseName = EscapeName (databaseName )
544+ tableName = EscapeName (tableName )
545+ equalsComparison , err := BuildEqualsPreparedComparison (uniqueKeyColumns .Names ())
546+ if err != nil {
547+ return nil , err
548+ }
549+
550+ stmt := fmt .Sprintf (`
551+ delete /* gh-ost %s.%s */
552+ from
553+ %s.%s
554+ where
555+ %s` ,
556+ databaseName , tableName ,
557+ databaseName , tableName ,
558+ equalsComparison ,
559+ )
560+
561+ b := & DMLDeleteQueryBuilder {
562+ tableColumns : tableColumns ,
563+ uniqueKeyColumns : uniqueKeyColumns ,
564+ preparedStatement : stmt ,
565+ }
566+ return b , nil
567+ }
568+
569+ func (b * DMLDeleteQueryBuilder ) BuildQuery (args []interface {}) (string , []interface {}, error ) {
570+ if len (args ) != b .tableColumns .Len () {
571+ return "" , nil , fmt .Errorf ("args count differs from table column count in BuildDMLDeleteQuery" )
572+ }
573+ uniqueKeyArgs := make ([]interface {}, 0 , b .uniqueKeyColumns .Len ())
574+ for _ , column := range b .uniqueKeyColumns .Columns () {
575+ tableOrdinal := b .tableColumns .Ordinals [column .Name ]
576+ arg := column .convertArg (args [tableOrdinal ], true )
577+ uniqueKeyArgs = append (uniqueKeyArgs , arg )
578+ }
579+ return b .preparedStatement , uniqueKeyArgs , nil
580+ }
581+
582+ type DMLInsertQueryBuilder struct {
583+ tableColumns , sharedColumns * ColumnList
584+ preparedStatement string
585+ }
586+
587+ func NewDMLInsertQueryBuilder (databaseName , tableName string , tableColumns , sharedColumns , mappedSharedColumns * ColumnList ) (* DMLInsertQueryBuilder , error ) {
588+ if ! sharedColumns .IsSubsetOf (tableColumns ) {
589+ return nil , fmt .Errorf ("shared columns is not a subset of table columns in NewDMLInsertQueryBuilder" )
590+ }
591+ if sharedColumns .Len () == 0 {
592+ return nil , fmt .Errorf ("no shared columns found in NewDMLInsertQueryBuilder" )
593+ }
594+ databaseName = EscapeName (databaseName )
595+ tableName = EscapeName (tableName )
596+ mappedSharedColumnNames := duplicateNames (mappedSharedColumns .Names ())
597+ for i := range mappedSharedColumnNames {
598+ mappedSharedColumnNames [i ] = EscapeName (mappedSharedColumnNames [i ])
599+ }
600+ preparedValues := buildColumnsPreparedValues (mappedSharedColumns )
601+
602+ stmt := fmt .Sprintf (`
603+ replace /* gh-ost %s.%s */
604+ into
605+ %s.%s
606+ (%s)
607+ values
608+ (%s)` ,
609+ databaseName , tableName ,
610+ databaseName , tableName ,
611+ strings .Join (mappedSharedColumnNames , ", " ),
612+ strings .Join (preparedValues , ", " ),
613+ )
614+
615+ return & DMLInsertQueryBuilder {
616+ tableColumns : tableColumns ,
617+ sharedColumns : sharedColumns ,
618+ preparedStatement : stmt ,
619+ }, nil
620+ }
621+
622+ func (b * DMLInsertQueryBuilder ) BuildQuery (args []interface {}) (string , []interface {}, error ) {
623+ if len (args ) != b .tableColumns .Len () {
624+ return "" , nil , fmt .Errorf ("args count differs from table column count in BuildDMLInsertQuery" )
625+ }
626+ sharedArgs := make ([]interface {}, 0 , b .sharedColumns .Len ())
627+ for _ , column := range b .sharedColumns .Columns () {
628+ tableOrdinal := b .tableColumns .Ordinals [column .Name ]
629+ arg := column .convertArg (args [tableOrdinal ], false )
630+ sharedArgs = append (sharedArgs , arg )
631+ }
632+ return b .preparedStatement , sharedArgs , nil
633+ }
634+
635+ type DMLUpdateQueryBuilder struct {
636+ tableColumns , sharedColumns , uniqueKeyColumns * ColumnList
637+ preparedStatement string
638+ }
639+
640+ func NewDMLUpdateQueryBuilder (databaseName , tableName string , tableColumns , sharedColumns , mappedSharedColumns , uniqueKeyColumns * ColumnList ) (* DMLUpdateQueryBuilder , error ) {
641+ if ! sharedColumns .IsSubsetOf (tableColumns ) {
642+ return nil , fmt .Errorf ("shared columns is not a subset of table columns in NewDMLUpdateQueryBuilder" )
643+ }
644+ if ! uniqueKeyColumns .IsSubsetOf (sharedColumns ) {
645+ return nil , fmt .Errorf ("unique key columns is not a subset of shared columns in NewDMLUpdateQueryBuilder" )
646+ }
647+ if sharedColumns .Len () == 0 {
648+ return nil , fmt .Errorf ("no shared columns found in NewDMLUpdateQueryBuilder" )
649+ }
650+ if uniqueKeyColumns .Len () == 0 {
651+ return nil , fmt .Errorf ("no unique key columns found in NewDMLUpdateQueryBuilder" )
652+ }
653+ databaseName = EscapeName (databaseName )
654+ tableName = EscapeName (tableName )
655+ setClause , err := BuildSetPreparedClause (mappedSharedColumns )
656+ if err != nil {
657+ return nil , err
658+ }
659+
660+ equalsComparison , err := BuildEqualsPreparedComparison (uniqueKeyColumns .Names ())
661+ if err != nil {
662+ return nil , err
663+ }
664+ stmt := fmt .Sprintf (`
665+ update /* gh-ost %s.%s */
666+ %s.%s
667+ set
668+ %s
669+ where
670+ %s` ,
671+ databaseName , tableName ,
672+ databaseName , tableName ,
673+ setClause ,
674+ equalsComparison ,
675+ )
676+ return & DMLUpdateQueryBuilder {
677+ tableColumns : tableColumns ,
678+ sharedColumns : sharedColumns ,
679+ uniqueKeyColumns : uniqueKeyColumns ,
680+ preparedStatement : stmt ,
681+ }, nil
682+ }
683+
684+ func (b * DMLUpdateQueryBuilder ) BuildQuery (valueArgs , whereArgs []interface {}) (string , []interface {}, []interface {}, error ) {
685+ sharedArgs := make ([]interface {}, 0 , b .sharedColumns .Len ())
686+ for _ , column := range b .sharedColumns .Columns () {
687+ tableOrdinal := b .tableColumns .Ordinals [column .Name ]
688+ arg := column .convertArg (valueArgs [tableOrdinal ], false )
689+ sharedArgs = append (sharedArgs , arg )
690+ }
691+
692+ uniqueKeyArgs := make ([]interface {}, 0 , b .uniqueKeyColumns .Len ())
693+ for _ , column := range b .uniqueKeyColumns .Columns () {
694+ tableOrdinal := b .tableColumns .Ordinals [column .Name ]
695+ arg := column .convertArg (whereArgs [tableOrdinal ], true )
696+ uniqueKeyArgs = append (uniqueKeyArgs , arg )
697+ }
698+
699+ return b .preparedStatement , sharedArgs , uniqueKeyArgs , nil
700+ }
0 commit comments