timescaledb-rails 0.0.1 → 0.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ff972c0e2773b5032e350089f1f7c75c6975aa619db5c7b8b99350c5f9250347
4
- data.tar.gz: 2b799232bb7927e2c73dd35d2c54b90c23b1a86f424d282593512269988d06c4
3
+ metadata.gz: af4399bfd70056ed23cfb0994580a8c61fcd88722a72ce7839761b305c6d2029
4
+ data.tar.gz: dad61e01554eee6ee23fd780a6745196d7fb5b3703398c795bbe3e00dfbe028b
5
5
  SHA512:
6
- metadata.gz: 1e0229939288334ef8a612f16fd5f721b24fcba54340093ab9fa65ae538effd2a864294c3f3b6cf9f08ebc3db95fffe26b7f355503639630f7db48a15a57b942
7
- data.tar.gz: 04d6a4d2fd560a53ecbe45ed3a20fba0d901971b10b0a7af80b61ec9dc80c0ae2c2adf1715f4e484edaf15da3a7aaf213343e716368f5d278093e66fdb5d7ae5
6
+ metadata.gz: 1679b7421eca2f5b557b83a7b338f72444d073009f532b77d75e8e233c07828750d02afc96f4b2ee0a5c61ce6c750f03832742621df1187529cddcec3e46995f
7
+ data.tar.gz: 3628e056c77754629a65c2ef343c59702272bbec882b47f2e70564fbd1008080729e05017f923a0145d78e186bb272a5e13394605ccf96bcb39a34f520c3ad9a
data/README.md CHANGED
@@ -1,2 +1,77 @@
1
- # timescaledb-rails
2
- Ruby on Rails helpers for TimescaleDB
1
+ # TimescaleDB extension for Rails [![Actions Status](https://github.com/crunchloop/timescaledb-rails/workflows/CI/badge.svg?branch=main)](https://github.com/crunchloop/timescaledb-rails/actions?query=workflow%3ACI)
2
+
3
+ `timescaledb-rails` extends ActiveRecord PostgreSQL adapter and provides features from [`TimescaleDB`](https://www.timescale.com). It provides support for hypertables and other features added by TimescaleDB PostgreSQL extension.
4
+
5
+
6
+ ## Installation
7
+
8
+ Install `timescaledb-rails` from RubyGems:
9
+
10
+ ``` sh
11
+ $ gem install timescaledb-rails
12
+ ```
13
+
14
+ Or include it in your project's `Gemfile` with Bundler:
15
+
16
+ ``` ruby
17
+ gem 'timescaledb-rails', '~> 0.1'
18
+ ```
19
+
20
+ ## Examples
21
+
22
+ Create a hypertable from a PostgreSQL table by doing:
23
+
24
+ ```ruby
25
+ class CreateEvent < ActiveRecord::Migration[7.0]
26
+ def change
27
+ create_table :events, id: false do |t|
28
+ t.string :name, null: false
29
+ t.time :occured_at, null: false
30
+
31
+ t.timestamps
32
+ end
33
+
34
+ create_hypertable :events, :created_at, chunk_time_interval: '2 days'
35
+ end
36
+ end
37
+ ```
38
+
39
+ Create a hypertable without a PostgreSQL table by doing:
40
+
41
+ ```ruby
42
+ class CreatePayloadHypertable < ActiveRecord::Migration[7.0]
43
+ def change
44
+ create_hypertable :payloads, :created_at, chunk_time_interval: '5 days' do |t|
45
+ t.string :ip, null: false
46
+
47
+ t.timestamps
48
+ end
49
+ end
50
+ end
51
+ ```
52
+
53
+ Enable hypertable compression by doing:
54
+
55
+ ```ruby
56
+ class AddEventCompression < ActiveRecord::Migration[7.0]
57
+ def change
58
+ add_hypertable_compression :events, 20.days, segment_by: :name, order_by: 'occured_at DESC'
59
+ end
60
+ end
61
+ ```
62
+
63
+ ## Supported Ruby/Rails versions
64
+
65
+ Supported Ruby/Rails versions are listed in [`.github/workflows/ci.yaml`](https://github.com/crunchloop/timescaledb-rails/blob/main/.github/workflows/ci.yaml)
66
+
67
+ ## License
68
+
69
+ Released under the MIT License. See the [LICENSE][] file for further details.
70
+
71
+ [license]: LICENSE
72
+
73
+ ## About Crunchloop
74
+
75
+ ![crunchloop](https://crunchloop.io/logo-blue.png)
76
+
77
+ `timescaledb-rails` is supported with :heart: by [Crunchloop](https://crunchloop.io). We strongly believe in giving back :rocket:. Let's work together [`Get in touch`](https://crunchloop.io/contact).
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Timescaledb
4
+ module Rails
5
+ module ActiveRecord
6
+ # :nodoc:
7
+ module DatabaseTasks
8
+ # @override
9
+ def structure_dump_flags_for(adapter)
10
+ return (flags = super) if adapter != 'postgresql'
11
+
12
+ if flags.nil?
13
+ timescaledb_structure_dump_default_flags
14
+ elsif flags.is_a?(Array)
15
+ flags << timescaledb_structure_dump_default_flags
16
+ elsif flags.is_a?(String)
17
+ "#{flags} #{timescaledb_structure_dump_default_flags}"
18
+ else
19
+ flags
20
+ end
21
+ end
22
+
23
+ # Returns `pg_dump` flag to exclude `_timescaledb_internal` schema tables.
24
+ #
25
+ # @return [String]
26
+ def timescaledb_structure_dump_default_flags
27
+ '--exclude-schema=_timescaledb_internal'
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_record/tasks/postgresql_database_tasks'
4
+ require 'timescaledb/rails/orderby_compression'
5
+
6
+ module Timescaledb
7
+ module Rails
8
+ module ActiveRecord
9
+ # :nodoc:
10
+ module PostgreSQLDatabaseTasks
11
+ # @override
12
+ def structure_dump(filename, extra_flags)
13
+ super
14
+
15
+ return unless timescale_enabled?
16
+
17
+ File.open(filename, 'a') do |file|
18
+ Timescaledb::Rails::Hypertable.all.each do |hypertable|
19
+ drop_ts_insert_trigger_statment(hypertable, file)
20
+ create_hypertable_statement(hypertable, file)
21
+ add_hypertable_compression_statement(hypertable, file)
22
+ end
23
+ end
24
+ end
25
+
26
+ def drop_ts_insert_trigger_statment(hypertable, file)
27
+ file << "---\n"
28
+ file << "--- Drop ts_insert_blocker previously created by pg_dump to avoid pg errors, create_hypertable will re-create it again.\n" # rubocop:disable Layout/LineLength
29
+ file << "---\n\n"
30
+ file << "DROP TRIGGER IF EXISTS ts_insert_blocker ON #{hypertable.hypertable_name};\n"
31
+ end
32
+
33
+ def create_hypertable_statement(hypertable, file)
34
+ options = hypertable_options(hypertable)
35
+
36
+ file << "SELECT create_hypertable('#{hypertable.hypertable_name}', '#{hypertable.time_column_name}', #{options});\n\n" # rubocop:disable Layout/LineLength
37
+ end
38
+
39
+ def add_hypertable_compression_statement(hypertable, file)
40
+ return unless hypertable.compression?
41
+
42
+ options = hypertable_compression_options(hypertable)
43
+
44
+ file << "ALTER TABLE #{hypertable.hypertable_name} SET (#{options});\n\n"
45
+ file << "SELECT add_compression_policy('#{hypertable.hypertable_name}', INTERVAL '#{hypertable.compression_policy_interval}');\n\n" # rubocop:disable Layout/LineLength
46
+ end
47
+
48
+ def hypertable_options(hypertable)
49
+ sql_statements = ["if_not_exists => 'TRUE'"]
50
+ sql_statements << "chunk_time_interval => INTERVAL '#{hypertable.chunk_time_interval.inspect}'"
51
+
52
+ sql_statements.compact.join(', ')
53
+ end
54
+
55
+ def hypertable_compression_options(hypertable)
56
+ segmentby_setting = hypertable.compression_settings.segmentby_setting.first
57
+ orderby_setting = hypertable.compression_settings.orderby_setting.first
58
+
59
+ sql_statements = ['timescaledb.compress']
60
+ sql_statements << "timescaledb.compress_segmentby = '#{segmentby_setting.attname}'" if segmentby_setting
61
+
62
+ if orderby_setting
63
+ orderby = Timescaledb::Rails::OrderbyCompression.new(orderby_setting.attname,
64
+ orderby_setting.orderby_asc).to_s
65
+
66
+ sql_statements << "timescaledb.compress_orderby = '#{orderby}'"
67
+ end
68
+
69
+ sql_statements.join(', ')
70
+ end
71
+
72
+ def timescale_enabled?
73
+ Timescaledb::Rails::Hypertable.table_exists?
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_record/connection_adapters/postgresql_adapter'
4
+ require 'timescaledb/rails/orderby_compression'
5
+
6
+ module Timescaledb
7
+ module Rails
8
+ module ActiveRecord
9
+ # :nodoc:
10
+ module SchemaDumper
11
+ def table(table, stream)
12
+ super(table, stream)
13
+
14
+ return unless timescale_enabled?
15
+ return if (hypertable = Timescaledb::Rails::Hypertable.find_by(hypertable_name: table)).nil?
16
+
17
+ hypertable(hypertable, stream)
18
+ hypertable_compression(hypertable, stream)
19
+ end
20
+
21
+ private
22
+
23
+ def hypertable(hypertable, stream)
24
+ options = [hypertable.hypertable_name.inspect, hypertable.time_column_name.inspect]
25
+ options |= hypertable_options(hypertable)
26
+
27
+ stream.puts " create_hypertable #{options.join(', ')}"
28
+ stream.puts
29
+ end
30
+
31
+ def hypertable_compression(hypertable, stream)
32
+ return unless hypertable.compression?
33
+
34
+ options = [hypertable.hypertable_name.inspect, hypertable.compression_policy_interval.inspect]
35
+ options |= hypertable_compression_options(hypertable)
36
+
37
+ stream.puts " add_hypertable_compression #{options.join(', ')}"
38
+ stream.puts
39
+ end
40
+
41
+ def hypertable_options(hypertable)
42
+ options = {
43
+ chunk_time_interval: hypertable.chunk_time_interval
44
+ }
45
+
46
+ options.each_with_object([]) do |(key, value), memo|
47
+ memo << "#{key}: #{format_hypertable_option_value(value)}"
48
+ memo
49
+ end
50
+ end
51
+
52
+ def hypertable_compression_options(hypertable)
53
+ segmentby_setting = hypertable.compression_settings.segmentby_setting.first
54
+ orderby_setting = hypertable.compression_settings.orderby_setting.first
55
+
56
+ [].tap do |result|
57
+ result << "segment_by: #{segmentby_setting.attname.inspect}" if segmentby_setting
58
+
59
+ if orderby_setting
60
+ orderby = Timescaledb::Rails::OrderbyCompression.new(orderby_setting.attname,
61
+ orderby_setting.orderby_asc).to_s
62
+
63
+ result << "order_by: #{orderby.inspect}"
64
+ end
65
+ end
66
+ end
67
+
68
+ def format_hypertable_option_value(value)
69
+ case value
70
+ when String then value.inspect
71
+ when ActiveSupport::Duration then value.inspect.inspect
72
+ else
73
+ value
74
+ end
75
+ end
76
+
77
+ def timescale_enabled?
78
+ Timescaledb::Rails::Hypertable.table_exists?
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_record/connection_adapters/postgresql_adapter'
4
+
5
+ module Timescaledb
6
+ module Rails
7
+ module ActiveRecord
8
+ # :nodoc:
9
+ module SchemaStatements
10
+ # Converts given standard PG table into a hypertable.
11
+ #
12
+ # create_hypertable('readings', 'created_at', chunk_time_interval: '7 days')
13
+ #
14
+ def create_hypertable(table_name, time_column_name, **options, &block)
15
+ options = options.symbolize_keys
16
+ options_as_sql = hypertable_options_to_sql(options)
17
+
18
+ if block
19
+ primary_key = options[:primary_key]
20
+ force = options[:force]
21
+
22
+ create_table(table_name, id: false, primary_key: primary_key, force: force, **options, &block)
23
+ end
24
+
25
+ execute "SELECT create_hypertable('#{table_name}', '#{time_column_name}', #{options_as_sql})"
26
+ end
27
+
28
+ # Enables compression and sets compression options.
29
+ #
30
+ # add_hypertable_compression('events', 7.days, segment_by: :created_at, order_by: :name)
31
+ #
32
+ def add_hypertable_compression(table_name, compress_after, segment_by: nil, order_by: nil)
33
+ compress_after = compress_after.inspect if compress_after.is_a?(ActiveSupport::Duration)
34
+
35
+ options = ['timescaledb.compress']
36
+ options << "timescaledb.compress_orderby = '#{order_by}'" unless order_by.nil?
37
+ options << "timescaledb.compress_segmentby = '#{segment_by}'" unless segment_by.nil?
38
+
39
+ execute "ALTER TABLE #{table_name} SET (#{options.join(', ')})"
40
+
41
+ execute "SELECT add_compression_policy('#{table_name}', INTERVAL '#{compress_after}')"
42
+ end
43
+
44
+ def hypertable_options_to_sql(options)
45
+ sql_statements = options.map do |option, value|
46
+ case option
47
+ when :chunk_time_interval then "chunk_time_interval => INTERVAL '#{value}'"
48
+ when :if_not_exists then "if_not_exists => #{value ? 'TRUE' : 'FALSE'}"
49
+ end
50
+ end
51
+
52
+ sql_statements.compact.join(', ')
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Timescaledb
4
+ module Rails
5
+ # :nodoc:
6
+ class CompressionSetting < ::ActiveRecord::Base
7
+ self.table_name = 'timescaledb_information.compression_settings'
8
+ self.primary_key = 'hypertable_name'
9
+
10
+ scope :segmentby_setting, -> { where.not(segmentby_column_index: nil).order(:segmentby_column_index) }
11
+ scope :orderby_setting, -> { where.not(orderby_column_index: nil).order(:orderby_column_index) }
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Timescaledb
4
+ module Rails
5
+ # :nodoc:
6
+ class Dimension < ::ActiveRecord::Base
7
+ TIME_TYPE = 'Time'
8
+
9
+ self.table_name = 'timescaledb_information.dimensions'
10
+
11
+ attribute :time_interval, :interval if ::Rails.version.to_i >= 7
12
+
13
+ scope :time, -> { where(dimension_type: TIME_TYPE) }
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Timescaledb
4
+ module Rails
5
+ # :nodoc:
6
+ class Hypertable < ::ActiveRecord::Base
7
+ self.table_name = 'timescaledb_information.hypertables'
8
+ self.primary_key = 'hypertable_name'
9
+
10
+ has_many :compression_settings, foreign_key: 'hypertable_name',
11
+ class_name: 'Timescaledb::Rails::CompressionSetting'
12
+ has_many :dimensions, foreign_key: 'hypertable_name', class_name: 'Timescaledb::Rails::Dimension'
13
+ has_many :jobs, foreign_key: 'hypertable_name', class_name: 'Timescaledb::Rails::Job'
14
+
15
+ # @return [String]
16
+ def time_column_name
17
+ time_dimension.column_name
18
+ end
19
+
20
+ # @return [String]
21
+ def chunk_time_interval
22
+ time_dimension.time_interval
23
+ end
24
+
25
+ # @return [String]
26
+ def compression_policy_interval
27
+ ActiveSupport::Duration.parse(compression_job.config['compress_after']).inspect
28
+ rescue ActiveSupport::Duration::ISO8601Parser::ParsingError
29
+ compression_job.config['compress_after']
30
+ end
31
+
32
+ # @return [Boolean]
33
+ def compression?
34
+ compression_job.present?
35
+ end
36
+
37
+ private
38
+
39
+ # @return [Job]
40
+ def compression_job
41
+ @compression_job ||= jobs.policy_compression.first
42
+ end
43
+
44
+ # @return [Dimension]
45
+ def time_dimension
46
+ @time_dimension ||= dimensions.time.first
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Timescaledb
4
+ module Rails
5
+ # :nodoc:
6
+ class Job < ::ActiveRecord::Base
7
+ self.table_name = 'timescaledb_information.jobs'
8
+ self.primary_key = 'hypertable_name'
9
+
10
+ POLICY_COMPRESSION = 'policy_compression'
11
+
12
+ scope :policy_compression, -> { where(proc_name: POLICY_COMPRESSION) }
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './models/compression_setting'
4
+ require_relative './models/dimension'
5
+ require_relative './models/job'
6
+ require_relative './models/hypertable'
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Timescaledb
4
+ module Rails
5
+ # :nodoc:
6
+ class OrderbyCompression
7
+ # @param [String] column_name.
8
+ # @param [Boolean] orderby_asc.
9
+ def initialize(column_name, orderby_asc)
10
+ @column_name = column_name
11
+ @orderby_asc = orderby_asc
12
+ end
13
+
14
+ # @return [String]
15
+ def to_s
16
+ [@column_name, (@orderby_asc ? 'ASC' : 'DESC')].join(' ')
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails'
4
+
5
+ require_relative 'extensions/active_record/database_tasks'
6
+ require_relative 'extensions/active_record/postgresql_database_tasks'
7
+ require_relative 'extensions/active_record/schema_dumper'
8
+ require_relative 'extensions/active_record/schema_statements'
9
+
10
+ module Timescaledb
11
+ module Rails
12
+ # :nodoc:
13
+ class Railtie < ::Rails::Railtie
14
+ initializer 'timescaledb-rails.require_timescale_models' do
15
+ ActiveSupport.on_load(:active_record) do
16
+ require 'timescaledb/rails/models'
17
+ end
18
+ end
19
+
20
+ initializer 'timescaledb-rails.add_timescale_support_to_active_record' do
21
+ ActiveSupport.on_load(:active_record) do
22
+ ::ActiveRecord::Tasks::DatabaseTasks.extend(
23
+ Timescaledb::Rails::ActiveRecord::DatabaseTasks
24
+ )
25
+
26
+ ::ActiveRecord::Tasks::PostgreSQLDatabaseTasks.prepend(
27
+ Timescaledb::Rails::ActiveRecord::PostgreSQLDatabaseTasks
28
+ )
29
+
30
+ ::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.prepend(
31
+ Timescaledb::Rails::ActiveRecord::SchemaStatements
32
+ )
33
+
34
+ ::ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaDumper.prepend(
35
+ Timescaledb::Rails::ActiveRecord::SchemaDumper
36
+ )
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -1,5 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Timescaledb
4
+ # :nodoc:
2
5
  module Rails
3
- VERSION = '0.0.1'
6
+ VERSION = '0.1.2'
4
7
  end
5
8
  end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Timescaledb
4
+ # :nodoc:
5
+ module Rails
6
+ end
7
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'timescaledb/rails/version'
4
+ require_relative 'timescaledb/rails/railtie'
5
+
6
+ require_relative 'timescaledb/rails'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: timescaledb-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Iván Etchart
@@ -9,8 +9,106 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2022-10-27 00:00:00.000000000 Z
13
- dependencies: []
12
+ date: 2022-11-24 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rails
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: '6.0'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: '6.0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: pg
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '1.2'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '1.2'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rspec
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '3.12'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '3.12'
56
+ - !ruby/object:Gem::Dependency
57
+ name: rubocop
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: '1.39'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '1.39'
70
+ - !ruby/object:Gem::Dependency
71
+ name: rubocop-performance
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - "~>"
75
+ - !ruby/object:Gem::Version
76
+ version: '1.15'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: '1.15'
84
+ - !ruby/object:Gem::Dependency
85
+ name: rubocop-rails
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - "~>"
89
+ - !ruby/object:Gem::Version
90
+ version: '2.17'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - "~>"
96
+ - !ruby/object:Gem::Version
97
+ version: '2.17'
98
+ - !ruby/object:Gem::Dependency
99
+ name: rubocop-rspec
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - "~>"
103
+ - !ruby/object:Gem::Version
104
+ version: '2.15'
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - "~>"
110
+ - !ruby/object:Gem::Version
111
+ version: '2.15'
14
112
  description:
15
113
  email: oss@crunchloop.io
16
114
  executables: []
@@ -19,11 +117,25 @@ extra_rdoc_files: []
19
117
  files:
20
118
  - LICENSE
21
119
  - README.md
120
+ - lib/timescaledb-rails.rb
121
+ - lib/timescaledb/rails.rb
122
+ - lib/timescaledb/rails/extensions/active_record/database_tasks.rb
123
+ - lib/timescaledb/rails/extensions/active_record/postgresql_database_tasks.rb
124
+ - lib/timescaledb/rails/extensions/active_record/schema_dumper.rb
125
+ - lib/timescaledb/rails/extensions/active_record/schema_statements.rb
126
+ - lib/timescaledb/rails/models.rb
127
+ - lib/timescaledb/rails/models/compression_setting.rb
128
+ - lib/timescaledb/rails/models/dimension.rb
129
+ - lib/timescaledb/rails/models/hypertable.rb
130
+ - lib/timescaledb/rails/models/job.rb
131
+ - lib/timescaledb/rails/orderby_compression.rb
132
+ - lib/timescaledb/rails/railtie.rb
22
133
  - lib/timescaledb/rails/version.rb
23
134
  homepage: http://github.com/crunchloop/timescaledb-rails
24
135
  licenses:
25
136
  - MIT
26
- metadata: {}
137
+ metadata:
138
+ rubygems_mfa_required: 'true'
27
139
  post_install_message:
28
140
  rdoc_options: []
29
141
  require_paths:
@@ -32,14 +144,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
32
144
  requirements:
33
145
  - - ">="
34
146
  - !ruby/object:Gem::Version
35
- version: '2.5'
147
+ version: '2.6'
36
148
  required_rubygems_version: !ruby/object:Gem::Requirement
37
149
  requirements:
38
150
  - - ">="
39
151
  - !ruby/object:Gem::Version
40
152
  version: '0'
41
153
  requirements: []
42
- rubygems_version: 3.0.3.1
154
+ rubygems_version: 3.3.26
43
155
  signing_key:
44
156
  specification_version: 4
45
157
  summary: TimescaleDB Rails integration