chdb-ruby 0.1.0.rc.2
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 +7 -0
- data/INSTALLATION.md +27 -0
- data/LICENSE +203 -0
- data/README.md +128 -0
- data/dependencies.yml +2 -0
- data/ext/chdb/chdb.c +32 -0
- data/ext/chdb/chdb_handle.c +49 -0
- data/ext/chdb/chdb_handle.h +16 -0
- data/ext/chdb/connection.c +118 -0
- data/ext/chdb/connection.h +23 -0
- data/ext/chdb/constants.h +15 -0
- data/ext/chdb/exception.c +16 -0
- data/ext/chdb/exception.h +10 -0
- data/ext/chdb/extconf.rb +196 -0
- data/ext/chdb/local_result.c +81 -0
- data/ext/chdb/local_result.h +26 -0
- data/lib/chdb/constants.rb +6 -0
- data/lib/chdb/data_path.rb +121 -0
- data/lib/chdb/database.rb +153 -0
- data/lib/chdb/errors.rb +22 -0
- data/lib/chdb/local_result.rb +12 -0
- data/lib/chdb/parameter_binding.rb +25 -0
- data/lib/chdb/result_handler.rb +28 -0
- data/lib/chdb/result_set.rb +57 -0
- data/lib/chdb/sql_processor.rb +23 -0
- data/lib/chdb/statement.rb +137 -0
- data/lib/chdb/version.rb +6 -0
- data/lib/chdb/version_info.rb +11 -0
- data/lib/chdb.rb +18 -0
- metadata +91 -0
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ChDB
|
4
|
+
# The ResultSet object encapsulates the enumerability of a query's output.
|
5
|
+
# It is a simple cursor over the data that the query returns. It will
|
6
|
+
# very rarely (if ever) be instantiated directly. Instead, clients should
|
7
|
+
# obtain a ResultSet instance via Statement#execute.
|
8
|
+
class ResultSet
|
9
|
+
include Enumerable
|
10
|
+
|
11
|
+
# Create a new ResultSet attached to the given database, using the
|
12
|
+
# given sql text.
|
13
|
+
def initialize(db, stmt)
|
14
|
+
@db = db
|
15
|
+
@stmt = stmt
|
16
|
+
end
|
17
|
+
|
18
|
+
def eof?
|
19
|
+
@stmt.done?
|
20
|
+
end
|
21
|
+
|
22
|
+
def next
|
23
|
+
@stmt.step
|
24
|
+
end
|
25
|
+
|
26
|
+
def each
|
27
|
+
while (node = self.next)
|
28
|
+
yield node
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Provides an internal iterator over the rows of the result set where
|
33
|
+
# each row is yielded as a hash.
|
34
|
+
def each_hash
|
35
|
+
while (node = next_hash)
|
36
|
+
yield node
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Returns the names of the columns returned by this result set.
|
41
|
+
def columns
|
42
|
+
@stmt.columns
|
43
|
+
end
|
44
|
+
|
45
|
+
# Return the next row as a hash
|
46
|
+
def next_hash
|
47
|
+
row = @stmt.step
|
48
|
+
return nil unless row
|
49
|
+
|
50
|
+
@stmt.columns.zip(row).to_h
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class HashResultSet < ResultSet # :nodoc:
|
55
|
+
alias next next_hash
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ChDB
|
4
|
+
# This module provides functionality for processing SQL queries,
|
5
|
+
# including binding variables and escaping values.
|
6
|
+
module SQLProcessor
|
7
|
+
def process_sql
|
8
|
+
escaped_values = @bind_vars.map { |v| escape(v) }
|
9
|
+
sql = @sql.dup
|
10
|
+
sql.gsub(/(?<!\\)\?/) { escaped_values.shift or '?' }
|
11
|
+
end
|
12
|
+
|
13
|
+
def escape(value)
|
14
|
+
case value
|
15
|
+
when String then "'#{value.gsub("'", "''")}'"
|
16
|
+
when NilClass then 'NULL'
|
17
|
+
when TrueClass then '1'
|
18
|
+
when FalseClass then '0'
|
19
|
+
else value.to_s
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'csv'
|
4
|
+
begin
|
5
|
+
RUBY_VERSION =~ /(\d+\.\d+)/
|
6
|
+
require "chdb/#{Regexp.last_match(1)}/chdb_native"
|
7
|
+
rescue LoadError
|
8
|
+
require 'chdb/chdb_native'
|
9
|
+
end
|
10
|
+
require 'chdb/local_result'
|
11
|
+
require 'chdb/result_set'
|
12
|
+
require 'chdb/result_handler'
|
13
|
+
require 'chdb/parameter_binding'
|
14
|
+
require 'chdb/sql_processor'
|
15
|
+
|
16
|
+
module ChDB
|
17
|
+
# Represents a prepared SQL statement in the ChDB database.
|
18
|
+
# This class provides methods for executing SQL statements, binding parameters,
|
19
|
+
# and iterating over the result set.
|
20
|
+
class Statement
|
21
|
+
include Enumerable
|
22
|
+
include ParameterBinding
|
23
|
+
include SQLProcessor
|
24
|
+
include ResultHandler
|
25
|
+
|
26
|
+
attr_reader :result, :columns, :parsed_data
|
27
|
+
|
28
|
+
def initialize(db, sql_str)
|
29
|
+
validate_inputs(db, sql_str)
|
30
|
+
@sql = encode_sql(sql_str)
|
31
|
+
@connection = db
|
32
|
+
@executed = false
|
33
|
+
@parsed = false
|
34
|
+
@row_idx = 0
|
35
|
+
@bind_vars = []
|
36
|
+
@parsed_data = []
|
37
|
+
@columns = []
|
38
|
+
end
|
39
|
+
|
40
|
+
def execute(*bind_vars)
|
41
|
+
reset! if @executed
|
42
|
+
@executed = true
|
43
|
+
|
44
|
+
bind_params(*bind_vars) unless bind_vars.empty?
|
45
|
+
|
46
|
+
@processed_sql = process_sql
|
47
|
+
|
48
|
+
results = @connection.build_result_set self
|
49
|
+
@result = @connection.conn.query(@processed_sql, 'CSVWithNames')
|
50
|
+
@result.output_format = 'CSVWithNames'
|
51
|
+
|
52
|
+
yield results if block_given?
|
53
|
+
results
|
54
|
+
end
|
55
|
+
|
56
|
+
def execute!(*bind_vars, &block)
|
57
|
+
execute(*bind_vars)
|
58
|
+
block ? each(&block) : to_a
|
59
|
+
end
|
60
|
+
|
61
|
+
def execute_with_format(*bind_vars, format)
|
62
|
+
reset! if @executed
|
63
|
+
@executed = true
|
64
|
+
|
65
|
+
bind_params(*bind_vars) unless bind_vars.empty?
|
66
|
+
|
67
|
+
@processed_sql = process_sql
|
68
|
+
@result = @connection.conn.query(@processed_sql, format)
|
69
|
+
|
70
|
+
yield @result.buf if block_given?
|
71
|
+
@result.buf
|
72
|
+
end
|
73
|
+
|
74
|
+
def reset!
|
75
|
+
@executed = false
|
76
|
+
@parsed = false
|
77
|
+
@row_idx = 0
|
78
|
+
@bind_vars.clear
|
79
|
+
@parsed_data.clear
|
80
|
+
@columns.clear
|
81
|
+
@results = nil
|
82
|
+
end
|
83
|
+
|
84
|
+
def step
|
85
|
+
parse
|
86
|
+
return nil if @row_idx >= @parsed_data.size
|
87
|
+
|
88
|
+
current_row = @parsed_data[@row_idx]
|
89
|
+
@row_idx += 1
|
90
|
+
current_row
|
91
|
+
end
|
92
|
+
|
93
|
+
def parse
|
94
|
+
return if @parsed
|
95
|
+
|
96
|
+
if @result&.buf.to_s.empty?
|
97
|
+
@columns = []
|
98
|
+
@parsed_data = []
|
99
|
+
else
|
100
|
+
@columns, @parsed_data = ResultHandler.parse_output(@result.buf)
|
101
|
+
end
|
102
|
+
|
103
|
+
@parsed = true
|
104
|
+
@results = nil
|
105
|
+
end
|
106
|
+
|
107
|
+
private
|
108
|
+
|
109
|
+
def validate_inputs(db, sql_str)
|
110
|
+
raise ArgumentError, 'SQL statement cannot be nil' if sql_str.nil?
|
111
|
+
raise ArgumentError, 'prepare called on a closed database' if db.nil? || db.closed?
|
112
|
+
end
|
113
|
+
|
114
|
+
def encode_sql(sql_str)
|
115
|
+
if sql_str.encoding == Encoding::UTF_8
|
116
|
+
sql_str.dup
|
117
|
+
else
|
118
|
+
sql_str.encode(Encoding::UTF_8)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
# Returns true if the statement is currently active, meaning it has an
|
123
|
+
# open result set.
|
124
|
+
def active?
|
125
|
+
@executed && !done?
|
126
|
+
end
|
127
|
+
|
128
|
+
def each
|
129
|
+
loop do
|
130
|
+
val = step
|
131
|
+
break if val.nil?
|
132
|
+
|
133
|
+
yield val
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
data/lib/chdb/version.rb
ADDED
data/lib/chdb.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ChDB
|
4
|
+
def self.lib_file_path
|
5
|
+
@lib_file_path ||= File.expand_path(__FILE__)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
begin
|
10
|
+
RUBY_VERSION =~ /(\d+\.\d+)/
|
11
|
+
require "chdb/#{Regexp.last_match(1)}/chdb_native"
|
12
|
+
rescue LoadError
|
13
|
+
require 'chdb/chdb_native'
|
14
|
+
end
|
15
|
+
|
16
|
+
require 'chdb/database'
|
17
|
+
require 'chdb/version'
|
18
|
+
require 'chdb/version_info'
|
metadata
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: chdb-ruby
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0.rc.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Xiaozhe Yu
|
8
|
+
- Auxten Wang
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2025-04-01 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: csv
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.1'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.1'
|
27
|
+
description: |
|
28
|
+
Ruby library to interface with the chDB database engine (https://clickhouse.com/docs/chdb). Precompiled
|
29
|
+
binaries are available for common platforms for recent versions of Ruby.
|
30
|
+
executables: []
|
31
|
+
extensions:
|
32
|
+
- ext/chdb/extconf.rb
|
33
|
+
extra_rdoc_files: []
|
34
|
+
files:
|
35
|
+
- INSTALLATION.md
|
36
|
+
- LICENSE
|
37
|
+
- README.md
|
38
|
+
- dependencies.yml
|
39
|
+
- ext/chdb/chdb.c
|
40
|
+
- ext/chdb/chdb_handle.c
|
41
|
+
- ext/chdb/chdb_handle.h
|
42
|
+
- ext/chdb/connection.c
|
43
|
+
- ext/chdb/connection.h
|
44
|
+
- ext/chdb/constants.h
|
45
|
+
- ext/chdb/exception.c
|
46
|
+
- ext/chdb/exception.h
|
47
|
+
- ext/chdb/extconf.rb
|
48
|
+
- ext/chdb/local_result.c
|
49
|
+
- ext/chdb/local_result.h
|
50
|
+
- lib/chdb.rb
|
51
|
+
- lib/chdb/constants.rb
|
52
|
+
- lib/chdb/data_path.rb
|
53
|
+
- lib/chdb/database.rb
|
54
|
+
- lib/chdb/errors.rb
|
55
|
+
- lib/chdb/local_result.rb
|
56
|
+
- lib/chdb/parameter_binding.rb
|
57
|
+
- lib/chdb/result_handler.rb
|
58
|
+
- lib/chdb/result_set.rb
|
59
|
+
- lib/chdb/sql_processor.rb
|
60
|
+
- lib/chdb/statement.rb
|
61
|
+
- lib/chdb/version.rb
|
62
|
+
- lib/chdb/version_info.rb
|
63
|
+
homepage: https://github.com/chdb-io/chdb-ruby
|
64
|
+
licenses:
|
65
|
+
- Apache-2.0
|
66
|
+
metadata:
|
67
|
+
homepage_uri: https://github.com/chdb-io/chdb-ruby
|
68
|
+
bug_tracker_uri: https://github.com/chdb-io/chdb-ruby/issues
|
69
|
+
changelog_uri: https://github.com/chdb-io/chdb-ruby/blob/main/CHANGELOG.md
|
70
|
+
source_code_uri: https://github.com/chdb-io/chdb-ruby
|
71
|
+
rubygems_mfa_required: 'true'
|
72
|
+
rdoc_options:
|
73
|
+
- "--main"
|
74
|
+
- README.md
|
75
|
+
require_paths:
|
76
|
+
- lib
|
77
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '3.1'
|
82
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
83
|
+
requirements:
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '0'
|
87
|
+
requirements: []
|
88
|
+
rubygems_version: 3.6.2
|
89
|
+
specification_version: 4
|
90
|
+
summary: Ruby library to interface with the chDB database engine (https://clickhouse.com/docs/chdb).
|
91
|
+
test_files: []
|