clickhouse-native 0.1.3 → 0.2.1
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 +4 -4
- data/ext/clickhouse_native/client.cpp +40 -16
- data/lib/clickhouse_native/pool.rb +5 -0
- data/lib/clickhouse_native/version.rb +1 -1
- data/lib/clickhouse_native.rb +1 -0
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ec4d2e97965b571da7367ccc55b66dbdcd12ab021205dd557b9cc5caca351ade
|
|
4
|
+
data.tar.gz: 2cea94982674d7b200b7decca83f2436cde647c2305b4b64aba201b50a9365c0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8d35945de6ccb097385ddb5e21584d8b3f99df1db01bd4f631e52c27b0b7d1faafbcc85d511e07269606c441a10cf6ded46c14089af2cf519d78a53f5739d611
|
|
7
|
+
data.tar.gz: add830a89e72da435b26521dbc61a8e7fec42403932af2b53fe2eefa896b672e8431083d0c0e4a1db8258d5dc31dc2932c799bb495f40857aaa13c7ec2a5a9be
|
|
@@ -174,16 +174,24 @@ static VALUE value_at(const ColumnRef& col, size_t idx) {
|
|
|
174
174
|
}
|
|
175
175
|
|
|
176
176
|
case Type::Date: {
|
|
177
|
-
|
|
178
|
-
|
|
177
|
+
// Return a Ruby Date so as_json/to_s gives "YYYY-MM-DD" instead of
|
|
178
|
+
// a full ISO8601 timestamp. CH Date is days since 1970-01-01 UTC.
|
|
179
|
+
std::time_t t = col->As<ColumnDate>()->At(idx);
|
|
180
|
+
long days = static_cast<long>(t / 86400);
|
|
181
|
+
VALUE rb_cDate = rb_const_get(rb_cObject, rb_intern("Date"));
|
|
182
|
+
return rb_funcall(rb_cDate, rb_intern("jd"), 1, LONG2NUM(days + 2440588));
|
|
179
183
|
}
|
|
180
184
|
case Type::Date32: {
|
|
181
|
-
|
|
182
|
-
|
|
185
|
+
std::time_t t = col->As<ColumnDate32>()->At(idx);
|
|
186
|
+
long days = static_cast<long>(t / 86400);
|
|
187
|
+
VALUE rb_cDate = rb_const_get(rb_cObject, rb_intern("Date"));
|
|
188
|
+
return rb_funcall(rb_cDate, rb_intern("jd"), 1, LONG2NUM(days + 2440588));
|
|
183
189
|
}
|
|
184
190
|
case Type::DateTime: {
|
|
185
191
|
auto t = col->As<ColumnDateTime>()->At(idx);
|
|
186
|
-
|
|
192
|
+
VALUE rb_t = rb_time_new(t, 0);
|
|
193
|
+
rb_funcall(rb_t, rb_intern("utc"), 0);
|
|
194
|
+
return rb_t;
|
|
187
195
|
}
|
|
188
196
|
case Type::DateTime64: {
|
|
189
197
|
auto ct = col->As<ColumnDateTime64>();
|
|
@@ -194,7 +202,9 @@ static VALUE value_at(const ColumnRef& col, size_t idx) {
|
|
|
194
202
|
int64_t frac = ticks % denom;
|
|
195
203
|
int64_t usec = (prec <= 6) ? frac * pow10_i64(6 - prec)
|
|
196
204
|
: frac / pow10_i64(prec - 6);
|
|
197
|
-
|
|
205
|
+
VALUE rb_t = rb_time_new(secs, usec);
|
|
206
|
+
rb_funcall(rb_t, rb_intern("utc"), 0);
|
|
207
|
+
return rb_t;
|
|
198
208
|
}
|
|
199
209
|
|
|
200
210
|
case Type::Array: {
|
|
@@ -340,6 +350,28 @@ static bool has_trailing_tz(const char* s, size_t len) {
|
|
|
340
350
|
return false;
|
|
341
351
|
}
|
|
342
352
|
|
|
353
|
+
// For Date columns: normalise the value to its UTC-midnight epoch so the
|
|
354
|
+
// calendar day is preserved regardless of the process's local timezone.
|
|
355
|
+
// Handles Date, DateTime, Time, String ("YYYY-MM-DD" etc.), Integer epoch.
|
|
356
|
+
static int64_t coerce_to_date_epoch(VALUE value) {
|
|
357
|
+
if (RB_INTEGER_TYPE_P(value)) return NUM2LL(value);
|
|
358
|
+
VALUE date_src = value;
|
|
359
|
+
if (RB_TYPE_P(value, T_STRING)) {
|
|
360
|
+
VALUE rb_cDate = rb_const_get(rb_cObject, rb_intern("Date"));
|
|
361
|
+
date_src = rb_funcall(rb_cDate, rb_intern("parse"), 1, value);
|
|
362
|
+
} else if (rb_respond_to(value, rb_intern("hour"))) {
|
|
363
|
+
// Time / DateTime: take the wall-clock date portion as UTC midnight.
|
|
364
|
+
// We intentionally ignore the TZ offset here — callers who need
|
|
365
|
+
// strict moment semantics should use DateTime64 instead.
|
|
366
|
+
date_src = value;
|
|
367
|
+
}
|
|
368
|
+
VALUE y = rb_funcall(date_src, rb_intern("year"), 0);
|
|
369
|
+
VALUE m = rb_funcall(date_src, rb_intern("month"), 0);
|
|
370
|
+
VALUE d = rb_funcall(date_src, rb_intern("day"), 0);
|
|
371
|
+
VALUE utc = rb_funcall(rb_cTime, rb_intern("utc"), 3, y, m, d);
|
|
372
|
+
return NUM2LL(rb_funcall(utc, rb_intern("to_i"), 0));
|
|
373
|
+
}
|
|
374
|
+
|
|
343
375
|
// Accepts a Time, a String (parsed via Time.parse), or a numeric (epoch
|
|
344
376
|
// seconds). Mirrors how the HTTP gem's JSONEachRow coerced date cells.
|
|
345
377
|
//
|
|
@@ -429,16 +461,8 @@ static void append_value(const ColumnRef& col, VALUE value) {
|
|
|
429
461
|
return;
|
|
430
462
|
}
|
|
431
463
|
|
|
432
|
-
case Type::Date:
|
|
433
|
-
|
|
434
|
-
col->As<ColumnDate>()->Append(static_cast<std::time_t>(NUM2LL(rb_funcall(t, rb_intern("to_i"), 0))));
|
|
435
|
-
return;
|
|
436
|
-
}
|
|
437
|
-
case Type::Date32: {
|
|
438
|
-
VALUE t = coerce_to_time(value);
|
|
439
|
-
col->As<ColumnDate32>()->Append(static_cast<std::time_t>(NUM2LL(rb_funcall(t, rb_intern("to_i"), 0))));
|
|
440
|
-
return;
|
|
441
|
-
}
|
|
464
|
+
case Type::Date: col->As<ColumnDate>()->Append(static_cast<std::time_t>(coerce_to_date_epoch(value))); return;
|
|
465
|
+
case Type::Date32: col->As<ColumnDate32>()->Append(static_cast<std::time_t>(coerce_to_date_epoch(value))); return;
|
|
442
466
|
case Type::DateTime: {
|
|
443
467
|
VALUE t = coerce_to_time(value);
|
|
444
468
|
col->As<ColumnDateTime>()->Append(static_cast<std::time_t>(NUM2LL(rb_funcall(t, rb_intern("to_i"), 0))));
|
|
@@ -4,8 +4,13 @@ require "connection_pool"
|
|
|
4
4
|
|
|
5
5
|
module ClickhouseNative
|
|
6
6
|
class Pool
|
|
7
|
+
attr_reader :host, :port, :database
|
|
8
|
+
|
|
7
9
|
def initialize(host:, port:, database: "default", user: "default", password: "",
|
|
8
10
|
compression: :none, logger: nil, pool_size: 5, pool_timeout: 5)
|
|
11
|
+
@host = host
|
|
12
|
+
@port = port
|
|
13
|
+
@database = database
|
|
9
14
|
client_kwargs = { host:, port:, database:, user:, password:, compression:, logger: }
|
|
10
15
|
@pool = ConnectionPool.new(size: pool_size, timeout: pool_timeout) do
|
|
11
16
|
Client.new(**client_kwargs)
|
data/lib/clickhouse_native.rb
CHANGED