timescaledb 0.3.1 → 0.3.3
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/bin/tsdb +16 -13
- data/lib/timescaledb/acts_as_hypertable/core.rb +23 -23
- data/lib/timescaledb/acts_as_hypertable.rb +0 -1
- data/lib/timescaledb/configuration.rb +32 -0
- data/lib/timescaledb/connection_handling.rb +20 -3
- data/lib/timescaledb/continuous_aggregates.rb +1 -2
- data/lib/timescaledb/continuous_aggregates_helper.rb +36 -12
- data/lib/timescaledb/migration_helpers.rb +9 -3
- data/lib/timescaledb/scenic/extension.rb +0 -2
- data/lib/timescaledb/schema_dumper.rb +6 -3
- data/lib/timescaledb/version.rb +1 -1
- data/lib/timescaledb.rb +43 -10
- metadata +4 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2a82c28a5761d43b30d50afa56a1b41b4e27e81c0280c1a79659cef76430fed8
|
|
4
|
+
data.tar.gz: c7b912b564a84a5904194f4a05e4767229538285298513d7f1940d93208dbfe0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 82f1e4582467e4ac74cb9a14323667a40be51b12edd4181fe50be5c73779b6256833c2885863fa10b23c1808cf82b06328f477e2cf0ca4e554db444ddb4f20ab
|
|
7
|
+
data.tar.gz: 51bcf8fa51b7463fcd99542d4917217e51507388eb7bb660a15406d0a0a690b7f612efd3d0514e1a6189156983a031f461fc0a58976e6145f43cfe55368f82f7
|
data/bin/tsdb
CHANGED
|
@@ -6,17 +6,19 @@ require "pry"
|
|
|
6
6
|
|
|
7
7
|
Timescaledb.establish_connection(ARGV[0])
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
ActiveSupport.on_load(:active_record) { extend Timescaledb::ActsAsHypertable }
|
|
10
|
+
|
|
10
11
|
|
|
11
12
|
if ARGV.index("--stats")
|
|
13
|
+
hypertables = Timescaledb::Hypertable.all
|
|
12
14
|
if (only = ARGV.index("--only"))
|
|
13
15
|
only_hypertables = ARGV[only+1].split(",")
|
|
14
16
|
|
|
15
|
-
hypertables.select! { |hypertable| only_hypertables.
|
|
17
|
+
hypertables.select! { |hypertable| only_hypertables.include?(hypertable.hypertable_name) }
|
|
16
18
|
elsif (except = ARGV.index("--except"))
|
|
17
19
|
except_hypertables = ARGV[except+1].split(",")
|
|
18
20
|
|
|
19
|
-
hypertables.select! { |hypertable| except_hypertables.
|
|
21
|
+
hypertables.select! { |hypertable| except_hypertables.include?(hypertable.hypertable_name) }
|
|
20
22
|
end
|
|
21
23
|
|
|
22
24
|
stats = Timescaledb::Stats.new(hypertables).to_h
|
|
@@ -25,25 +27,26 @@ if ARGV.index("--stats")
|
|
|
25
27
|
end
|
|
26
28
|
|
|
27
29
|
if ARGV.index("--console")
|
|
28
|
-
ActiveRecord::Base.establish_connection(ARGV[0])
|
|
29
|
-
|
|
30
30
|
Timescaledb::Hypertable.find_each do |hypertable|
|
|
31
31
|
class_name = hypertable.hypertable_name.singularize.camelize
|
|
32
32
|
model = Class.new(ActiveRecord::Base) do
|
|
33
|
-
self.table_name = hypertable.hypertable_name
|
|
33
|
+
self.table_name = "#{hypertable.hypertable_schema}.#{hypertable.hypertable_name}"
|
|
34
|
+
|
|
34
35
|
acts_as_hypertable time_column: hypertable.main_dimension.column_name
|
|
35
36
|
end
|
|
36
|
-
Timescaledb.const_set(class_name, model)
|
|
37
|
-
end
|
|
38
37
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
38
|
+
Timescaledb::ContinuousAggregate.where( hypertable_schema: hypertable.hypertable_schema, hypertable_name: hypertable.hypertable_name).hierarchical.find_each do |cagg|
|
|
39
|
+
cagg_model_name = cagg.view_name.singularize.camelize
|
|
40
|
+
cagg_model = Class.new(ActiveRecord::Base) do
|
|
41
|
+
self.table_name = cagg.view_name
|
|
42
|
+
self.schema_name = cagg.view_schema
|
|
43
|
+
acts_as_hypertable
|
|
44
|
+
end
|
|
45
|
+
model.const_set(cagg_model_name, cagg_model)
|
|
44
46
|
end
|
|
45
47
|
Timescaledb.const_set(class_name, model)
|
|
46
48
|
end
|
|
47
49
|
|
|
50
|
+
|
|
48
51
|
Pry.start(Timescaledb)
|
|
49
52
|
end
|
|
@@ -41,41 +41,41 @@ module Timescaledb
|
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
def define_default_scopes
|
|
44
|
+
scope :between, ->(start_time, end_time) do
|
|
45
|
+
where("#{time_column} BETWEEN ? AND ?", start_time, end_time)
|
|
46
|
+
end
|
|
47
|
+
|
|
44
48
|
scope :previous_month, -> do
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
start_time: Date.today.last_month.in_time_zone.beginning_of_month.to_date,
|
|
48
|
-
end_time: Date.today.last_month.in_time_zone.end_of_month.to_date
|
|
49
|
-
)
|
|
49
|
+
ref = 1.month.ago.in_time_zone
|
|
50
|
+
between(ref.beginning_of_month, ref.end_of_month)
|
|
50
51
|
end
|
|
51
52
|
|
|
52
53
|
scope :previous_week, -> do
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
start_time: Date.today.last_week.in_time_zone.beginning_of_week.to_date,
|
|
56
|
-
end_time: Date.today.last_week.in_time_zone.end_of_week.to_date
|
|
57
|
-
)
|
|
54
|
+
ref = 1.week.ago.in_time_zone
|
|
55
|
+
between(ref.beginning_of_week, ref.end_of_week)
|
|
58
56
|
end
|
|
59
57
|
|
|
60
58
|
scope :this_month, -> do
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
start_time: Date.today.in_time_zone.beginning_of_month.to_date,
|
|
64
|
-
end_time: Date.today.in_time_zone.end_of_month.to_date
|
|
65
|
-
)
|
|
59
|
+
ref = Time.now.in_time_zone
|
|
60
|
+
between(ref.beginning_of_month, ref.end_of_month)
|
|
66
61
|
end
|
|
67
62
|
|
|
68
63
|
scope :this_week, -> do
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
64
|
+
ref = Time.now.in_time_zone
|
|
65
|
+
between(ref.beginning_of_week, ref.end_of_week)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
scope :yesterday, -> do
|
|
69
|
+
ref = 1.day.ago.in_time_zone
|
|
70
|
+
between(ref.yesterday, ref.yesterday)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
scope :today, -> do
|
|
74
|
+
ref = Time.now.in_time_zone
|
|
75
|
+
between(ref.beginning_of_day, ref.end_of_day)
|
|
74
76
|
end
|
|
75
77
|
|
|
76
|
-
scope :
|
|
77
|
-
scope :today, -> { where("DATE(#{time_column}) = ?", Date.today.in_time_zone.to_date) }
|
|
78
|
-
scope :last_hour, -> { where("#{time_column} between ? and ?", 1.hour.ago.in_time_zone, Time.now.end_of_hour.in_time_zone) }
|
|
78
|
+
scope :last_hour, -> { where("#{time_column} > ?", 1.hour.ago.in_time_zone) }
|
|
79
79
|
end
|
|
80
80
|
|
|
81
81
|
def normalize_hypertable_options
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Timescaledb
|
|
4
|
+
class Configuration
|
|
5
|
+
attr_accessor :scenic_integration
|
|
6
|
+
|
|
7
|
+
DEFAULTS = {
|
|
8
|
+
scenic_integration: :enabled
|
|
9
|
+
}.freeze
|
|
10
|
+
|
|
11
|
+
def initialize
|
|
12
|
+
@scenic_integration = DEFAULTS[:scenic_integration]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def enable_scenic_integration?
|
|
16
|
+
case @scenic_integration
|
|
17
|
+
when :enabled then scenic_detected?
|
|
18
|
+
else false # :disabled, :false, nil, etc.
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def scenic_detected?
|
|
25
|
+
# Try to require scenic to see if it's available
|
|
26
|
+
require 'scenic'
|
|
27
|
+
true
|
|
28
|
+
rescue LoadError
|
|
29
|
+
false
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -2,15 +2,32 @@ module Timescaledb
|
|
|
2
2
|
class ConnectionNotEstablishedError < StandardError; end
|
|
3
3
|
|
|
4
4
|
module_function
|
|
5
|
-
|
|
5
|
+
|
|
6
6
|
# @param [String] config with the postgres connection string.
|
|
7
7
|
def establish_connection(config)
|
|
8
|
+
# Establish connection for Timescaledb
|
|
8
9
|
Connection.instance.config = config
|
|
10
|
+
|
|
11
|
+
# Also establish connection for ActiveRecord if it's defined
|
|
12
|
+
if defined?(ActiveRecord::Base)
|
|
13
|
+
ActiveRecord::Base.establish_connection(config)
|
|
14
|
+
end
|
|
9
15
|
end
|
|
10
16
|
|
|
11
17
|
# @param [PG::Connection] to use it directly from a raw connection
|
|
12
|
-
def use_connection
|
|
13
|
-
Connection.instance.use_connection
|
|
18
|
+
def use_connection(conn)
|
|
19
|
+
Connection.instance.use_connection(conn)
|
|
20
|
+
|
|
21
|
+
# Also set ActiveRecord connection if it's defined
|
|
22
|
+
if defined?(ActiveRecord::Base) && ActiveRecord::Base.connected?
|
|
23
|
+
ar_conn = ActiveRecord::Base.connection
|
|
24
|
+
current_conn = ar_conn.raw_connection
|
|
25
|
+
|
|
26
|
+
# Only set if it's different to avoid redundant assignment
|
|
27
|
+
if current_conn != conn
|
|
28
|
+
ar_conn.instance_variable_set(:@raw_connection, conn)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
14
31
|
end
|
|
15
32
|
|
|
16
33
|
def connection
|
|
@@ -3,8 +3,7 @@ module Timescaledb
|
|
|
3
3
|
self.table_name = "timescaledb_information.continuous_aggregates"
|
|
4
4
|
self.primary_key = 'materialization_hypertable_name'
|
|
5
5
|
|
|
6
|
-
has_many :jobs, foreign_key:
|
|
7
|
-
class_name: "Timescaledb::Job"
|
|
6
|
+
has_many :jobs, foreign_key: 'hypertable_name', primary_key: 'view_name', class_name: 'Timescaledb::Job'
|
|
8
7
|
|
|
9
8
|
has_many :chunks, foreign_key: "hypertable_name",
|
|
10
9
|
class_name: "Timescaledb::Chunk"
|
|
@@ -18,6 +18,8 @@ module Timescaledb
|
|
|
18
18
|
/state_agg\((\w+)\)\s+as\s+(\w+)/ => 'rollup(\2) as \2',
|
|
19
19
|
/percentile_agg\((\w+),\s*(\w+)\)\s+as\s+(\w+)/ => 'rollup(\3) as \3',
|
|
20
20
|
/heartbeat_agg\((\w+)\)\s+as\s+(\w+)/ => 'rollup(\2) as \2',
|
|
21
|
+
/stats_agg\(([^)]+)\)\s+(as\s+(\w+))/ => 'rollup(\3) \2',
|
|
22
|
+
/stats_agg\((.*)\)\s+(as\s+(\w+))/ => 'rollup(\3) \2'
|
|
21
23
|
}
|
|
22
24
|
|
|
23
25
|
scope :rollup, ->(interval) do
|
|
@@ -134,25 +136,47 @@ module Timescaledb
|
|
|
134
136
|
class_name = "#{aggregate_name}_per_#{timeframe}".classify
|
|
135
137
|
const_set(class_name, Class.new(base_model) do
|
|
136
138
|
class << self
|
|
137
|
-
attr_accessor :config, :timeframe, :base_query, :base_model
|
|
139
|
+
attr_accessor :config, :timeframe, :base_query, :base_model, :previous_timeframe, :interval, :aggregate_name, :prev_klass
|
|
138
140
|
end
|
|
139
141
|
|
|
140
142
|
self.table_name = _table_name
|
|
141
143
|
self.config = config
|
|
142
144
|
self.timeframe = timeframe
|
|
145
|
+
self.previous_timeframe = previous_timeframe
|
|
146
|
+
self.aggregate_name = aggregate_name
|
|
143
147
|
|
|
144
|
-
interval = "'1 #{timeframe.to_s}'"
|
|
148
|
+
self.interval = "'1 #{timeframe.to_s}'"
|
|
145
149
|
self.base_model = base_model
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
150
|
+
|
|
151
|
+
def self.prev_klass
|
|
152
|
+
base_model.const_get("#{aggregate_name}_per_#{previous_timeframe}".classify)
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def self.base_query
|
|
156
|
+
@base_query ||= begin
|
|
157
|
+
tb = "time_bucket(#{interval}, #{time_column})"
|
|
158
|
+
if previous_timeframe
|
|
159
|
+
select_clause = base_model.apply_rollup_rules("#{config[:select]}")
|
|
160
|
+
# Note there's no where clause here, because we're using the previous timeframe's data
|
|
161
|
+
"SELECT #{tb} as #{time_column}, #{select_clause} FROM \"#{prev_klass.table_name}\" GROUP BY #{[tb, *config[:group_by]].join(', ')}"
|
|
162
|
+
else
|
|
163
|
+
scope = base_model.public_send(config[:scope_name])
|
|
164
|
+
config[:select] = scope.select_values.select{|e|!e.downcase.start_with?("time_bucket")}.join(', ')
|
|
165
|
+
config[:group_by] = scope.group_values
|
|
166
|
+
config[:where] =
|
|
167
|
+
if scope.where_values_hash.present?
|
|
168
|
+
scope.where_values_hash.map { |key, value| "#{key} = '#{value}'" }.join(' AND ')
|
|
169
|
+
elsif scope.where_clause.ast.present? && scope.where_clause.ast.to_sql.present?
|
|
170
|
+
scope.where_clause.ast.to_sql
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
sql = "SELECT #{tb} as #{time_column}, #{config[:select]}"
|
|
174
|
+
sql += " FROM \"#{base_model.table_name}\""
|
|
175
|
+
sql += " WHERE #{config[:where]}" if config[:where]
|
|
176
|
+
sql += " GROUP BY #{[tb, *config[:group_by]].join(', ')}"
|
|
177
|
+
sql
|
|
178
|
+
end
|
|
179
|
+
end
|
|
156
180
|
end
|
|
157
181
|
|
|
158
182
|
def self.refresh!(start_time = nil, end_time = nil)
|
|
@@ -48,7 +48,7 @@ module Timescaledb
|
|
|
48
48
|
**hypertable_options)
|
|
49
49
|
|
|
50
50
|
original_logger = ActiveRecord::Base.logger
|
|
51
|
-
ActiveRecord::Base.logger = Logger.new(STDOUT)
|
|
51
|
+
ActiveRecord::Base.logger = Logger.new(STDOUT) unless original_logger.nil?
|
|
52
52
|
|
|
53
53
|
dimension = "by_range(#{quote(time_column)}, #{parse_interval(chunk_time_interval)})"
|
|
54
54
|
|
|
@@ -84,7 +84,9 @@ module Timescaledb
|
|
|
84
84
|
# @option refresh_policies [String] schedule_interval: INTERVAL
|
|
85
85
|
# @option materialized_only [Boolean] Override the WITH clause 'timescaledb.materialized_only'
|
|
86
86
|
# @option create_group_indexes [Boolean] Override the WITH clause 'timescaledb.create_group_indexes'
|
|
87
|
-
# @option finalized [Boolean]
|
|
87
|
+
# @option finalized [Boolean] Set to false for legacy (non-finalized) format. Note: the finalized
|
|
88
|
+
# parameter was removed in TimescaleDB 2.14+ where all aggregates are finalized by default.
|
|
89
|
+
# Only use finalized: false on TimescaleDB 2.7-2.13 for legacy compatibility.
|
|
88
90
|
#
|
|
89
91
|
# @see https://docs.timescale.com/api/latest/continuous-aggregates/create_materialized_view/
|
|
90
92
|
# @see https://docs.timescale.com/api/latest/continuous-aggregates/add_continuous_aggregate_policy/
|
|
@@ -99,13 +101,17 @@ module Timescaledb
|
|
|
99
101
|
# SQL
|
|
100
102
|
#
|
|
101
103
|
def create_continuous_aggregate(table_name, query, **options)
|
|
104
|
+
# Only include finalized when explicitly false (legacy format).
|
|
105
|
+
# The parameter was removed in TimescaleDB 2.14+ where all aggregates are finalized by default.
|
|
106
|
+
finalized_clause = options[:finalized] == false ? ",timescaledb.finalized=false" : ""
|
|
107
|
+
|
|
102
108
|
execute <<~SQL
|
|
103
109
|
CREATE MATERIALIZED VIEW #{table_name}
|
|
104
110
|
WITH (
|
|
105
111
|
timescaledb.continuous
|
|
106
112
|
#{build_with_clause_option_string(:materialized_only, options)}
|
|
107
113
|
#{build_with_clause_option_string(:create_group_indexes, options)}
|
|
108
|
-
#{
|
|
114
|
+
#{finalized_clause}
|
|
109
115
|
) AS
|
|
110
116
|
#{query.respond_to?(:to_sql) ? query.to_sql : query}
|
|
111
117
|
WITH #{'NO' unless options[:with_data]} DATA;
|
|
@@ -90,7 +90,7 @@ module Timescaledb
|
|
|
90
90
|
|
|
91
91
|
def timescale_retention_policy(hypertable, stream)
|
|
92
92
|
hypertable.jobs.where(proc_name: "policy_retention").each do |job|
|
|
93
|
-
stream.puts %Q[ create_retention_policy "#{job.hypertable_name}",
|
|
93
|
+
stream.puts %Q[ create_retention_policy "#{job.hypertable_name}", drop_after: "#{job.config["drop_after"]}"]
|
|
94
94
|
end
|
|
95
95
|
end
|
|
96
96
|
|
|
@@ -119,7 +119,7 @@ module Timescaledb
|
|
|
119
119
|
end
|
|
120
120
|
|
|
121
121
|
hypertable.jobs.compression.each do |job|
|
|
122
|
-
compression_settings[:
|
|
122
|
+
compression_settings[:compress_after] = job.config["compress_after"]
|
|
123
123
|
end
|
|
124
124
|
|
|
125
125
|
# Pack the compression setting arrays into a comma-separated string instead.
|
|
@@ -162,7 +162,10 @@ module Timescaledb
|
|
|
162
162
|
""
|
|
163
163
|
end
|
|
164
164
|
|
|
165
|
-
|
|
165
|
+
# Only output finalized when false (legacy format) - the parameter was
|
|
166
|
+
# removed in TimescaleDB 2.14+ where all aggregates are finalized by default
|
|
167
|
+
with_clause_opts = "materialized_only: #{aggregate[:materialized_only]}"
|
|
168
|
+
with_clause_opts += ", finalized: false" if aggregate[:finalized] == false
|
|
166
169
|
stream.puts <<~AGG.indent(2)
|
|
167
170
|
create_continuous_aggregate("#{aggregate.view_name}", <<-SQL, #{refresh_policies_opts}#{with_clause_opts})
|
|
168
171
|
#{aggregate.view_definition.strip.gsub(/;$/, '')}
|
data/lib/timescaledb/version.rb
CHANGED
data/lib/timescaledb.rb
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'active_record'
|
|
2
4
|
|
|
5
|
+
require_relative 'timescaledb/configuration'
|
|
3
6
|
require_relative 'timescaledb/application_record'
|
|
4
7
|
require_relative 'timescaledb/acts_as_hypertable'
|
|
5
8
|
require_relative 'timescaledb/acts_as_hypertable/core'
|
|
@@ -22,6 +25,39 @@ require_relative 'timescaledb/extension'
|
|
|
22
25
|
require_relative 'timescaledb/version'
|
|
23
26
|
|
|
24
27
|
module Timescaledb
|
|
28
|
+
class << self
|
|
29
|
+
def configure
|
|
30
|
+
yield(configuration) if block_given?
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def configuration
|
|
34
|
+
@configuration ||= Configuration.new
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def setup_scenic_integration
|
|
38
|
+
return unless configuration.enable_scenic_integration?
|
|
39
|
+
return if @scenic_integration_setup
|
|
40
|
+
|
|
41
|
+
begin
|
|
42
|
+
require 'scenic'
|
|
43
|
+
require_relative 'timescaledb/scenic/adapter'
|
|
44
|
+
require_relative 'timescaledb/scenic/extension'
|
|
45
|
+
|
|
46
|
+
::Scenic.configure do |config|
|
|
47
|
+
config.database = Timescaledb::Scenic::Adapter.new
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
::Scenic::Adapters::Postgres.include(Timescaledb::Scenic::Extension)
|
|
51
|
+
::ActiveRecord::ConnectionAdapters::AbstractAdapter.prepend(Timescaledb::Scenic::MigrationHelpers)
|
|
52
|
+
|
|
53
|
+
@scenic_integration_setup = true
|
|
54
|
+
rescue LoadError
|
|
55
|
+
# This is expected when the scenic gem is not being used
|
|
56
|
+
@scenic_integration_setup = false
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
25
61
|
module_function
|
|
26
62
|
|
|
27
63
|
def connection
|
|
@@ -65,15 +101,12 @@ module Timescaledb
|
|
|
65
101
|
end
|
|
66
102
|
end
|
|
67
103
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
Scenic.configure do |config|
|
|
74
|
-
config.database = Timescaledb::Scenic::Adapter.new
|
|
104
|
+
# Delay scenic integration setup to respect user configuration when using Rails
|
|
105
|
+
if defined?(ActiveSupport) && ActiveSupport.respond_to?(:on_load)
|
|
106
|
+
ActiveSupport.on_load(:active_record) do
|
|
107
|
+
Timescaledb.setup_scenic_integration
|
|
75
108
|
end
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
109
|
+
else
|
|
110
|
+
# For non-Rails usage, setup immediately
|
|
111
|
+
Timescaledb.setup_scenic_integration
|
|
79
112
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: timescaledb
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.3.
|
|
4
|
+
version: 0.3.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jônatas Davi Paganini
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 2026-02-11 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: pg
|
|
@@ -166,6 +165,7 @@ files:
|
|
|
166
165
|
- lib/timescaledb/application_record.rb
|
|
167
166
|
- lib/timescaledb/chunk.rb
|
|
168
167
|
- lib/timescaledb/compression_settings.rb
|
|
168
|
+
- lib/timescaledb/configuration.rb
|
|
169
169
|
- lib/timescaledb/connection.rb
|
|
170
170
|
- lib/timescaledb/connection_handling.rb
|
|
171
171
|
- lib/timescaledb/continuous_aggregates.rb
|
|
@@ -202,7 +202,6 @@ metadata:
|
|
|
202
202
|
allowed_push_host: https://rubygems.org
|
|
203
203
|
homepage_uri: https://timescale.github.io/timescaledb-ruby/
|
|
204
204
|
source_code_uri: https://github.com/timescale/timescaledb-ruby
|
|
205
|
-
post_install_message:
|
|
206
205
|
rdoc_options: []
|
|
207
206
|
require_paths:
|
|
208
207
|
- lib
|
|
@@ -217,8 +216,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
217
216
|
- !ruby/object:Gem::Version
|
|
218
217
|
version: '0'
|
|
219
218
|
requirements: []
|
|
220
|
-
rubygems_version: 3.
|
|
221
|
-
signing_key:
|
|
219
|
+
rubygems_version: 3.6.3
|
|
222
220
|
specification_version: 4
|
|
223
221
|
summary: TimescaleDB helpers for Ruby ecosystem.
|
|
224
222
|
test_files: []
|