@@ -530,3 +530,171 @@ func BuildDMLUpdateQuery(databaseName, tableName string, tableColumns, sharedCol
530
530
)
531
531
return result , sharedArgs , uniqueKeyArgs , nil
532
532
}
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