clickhouse-ruby 0.1.0 → 0.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.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +74 -1
  3. data/README.md +165 -79
  4. data/lib/clickhouse_ruby/active_record/arel_visitor.rb +205 -76
  5. data/lib/clickhouse_ruby/active_record/connection_adapter.rb +103 -98
  6. data/lib/clickhouse_ruby/active_record/railtie.rb +20 -15
  7. data/lib/clickhouse_ruby/active_record/relation_extensions.rb +398 -0
  8. data/lib/clickhouse_ruby/active_record/schema_statements.rb +90 -104
  9. data/lib/clickhouse_ruby/active_record.rb +24 -10
  10. data/lib/clickhouse_ruby/client.rb +181 -74
  11. data/lib/clickhouse_ruby/configuration.rb +51 -10
  12. data/lib/clickhouse_ruby/connection.rb +180 -64
  13. data/lib/clickhouse_ruby/connection_pool.rb +25 -19
  14. data/lib/clickhouse_ruby/errors.rb +13 -1
  15. data/lib/clickhouse_ruby/result.rb +11 -16
  16. data/lib/clickhouse_ruby/retry_handler.rb +172 -0
  17. data/lib/clickhouse_ruby/streaming_result.rb +309 -0
  18. data/lib/clickhouse_ruby/types/array.rb +11 -64
  19. data/lib/clickhouse_ruby/types/base.rb +59 -0
  20. data/lib/clickhouse_ruby/types/boolean.rb +28 -25
  21. data/lib/clickhouse_ruby/types/date_time.rb +10 -27
  22. data/lib/clickhouse_ruby/types/decimal.rb +173 -0
  23. data/lib/clickhouse_ruby/types/enum.rb +262 -0
  24. data/lib/clickhouse_ruby/types/float.rb +14 -28
  25. data/lib/clickhouse_ruby/types/integer.rb +21 -43
  26. data/lib/clickhouse_ruby/types/low_cardinality.rb +1 -1
  27. data/lib/clickhouse_ruby/types/map.rb +21 -36
  28. data/lib/clickhouse_ruby/types/null_safe.rb +81 -0
  29. data/lib/clickhouse_ruby/types/nullable.rb +2 -2
  30. data/lib/clickhouse_ruby/types/parser.rb +28 -18
  31. data/lib/clickhouse_ruby/types/registry.rb +40 -29
  32. data/lib/clickhouse_ruby/types/string.rb +9 -13
  33. data/lib/clickhouse_ruby/types/string_parser.rb +135 -0
  34. data/lib/clickhouse_ruby/types/tuple.rb +11 -68
  35. data/lib/clickhouse_ruby/types/uuid.rb +15 -22
  36. data/lib/clickhouse_ruby/types.rb +19 -15
  37. data/lib/clickhouse_ruby/version.rb +1 -1
  38. data/lib/clickhouse_ruby.rb +11 -11
  39. metadata +41 -6
@@ -1,8 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'active_record/connection_adapters/abstract_adapter'
4
- require_relative 'arel_visitor'
5
- require_relative 'schema_statements'
3
+ require "active_record/connection_adapters/abstract_adapter"
4
+ require_relative "arel_visitor"
5
+ require_relative "schema_statements"
6
+ require_relative "relation_extensions"
6
7
 
7
8
  module ClickhouseRuby
8
9
  module ActiveRecord
@@ -39,28 +40,28 @@ module ClickhouseRuby
39
40
  # Event.where(status: 'old').delete_all # Raises on error!
40
41
  #
41
42
  class ConnectionAdapter < ::ActiveRecord::ConnectionAdapters::AbstractAdapter
42
- ADAPTER_NAME = 'Clickhouse'
43
+ ADAPTER_NAME = "Clickhouse"
43
44
 
44
45
  include SchemaStatements
45
46
 
46
47
  # Native database types mapping for ClickHouse
47
48
  # Used by migrations and schema definitions
48
49
  NATIVE_DATABASE_TYPES = {
49
- primary_key: 'UInt64',
50
- string: { name: 'String' },
51
- text: { name: 'String' },
52
- integer: { name: 'Int32' },
53
- bigint: { name: 'Int64' },
54
- float: { name: 'Float32' },
55
- decimal: { name: 'Decimal', precision: 10, scale: 0 },
56
- datetime: { name: 'DateTime' },
57
- timestamp: { name: 'DateTime64', precision: 3 },
58
- time: { name: 'DateTime' },
59
- date: { name: 'Date' },
60
- binary: { name: 'String' },
61
- boolean: { name: 'UInt8' },
62
- uuid: { name: 'UUID' },
63
- json: { name: 'String' }
50
+ primary_key: "UInt64",
51
+ string: { name: "String" },
52
+ text: { name: "String" },
53
+ integer: { name: "Int32" },
54
+ bigint: { name: "Int64" },
55
+ float: { name: "Float32" },
56
+ decimal: { name: "Decimal", precision: 10, scale: 0 },
57
+ datetime: { name: "DateTime" },
58
+ timestamp: { name: "DateTime64", precision: 3 },
59
+ time: { name: "DateTime" },
60
+ date: { name: "Date" },
61
+ binary: { name: "String" },
62
+ boolean: { name: "UInt8" },
63
+ uuid: { name: "UUID" },
64
+ json: { name: "String" },
64
65
  }.freeze
65
66
 
66
67
  class << self
@@ -73,9 +74,9 @@ module ClickhouseRuby
73
74
  # @param config [Hash] database configuration
74
75
  # @return [ConnectionAdapter] the adapter instance
75
76
  def new_client(config)
76
- chruby_config = build_chruby_config(config)
77
- chruby_config.validate!
78
- ClickhouseRuby::Client.new(chruby_config)
77
+ clickhouse_config = build_clickhouse_config(config)
78
+ clickhouse_config.validate!
79
+ ClickhouseRuby::Client.new(clickhouse_config)
79
80
  end
80
81
 
81
82
  private
@@ -84,11 +85,11 @@ module ClickhouseRuby
84
85
  #
85
86
  # @param config [Hash] database configuration hash
86
87
  # @return [ClickhouseRuby::Configuration] configured client
87
- def build_chruby_config(config)
88
+ def build_clickhouse_config(config)
88
89
  ClickhouseRuby::Configuration.new.tap do |c|
89
- c.host = config[:host] || 'localhost'
90
+ c.host = config[:host] || "localhost"
90
91
  c.port = config[:port]&.to_i || 8123
91
- c.database = config[:database] || 'default'
92
+ c.database = config[:database] || "default"
92
93
  c.username = config[:username]
93
94
  c.password = config[:password]
94
95
  c.ssl = config[:ssl]
@@ -110,12 +111,15 @@ module ClickhouseRuby
110
111
  # @param logger [Logger] Rails logger
111
112
  # @param connection_options [Array] connection options
112
113
  # @param config [Hash] database configuration
113
- def initialize(connection, logger = nil, connection_options = nil, config = {})
114
+ def initialize(connection, logger = nil, _connection_options = nil, config = {})
114
115
  @config = config.symbolize_keys
115
- @chruby_client = nil
116
+ @clickhouse_client = nil
116
117
  @connection_parameters = nil
117
118
 
118
119
  super(connection, logger, config)
120
+
121
+ # Extend ActiveRecord::Relation with our methods
122
+ ::ActiveRecord::Relation.include(RelationExtensions)
119
123
  end
120
124
 
121
125
  # Returns the adapter name
@@ -140,10 +144,10 @@ module ClickhouseRuby
140
144
  #
141
145
  # @return [Boolean] true if connected and responding
142
146
  def active?
143
- return false unless @chruby_client
147
+ return false unless @clickhouse_client
144
148
 
145
149
  # Ping ClickHouse to verify connection
146
- execute_internal('SELECT 1')
150
+ execute_internal("SELECT 1")
147
151
  true
148
152
  rescue ClickhouseRuby::Error
149
153
  false
@@ -153,7 +157,7 @@ module ClickhouseRuby
153
157
  #
154
158
  # @return [Boolean] true if we have a client instance
155
159
  def connected?
156
- !@chruby_client.nil?
160
+ !@clickhouse_client.nil?
157
161
  end
158
162
 
159
163
  # Disconnect from the database
@@ -161,8 +165,8 @@ module ClickhouseRuby
161
165
  # @return [void]
162
166
  def disconnect!
163
167
  super
164
- @chruby_client&.close if @chruby_client.respond_to?(:close)
165
- @chruby_client = nil
168
+ @clickhouse_client&.close if @clickhouse_client.respond_to?(:close)
169
+ @clickhouse_client = nil
166
170
  end
167
171
 
168
172
  # Reconnect to the database
@@ -185,7 +189,7 @@ module ClickhouseRuby
185
189
  #
186
190
  # @return [void]
187
191
  def connect
188
- @chruby_client = self.class.new_client(@config)
192
+ @clickhouse_client = self.class.new_client(@config)
189
193
  end
190
194
 
191
195
  # ========================================
@@ -322,7 +326,7 @@ module ClickhouseRuby
322
326
  raise ClickhouseRuby::QueryError.new(
323
327
  "Query execution failed: #{e.message}",
324
328
  sql: sql,
325
- original_error: e
329
+ original_error: e,
326
330
  )
327
331
  end
328
332
 
@@ -337,7 +341,7 @@ module ClickhouseRuby
337
341
  # @param binds [Array] bind values
338
342
  # @return [Object] the id value
339
343
  # @raise [ClickhouseRuby::QueryError] on ClickHouse errors
340
- def exec_insert(sql, name = nil, binds = [], pk = nil, sequence_name = nil)
344
+ def exec_insert(sql, name = nil, _binds = [], _pk = nil, _sequence_name = nil)
341
345
  execute(sql, name)
342
346
  # ClickHouse doesn't return inserted IDs
343
347
  # Return nil as we can't get the last insert ID
@@ -355,7 +359,7 @@ module ClickhouseRuby
355
359
  # @param binds [Array] bind values
356
360
  # @return [Integer] number of affected rows (estimated, ClickHouse doesn't return exact count)
357
361
  # @raise [ClickhouseRuby::QueryError] on ClickHouse errors - NEVER silently fails
358
- def exec_delete(sql, name = nil, binds = [])
362
+ def exec_delete(sql, name = nil, _binds = [])
359
363
  ensure_connected!
360
364
 
361
365
  # The Arel visitor should have already converted this to
@@ -363,7 +367,7 @@ module ClickhouseRuby
363
367
  # But if it's standard DELETE, convert it here
364
368
  clickhouse_sql = convert_delete_to_alter(sql)
365
369
 
366
- log(clickhouse_sql, name || 'DELETE') do
370
+ log(clickhouse_sql, name || "DELETE") do
367
371
  result = execute_internal(clickhouse_sql)
368
372
  # CRITICAL: Raise on any error
369
373
  raise_if_error!(result)
@@ -379,7 +383,7 @@ module ClickhouseRuby
379
383
  raise ClickhouseRuby::QueryError.new(
380
384
  "DELETE failed: #{e.message}",
381
385
  sql: sql,
382
- original_error: e
386
+ original_error: e,
383
387
  )
384
388
  end
385
389
 
@@ -394,14 +398,14 @@ module ClickhouseRuby
394
398
  # @param binds [Array] bind values
395
399
  # @return [Integer] number of affected rows (estimated)
396
400
  # @raise [ClickhouseRuby::QueryError] on ClickHouse errors
397
- def exec_update(sql, name = nil, binds = [])
401
+ def exec_update(sql, name = nil, _binds = [])
398
402
  ensure_connected!
399
403
 
400
404
  # The Arel visitor should have already converted this to
401
405
  # ALTER TABLE ... UPDATE ... WHERE syntax
402
406
  clickhouse_sql = convert_update_to_alter(sql)
403
407
 
404
- log(clickhouse_sql, name || 'UPDATE') do
408
+ log(clickhouse_sql, name || "UPDATE") do
405
409
  result = execute_internal(clickhouse_sql)
406
410
  raise_if_error!(result)
407
411
 
@@ -414,7 +418,7 @@ module ClickhouseRuby
414
418
  raise ClickhouseRuby::QueryError.new(
415
419
  "UPDATE failed: #{e.message}",
416
420
  sql: sql,
417
- original_error: e
421
+ original_error: e,
418
422
  )
419
423
  end
420
424
 
@@ -425,7 +429,7 @@ module ClickhouseRuby
425
429
  # @param binds [Array] bind values
426
430
  # @param prepare [Boolean] whether to prepare (ignored, ClickHouse doesn't support)
427
431
  # @return [ClickhouseRuby::Result] query result
428
- def exec_query(sql, name = 'SQL', binds = [], prepare: false)
432
+ def exec_query(sql, name = "SQL", _binds = [], prepare: false)
429
433
  execute(sql, name)
430
434
  end
431
435
 
@@ -456,7 +460,7 @@ module ClickhouseRuby
456
460
  def exec_rollback_db_transaction
457
461
  # No-op: ClickHouse doesn't support transactions
458
462
  # Log a warning since rollback was requested but cannot be performed
459
- @logger&.warn('ClickHouse does not support transaction rollback')
463
+ @logger&.warn("ClickHouse does not support transaction rollback")
460
464
  end
461
465
 
462
466
  # ========================================
@@ -469,7 +473,7 @@ module ClickhouseRuby
469
473
  # @param name [String, Symbol] the column name
470
474
  # @return [String] the quoted column name
471
475
  def quote_column_name(name)
472
- "`#{name.to_s.gsub('`', '``')}`"
476
+ "`#{name.to_s.gsub("`", "``")}`"
473
477
  end
474
478
 
475
479
  # Quote a table name for ClickHouse
@@ -477,7 +481,7 @@ module ClickhouseRuby
477
481
  # @param name [String, Symbol] the table name
478
482
  # @return [String] the quoted table name
479
483
  def quote_table_name(name)
480
- "`#{name.to_s.gsub('`', '``')}`"
484
+ "`#{name.to_s.gsub("`", "``")}`"
481
485
  end
482
486
 
483
487
  # Quote a string value for ClickHouse
@@ -509,58 +513,58 @@ module ClickhouseRuby
509
513
  # @return [void]
510
514
  def initialize_type_map(m = type_map)
511
515
  # Register standard types
512
- register_class_with_limit m, %r{^String}i, ::ActiveRecord::Type::String
513
- register_class_with_limit m, %r{^FixedString}i, ::ActiveRecord::Type::String
516
+ register_class_with_limit m, /^String/i, ::ActiveRecord::Type::String
517
+ register_class_with_limit m, /^FixedString/i, ::ActiveRecord::Type::String
514
518
 
515
519
  # Integer types
516
- m.register_type %r{^Int8}i, ::ActiveRecord::Type::Integer.new(limit: 1)
517
- m.register_type %r{^Int16}i, ::ActiveRecord::Type::Integer.new(limit: 2)
518
- m.register_type %r{^Int32}i, ::ActiveRecord::Type::Integer.new(limit: 4)
519
- m.register_type %r{^Int64}i, ::ActiveRecord::Type::Integer.new(limit: 8)
520
- m.register_type %r{^UInt8}i, ::ActiveRecord::Type::Integer.new(limit: 1)
521
- m.register_type %r{^UInt16}i, ::ActiveRecord::Type::Integer.new(limit: 2)
522
- m.register_type %r{^UInt32}i, ::ActiveRecord::Type::Integer.new(limit: 4)
523
- m.register_type %r{^UInt64}i, ::ActiveRecord::Type::Integer.new(limit: 8)
520
+ m.register_type(/^Int8/i, ::ActiveRecord::Type::Integer.new(limit: 1))
521
+ m.register_type(/^Int16/i, ::ActiveRecord::Type::Integer.new(limit: 2))
522
+ m.register_type(/^Int32/i, ::ActiveRecord::Type::Integer.new(limit: 4))
523
+ m.register_type(/^Int64/i, ::ActiveRecord::Type::Integer.new(limit: 8))
524
+ m.register_type(/^UInt8/i, ::ActiveRecord::Type::Integer.new(limit: 1))
525
+ m.register_type(/^UInt16/i, ::ActiveRecord::Type::Integer.new(limit: 2))
526
+ m.register_type(/^UInt32/i, ::ActiveRecord::Type::Integer.new(limit: 4))
527
+ m.register_type(/^UInt64/i, ::ActiveRecord::Type::Integer.new(limit: 8))
524
528
 
525
529
  # Float types
526
- m.register_type %r{^Float32}i, ::ActiveRecord::Type::Float.new
527
- m.register_type %r{^Float64}i, ::ActiveRecord::Type::Float.new
530
+ m.register_type(/^Float32/i, ::ActiveRecord::Type::Float.new)
531
+ m.register_type(/^Float64/i, ::ActiveRecord::Type::Float.new)
528
532
 
529
533
  # Decimal types
530
- m.register_type %r{^Decimal}i, ::ActiveRecord::Type::Decimal.new
534
+ m.register_type(/^Decimal/i, ::ActiveRecord::Type::Decimal.new)
531
535
 
532
536
  # Date/Time types
533
- m.register_type %r{^Date$}i, ::ActiveRecord::Type::Date.new
534
- m.register_type %r{^DateTime}i, ::ActiveRecord::Type::DateTime.new
535
- m.register_type %r{^DateTime64}i, ::ActiveRecord::Type::DateTime.new
537
+ m.register_type(/^Date$/i, ::ActiveRecord::Type::Date.new)
538
+ m.register_type(/^DateTime/i, ::ActiveRecord::Type::DateTime.new)
539
+ m.register_type(/^DateTime64/i, ::ActiveRecord::Type::DateTime.new)
536
540
 
537
541
  # Boolean (UInt8 with 0/1)
538
- m.register_type %r{^Bool}i, ::ActiveRecord::Type::Boolean.new
542
+ m.register_type(/^Bool/i, ::ActiveRecord::Type::Boolean.new)
539
543
 
540
544
  # UUID
541
- m.register_type %r{^UUID}i, ::ActiveRecord::Type::String.new
545
+ m.register_type(/^UUID/i, ::ActiveRecord::Type::String.new)
542
546
 
543
547
  # Nullable wrapper - extract inner type
544
- m.register_type %r{^Nullable\((.+)\)}i do |sql_type|
545
- inner_type = sql_type.match(%r{^Nullable\((.+)\)}i)[1]
548
+ m.register_type(/^Nullable\((.+)\)/i) do |sql_type|
549
+ inner_type = sql_type.match(/^Nullable\((.+)\)/i)[1]
546
550
  lookup_cast_type(inner_type)
547
551
  end
548
552
 
549
553
  # Array types
550
- m.register_type %r{^Array\(}i, ::ActiveRecord::Type::String.new
554
+ m.register_type(/^Array\(/i, ::ActiveRecord::Type::String.new)
551
555
 
552
556
  # Map types
553
- m.register_type %r{^Map\(}i, ::ActiveRecord::Type::String.new
557
+ m.register_type(/^Map\(/i, ::ActiveRecord::Type::String.new)
554
558
 
555
559
  # Tuple types
556
- m.register_type %r{^Tuple\(}i, ::ActiveRecord::Type::String.new
560
+ m.register_type(/^Tuple\(/i, ::ActiveRecord::Type::String.new)
557
561
 
558
562
  # Enum types (treated as strings)
559
- m.register_type %r{^Enum}i, ::ActiveRecord::Type::String.new
563
+ m.register_type(/^Enum/i, ::ActiveRecord::Type::String.new)
560
564
 
561
565
  # LowCardinality wrapper
562
- m.register_type %r{^LowCardinality\((.+)\)}i do |sql_type|
563
- inner_type = sql_type.match(%r{^LowCardinality\((.+)\)}i)[1]
566
+ m.register_type(/^LowCardinality\((.+)\)/i) do |sql_type|
567
+ inner_type = sql_type.match(/^LowCardinality\((.+)\)/i)[1]
564
568
  lookup_cast_type(inner_type)
565
569
  end
566
570
  end
@@ -573,10 +577,10 @@ module ClickhouseRuby
573
577
  def ensure_connected!
574
578
  connect unless connected?
575
579
 
576
- unless @chruby_client
577
- raise ClickhouseRuby::ConnectionNotEstablished,
578
- 'No connection to ClickHouse. Call connect first.'
579
- end
580
+ return if @clickhouse_client
581
+
582
+ raise ClickhouseRuby::ConnectionNotEstablished,
583
+ "No connection to ClickHouse. Call connect first."
580
584
  end
581
585
 
582
586
  # Execute SQL through the ClickhouseRuby client
@@ -584,7 +588,7 @@ module ClickhouseRuby
584
588
  # @param sql [String] the SQL to execute
585
589
  # @return [ClickhouseRuby::Result] the result
586
590
  def execute_internal(sql)
587
- @chruby_client.execute(sql)
591
+ @clickhouse_client.execute(sql)
588
592
  end
589
593
 
590
594
  # Check if result contains an error and raise it
@@ -598,7 +602,7 @@ module ClickhouseRuby
598
602
  raise ClickhouseRuby::QueryError.new(
599
603
  result.error_message,
600
604
  code: result.error_code,
601
- http_status: result.http_status
605
+ http_status: result.http_status,
602
606
  )
603
607
  end
604
608
 
@@ -610,22 +614,21 @@ module ClickhouseRuby
610
614
  def raise_query_error(error, sql)
611
615
  if error.is_a?(ClickhouseRuby::QueryError)
612
616
  # Re-raise with SQL if not already set
613
- if error.sql.nil?
614
- raise ClickhouseRuby::QueryError.new(
615
- error.message,
616
- code: error.code,
617
- http_status: error.http_status,
618
- sql: sql,
619
- original_error: error.original_error
620
- )
621
- else
622
- raise error
623
- end
617
+ raise error unless error.sql.nil?
618
+
619
+ raise ClickhouseRuby::QueryError.new(
620
+ error.message,
621
+ code: error.code,
622
+ http_status: error.http_status,
623
+ sql: sql,
624
+ original_error: error.original_error,
625
+ )
626
+
624
627
  else
625
628
  raise ClickhouseRuby::QueryError.new(
626
629
  error.message,
627
630
  sql: sql,
628
- original_error: error
631
+ original_error: error,
629
632
  )
630
633
  end
631
634
  end
@@ -705,19 +708,21 @@ module ClickhouseRuby
705
708
  # @param sql_type [String] the SQL type
706
709
  # @return [Integer, nil] the limit or nil
707
710
  def extract_limit(sql_type)
708
- if (match = sql_type.match(/\((\d+)\)/))
709
- match[1].to_i
710
- end
711
+ return unless (match = sql_type.match(/\((\d+)\)/))
712
+
713
+ match[1].to_i
711
714
  end
712
715
  end
713
716
  end
714
717
  end
715
718
 
716
719
  # Register the adapter with ActiveRecord
717
- if defined?(::ActiveRecord::ConnectionAdapters)
718
- ::ActiveRecord::ConnectionAdapters.register(
719
- 'clickhouse',
720
- 'ClickhouseRuby::ActiveRecord::ConnectionAdapter',
721
- 'chruby/active_record/connection_adapter'
722
- )
720
+ if defined?(ActiveRecord::ConnectionAdapters)
721
+ if ActiveRecord::ConnectionAdapters.respond_to?(:register)
722
+ ActiveRecord::ConnectionAdapters.register(
723
+ "clickhouse",
724
+ "ClickhouseRuby::ActiveRecord::ConnectionAdapter",
725
+ "clickhouse_ruby/active_record/connection_adapter",
726
+ )
727
+ end
723
728
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'rails/railtie'
3
+ require "rails/railtie"
4
4
 
5
5
  module ClickhouseRuby
6
6
  module ActiveRecord
@@ -28,24 +28,25 @@ module ClickhouseRuby
28
28
  #
29
29
  class Railtie < ::Rails::Railtie
30
30
  # Initialize the adapter when ActiveRecord loads
31
- initializer 'chruby.initialize_active_record' do
31
+ initializer "clickhouse_ruby.initialize_active_record" do
32
32
  # Register the adapter
33
33
  ::ActiveSupport.on_load(:active_record) do
34
- require_relative 'connection_adapter'
34
+ require_relative "connection_adapter"
35
35
 
36
36
  # Log that the adapter is being registered
37
37
  if defined?(Rails.logger) && Rails.logger
38
- Rails.logger.info '[ClickhouseRuby] ClickHouse adapter registered with ActiveRecord'
38
+ Rails.logger.info "[ClickhouseRuby] ClickHouse adapter registered with ActiveRecord"
39
39
  end
40
40
  end
41
41
  end
42
42
 
43
43
  # Configure database tasks (db:create, db:drop, etc.)
44
- initializer 'chruby.configure_database_tasks' do
44
+ initializer "clickhouse_ruby.configure_database_tasks" do
45
45
  ::ActiveSupport.on_load(:active_record) do
46
46
  # Register ClickHouse-specific database tasks
47
47
  if defined?(::ActiveRecord::Tasks::DatabaseTasks)
48
- ::ActiveRecord::Tasks::DatabaseTasks.register_task(/clickhouse/, 'ClickhouseRuby::ActiveRecord::DatabaseTasks')
48
+ ::ActiveRecord::Tasks::DatabaseTasks.register_task(/clickhouse/,
49
+ "ClickhouseRuby::ActiveRecord::DatabaseTasks",)
49
50
  end
50
51
  end
51
52
  end
@@ -55,21 +56,25 @@ module ClickhouseRuby
55
56
  # Set up connection pool based on Rails configuration
56
57
  if defined?(ActiveRecord::Base)
57
58
  # Ensure connections are properly managed
58
- ActiveRecord::Base.connection_pool.disconnect! rescue nil
59
+ begin
60
+ ActiveRecord::Base.connection_pool.disconnect!
61
+ rescue StandardError
62
+ nil
63
+ end
59
64
  end
60
65
  end
61
66
 
62
67
  # Add generators namespace for Rails generators
63
68
  generators do
64
- require_relative 'generators/migration_generator' if defined?(::Rails::Generators)
69
+ require_relative "generators/migration_generator" if defined?(::Rails::Generators)
65
70
  end
66
71
 
67
72
  # Log deprecation warnings for known issues
68
- initializer 'chruby.log_deprecation_warnings' do
73
+ initializer "clickhouse_ruby.log_deprecation_warnings" do
69
74
  ::ActiveSupport.on_load(:active_record) do
70
75
  # Warn about features that don't work with ClickHouse
71
76
  if defined?(Rails.logger) && Rails.logger
72
- Rails.logger.debug '[ClickhouseRuby] Note: ClickHouse does not support transactions, savepoints, or foreign keys'
77
+ Rails.logger.debug "[ClickhouseRuby] Note: ClickHouse does not support transactions, savepoints, or foreign keys"
73
78
  end
74
79
  end
75
80
  end
@@ -94,7 +99,7 @@ module ClickhouseRuby
94
99
 
95
100
  # Connect without database to create it
96
101
  temp_config = config.dup
97
- temp_config[:database] = 'default'
102
+ temp_config[:database] = "default"
98
103
 
99
104
  adapter = ConnectionAdapter.new(nil, nil, nil, temp_config)
100
105
  adapter.connect
@@ -117,7 +122,7 @@ module ClickhouseRuby
117
122
 
118
123
  # Connect without database to drop it
119
124
  temp_config = config.dup
120
- temp_config[:database] = 'default'
125
+ temp_config[:database] = "default"
121
126
 
122
127
  adapter = ConnectionAdapter.new(nil, nil, nil, temp_config)
123
128
  adapter.connect
@@ -145,11 +150,11 @@ module ClickhouseRuby
145
150
  adapter = ConnectionAdapter.new(nil, nil, nil, config)
146
151
  adapter.connect
147
152
 
148
- File.open(filename, 'w') do |file|
153
+ File.open(filename, "w") do |file|
149
154
  # Dump each table's CREATE statement
150
155
  adapter.tables.each do |table_name|
151
156
  result = adapter.execute("SHOW CREATE TABLE #{adapter.quote_table_name(table_name)}")
152
- create_statement = result.first['statement'] || result.first['Create Table']
157
+ create_statement = result.first["statement"] || result.first["Create Table"]
153
158
  file.puts "#{create_statement};\n\n"
154
159
  end
155
160
  end
@@ -180,7 +185,7 @@ module ClickhouseRuby
180
185
 
181
186
  # Charset (not applicable to ClickHouse)
182
187
  def charset(_master_configuration_hash = configuration_hash)
183
- 'UTF-8'
188
+ "UTF-8"
184
189
  end
185
190
 
186
191
  # Collation (not applicable to ClickHouse)