exploded args on range query building; iteration works
This commit is contained in:
parent
3583ab5dc5
commit
d8fefb3d6f
@ -11,7 +11,6 @@ import (
|
|||||||
"github.com/github/gh-osc/go/base"
|
"github.com/github/gh-osc/go/base"
|
||||||
"github.com/github/gh-osc/go/mysql"
|
"github.com/github/gh-osc/go/mysql"
|
||||||
"github.com/github/gh-osc/go/sql"
|
"github.com/github/gh-osc/go/sql"
|
||||||
"reflect"
|
|
||||||
|
|
||||||
"github.com/outbrain/golib/log"
|
"github.com/outbrain/golib/log"
|
||||||
"github.com/outbrain/golib/sqlutils"
|
"github.com/outbrain/golib/sqlutils"
|
||||||
@ -156,17 +155,17 @@ func (this *Applier) IterationIsComplete() (bool, error) {
|
|||||||
if this.migrationContext.MigrationIterationRangeMinValues == nil {
|
if this.migrationContext.MigrationIterationRangeMinValues == nil {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
compareWithIterationRangeStart, err := sql.BuildRangePreparedComparison(this.migrationContext.UniqueKey.Columns, sql.GreaterThanOrEqualsComparisonSign)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
compareWithRangeEnd, err := sql.BuildRangePreparedComparison(this.migrationContext.UniqueKey.Columns, sql.LessThanComparisonSign)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
args := sqlutils.Args()
|
args := sqlutils.Args()
|
||||||
args = append(args, this.migrationContext.MigrationIterationRangeMinValues.AbstractValues()...)
|
compareWithIterationRangeStart, explodedArgs, err := sql.BuildRangePreparedComparison(this.migrationContext.UniqueKey.Columns, this.migrationContext.MigrationIterationRangeMinValues.AbstractValues(), sql.GreaterThanOrEqualsComparisonSign)
|
||||||
args = append(args, this.migrationContext.MigrationRangeMaxValues.AbstractValues()...)
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
args = append(args, explodedArgs...)
|
||||||
|
compareWithRangeEnd, explodedArgs, err := sql.BuildRangePreparedComparison(this.migrationContext.UniqueKey.Columns, this.migrationContext.MigrationRangeMaxValues.AbstractValues(), sql.LessThanComparisonSign)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
args = append(args, explodedArgs...)
|
||||||
query := fmt.Sprintf(`
|
query := fmt.Sprintf(`
|
||||||
select /* gh-osc IterationIsComplete */ 1
|
select /* gh-osc IterationIsComplete */ 1
|
||||||
from %s.%s
|
from %s.%s
|
||||||
@ -178,13 +177,12 @@ func (this *Applier) IterationIsComplete() (bool, error) {
|
|||||||
compareWithIterationRangeStart,
|
compareWithIterationRangeStart,
|
||||||
compareWithRangeEnd,
|
compareWithRangeEnd,
|
||||||
)
|
)
|
||||||
log.Debugf(query)
|
|
||||||
|
|
||||||
moreRowsFound := false
|
moreRowsFound := false
|
||||||
err = sqlutils.QueryRowsMap(this.db, query, func(rowMap sqlutils.RowMap) error {
|
err = sqlutils.QueryRowsMap(this.db, query, func(rowMap sqlutils.RowMap) error {
|
||||||
moreRowsFound = true
|
moreRowsFound = true
|
||||||
return nil
|
return nil
|
||||||
}, args)
|
}, args...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
@ -192,16 +190,24 @@ func (this *Applier) IterationIsComplete() (bool, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (this *Applier) CalculateNextIterationRangeEndValues() error {
|
func (this *Applier) CalculateNextIterationRangeEndValues() error {
|
||||||
query, err := sql.BuildUniqueKeyRangeEndPreparedQuery(this.migrationContext.DatabaseName, this.migrationContext.OriginalTableName, this.migrationContext.UniqueKey.Columns, this.migrationContext.ChunkSize)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
startingFromValues := this.migrationContext.MigrationRangeMinValues
|
startingFromValues := this.migrationContext.MigrationRangeMinValues
|
||||||
this.migrationContext.MigrationIterationRangeMinValues = this.migrationContext.MigrationIterationRangeMaxValues
|
this.migrationContext.MigrationIterationRangeMinValues = this.migrationContext.MigrationIterationRangeMaxValues
|
||||||
if this.migrationContext.MigrationIterationRangeMinValues != nil {
|
if this.migrationContext.MigrationIterationRangeMinValues != nil {
|
||||||
startingFromValues = this.migrationContext.MigrationIterationRangeMinValues
|
startingFromValues = this.migrationContext.MigrationIterationRangeMinValues
|
||||||
}
|
}
|
||||||
rows, err := this.db.Query(query, startingFromValues.AbstractValues()...)
|
query, explodedArgs, err := sql.BuildUniqueKeyRangeEndPreparedQuery(
|
||||||
|
this.migrationContext.DatabaseName,
|
||||||
|
this.migrationContext.OriginalTableName,
|
||||||
|
this.migrationContext.UniqueKey.Columns,
|
||||||
|
startingFromValues.AbstractValues(),
|
||||||
|
this.migrationContext.MigrationRangeMaxValues.AbstractValues(),
|
||||||
|
this.migrationContext.ChunkSize,
|
||||||
|
fmt.Sprintf("iteration:%d", this.migrationContext.Iteration),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
rows, err := this.db.Query(query, explodedArgs...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -213,12 +219,12 @@ func (this *Applier) CalculateNextIterationRangeEndValues() error {
|
|||||||
}
|
}
|
||||||
iterationRangeEndFound = true
|
iterationRangeEndFound = true
|
||||||
}
|
}
|
||||||
log.Debugf("5")
|
|
||||||
if !iterationRangeEndFound {
|
if !iterationRangeEndFound {
|
||||||
return fmt.Errorf("Cannot find iteration range end")
|
log.Debugf("Iteration complete: cannot find iteration end")
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
this.migrationContext.MigrationIterationRangeMaxValues = iterationRangeMaxValues
|
this.migrationContext.MigrationIterationRangeMaxValues = iterationRangeMaxValues
|
||||||
log.Debugf("column values: %s", this.migrationContext.MigrationIterationRangeMaxValues)
|
log.Debugf("column values: %s; iteration: %d; chunk-size: %d", this.migrationContext.MigrationIterationRangeMaxValues, this.migrationContext.Iteration, this.migrationContext.ChunkSize)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,10 +244,6 @@ func (this *Applier) IterateTable(uniqueKey *sql.UniqueKey) error {
|
|||||||
if err = rows.Scan(columnValues.ValuesPointers...); err != nil {
|
if err = rows.Scan(columnValues.ValuesPointers...); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, val := range columnValues.BinaryValues() {
|
|
||||||
log.Debugf("%s", reflect.TypeOf(val))
|
|
||||||
log.Debugf("%s", string(val))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
log.Debugf("column values: %s", columnValues)
|
log.Debugf("column values: %s", columnValues)
|
||||||
query = `insert into test.sample_data_dump (category, ts) values (?, ?)`
|
query = `insert into test.sample_data_dump (category, ts) values (?, ?)`
|
||||||
|
@ -56,12 +56,10 @@ func (this *Migrator) Migrate() (err error) {
|
|||||||
// return err
|
// return err
|
||||||
// }
|
// }
|
||||||
this.migrationContext.UniqueKey = uniqueKeys[0]
|
this.migrationContext.UniqueKey = uniqueKeys[0]
|
||||||
this.migrationContext.ChunkSize = 100
|
|
||||||
if err := this.applier.ReadMigrationRangeValues(); err != nil {
|
if err := this.applier.ReadMigrationRangeValues(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for {
|
for {
|
||||||
log.Debugf("checking if complete")
|
|
||||||
isComplete, err := this.applier.IterationIsComplete()
|
isComplete, err := this.applier.IterationIsComplete()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -73,6 +71,7 @@ func (this *Migrator) Migrate() (err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
this.migrationContext.Iteration++
|
||||||
}
|
}
|
||||||
if err := this.applier.IterateTable(uniqueKeys[0]); err != nil {
|
if err := this.applier.IterateTable(uniqueKeys[0]); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -64,12 +64,15 @@ func BuildEqualsComparison(columns []string, values []string) (result string, er
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func BuildRangeComparison(columns []string, values []string, comparisonSign ValueComparisonSign) (result string, err error) {
|
func BuildRangeComparison(columns []string, values []string, args []interface{}, comparisonSign ValueComparisonSign) (result string, explodedArgs []interface{}, err error) {
|
||||||
if len(columns) == 0 {
|
if len(columns) == 0 {
|
||||||
return "", fmt.Errorf("Got 0 columns in GetRangeComparison")
|
return "", explodedArgs, fmt.Errorf("Got 0 columns in GetRangeComparison")
|
||||||
}
|
}
|
||||||
if len(columns) != len(values) {
|
if len(columns) != len(values) {
|
||||||
return "", fmt.Errorf("Got %d columns but %d values in GetEqualsComparison", len(columns), len(values))
|
return "", explodedArgs, fmt.Errorf("Got %d columns but %d values in GetEqualsComparison", len(columns), len(values))
|
||||||
|
}
|
||||||
|
if len(columns) != len(args) {
|
||||||
|
return "", explodedArgs, fmt.Errorf("Got %d columns but %d args in GetEqualsComparison", len(columns), len(args))
|
||||||
}
|
}
|
||||||
includeEquals := false
|
includeEquals := false
|
||||||
if comparisonSign == LessThanOrEqualsComparisonSign {
|
if comparisonSign == LessThanOrEqualsComparisonSign {
|
||||||
@ -87,43 +90,47 @@ func BuildRangeComparison(columns []string, values []string, comparisonSign Valu
|
|||||||
value := values[i]
|
value := values[i]
|
||||||
rangeComparison, err := BuildValueComparison(column, value, comparisonSign)
|
rangeComparison, err := BuildValueComparison(column, value, comparisonSign)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", explodedArgs, err
|
||||||
}
|
}
|
||||||
if len(columns[0:i]) > 0 {
|
if len(columns[0:i]) > 0 {
|
||||||
equalitiesComparison, err := BuildEqualsComparison(columns[0:i], values[0:i])
|
equalitiesComparison, err := BuildEqualsComparison(columns[0:i], values[0:i])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", explodedArgs, err
|
||||||
}
|
}
|
||||||
comparison := fmt.Sprintf("(%s AND %s)", equalitiesComparison, rangeComparison)
|
comparison := fmt.Sprintf("(%s AND %s)", equalitiesComparison, rangeComparison)
|
||||||
comparisons = append(comparisons, comparison)
|
comparisons = append(comparisons, comparison)
|
||||||
|
explodedArgs = append(explodedArgs, args[0:i]...)
|
||||||
|
explodedArgs = append(explodedArgs, args[i])
|
||||||
} else {
|
} else {
|
||||||
comparisons = append(comparisons, rangeComparison)
|
comparisons = append(comparisons, rangeComparison)
|
||||||
|
explodedArgs = append(explodedArgs, args[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if includeEquals {
|
if includeEquals {
|
||||||
comparison, err := BuildEqualsComparison(columns, values)
|
comparison, err := BuildEqualsComparison(columns, values)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil
|
return "", explodedArgs, nil
|
||||||
}
|
}
|
||||||
comparisons = append(comparisons, comparison)
|
comparisons = append(comparisons, comparison)
|
||||||
|
explodedArgs = append(explodedArgs, args...)
|
||||||
}
|
}
|
||||||
result = strings.Join(comparisons, " or ")
|
result = strings.Join(comparisons, " or ")
|
||||||
result = fmt.Sprintf("(%s)", result)
|
result = fmt.Sprintf("(%s)", result)
|
||||||
return result, nil
|
return result, explodedArgs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func BuildRangePreparedComparison(columns []string, comparisonSign ValueComparisonSign) (result string, err error) {
|
func BuildRangePreparedComparison(columns []string, args []interface{}, comparisonSign ValueComparisonSign) (result string, explodedArgs []interface{}, err error) {
|
||||||
values := make([]string, len(columns), len(columns))
|
values := make([]string, len(columns), len(columns))
|
||||||
for i := range columns {
|
for i := range columns {
|
||||||
values[i] = "?"
|
values[i] = "?"
|
||||||
}
|
}
|
||||||
return BuildRangeComparison(columns, values, comparisonSign)
|
return BuildRangeComparison(columns, values, args, comparisonSign)
|
||||||
}
|
}
|
||||||
|
|
||||||
func BuildRangeInsertQuery(databaseName, originalTableName, ghostTableName string, sharedColumns []string, uniqueKey string, uniqueKeyColumns, rangeStartValues, rangeEndValues []string, includeRangeStartValues bool) (string, error) {
|
func BuildRangeInsertQuery(databaseName, originalTableName, ghostTableName string, sharedColumns []string, uniqueKey string, uniqueKeyColumns, rangeStartValues, rangeEndValues []string, rangeStartArgs, rangeEndArgs []interface{}, includeRangeStartValues bool) (result string, explodedArgs []interface{}, err error) {
|
||||||
if len(sharedColumns) == 0 {
|
if len(sharedColumns) == 0 {
|
||||||
return "", fmt.Errorf("Got 0 shared columns in BuildRangeInsertQuery")
|
return "", explodedArgs, fmt.Errorf("Got 0 shared columns in BuildRangeInsertQuery")
|
||||||
}
|
}
|
||||||
databaseName = EscapeName(databaseName)
|
databaseName = EscapeName(databaseName)
|
||||||
originalTableName = EscapeName(originalTableName)
|
originalTableName = EscapeName(originalTableName)
|
||||||
@ -138,15 +145,17 @@ func BuildRangeInsertQuery(databaseName, originalTableName, ghostTableName strin
|
|||||||
if includeRangeStartValues {
|
if includeRangeStartValues {
|
||||||
minRangeComparisonSign = GreaterThanOrEqualsComparisonSign
|
minRangeComparisonSign = GreaterThanOrEqualsComparisonSign
|
||||||
}
|
}
|
||||||
rangeStartComparison, err := BuildRangeComparison(uniqueKeyColumns, rangeStartValues, minRangeComparisonSign)
|
rangeStartComparison, rangeExplodedArgs, err := BuildRangeComparison(uniqueKeyColumns, rangeStartValues, rangeStartArgs, minRangeComparisonSign)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", explodedArgs, err
|
||||||
}
|
}
|
||||||
rangeEndComparison, err := BuildRangeComparison(uniqueKeyColumns, rangeEndValues, LessThanOrEqualsComparisonSign)
|
explodedArgs = append(explodedArgs, rangeExplodedArgs...)
|
||||||
|
rangeEndComparison, rangeExplodedArgs, err := BuildRangeComparison(uniqueKeyColumns, rangeEndValues, rangeEndArgs, LessThanOrEqualsComparisonSign)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", explodedArgs, err
|
||||||
}
|
}
|
||||||
query := fmt.Sprintf(`
|
explodedArgs = append(explodedArgs, rangeExplodedArgs...)
|
||||||
|
result = fmt.Sprintf(`
|
||||||
insert /* gh-osc %s.%s */ ignore into %s.%s (%s)
|
insert /* gh-osc %s.%s */ ignore into %s.%s (%s)
|
||||||
(select %s from %s.%s force index (%s)
|
(select %s from %s.%s force index (%s)
|
||||||
where (%s and %s)
|
where (%s and %s)
|
||||||
@ -154,34 +163,37 @@ func BuildRangeInsertQuery(databaseName, originalTableName, ghostTableName strin
|
|||||||
`, databaseName, originalTableName, databaseName, ghostTableName, sharedColumnsListing,
|
`, databaseName, originalTableName, databaseName, ghostTableName, sharedColumnsListing,
|
||||||
sharedColumnsListing, databaseName, originalTableName, uniqueKey,
|
sharedColumnsListing, databaseName, originalTableName, uniqueKey,
|
||||||
rangeStartComparison, rangeEndComparison)
|
rangeStartComparison, rangeEndComparison)
|
||||||
return query, nil
|
return result, explodedArgs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func BuildRangeInsertPreparedQuery(databaseName, originalTableName, ghostTableName string, sharedColumns []string, uniqueKey string, uniqueKeyColumns []string, includeRangeStartValues bool) (string, error) {
|
func BuildRangeInsertPreparedQuery(databaseName, originalTableName, ghostTableName string, sharedColumns []string, uniqueKey string, uniqueKeyColumns []string, rangeStartArgs, rangeEndArgs []interface{}, includeRangeStartValues bool) (result string, explodedArgs []interface{}, err error) {
|
||||||
rangeStartValues := make([]string, len(uniqueKeyColumns), len(uniqueKeyColumns))
|
rangeStartValues := make([]string, len(uniqueKeyColumns), len(uniqueKeyColumns))
|
||||||
rangeEndValues := make([]string, len(uniqueKeyColumns), len(uniqueKeyColumns))
|
rangeEndValues := make([]string, len(uniqueKeyColumns), len(uniqueKeyColumns))
|
||||||
for i := range uniqueKeyColumns {
|
for i := range uniqueKeyColumns {
|
||||||
rangeStartValues[i] = "?"
|
rangeStartValues[i] = "?"
|
||||||
rangeEndValues[i] = "?"
|
rangeEndValues[i] = "?"
|
||||||
}
|
}
|
||||||
return BuildRangeInsertQuery(databaseName, originalTableName, ghostTableName, sharedColumns, uniqueKey, uniqueKeyColumns, rangeStartValues, rangeEndValues, includeRangeStartValues)
|
return BuildRangeInsertQuery(databaseName, originalTableName, ghostTableName, sharedColumns, uniqueKey, uniqueKeyColumns, rangeStartValues, rangeEndValues, rangeStartArgs, rangeEndArgs, includeRangeStartValues)
|
||||||
}
|
}
|
||||||
|
|
||||||
func BuildUniqueKeyRangeEndPreparedQuery(databaseName, tableName string, uniqueKeyColumns []string, chunkSize int) (string, error) {
|
func BuildUniqueKeyRangeEndPreparedQuery(databaseName, tableName string, uniqueKeyColumns []string, rangeStartArgs, rangeEndArgs []interface{}, chunkSize int, hint string) (result string, explodedArgs []interface{}, err error) {
|
||||||
if len(uniqueKeyColumns) == 0 {
|
if len(uniqueKeyColumns) == 0 {
|
||||||
return "", fmt.Errorf("Got 0 columns in BuildUniqueKeyRangeEndPreparedQuery")
|
return "", explodedArgs, fmt.Errorf("Got 0 columns in BuildUniqueKeyRangeEndPreparedQuery")
|
||||||
}
|
}
|
||||||
databaseName = EscapeName(databaseName)
|
databaseName = EscapeName(databaseName)
|
||||||
tableName = EscapeName(tableName)
|
tableName = EscapeName(tableName)
|
||||||
|
|
||||||
rangeStartComparison, err := BuildRangePreparedComparison(uniqueKeyColumns, GreaterThanComparisonSign)
|
rangeStartComparison, rangeExplodedArgs, err := BuildRangePreparedComparison(uniqueKeyColumns, rangeStartArgs, GreaterThanComparisonSign)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", explodedArgs, err
|
||||||
}
|
}
|
||||||
rangeEndComparison, err := BuildRangePreparedComparison(uniqueKeyColumns, LessThanOrEqualsComparisonSign)
|
explodedArgs = append(explodedArgs, rangeExplodedArgs...)
|
||||||
|
rangeEndComparison, rangeExplodedArgs, err := BuildRangePreparedComparison(uniqueKeyColumns, rangeEndArgs, LessThanOrEqualsComparisonSign)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", explodedArgs, err
|
||||||
}
|
}
|
||||||
|
explodedArgs = append(explodedArgs, rangeExplodedArgs...)
|
||||||
|
|
||||||
uniqueKeyColumnAscending := make([]string, len(uniqueKeyColumns), len(uniqueKeyColumns))
|
uniqueKeyColumnAscending := make([]string, len(uniqueKeyColumns), len(uniqueKeyColumns))
|
||||||
uniqueKeyColumnDescending := make([]string, len(uniqueKeyColumns), len(uniqueKeyColumns))
|
uniqueKeyColumnDescending := make([]string, len(uniqueKeyColumns), len(uniqueKeyColumns))
|
||||||
for i := range uniqueKeyColumns {
|
for i := range uniqueKeyColumns {
|
||||||
@ -189,8 +201,8 @@ func BuildUniqueKeyRangeEndPreparedQuery(databaseName, tableName string, uniqueK
|
|||||||
uniqueKeyColumnAscending[i] = fmt.Sprintf("%s asc", uniqueKeyColumns[i])
|
uniqueKeyColumnAscending[i] = fmt.Sprintf("%s asc", uniqueKeyColumns[i])
|
||||||
uniqueKeyColumnDescending[i] = fmt.Sprintf("%s desc", uniqueKeyColumns[i])
|
uniqueKeyColumnDescending[i] = fmt.Sprintf("%s desc", uniqueKeyColumns[i])
|
||||||
}
|
}
|
||||||
query := fmt.Sprintf(`
|
result = fmt.Sprintf(`
|
||||||
select /* gh-osc %s.%s */ %s
|
select /* gh-osc %s.%s %s */ %s
|
||||||
from (
|
from (
|
||||||
select
|
select
|
||||||
%s
|
%s
|
||||||
@ -204,13 +216,13 @@ func BuildUniqueKeyRangeEndPreparedQuery(databaseName, tableName string, uniqueK
|
|||||||
order by
|
order by
|
||||||
%s
|
%s
|
||||||
limit 1
|
limit 1
|
||||||
`, databaseName, tableName, strings.Join(uniqueKeyColumns, ", "),
|
`, databaseName, tableName, hint, strings.Join(uniqueKeyColumns, ", "),
|
||||||
strings.Join(uniqueKeyColumns, ", "), databaseName, tableName,
|
strings.Join(uniqueKeyColumns, ", "), databaseName, tableName,
|
||||||
rangeStartComparison, rangeEndComparison,
|
rangeStartComparison, rangeEndComparison,
|
||||||
strings.Join(uniqueKeyColumnAscending, ", "), chunkSize,
|
strings.Join(uniqueKeyColumnAscending, ", "), chunkSize,
|
||||||
strings.Join(uniqueKeyColumnDescending, ", "),
|
strings.Join(uniqueKeyColumnDescending, ", "),
|
||||||
)
|
)
|
||||||
return query, nil
|
return result, explodedArgs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func BuildUniqueKeyMinValuesPreparedQuery(databaseName, tableName string, uniqueKeyColumns []string) (string, error) {
|
func BuildUniqueKeyMinValuesPreparedQuery(databaseName, tableName string, uniqueKeyColumns []string) (string, error) {
|
||||||
|
@ -8,6 +8,7 @@ package sql
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"reflect"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -71,48 +72,60 @@ func TestBuildRangeComparison(t *testing.T) {
|
|||||||
{
|
{
|
||||||
columns := []string{"c1"}
|
columns := []string{"c1"}
|
||||||
values := []string{"@v1"}
|
values := []string{"@v1"}
|
||||||
comparison, err := BuildRangeComparison(columns, values, LessThanComparisonSign)
|
args := []interface{}{3}
|
||||||
|
comparison, explodedArgs, err := BuildRangeComparison(columns, values, args, LessThanComparisonSign)
|
||||||
test.S(t).ExpectNil(err)
|
test.S(t).ExpectNil(err)
|
||||||
test.S(t).ExpectEquals(comparison, "((`c1` < @v1))")
|
test.S(t).ExpectEquals(comparison, "((`c1` < @v1))")
|
||||||
|
test.S(t).ExpectTrue(reflect.DeepEqual(explodedArgs, []interface{}{3}))
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
columns := []string{"c1"}
|
columns := []string{"c1"}
|
||||||
values := []string{"@v1"}
|
values := []string{"@v1"}
|
||||||
comparison, err := BuildRangeComparison(columns, values, LessThanOrEqualsComparisonSign)
|
args := []interface{}{3}
|
||||||
|
comparison, explodedArgs, err := BuildRangeComparison(columns, values, args, LessThanOrEqualsComparisonSign)
|
||||||
test.S(t).ExpectNil(err)
|
test.S(t).ExpectNil(err)
|
||||||
test.S(t).ExpectEquals(comparison, "((`c1` < @v1) or ((`c1` = @v1)))")
|
test.S(t).ExpectEquals(comparison, "((`c1` < @v1) or ((`c1` = @v1)))")
|
||||||
|
test.S(t).ExpectTrue(reflect.DeepEqual(explodedArgs, []interface{}{3, 3}))
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
columns := []string{"c1", "c2"}
|
columns := []string{"c1", "c2"}
|
||||||
values := []string{"@v1", "@v2"}
|
values := []string{"@v1", "@v2"}
|
||||||
comparison, err := BuildRangeComparison(columns, values, LessThanComparisonSign)
|
args := []interface{}{3, 17}
|
||||||
|
comparison, explodedArgs, err := BuildRangeComparison(columns, values, args, LessThanComparisonSign)
|
||||||
test.S(t).ExpectNil(err)
|
test.S(t).ExpectNil(err)
|
||||||
test.S(t).ExpectEquals(comparison, "((`c1` < @v1) or (((`c1` = @v1)) AND (`c2` < @v2)))")
|
test.S(t).ExpectEquals(comparison, "((`c1` < @v1) or (((`c1` = @v1)) AND (`c2` < @v2)))")
|
||||||
|
test.S(t).ExpectTrue(reflect.DeepEqual(explodedArgs, []interface{}{3, 3, 17}))
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
columns := []string{"c1", "c2"}
|
columns := []string{"c1", "c2"}
|
||||||
values := []string{"@v1", "@v2"}
|
values := []string{"@v1", "@v2"}
|
||||||
comparison, err := BuildRangeComparison(columns, values, LessThanOrEqualsComparisonSign)
|
args := []interface{}{3, 17}
|
||||||
|
comparison, explodedArgs, err := BuildRangeComparison(columns, values, args, LessThanOrEqualsComparisonSign)
|
||||||
test.S(t).ExpectNil(err)
|
test.S(t).ExpectNil(err)
|
||||||
test.S(t).ExpectEquals(comparison, "((`c1` < @v1) or (((`c1` = @v1)) AND (`c2` < @v2)) or ((`c1` = @v1) and (`c2` = @v2)))")
|
test.S(t).ExpectEquals(comparison, "((`c1` < @v1) or (((`c1` = @v1)) AND (`c2` < @v2)) or ((`c1` = @v1) and (`c2` = @v2)))")
|
||||||
|
test.S(t).ExpectTrue(reflect.DeepEqual(explodedArgs, []interface{}{3, 3, 17, 3, 17}))
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
columns := []string{"c1", "c2", "c3"}
|
columns := []string{"c1", "c2", "c3"}
|
||||||
values := []string{"@v1", "@v2", "@v3"}
|
values := []string{"@v1", "@v2", "@v3"}
|
||||||
comparison, err := BuildRangeComparison(columns, values, LessThanOrEqualsComparisonSign)
|
args := []interface{}{3, 17, 22}
|
||||||
|
comparison, explodedArgs, err := BuildRangeComparison(columns, values, args, LessThanOrEqualsComparisonSign)
|
||||||
test.S(t).ExpectNil(err)
|
test.S(t).ExpectNil(err)
|
||||||
test.S(t).ExpectEquals(comparison, "((`c1` < @v1) or (((`c1` = @v1)) AND (`c2` < @v2)) or (((`c1` = @v1) and (`c2` = @v2)) AND (`c3` < @v3)) or ((`c1` = @v1) and (`c2` = @v2) and (`c3` = @v3)))")
|
test.S(t).ExpectEquals(comparison, "((`c1` < @v1) or (((`c1` = @v1)) AND (`c2` < @v2)) or (((`c1` = @v1) and (`c2` = @v2)) AND (`c3` < @v3)) or ((`c1` = @v1) and (`c2` = @v2) and (`c3` = @v3)))")
|
||||||
|
test.S(t).ExpectTrue(reflect.DeepEqual(explodedArgs, []interface{}{3, 3, 17, 3, 17, 22, 3, 17, 22}))
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
columns := []string{"c1"}
|
columns := []string{"c1"}
|
||||||
values := []string{"@v1", "@v2"}
|
values := []string{"@v1", "@v2"}
|
||||||
_, err := BuildRangeComparison(columns, values, LessThanOrEqualsComparisonSign)
|
args := []interface{}{3, 17}
|
||||||
|
_, _, err := BuildRangeComparison(columns, values, args, LessThanOrEqualsComparisonSign)
|
||||||
test.S(t).ExpectNotNil(err)
|
test.S(t).ExpectNotNil(err)
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
columns := []string{}
|
columns := []string{}
|
||||||
values := []string{}
|
values := []string{}
|
||||||
_, err := BuildRangeComparison(columns, values, LessThanOrEqualsComparisonSign)
|
args := []interface{}{}
|
||||||
|
_, _, err := BuildRangeComparison(columns, values, args, LessThanOrEqualsComparisonSign)
|
||||||
test.S(t).ExpectNotNil(err)
|
test.S(t).ExpectNotNil(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -127,8 +140,10 @@ func TestBuildRangeInsertQuery(t *testing.T) {
|
|||||||
uniqueKeyColumns := []string{"id"}
|
uniqueKeyColumns := []string{"id"}
|
||||||
rangeStartValues := []string{"@v1s"}
|
rangeStartValues := []string{"@v1s"}
|
||||||
rangeEndValues := []string{"@v1e"}
|
rangeEndValues := []string{"@v1e"}
|
||||||
|
rangeStartArgs := []interface{}{3}
|
||||||
|
rangeEndArgs := []interface{}{103}
|
||||||
|
|
||||||
query, err := BuildRangeInsertQuery(databaseName, originalTableName, ghostTableName, sharedColumns, uniqueKey, uniqueKeyColumns, rangeStartValues, rangeEndValues, true)
|
query, explodedArgs, err := BuildRangeInsertQuery(databaseName, originalTableName, ghostTableName, sharedColumns, uniqueKey, uniqueKeyColumns, rangeStartValues, rangeEndValues, rangeStartArgs, rangeEndArgs, true)
|
||||||
test.S(t).ExpectNil(err)
|
test.S(t).ExpectNil(err)
|
||||||
expected := `
|
expected := `
|
||||||
insert /* gh-osc mydb.tbl */ ignore into mydb.ghost (id, name, position)
|
insert /* gh-osc mydb.tbl */ ignore into mydb.ghost (id, name, position)
|
||||||
@ -137,14 +152,17 @@ func TestBuildRangeInsertQuery(t *testing.T) {
|
|||||||
)
|
)
|
||||||
`
|
`
|
||||||
test.S(t).ExpectEquals(normalizeQuery(query), normalizeQuery(expected))
|
test.S(t).ExpectEquals(normalizeQuery(query), normalizeQuery(expected))
|
||||||
|
test.S(t).ExpectTrue(reflect.DeepEqual(explodedArgs, []interface{}{3, 3, 103, 103}))
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
uniqueKey := "name_position_uidx"
|
uniqueKey := "name_position_uidx"
|
||||||
uniqueKeyColumns := []string{"name", "position"}
|
uniqueKeyColumns := []string{"name", "position"}
|
||||||
rangeStartValues := []string{"@v1s", "@v2s"}
|
rangeStartValues := []string{"@v1s", "@v2s"}
|
||||||
rangeEndValues := []string{"@v1e", "@v2e"}
|
rangeEndValues := []string{"@v1e", "@v2e"}
|
||||||
|
rangeStartArgs := []interface{}{3, 17}
|
||||||
|
rangeEndArgs := []interface{}{103, 117}
|
||||||
|
|
||||||
query, err := BuildRangeInsertQuery(databaseName, originalTableName, ghostTableName, sharedColumns, uniqueKey, uniqueKeyColumns, rangeStartValues, rangeEndValues, true)
|
query, explodedArgs, err := BuildRangeInsertQuery(databaseName, originalTableName, ghostTableName, sharedColumns, uniqueKey, uniqueKeyColumns, rangeStartValues, rangeEndValues, rangeStartArgs, rangeEndArgs, true)
|
||||||
test.S(t).ExpectNil(err)
|
test.S(t).ExpectNil(err)
|
||||||
expected := `
|
expected := `
|
||||||
insert /* gh-osc mydb.tbl */ ignore into mydb.ghost (id, name, position)
|
insert /* gh-osc mydb.tbl */ ignore into mydb.ghost (id, name, position)
|
||||||
@ -153,6 +171,7 @@ func TestBuildRangeInsertQuery(t *testing.T) {
|
|||||||
)
|
)
|
||||||
`
|
`
|
||||||
test.S(t).ExpectEquals(normalizeQuery(query), normalizeQuery(expected))
|
test.S(t).ExpectEquals(normalizeQuery(query), normalizeQuery(expected))
|
||||||
|
test.S(t).ExpectTrue(reflect.DeepEqual(explodedArgs, []interface{}{3, 3, 17, 3, 17, 103, 103, 117, 103, 117}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,8 +183,10 @@ func TestBuildRangeInsertPreparedQuery(t *testing.T) {
|
|||||||
{
|
{
|
||||||
uniqueKey := "name_position_uidx"
|
uniqueKey := "name_position_uidx"
|
||||||
uniqueKeyColumns := []string{"name", "position"}
|
uniqueKeyColumns := []string{"name", "position"}
|
||||||
|
rangeStartArgs := []interface{}{3, 17}
|
||||||
|
rangeEndArgs := []interface{}{103, 117}
|
||||||
|
|
||||||
query, err := BuildRangeInsertPreparedQuery(databaseName, originalTableName, ghostTableName, sharedColumns, uniqueKey, uniqueKeyColumns, true)
|
query, explodedArgs, err := BuildRangeInsertPreparedQuery(databaseName, originalTableName, ghostTableName, sharedColumns, uniqueKey, uniqueKeyColumns, rangeStartArgs, rangeEndArgs, true)
|
||||||
test.S(t).ExpectNil(err)
|
test.S(t).ExpectNil(err)
|
||||||
expected := `
|
expected := `
|
||||||
insert /* gh-osc mydb.tbl */ ignore into mydb.ghost (id, name, position)
|
insert /* gh-osc mydb.tbl */ ignore into mydb.ghost (id, name, position)
|
||||||
@ -174,6 +195,7 @@ func TestBuildRangeInsertPreparedQuery(t *testing.T) {
|
|||||||
)
|
)
|
||||||
`
|
`
|
||||||
test.S(t).ExpectEquals(normalizeQuery(query), normalizeQuery(expected))
|
test.S(t).ExpectEquals(normalizeQuery(query), normalizeQuery(expected))
|
||||||
|
test.S(t).ExpectTrue(reflect.DeepEqual(explodedArgs, []interface{}{3, 3, 17, 3, 17, 103, 103, 117, 103, 117}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,11 +205,13 @@ func TestBuildUniqueKeyRangeEndPreparedQuery(t *testing.T) {
|
|||||||
chunkSize := 500
|
chunkSize := 500
|
||||||
{
|
{
|
||||||
uniqueKeyColumns := []string{"name", "position"}
|
uniqueKeyColumns := []string{"name", "position"}
|
||||||
|
rangeStartArgs := []interface{}{3, 17}
|
||||||
|
rangeEndArgs := []interface{}{103, 117}
|
||||||
|
|
||||||
query, err := BuildUniqueKeyRangeEndPreparedQuery(databaseName, originalTableName, uniqueKeyColumns, chunkSize)
|
query, explodedArgs, err := BuildUniqueKeyRangeEndPreparedQuery(databaseName, originalTableName, uniqueKeyColumns, rangeStartArgs, rangeEndArgs, chunkSize, "test")
|
||||||
test.S(t).ExpectNil(err)
|
test.S(t).ExpectNil(err)
|
||||||
expected := `
|
expected := `
|
||||||
select /* gh-osc mydb.tbl */ name, position
|
select /* gh-osc mydb.tbl test */ name, position
|
||||||
from (
|
from (
|
||||||
select
|
select
|
||||||
name, position
|
name, position
|
||||||
@ -203,6 +227,7 @@ func TestBuildUniqueKeyRangeEndPreparedQuery(t *testing.T) {
|
|||||||
limit 1
|
limit 1
|
||||||
`
|
`
|
||||||
test.S(t).ExpectEquals(normalizeQuery(query), normalizeQuery(expected))
|
test.S(t).ExpectEquals(normalizeQuery(query), normalizeQuery(expected))
|
||||||
|
test.S(t).ExpectTrue(reflect.DeepEqual(explodedArgs, []interface{}{3, 3, 17, 103, 103, 117, 103, 117}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,18 +65,14 @@ func (this *ColumnValues) AbstractValues() []interface{} {
|
|||||||
return this.abstractValues
|
return this.abstractValues
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ColumnValues) BinaryValues() [][]uint8 {
|
|
||||||
result := make([][]uint8, len(this.abstractValues), len(this.abstractValues))
|
|
||||||
for i, val := range this.abstractValues {
|
|
||||||
result[i] = val.([]uint8)
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *ColumnValues) String() string {
|
func (this *ColumnValues) String() string {
|
||||||
stringValues := []string{}
|
stringValues := []string{}
|
||||||
for _, val := range this.BinaryValues() {
|
for _, val := range this.AbstractValues() {
|
||||||
stringValues = append(stringValues, string(val))
|
if ints, ok := val.([]uint8); ok {
|
||||||
|
stringValues = append(stringValues, string(ints))
|
||||||
|
} else {
|
||||||
|
stringValues = append(stringValues, fmt.Sprintf("%+v", val))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return strings.Join(stringValues, ",")
|
return strings.Join(stringValues, ",")
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user