Skip to content
This repository was archived by the owner on Jan 9, 2024. It is now read-only.
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ gem "rake"
gem "rspec"
gem "pry"
gem "dotenv"
gem "parallel"
4 changes: 3 additions & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
ruby_snowflake_client (1.1.0)
ruby_snowflake_client (1.3.0)

GEM
remote: https://rubygems.org/
Expand All @@ -10,6 +10,7 @@ GEM
diff-lcs (1.5.0)
dotenv (2.8.1)
method_source (1.0.0)
parallel (1.23.0)
pry (0.14.2)
coderay (~> 1.1)
method_source (~> 1.0)
Expand All @@ -34,6 +35,7 @@ PLATFORMS
DEPENDENCIES
bundler
dotenv
parallel
pry
rake
rspec
Expand Down
98 changes: 91 additions & 7 deletions ext/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,25 @@ import (
)

type SnowflakeClient struct {
db *sql.DB
db *sql.DB
cfg *sf.Config
}

func (x SnowflakeClient) Fetch(statement C.VALUE) C.VALUE {
func (x SnowflakeClient) Fetch(statement string) C.VALUE {
t1 := time.Now()

if LOG_LEVEL > 0 {
fmt.Println("statement", RbGoString(statement))
fmt.Println("statement", statement)
}
rows, err := x.db.QueryContext(sf.WithHigherPrecision(context.Background()), RbGoString(statement))
if LOG_LEVEL > 0 {
fmt.Println("getting conn")
}
dbCtx := context.Background()
conn, _ := x.db.Conn(dbCtx)
if LOG_LEVEL > 0 {
fmt.Println("got conn")
}
rows, err := conn.QueryContext(sf.WithHigherPrecision(context.Background()), statement)
if err != nil {
result := C.rb_class_new_instance(0, &empty, rbSnowflakeResultClass)
errStr := fmt.Sprintf("Query error: '%s'", err.Error())
Expand All @@ -42,22 +51,86 @@ func (x SnowflakeClient) Fetch(statement C.VALUE) C.VALUE {
if LOG_LEVEL > 0 {
fmt.Printf("Query duration: %s\n", time.Now().Sub(t1))
}

result := C.rb_class_new_instance(0, &empty, rbSnowflakeResultClass)
if LOG_LEVEL > 0 {
fmt.Println("create new instance")
}
cols, _ := rows.Columns()
for idx, col := range cols {
col := col
cols[idx] = strings.ToLower(col)
}
rs := SnowflakeResult{rows, cols, conn}
resultMap[result] = &rs
if LOG_LEVEL > 0 {
fmt.Println("after for & map")
}
C.rb_ivar_set(result, RESULT_DURATION, RbNumFromDouble(C.double(duration)))
if LOG_LEVEL > 0 {
fmt.Println("end of func")
}
return result
}

func (x SnowflakeClient) FetchWithDB(statement string, dbName string) C.VALUE {
t1 := time.Now()

if LOG_LEVEL > 0 {
fmt.Println("statement", statement)
}
if LOG_LEVEL > 0 {
fmt.Println("getting conn")
}
//dbCtx, _ := context.WithTimeout(context.Background(), 1*time.Second)
dbCtx := context.Background()
conn, _ := x.db.Conn(dbCtx)
if LOG_LEVEL > 0 {
fmt.Println("got conn")
}
stmt := fmt.Sprintf("USE DATABASE %s", dbName)
_, err := conn.ExecContext(context.Background(), stmt)
if err != nil {
result := C.rb_class_new_instance(0, &empty, rbSnowflakeResultClass)
errStr := fmt.Sprintf("Query %s had error \n error: '%s'", stmt, err.Error())
C.rb_ivar_set(result, ERROR_IDENT, RbString(errStr))
return result
}
if LOG_LEVEL > 0 {
fmt.Printf("exec duration: %s\n", time.Now().Sub(t1))
t1 = time.Now()
}
rows, err := conn.QueryContext(sf.WithHigherPrecision(context.Background()), statement)
if err != nil {
result := C.rb_class_new_instance(0, &empty, rbSnowflakeResultClass)
errStr := fmt.Sprintf("Query error: '%s'", err.Error())
C.rb_ivar_set(result, ERROR_IDENT, RbString(errStr))
return result
}

duration := time.Now().Sub(t1).Seconds()
if LOG_LEVEL > 0 {
fmt.Printf("Query duration: %s\n", time.Now().Sub(t1))
}

result := C.rb_class_new_instance(0, &empty, rbSnowflakeResultClass)
if LOG_LEVEL > 0 {
fmt.Println("create new instance")
}
cols, _ := rows.Columns()
for idx, col := range cols {
col := col
cols[idx] = strings.ToLower(col)
}
rs := SnowflakeResult{rows, cols}
rs := SnowflakeResult{rows, cols, conn}
resultMap[result] = &rs
if LOG_LEVEL > 0 {
fmt.Println("after for & map")
}
C.rb_ivar_set(result, RESULT_DURATION, RbNumFromDouble(C.double(duration)))
if LOG_LEVEL > 0 {
fmt.Println("end of func")
}
return result
}

Expand All @@ -76,6 +149,7 @@ func Connect(self C.VALUE, account C.VALUE, warehouse C.VALUE, database C.VALUE,
}

dsn, err := sf.DSN(cfg)
sf.GetLogger().SetLogLevel("trace")
if err != nil {
errStr := fmt.Sprintf("Snowflake Config Creation Error: '%s'", err.Error())
C.rb_ivar_set(self, ERROR_IDENT, RbString(errStr))
Expand All @@ -86,13 +160,23 @@ func Connect(self C.VALUE, account C.VALUE, warehouse C.VALUE, database C.VALUE,
errStr := fmt.Sprintf("Connection Error: '%s'", err.Error())
C.rb_ivar_set(self, ERROR_IDENT, RbString(errStr))
}
rs := SnowflakeClient{db}
rs := SnowflakeClient{db, cfg}
clientRef[self] = &rs
}

//export ObjFetch
func ObjFetch(self C.VALUE, statement C.VALUE) C.VALUE {
x, _ := clientRef[self]
stmt := RbGoString(statement)

return x.Fetch(stmt)
}

//export ObjFetchWithDB
func ObjFetchWithDB(self C.VALUE, statement C.VALUE, database C.VALUE) C.VALUE {
x, _ := clientRef[self]
stmt := RbGoString(statement)
db := RbGoString(database)

return x.Fetch(statement)
return x.FetchWithDB(stmt, db)
}
12 changes: 12 additions & 0 deletions ext/result.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
type SnowflakeResult struct {
rows *sql.Rows
columns []string
conn *sql.Conn
}

func wrapRbRaise(err error) {
Expand Down Expand Up @@ -66,6 +67,7 @@ func GetRowsNoEnum(self C.VALUE) C.VALUE {
C.rb_ary_store(rbArr, C.long(idx), elem)
}

res.Close()
return rbArr
}

Expand Down Expand Up @@ -95,6 +97,7 @@ func GetRows(self C.VALUE) C.VALUE {
if LOG_LEVEL > 0 {
fmt.Printf("done with rows.next: %s\n", time.Now().Sub(t1))
}
res.Close()

return self
}
Expand All @@ -112,9 +115,18 @@ func ObjNextRow(self C.VALUE) C.VALUE {
r := res.ScanNextRow(false)
return r
}
res.Close()
return C.Qnil
}

func (res SnowflakeResult) Close() {
if LOG_LEVEL > 0 {
fmt.Println("called res.close")
}
res.rows.Close()
res.conn.Close()
}

func (res SnowflakeResult) ScanNextRow(debug bool) C.VALUE {
rows := res.rows
if LOG_LEVEL > 0 {
Expand Down
2 changes: 2 additions & 0 deletions ext/ruby_snowflake.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package main
#include "ruby/ruby.h"
void Connect(VALUE,VALUE,VALUE,VALUE,VALUE,VALUE,VALUE,VALUE);
VALUE ObjFetch(VALUE,VALUE);
VALUE ObjFetchWithDB(VALUE,VALUE,VALUE);
VALUE ObjNextRow(VALUE);
VALUE Inspect(VALUE);
VALUE GetRows(VALUE);
Expand Down Expand Up @@ -66,6 +67,7 @@ func Init_ruby_snowflake_client_ext() {
C.rb_define_method(rbSnowflakeClientClass, C.CString("inspect"), (*[0]byte)(C.Inspect), 0)
C.rb_define_method(rbSnowflakeClientClass, C.CString("to_s"), (*[0]byte)(C.Inspect), 0)
C.rb_define_method(rbSnowflakeClientClass, C.CString("_fetch"), (*[0]byte)(C.ObjFetch), 1)
C.rb_define_method(rbSnowflakeClientClass, C.CString("_fetch_with_db"), (*[0]byte)(C.ObjFetchWithDB), 2)

if LOG_LEVEL > 0 {
fmt.Println("init ruby snowflake client")
Expand Down
Binary file not shown.
7 changes: 6 additions & 1 deletion ext/vendor/github.com/snowflakedb/gosnowflake/auth.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 16 additions & 8 deletions ext/vendor/github.com/snowflakedb/gosnowflake/connection.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 6 additions & 1 deletion ext/vendor/github.com/snowflakedb/gosnowflake/driver.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions ext/vendor/github.com/snowflakedb/gosnowflake/ocsp.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions ext/vendor/github.com/snowflakedb/gosnowflake/retry.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading