github.com/matrixorigin/matrixone@v1.2.0/pkg/stream/connector/converter.go (about)

     1  // Copyright 2021 - 2023 Matrix Origin
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package moconnector
    16  
    17  import (
    18  	"context"
    19  	"fmt"
    20  	"strings"
    21  
    22  	ie "github.com/matrixorigin/matrixone/pkg/util/internalExecutor"
    23  )
    24  
    25  type Converter interface {
    26  	Convert(context.Context, ie.InternalExecResult) (string, error)
    27  }
    28  
    29  type SQLConverter struct {
    30  	dbName    string
    31  	tableName string
    32  }
    33  
    34  func newSQLConverter(dbName, tableName string) Converter {
    35  	return &SQLConverter{
    36  		dbName:    dbName,
    37  		tableName: tableName,
    38  	}
    39  }
    40  
    41  func (c *SQLConverter) Convert(ctx context.Context, obj ie.InternalExecResult) (string, error) {
    42  
    43  	columnCount := int(obj.ColumnCount())
    44  	rowCount := int(obj.RowCount())
    45  
    46  	var fields, values string
    47  	var colNames []string
    48  
    49  	for i := 0; i < columnCount; i++ {
    50  		name, _, _, err := obj.Column(ctx, uint64(i))
    51  		if err != nil {
    52  			return "", err // Handle the error appropriately
    53  		}
    54  
    55  		if strings.Contains(name, ".") {
    56  			parts := strings.SplitN(name, ".", 2)
    57  			fields += "`" + parts[0] + "`.`" + parts[1] + "`"
    58  		} else {
    59  			fields += "`" + name + "`"
    60  		}
    61  
    62  		if i < columnCount-1 {
    63  			fields += ", "
    64  		}
    65  		colNames = append(colNames, name)
    66  	}
    67  	for i := 0; i < rowCount; i++ {
    68  		var rowValues string
    69  		var err error
    70  		for j := 0; j < columnCount; j++ {
    71  			var val string
    72  			val, err = obj.StringValueByName(ctx, uint64(i), colNames[j])
    73  			// Enclose the value in single quotes if it is a string
    74  			if err != nil {
    75  				rowValues += "NULL"
    76  			} else {
    77  				rowValues += "'" + val + "'"
    78  			}
    79  			if j < columnCount-1 {
    80  				rowValues += ", "
    81  			}
    82  		}
    83  
    84  		if i > 0 && len(values) > 0 {
    85  			values += ", "
    86  		}
    87  		values += fmt.Sprintf("(%s)", rowValues)
    88  	}
    89  	s := fmt.Sprintf("INSERT INTO %s.%s (%s) VALUES %s ",
    90  		c.dbName, c.tableName, fields, values)
    91  	return s, nil
    92  }