ruby_snowflake_client 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 75899b8f6ba98da01620d76f6d7077ba73ae8dd7fb1177815300b969d0dbf7b5
4
- data.tar.gz: 2fdbd266149c69bf17d59c83ab09418ca8f46d23707c5c3d98cc8e6800bf84e2
3
+ metadata.gz: 056a78a20053733ca15070ef4aec126052ad1b6eb1c3191788ffcae8acc4d80c
4
+ data.tar.gz: 3e33de5630c3f14f3b43e8076c672cbfa47295a28a9fc740f853a7b2dbbdb07e
5
5
  SHA512:
6
- metadata.gz: 180122aebc707aeda9e7cff2fad9ab6361b21d027b4dc23961bb64319ae192338091fff3b5600cbc15a86522c39bff2b4402723c7c0dfbd80570bdea3e3f96cb
7
- data.tar.gz: 65ab2555c42a044224ee1f5e010f43f7ddc9491205d271bd4459459ee5ffb3f65112bd310742c1bcab797c66e8a590e96f732032142ba3866e2e91afb5feb40b
6
+ metadata.gz: 215d13f6351cb22543bf1c3e356df1c98fb87e6bb2ecd2a99915a593e91316f8162e67dcce3d3e26d1135a7adf6de2538f4d2635a9bf53daf7532134e6f9a93f
7
+ data.tar.gz: 8c3b9d2a94d4641f96472ec923996940d1e7b99cf5f32989e0b3db431e046de23ec22009a0ce2a1002b3c5976484bea62de421d3c26de08af01de96de3bc0f09
@@ -32,7 +32,7 @@ jobs:
32
32
  ### limits ssh access and adds the ssh public key for the user which triggered the workflow
33
33
  #limit-access-to-actor: true
34
34
  - name: Install gem
35
- run: cd pkg && gem install --local *.gem --verbose
35
+ run: cd pkg && gem install --local *.gem
36
36
  - name: Run tests
37
37
  run: ruby -rruby_snowflake_client -S rspec spec/**/*_spec.rb -cfdoc
38
38
  env: # Or as an environment variable
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ruby_snowflake_client (1.1.0)
4
+ ruby_snowflake_client (1.2.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/ext/client.go ADDED
@@ -0,0 +1,98 @@
1
+ package main
2
+
3
+ /*
4
+ #include <stdlib.h>
5
+ #include "ruby/ruby.h"
6
+
7
+ void RbGcGuard(VALUE ptr);
8
+ VALUE ReturnEnumerator(VALUE cls);
9
+ VALUE RbNumFromDouble(double v);
10
+ */
11
+ import "C"
12
+
13
+ import (
14
+ "context"
15
+ "database/sql"
16
+ "fmt"
17
+ "strings"
18
+ "time"
19
+
20
+ sf "github.com/snowflakedb/gosnowflake"
21
+ )
22
+
23
+ type SnowflakeClient struct {
24
+ db *sql.DB
25
+ }
26
+
27
+ func (x SnowflakeClient) Fetch(statement C.VALUE) C.VALUE {
28
+ t1 := time.Now()
29
+
30
+ if LOG_LEVEL > 0 {
31
+ fmt.Println("statement", RbGoString(statement))
32
+ }
33
+ rows, err := x.db.QueryContext(sf.WithHigherPrecision(context.Background()), RbGoString(statement))
34
+ if err != nil {
35
+ result := C.rb_class_new_instance(0, &empty, rbSnowflakeResultClass)
36
+ errStr := fmt.Sprintf("Query error: '%s'", err.Error())
37
+ C.rb_ivar_set(result, ERROR_IDENT, RbString(errStr))
38
+ return result
39
+ }
40
+
41
+ duration := time.Now().Sub(t1).Seconds()
42
+ if LOG_LEVEL > 0 {
43
+ fmt.Printf("Query duration: %s\n", time.Now().Sub(t1))
44
+ }
45
+ if err != nil {
46
+ result := C.rb_class_new_instance(0, &empty, rbSnowflakeResultClass)
47
+ errStr := fmt.Sprintf("Query error: '%s'", err.Error())
48
+ C.rb_ivar_set(result, ERROR_IDENT, RbString(errStr))
49
+ return result
50
+ }
51
+
52
+ result := C.rb_class_new_instance(0, &empty, rbSnowflakeResultClass)
53
+ cols, _ := rows.Columns()
54
+ for idx, col := range cols {
55
+ col := col
56
+ cols[idx] = strings.ToLower(col)
57
+ }
58
+ rs := SnowflakeResult{rows, cols}
59
+ resultMap[result] = &rs
60
+ C.rb_ivar_set(result, RESULT_DURATION, RbNumFromDouble(C.double(duration)))
61
+ return result
62
+ }
63
+
64
+ //export Connect
65
+ func Connect(self C.VALUE, account C.VALUE, warehouse C.VALUE, database C.VALUE, schema C.VALUE, user C.VALUE, password C.VALUE, role C.VALUE) {
66
+ // other optional parms: Application, Host, and alt auth schemes
67
+ cfg := &sf.Config{
68
+ Account: RbGoString(account),
69
+ Warehouse: RbGoString(warehouse),
70
+ Database: RbGoString(database),
71
+ Schema: RbGoString(schema),
72
+ User: RbGoString(user),
73
+ Password: RbGoString(password),
74
+ Role: RbGoString(role),
75
+ Port: int(443),
76
+ }
77
+
78
+ dsn, err := sf.DSN(cfg)
79
+ if err != nil {
80
+ errStr := fmt.Sprintf("Snowflake Config Creation Error: '%s'", err.Error())
81
+ C.rb_ivar_set(self, ERROR_IDENT, RbString(errStr))
82
+ }
83
+
84
+ db, err := sql.Open("snowflake", dsn)
85
+ if err != nil {
86
+ errStr := fmt.Sprintf("Connection Error: '%s'", err.Error())
87
+ C.rb_ivar_set(self, ERROR_IDENT, RbString(errStr))
88
+ }
89
+ rs := SnowflakeClient{db}
90
+ clientRef[self] = &rs
91
+ }
92
+
93
+ //export ObjFetch
94
+ func ObjFetch(self C.VALUE, statement C.VALUE) C.VALUE {
95
+ x, _ := clientRef[self]
96
+
97
+ return x.Fetch(statement)
98
+ }
data/ext/result.go CHANGED
@@ -5,12 +5,11 @@ package main
5
5
  #include "ruby/ruby.h"
6
6
 
7
7
  VALUE ReturnEnumerator(VALUE cls);
8
- VALUE createRbString(char* str);
9
- VALUE funcall0param(VALUE obj, ID id);
10
8
  */
11
9
  import "C"
12
10
 
13
11
  import (
12
+ "database/sql"
14
13
  "fmt"
15
14
  "math/big"
16
15
  "time"
@@ -18,6 +17,11 @@ import (
18
17
  gopointer "github.com/mattn/go-pointer"
19
18
  )
20
19
 
20
+ type SnowflakeResult struct {
21
+ rows *sql.Rows
22
+ columns []string
23
+ }
24
+
21
25
  func wrapRbRaise(err error) {
22
26
  fmt.Printf("[ruby-snowflake-client] Error encountered: %s\n", err.Error())
23
27
  fmt.Printf("[ruby-snowflake-client] Will call `rb_raise`\n")
@@ -10,9 +10,6 @@ VALUE Inspect(VALUE);
10
10
  VALUE GetRows(VALUE);
11
11
  VALUE GetRowsNoEnum(VALUE);
12
12
 
13
- VALUE NewGoStruct(VALUE klass, char* reason, void *p);
14
- VALUE GoRetEnum(VALUE,int,VALUE);
15
- void* GetGoStruct(VALUE obj);
16
13
  void RbGcGuard(VALUE ptr);
17
14
  VALUE ReturnEnumerator(VALUE cls);
18
15
  VALUE RbNumFromDouble(double v);
@@ -20,25 +17,9 @@ VALUE RbNumFromDouble(double v);
20
17
  import "C"
21
18
 
22
19
  import (
23
- "context"
24
- "database/sql"
25
20
  "fmt"
26
- "strings"
27
- "time"
28
-
29
- sf "github.com/snowflakedb/gosnowflake"
30
21
  )
31
22
 
32
- type SnowflakeResult struct {
33
- rows *sql.Rows
34
- //keptHash C.VALUE
35
- columns []string
36
- //cols []C.VALUE
37
- }
38
- type SnowflakeClient struct {
39
- db *sql.DB
40
- }
41
-
42
23
  var rbSnowflakeClientClass C.VALUE
43
24
  var rbSnowflakeResultClass C.VALUE
44
25
  var rbSnowflakeModule C.VALUE
@@ -54,79 +35,6 @@ var clientRef = make(map[C.VALUE]*SnowflakeClient)
54
35
  var LOG_LEVEL = 0
55
36
  var empty C.VALUE = C.Qnil
56
37
 
57
- //export Connect
58
- func Connect(self C.VALUE, account C.VALUE, warehouse C.VALUE, database C.VALUE, schema C.VALUE, user C.VALUE, password C.VALUE, role C.VALUE) {
59
- // other optional parms: Application, Host, and alt auth schemes
60
- cfg := &sf.Config{
61
- Account: RbGoString(account),
62
- Warehouse: RbGoString(warehouse),
63
- Database: RbGoString(database),
64
- Schema: RbGoString(schema),
65
- User: RbGoString(user),
66
- Password: RbGoString(password),
67
- Role: RbGoString(role),
68
- Port: int(443),
69
- }
70
-
71
- dsn, err := sf.DSN(cfg)
72
- if err != nil {
73
- errStr := fmt.Sprintf("Snowflake Config Creation Error: '%s'", err.Error())
74
- C.rb_ivar_set(self, ERROR_IDENT, RbString(errStr))
75
- }
76
-
77
- db, err := sql.Open("snowflake", dsn)
78
- if err != nil {
79
- errStr := fmt.Sprintf("Connection Error: '%s'", err.Error())
80
- C.rb_ivar_set(self, ERROR_IDENT, RbString(errStr))
81
- }
82
- rs := SnowflakeClient{db}
83
- clientRef[self] = &rs
84
- }
85
-
86
- func (x SnowflakeClient) Fetch(statement C.VALUE) C.VALUE {
87
- t1 := time.Now()
88
-
89
- if LOG_LEVEL > 0 {
90
- fmt.Println("statement", RbGoString(statement))
91
- }
92
- rows, err := x.db.QueryContext(sf.WithHigherPrecision(context.Background()), RbGoString(statement))
93
- if err != nil {
94
- result := C.rb_class_new_instance(0, &empty, rbSnowflakeResultClass)
95
- errStr := fmt.Sprintf("Query error: '%s'", err.Error())
96
- C.rb_ivar_set(result, ERROR_IDENT, RbString(errStr))
97
- return result
98
- }
99
-
100
- duration := time.Now().Sub(t1).Seconds()
101
- if LOG_LEVEL > 0 {
102
- fmt.Printf("Query duration: %s\n", time.Now().Sub(t1))
103
- }
104
- if err != nil {
105
- result := C.rb_class_new_instance(0, &empty, rbSnowflakeResultClass)
106
- errStr := fmt.Sprintf("Query error: '%s'", err.Error())
107
- C.rb_ivar_set(result, ERROR_IDENT, RbString(errStr))
108
- return result
109
- }
110
-
111
- result := C.rb_class_new_instance(0, &empty, rbSnowflakeResultClass)
112
- cols, _ := rows.Columns()
113
- for idx, col := range cols {
114
- col := col
115
- cols[idx] = strings.ToLower(col)
116
- }
117
- rs := SnowflakeResult{rows, cols}
118
- resultMap[result] = &rs
119
- C.rb_ivar_set(result, RESULT_DURATION, RbNumFromDouble(C.double(duration)))
120
- return result
121
- }
122
-
123
- //export ObjFetch
124
- func ObjFetch(self C.VALUE, statement C.VALUE) C.VALUE {
125
- x, _ := clientRef[self]
126
-
127
- return x.Fetch(statement)
128
- }
129
-
130
38
  //export Inspect
131
39
  func Inspect(self C.VALUE) C.VALUE {
132
40
  x := clientRef[self]
data/ext/wrapper.go CHANGED
@@ -24,57 +24,14 @@ VALUE RbNumFromLong(long v) {
24
24
  return LONG2NUM(v);
25
25
  }
26
26
 
27
- void goobj_retain(void *, char*);
28
- void goobj_free(void *);
29
- void goobj_log(void *);
30
- void goobj_mark(void *);
31
- void goobj_compact(void *);
32
-
33
- static const rb_data_type_t go_type = {
34
- "GoStruct",
35
- {
36
- goobj_mark,
37
- goobj_free,
38
- NULL,
39
- (goobj_compact),
40
- },
41
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
42
- };
43
-
44
- VALUE
45
- NewGoStruct(VALUE klass, char* reason, void *p)
46
- {
47
- goobj_retain(p, reason);
48
- return TypedData_Wrap_Struct(klass, &go_type, p);
49
- }
50
-
51
27
  VALUE ReturnEnumerator(VALUE cls) {
52
28
  RETURN_ENUMERATOR(cls, 0, NULL);
53
29
  return Qnil;
54
30
  }
55
31
 
56
- void *
57
- GetGoStruct(VALUE obj)
58
- {
59
- void *val;
60
- return TypedData_Get_Struct(obj, void *, &go_type, val);
61
- }
62
-
63
32
  void RbGcGuard(VALUE ptr) {
64
33
  RB_GC_GUARD(ptr);
65
34
  }
66
-
67
- VALUE createRbString(char* str) {
68
- volatile VALUE rbStr;
69
- rbStr = rb_tainted_str_new_cstr(str);
70
- return rbStr;
71
- }
72
-
73
- VALUE funcall0param(VALUE obj, ID id) {
74
- RB_GC_GUARD(obj);
75
- return rb_funcall(obj, id, 0);
76
- }
77
-
78
35
  */
79
36
  import "C"
80
37
  import (
@@ -90,10 +47,6 @@ func RbNumFromDouble(v C.double) C.VALUE {
90
47
  return C.RbNumFromDouble(v)
91
48
  }
92
49
 
93
- func GetGoStruct(obj C.VALUE) unsafe.Pointer {
94
- return C.GetGoStruct(obj)
95
- }
96
-
97
50
  func returnEnum(cls C.VALUE) C.VALUE {
98
51
  return C.ReturnEnumerator(cls)
99
52
  }
@@ -1,3 +1,3 @@
1
1
  module RubySnowflakeClient
2
- VERSION = '1.1.0'
2
+ VERSION = '1.2.0'
3
3
  end
@@ -5,10 +5,12 @@ module Snowflake
5
5
  LOG_LEVEL = 0
6
6
 
7
7
  class Error < StandardError
8
- attr_reader :details
8
+ # This will get pulled through to Sentry, see:
9
+ # https://github.com/getsentry/sentry-ruby/blob/11ecd254c0d2cae2b327f0348074e849095aa32d/sentry-ruby/lib/sentry/error_event.rb#L31-L33
10
+ attr_reader :sentry_context
9
11
 
10
12
  def initialize(details)
11
- @details = details
13
+ @sentry_context = details
12
14
  end
13
15
  end
14
16
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_snowflake_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rinsed
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-06-09 00:00:00.000000000 Z
11
+ date: 2023-06-26 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: |
14
14
  Using the `Go` library for Snowflake to query and creating native Ruby objects,
@@ -29,7 +29,7 @@ files:
29
29
  - LICENSE.txt
30
30
  - README.md
31
31
  - Rakefile
32
- - ext/c-decl.go
32
+ - ext/client.go
33
33
  - ext/extconf.rb
34
34
  - ext/go.mod
35
35
  - ext/go.sum
data/ext/c-decl.go DELETED
@@ -1,54 +0,0 @@
1
- package main
2
-
3
- /*
4
- #include <stdlib.h>
5
- #include "ruby/ruby.h"
6
- */
7
- import "C"
8
-
9
- import (
10
- "fmt"
11
- "unsafe"
12
- )
13
-
14
- var marked = make(map[unsafe.Pointer]int)
15
-
16
- //export goobj_mark
17
- func goobj_mark(obj unsafe.Pointer) {
18
- if LOG_LEVEL > 0 {
19
- marked[obj] = marked[obj] + 1
20
- fmt.Printf("MARK log obj %v; counter: %d; total number of MARKED objects: %d\n", obj, marked[obj], len(marked))
21
- }
22
- }
23
-
24
- //export goobj_log
25
- func goobj_log(obj unsafe.Pointer) {
26
- if LOG_LEVEL > 0 {
27
- fmt.Println("log obj", obj)
28
- }
29
- }
30
-
31
- //export goobj_retain
32
- func goobj_retain(obj unsafe.Pointer, x *C.char) {
33
- if LOG_LEVEL > 0 {
34
- fmt.Printf("retain obj [%v] %v - currently keeping %d\n", C.GoString(x), obj, len(objects))
35
- }
36
- objects[obj] = true
37
- marked[obj] = 0
38
- }
39
-
40
- //export goobj_free
41
- func goobj_free(obj unsafe.Pointer) {
42
- if LOG_LEVEL > 0 {
43
- fmt.Printf("CALLED GOOBJ FREE %v - CURRENTLY %d objects left\n", obj, len(objects))
44
- }
45
- delete(objects, obj)
46
- delete(marked, obj)
47
- }
48
-
49
- //export goobj_compact
50
- func goobj_compact(obj unsafe.Pointer) {
51
- if LOG_LEVEL > 0 {
52
- fmt.Printf("CALLED GOOBJ COMPACT %v", obj)
53
- }
54
- }