click_house 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/Makefile +4 -1
- data/README.md +63 -0
- data/bin/release.sh +5 -0
- data/lib/click_house.rb +5 -0
- data/lib/click_house/connection.rb +1 -0
- data/lib/click_house/errors.rb +1 -0
- data/lib/click_house/extend.rb +1 -0
- data/lib/click_house/extend/connection_altering.rb +47 -0
- data/lib/click_house/extend/connection_table.rb +37 -3
- data/lib/click_house/response/result_set.rb +1 -1
- data/lib/click_house/type.rb +2 -0
- data/lib/click_house/type/array_type.rb +38 -0
- data/lib/click_house/type/string_type.rb +15 -0
- data/lib/click_house/version.rb +1 -1
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e21fcc0831f8f6612fac22c8e64eebb78b6e6f5d5d371c6db57dbfc0556610fd
|
4
|
+
data.tar.gz: 792ac875a51e3f545b9b49b55618a4161183056b82cad7e213d05ef46974d69c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bca7f416a90d0d92046c8ac171511110fe2c02329e67260279b36a475bf2b59a0c65051c3f25f1f12f5ceb26bdabc659a94a75fea499fa0de65a9d3473d85156
|
7
|
+
data.tar.gz: 5eee878068a827c4875a65a4435b44c87adc2fbe83b824bbb143e9086dc6ae2aad5fe4a07d43efc3fcb5bf8c2cc56003d7ca56d7fc9a4cf17db717bff90caa41
|
data/.gitignore
CHANGED
data/Makefile
CHANGED
data/README.md
CHANGED
@@ -28,7 +28,9 @@ Despite we have full compatibility of protocol of different versions of client a
|
|
28
28
|
* [Usage](#usage)
|
29
29
|
* [Queries](#queries)
|
30
30
|
* [Insert](#insert)
|
31
|
+
* [Insert an Array](#insert-an-array)
|
31
32
|
* [Create a table](#create-a-table)
|
33
|
+
* [Alter table](#alter-table)
|
32
34
|
* [Type casting](#type-casting)
|
33
35
|
* [Using with a connection pool](#using-with-a-connection-pool)
|
34
36
|
* [Using with Rails](#using-with-rails)
|
@@ -89,6 +91,11 @@ ClickHouse.connection.describe_table('visits') #=> [{"name"=>"id", "type"=>"Fixe
|
|
89
91
|
ClickHouse.connection.table_exists?('visits', temporary: nil) #=> true
|
90
92
|
ClickHouse.connection.drop_table('visits', if_exists: true, temporary: nil, cluster: nil)
|
91
93
|
ClickHouse.connection.create_table(*) # see <Create a table> section
|
94
|
+
ClickHouse.connection.truncate_table('name', if_exists: true, cluster: nil)
|
95
|
+
ClickHouse.connection.truncate_tables(['table_1', 'table_2'], if_exists: true, cluster: nil)
|
96
|
+
ClickHouse.connection.truncate_tables # will truncate all tables in database
|
97
|
+
ClickHouse.connection.rename_table('old_name', 'new_name', cluster: nil)
|
98
|
+
ClickHouse.connection.rename_table(%w[table_1 table_2], %w[new_1 new_2], cluster: nil)
|
92
99
|
```
|
93
100
|
|
94
101
|
## Queries
|
@@ -174,6 +181,24 @@ ClickHouse.connection.insert('table', columns: %i[id name], values: [[1, 'Mercur
|
|
174
181
|
#=> true
|
175
182
|
```
|
176
183
|
|
184
|
+
## Insert an Array
|
185
|
+
|
186
|
+
Serializing an Array of strings is pretty low level at the moment but it works (and thanks for that).
|
187
|
+
Array of numeric types works as expected without pre-serialization
|
188
|
+
|
189
|
+
```ruby
|
190
|
+
string_type = ClickHouse::Type::StringType.new
|
191
|
+
array_of_string = ClickHouse::Type::ArrayType.new(string_type)
|
192
|
+
|
193
|
+
data = [
|
194
|
+
{ id: 1, tags: array_of_string.serialize(%w[ruby redis rails node]) }
|
195
|
+
]
|
196
|
+
|
197
|
+
subject.insert('rspec', columns: data.first.keys) do |buffer|
|
198
|
+
buffer.concat(data.map(&:values))
|
199
|
+
end
|
200
|
+
```
|
201
|
+
|
177
202
|
## Create a table
|
178
203
|
### Create table using DSL
|
179
204
|
|
@@ -253,6 +278,27 @@ ClickHouse.connection.execute <<~SQL
|
|
253
278
|
SQL
|
254
279
|
```
|
255
280
|
|
281
|
+
## Alter table
|
282
|
+
### Alter table with DSL
|
283
|
+
```ruby
|
284
|
+
ClickHouse.connection.add_column('table', 'column_name', :UInt64, default: nil, after: nil, cluster: nil)
|
285
|
+
ClickHouse.connection.drop_column('table', 'column_name', if_exists: nil, cluster: nil)
|
286
|
+
```
|
287
|
+
|
288
|
+
### Alter table with SQL
|
289
|
+
|
290
|
+
```ruby
|
291
|
+
# By SQL in argument
|
292
|
+
ClickHouse.connection.alter_table('table', 'DROP COLUMN user_id', cluster: nil)
|
293
|
+
|
294
|
+
# By SQL in a block
|
295
|
+
ClickHouse.connection.alter_table('table', cluster: nil) do
|
296
|
+
<<~SQL
|
297
|
+
DROP COLUMN user_id
|
298
|
+
SQL
|
299
|
+
end
|
300
|
+
```
|
301
|
+
|
256
302
|
## Type casting
|
257
303
|
|
258
304
|
By default gem provides all necessary type casting, but you may overwrite or define
|
@@ -404,6 +450,23 @@ scope = Visit.with_os.select('COUNT(*) as counter').group(:ipv4)
|
|
404
450
|
ClickHouse.connection.select_all(scope.to_sql)
|
405
451
|
````
|
406
452
|
|
453
|
+
You can clear the data table before each test with RSpec
|
454
|
+
|
455
|
+
```ruby
|
456
|
+
RSpec.configure do |config|
|
457
|
+
config.before(:each, clean_click_house: true) do
|
458
|
+
ClickHouse.connection.truncate_tables
|
459
|
+
end
|
460
|
+
end
|
461
|
+
```
|
462
|
+
|
463
|
+
```ruby
|
464
|
+
RSpec.describe Api::MetricsCountroller, clean_click_house: true do
|
465
|
+
it { }
|
466
|
+
it { }
|
467
|
+
end
|
468
|
+
```
|
469
|
+
|
407
470
|
## Development
|
408
471
|
|
409
472
|
```bash
|
data/bin/release.sh
ADDED
data/lib/click_house.rb
CHANGED
@@ -31,6 +31,11 @@ module ClickHouse
|
|
31
31
|
add_type "Nullable(#{column})", Type::NullableType.new(Type::DateType.new)
|
32
32
|
end
|
33
33
|
|
34
|
+
%w[String].each do |column|
|
35
|
+
add_type column, Type::StringType.new
|
36
|
+
add_type "Nullable(#{column})", Type::NullableType.new(Type::StringType.new)
|
37
|
+
end
|
38
|
+
|
34
39
|
['DateTime(%s)'].each do |column|
|
35
40
|
add_type column, Type::DateTimeType.new
|
36
41
|
add_type "Nullable(#{column})", Type::NullableType.new(Type::DateTimeType.new)
|
data/lib/click_house/errors.rb
CHANGED
data/lib/click_house/extend.rb
CHANGED
@@ -10,5 +10,6 @@ module ClickHouse
|
|
10
10
|
autoload :ConnectionTable, 'click_house/extend/connection_table'
|
11
11
|
autoload :ConnectionSelective, 'click_house/extend/connection_selective'
|
12
12
|
autoload :ConnectionInserting, 'click_house/extend/connection_inserting'
|
13
|
+
autoload :ConnectionAltering, 'click_house/extend/connection_altering'
|
13
14
|
end
|
14
15
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# rubocop:disable Metrics/ParameterLists
|
4
|
+
module ClickHouse
|
5
|
+
module Extend
|
6
|
+
module ConnectionAltering
|
7
|
+
def add_column(table, name, type, default: nil, if_not_exists: false, after: nil, cluster: nil)
|
8
|
+
sql = 'ADD COLUMN %<exists>s %<name>s %<type>s %<default>s %<after>s'
|
9
|
+
|
10
|
+
pattern = {
|
11
|
+
name: name,
|
12
|
+
exists: Util::Statement.ensure(if_not_exists, 'IF NOT EXISTS'),
|
13
|
+
type: Util::Statement.ensure(type, type),
|
14
|
+
default: Util::Statement.ensure(default, "DEFAULT #{default}"),
|
15
|
+
after: Util::Statement.ensure(after, "AFTER #{after}")
|
16
|
+
}
|
17
|
+
|
18
|
+
alter_table(table, format(sql, pattern), cluster: cluster)
|
19
|
+
end
|
20
|
+
|
21
|
+
def drop_column(table, name, if_exists: false, cluster: nil)
|
22
|
+
sql = 'DROP COLUMN %<exists>s %<name>s'
|
23
|
+
|
24
|
+
pattern = {
|
25
|
+
name: name,
|
26
|
+
exists: Util::Statement.ensure(if_exists, 'IF EXISTS')
|
27
|
+
}
|
28
|
+
|
29
|
+
alter_table(table, format(sql, pattern), cluster: cluster)
|
30
|
+
end
|
31
|
+
|
32
|
+
def alter_table(name, sql = nil, cluster: nil)
|
33
|
+
template = 'ALTER TABLE %<name>s %<cluster>s %<sql>s'
|
34
|
+
sql = yield(sql) if sql.nil?
|
35
|
+
|
36
|
+
pattern = {
|
37
|
+
name: name,
|
38
|
+
sql: sql,
|
39
|
+
cluster: Util::Statement.ensure(cluster, "ON CLUSTER #{cluster}"),
|
40
|
+
}
|
41
|
+
|
42
|
+
execute(format(template, pattern)).success?
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
# rubocop:enable Metrics/ParameterLists
|
@@ -68,14 +68,48 @@ module ClickHouse
|
|
68
68
|
sample: Util::Statement.ensure(sample, "SAMPLE BY #{sample}"),
|
69
69
|
ttl: Util::Statement.ensure(ttl, "TTL #{ttl}"),
|
70
70
|
settings: Util::Statement.ensure(settings, "SETTINGS #{settings}"),
|
71
|
-
engine: Util::Statement.ensure(engine, "ENGINE = #{engine}")
|
71
|
+
engine: Util::Statement.ensure(engine, "ENGINE = #{engine}")
|
72
72
|
}
|
73
73
|
|
74
|
-
puts format(sql, pattern)
|
75
|
-
|
76
74
|
execute(format(sql, pattern)).success?
|
77
75
|
end
|
78
76
|
# rubocop:enable Metrics/ParameterLists
|
77
|
+
|
78
|
+
def truncate_table(name, if_exists: false, cluster: nil)
|
79
|
+
sql = 'TRUNCATE TABLE %<exists>s %<name>s %<cluster>s'
|
80
|
+
|
81
|
+
pattern = {
|
82
|
+
name: name,
|
83
|
+
exists: Util::Statement.ensure(if_exists, 'IF EXISTS'),
|
84
|
+
cluster: Util::Statement.ensure(cluster, "ON CLUSTER #{cluster}")
|
85
|
+
}
|
86
|
+
|
87
|
+
execute(format(sql, pattern)).success?
|
88
|
+
end
|
89
|
+
|
90
|
+
def truncate_tables(names = tables, *argv)
|
91
|
+
Array(names).each { |name| truncate_table(name, *argv) }
|
92
|
+
end
|
93
|
+
|
94
|
+
def rename_table(from, to, cluster: nil)
|
95
|
+
from = Array(from)
|
96
|
+
to = Array(to)
|
97
|
+
|
98
|
+
unless from.length == to.length
|
99
|
+
raise StatementException, '<from> tables length should equal <to> length'
|
100
|
+
end
|
101
|
+
|
102
|
+
sql = <<~SQL
|
103
|
+
RENAME TABLE %<names>s %<cluster>s
|
104
|
+
SQL
|
105
|
+
|
106
|
+
pattern = {
|
107
|
+
names: from.zip(to).map { |a| a.join(' TO ') }.join(', '),
|
108
|
+
cluster: Util::Statement.ensure(cluster, "ON CLUSTER #{cluster}")
|
109
|
+
}
|
110
|
+
|
111
|
+
execute(format(sql, pattern)).success?
|
112
|
+
end
|
79
113
|
end
|
80
114
|
end
|
81
115
|
end
|
data/lib/click_house/type.rb
CHANGED
@@ -12,5 +12,7 @@ module ClickHouse
|
|
12
12
|
autoload :BooleanType, 'click_house/type/boolean_type'
|
13
13
|
autoload :DecimalType, 'click_house/type/decimal_type'
|
14
14
|
autoload :FixedStringType, 'click_house/type/fixed_string_type'
|
15
|
+
autoload :ArrayType, 'click_house/type/array_type'
|
16
|
+
autoload :StringType, 'click_house/type/string_type'
|
15
17
|
end
|
16
18
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ClickHouse
|
4
|
+
module Type
|
5
|
+
class ArrayType < BaseType
|
6
|
+
attr_reader :subtype
|
7
|
+
|
8
|
+
STRING_QUOTE = "'"
|
9
|
+
|
10
|
+
def initialize(subtype)
|
11
|
+
@subtype = subtype
|
12
|
+
end
|
13
|
+
|
14
|
+
def cast(value, *)
|
15
|
+
value
|
16
|
+
end
|
17
|
+
|
18
|
+
def serialize(array, *argv)
|
19
|
+
return array unless string?
|
20
|
+
|
21
|
+
serialized = array.map do |value|
|
22
|
+
escaped = subtype.serialize(value, *argv).tr(STRING_QUOTE, '\\\\' + STRING_QUOTE)
|
23
|
+
format("%<quote>s#{escaped}%<quote>s", quote: STRING_QUOTE)
|
24
|
+
end
|
25
|
+
|
26
|
+
"[#{serialized.join(',')}]"
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def string?
|
32
|
+
return @is_string if defined?(@is_string)
|
33
|
+
|
34
|
+
@is_string = subtype.is_a?(StringType) || subtype.is_a?(FixedStringType)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/click_house/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: click_house
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aliaksandr Shylau
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-11-
|
11
|
+
date: 2019-11-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -139,6 +139,7 @@ files:
|
|
139
139
|
- README.md
|
140
140
|
- Rakefile
|
141
141
|
- bin/console
|
142
|
+
- bin/release.sh
|
142
143
|
- bin/setup
|
143
144
|
- click_house.gemspec
|
144
145
|
- doc/logo.svg
|
@@ -153,6 +154,7 @@ files:
|
|
153
154
|
- lib/click_house/extend.rb
|
154
155
|
- lib/click_house/extend/configurable.rb
|
155
156
|
- lib/click_house/extend/connectible.rb
|
157
|
+
- lib/click_house/extend/connection_altering.rb
|
156
158
|
- lib/click_house/extend/connection_database.rb
|
157
159
|
- lib/click_house/extend/connection_healthy.rb
|
158
160
|
- lib/click_house/extend/connection_inserting.rb
|
@@ -167,6 +169,7 @@ files:
|
|
167
169
|
- lib/click_house/response/factory.rb
|
168
170
|
- lib/click_house/response/result_set.rb
|
169
171
|
- lib/click_house/type.rb
|
172
|
+
- lib/click_house/type/array_type.rb
|
170
173
|
- lib/click_house/type/base_type.rb
|
171
174
|
- lib/click_house/type/boolean_type.rb
|
172
175
|
- lib/click_house/type/date_time_type.rb
|
@@ -176,6 +179,7 @@ files:
|
|
176
179
|
- lib/click_house/type/float_type.rb
|
177
180
|
- lib/click_house/type/integer_type.rb
|
178
181
|
- lib/click_house/type/nullable_type.rb
|
182
|
+
- lib/click_house/type/string_type.rb
|
179
183
|
- lib/click_house/type/undefined_type.rb
|
180
184
|
- lib/click_house/util.rb
|
181
185
|
- lib/click_house/util/pretty.rb
|