Skip to content

Commit

Permalink
fixup! feat: sqlconnect library
Browse files Browse the repository at this point in the history
  • Loading branch information
atzoum committed Feb 21, 2024
1 parent 1c0faba commit 9490d57
Show file tree
Hide file tree
Showing 2 changed files with 147 additions and 34 deletions.
136 changes: 136 additions & 0 deletions sqlconnect/internal/bigquery/driver/driver_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
package driver_test

import (
"context"
"database/sql"
"encoding/json"
"fmt"
"os"
"strings"
"testing"
"time"

"github.com/stretchr/testify/require"
"google.golang.org/api/option"

"github.com/rudderlabs/rudder-go-kit/testhelper/rand"
"github.com/rudderlabs/sqlconnect-go/sqlconnect/internal/bigquery/driver"
)

func TestBigqueryDriver(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)

configJSON, ok := os.LookupEnv("BIGQUERY_TEST_ENVIRONMENT_CREDENTIALS")
if !ok {
t.Skip("skipping bigquery driver test due to lack of a test environment")
}
var c config
require.NoError(t, json.Unmarshal([]byte(configJSON), &c))

db := sql.OpenDB(driver.NewConnector(c.ProjectID, option.WithCredentialsJSON([]byte(c.CredentialsJSON))))
t.Cleanup(func() {
require.NoError(t, db.Close(), "it should be able to close the database connection")
})

schema := GenerateTestSchema()

t.Run("Transaction unsupported", func(t *testing.T) {
t.Run("Begin", func(t *testing.T) {
_, err := db.Begin()
require.Error(t, err, "it should not be able to begin a transaction")
})

t.Run("BeginTx", func(t *testing.T) {
_, err := db.BeginTx(ctx, nil)
require.Error(t, err, "it should not be able to begin a transaction")
})
})
t.Run("Exec", func(t *testing.T) {
_, err := db.Exec(fmt.Sprintf("CREATE SCHEMA `%s`", schema))
require.NoError(t, err, "it should be able to create a schema")
})

t.Run("ExecContext", func(t *testing.T) {
_, err := db.ExecContext(ctx, fmt.Sprintf("CREATE TABLE `%s`.`test_table` (C1 INT)", schema))
require.NoError(t, err, "it should be able to create a table")
})

t.Run("prepared statement", func(t *testing.T) {
t.Run("QueryRow", func(t *testing.T) {
stmt, err := db.Prepare(fmt.Sprintf("SELECT COUNT(*) FROM `%s`.`test_table`", schema))
require.NoError(t, err, "it should be able to prepare a statement")
defer func() {
require.NoError(t, stmt.Close(), "it should be able to close the prepared statement")
}()

var count int
err = stmt.QueryRow().Scan(&count)
require.NoError(t, err, "it should be able to execute a prepared statement")
})

t.Run("Exec", func(t *testing.T) {
stmt, err := db.Prepare(fmt.Sprintf("INSERT INTO `%s`.`test_table` VALUES (?)", schema))
require.NoError(t, err, "it should be able to prepare a statement")
defer func() {
require.NoError(t, stmt.Close(), "it should be able to close the prepared statement")
}()
result, err := stmt.Exec(1)
require.NoError(t, err, "it should be able to execute a prepared statement")
rowsAffected, err := result.RowsAffected()
require.NoError(t, err, "it should be able to get rows affected")
require.EqualValues(t, 0, rowsAffected, "rows affected should be 0 (not supported)")
})

t.Run("Query", func(t *testing.T) {
stmt, err := db.Prepare(fmt.Sprintf("SELECT C1 FROM `%s`.`test_table` WHERE C1 = ?", schema))
require.NoError(t, err, "it should be able to prepare a statement")
defer func() {
require.NoError(t, stmt.Close(), "it should be able to close the prepared statement")
}()
rows, err := stmt.Query(1)
require.NoError(t, err, "it should be able to execute a prepared statement")
defer func() {
require.NoError(t, rows.Close(), "it should be able to close the rows")
}()
require.True(t, rows.Next(), "it should be able to get a row")
var c1 int
err = rows.Scan(&c1)
require.NoError(t, err, "it should be able to scan the row")
require.EqualValues(t, 1, c1, "it should be able to get the correct value")
require.False(t, rows.Next(), "it shouldn't have next row")

require.NoError(t, rows.Err())
})

t.Run("Query with named parameters", func(t *testing.T) {
stmt, err := db.Prepare(fmt.Sprintf("SELECT C1 FROM `%s`.`test_table` WHERE C1 = @c1_value", schema))
require.NoError(t, err, "it should be able to prepare a statement")
defer func() {
require.NoError(t, stmt.Close(), "it should be able to close the prepared statement")
}()
rows, err := stmt.Query(sql.Named("c1_value", 1))
require.NoError(t, err, "it should be able to execute a prepared statement")
defer func() {
require.NoError(t, rows.Close(), "it should be able to close the rows")
}()
require.True(t, rows.Next(), "it should be able to get a row")
var c1 int
err = rows.Scan(&c1)
require.NoError(t, err, "it should be able to scan the row")
require.EqualValues(t, 1, c1, "it should be able to get the correct value")
require.False(t, rows.Next(), "it shouldn't have next row")

require.NoError(t, rows.Err())
})
})
}

type config struct {
ProjectID string `json:"project"`
CredentialsJSON string `json:"credentials"`
}

func GenerateTestSchema() string {
return strings.ToLower(fmt.Sprintf("tbqdrv_%s_%d", rand.String(12), time.Now().Unix()))
}
45 changes: 11 additions & 34 deletions sqlconnect/internal/bigquery/driver/statement.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,16 @@ package driver
import (
"context"
"database/sql/driver"
"regexp"
"strings"

"cloud.google.com/go/bigquery"
"github.com/samber/lo"
"github.com/sirupsen/logrus"
)

var namedParamsRegexp = regexp.MustCompile(`@[\w]+`)

type bigQueryStatement struct {
connection *bigQueryConnection
query string
Expand All @@ -18,22 +23,19 @@ func (statement bigQueryStatement) Close() error {
}

func (statement bigQueryStatement) NumInput() int {
return 0
params := strings.Count(statement.query, "?")
if params > 0 {
return params
}
uniqueMatches := lo.Uniq(namedParamsRegexp.FindAllString(statement.query, -1))
return len(uniqueMatches)
}

func (bigQueryStatement) CheckNamedValue(*driver.NamedValue) error {
return nil
}

func (statement *bigQueryStatement) ExecContext(ctx context.Context, args []driver.NamedValue) (driver.Result, error) {
// logrus.Debugf("exec:%s", statement.query)

// if logrus.IsLevelEnabled(logrus.DebugLevel) {
// for _, arg := range args {
// logrus.Debugf("- param:%s", convertParameterToValue(arg))
// }
// }

query, err := statement.buildQuery(convertParameters(args))
if err != nil {
return nil, err

Check warning on line 41 in sqlconnect/internal/bigquery/driver/statement.go

View check run for this annotation

Codecov / codecov/patch

sqlconnect/internal/bigquery/driver/statement.go#L41

Added line #L41 was not covered by tests
Expand All @@ -48,14 +50,6 @@ func (statement *bigQueryStatement) ExecContext(ctx context.Context, args []driv
}

func (statement *bigQueryStatement) QueryContext(ctx context.Context, args []driver.NamedValue) (driver.Rows, error) {
// logrus.Debugf("query:%s", statement.query)

// if logrus.IsLevelEnabled(logrus.DebugLevel) {
// for _, arg := range args {
// logrus.Debugf("- param:%s", convertParameterToValue(arg))
// }
// }

query, err := statement.buildQuery(convertParameters(args))
if err != nil {
return nil, err

Check warning on line 55 in sqlconnect/internal/bigquery/driver/statement.go

View check run for this annotation

Codecov / codecov/patch

sqlconnect/internal/bigquery/driver/statement.go#L55

Added line #L55 was not covered by tests
Expand All @@ -72,14 +66,6 @@ func (statement *bigQueryStatement) QueryContext(ctx context.Context, args []dri
}

func (statement bigQueryStatement) Exec(args []driver.Value) (driver.Result, error) {
// logrus.Debugf("exec:%s", statement.query)

// if logrus.IsLevelEnabled(logrus.DebugLevel) {
// for _, arg := range args {
// logrus.Debugf("- param:%s", convertParameterToValue(arg))
// }
// }

query, err := statement.buildQuery(args)
if err != nil {
return nil, err

Check warning on line 71 in sqlconnect/internal/bigquery/driver/statement.go

View check run for this annotation

Codecov / codecov/patch

sqlconnect/internal/bigquery/driver/statement.go#L68-L71

Added lines #L68 - L71 were not covered by tests
Expand All @@ -94,13 +80,6 @@ func (statement bigQueryStatement) Exec(args []driver.Value) (driver.Result, err
}

func (statement bigQueryStatement) Query(args []driver.Value) (driver.Rows, error) {
// logrus.Debugf("query:%s", statement.query)
// if logrus.IsLevelEnabled(logrus.DebugLevel) {
// for _, arg := range args {
// logrus.Debugf("- param:%s", convertParameterToValue(arg))
// }
// }

query, err := statement.buildQuery(args)
if err != nil {
return nil, err

Check warning on line 85 in sqlconnect/internal/bigquery/driver/statement.go

View check run for this annotation

Codecov / codecov/patch

sqlconnect/internal/bigquery/driver/statement.go#L82-L85

Added lines #L82 - L85 were not covered by tests
Expand Down Expand Up @@ -153,8 +132,6 @@ func buildParameter(arg driver.Value, parameters []bigquery.QueryParameter) []bi
}

func buildParameterFromNamedValue(namedValue driver.NamedValue, parameters []bigquery.QueryParameter) []bigquery.QueryParameter {
// logrus.Debugf("-param:%s=%s", namedValue.Name, namedValue.Value)

if namedValue.Name == "" {
return append(parameters, bigquery.QueryParameter{
Value: namedValue.Value,
Expand Down

0 comments on commit 9490d57

Please sign in to comment.