timescaledb 0.2.4 → 0.2.6
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/.github/workflows/ci.yml +72 -0
- data/.travis.yml +2 -2
- data/Gemfile.lock +2 -2
- data/Gemfile.scenic.lock +2 -4
- data/lib/timescaledb/application_record.rb +7 -0
- data/lib/timescaledb/chunk.rb +1 -1
- data/lib/timescaledb/compression_settings.rb +1 -1
- data/lib/timescaledb/continuous_aggregates.rb +1 -1
- data/lib/timescaledb/dimensions.rb +1 -1
- data/lib/timescaledb/hypertable.rb +1 -1
- data/lib/timescaledb/job.rb +1 -1
- data/lib/timescaledb/job_stats.rb +1 -1
- data/lib/timescaledb/migration_helpers.rb +27 -8
- data/lib/timescaledb/scenic/extension.rb +1 -1
- data/lib/timescaledb/schema_dumper.rb +63 -21
- data/lib/timescaledb/version.rb +1 -1
- data/lib/timescaledb.rb +1 -0
- metadata +4 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 06f324ce8793264ad6acb6a0f0f8f107511be08ecf2952e2fab285aeac366d35
         | 
| 4 | 
            +
              data.tar.gz: d95da2805b53dafd174bb83fce7cf29cc2f13b5e8543bfa144d424e679aba701
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 14ce31badc6ae1eae1f51161a806354fcaea6b2d39197498766b4cefa2022565410f7fc745adfbaf0d51b68d67454460f3aabab2a94444dd377a93193d0465b2
         | 
| 7 | 
            +
              data.tar.gz: 573dd6b5ae3bcfa0948176a86561c080a860d72634e1800b750554a694e17a17890a31492e2702b38ced8444b5725586bfcca6cb23109c968748edeb509bcf12
         | 
| @@ -0,0 +1,72 @@ | |
| 1 | 
            +
            name: CI
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            on:
         | 
| 4 | 
            +
              push:
         | 
| 5 | 
            +
              pull_request:
         | 
| 6 | 
            +
              workflow_dispatch:
         | 
| 7 | 
            +
            #  schedule:
         | 
| 8 | 
            +
            #    - cron: '42 5 * * *'
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            jobs:
         | 
| 11 | 
            +
              test-in-container:
         | 
| 12 | 
            +
                strategy:
         | 
| 13 | 
            +
                  fail-fast: false
         | 
| 14 | 
            +
                  matrix:
         | 
| 15 | 
            +
                    ruby: [ '3.1.2' ]
         | 
| 16 | 
            +
                    database:
         | 
| 17 | 
            +
                      - 'pg14.6-ts2.9.0-patroni-static-primary-latest'
         | 
| 18 | 
            +
                      - 'pg13.9-ts2.9-latest'
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                services:
         | 
| 21 | 
            +
                  database:
         | 
| 22 | 
            +
                    image: timescale/timescaledb-ha:${{matrix.database}}
         | 
| 23 | 
            +
                    env:
         | 
| 24 | 
            +
                      POSTGRES_USER: username
         | 
| 25 | 
            +
                      POSTGRES_PASSWORD: secret
         | 
| 26 | 
            +
                      POSTGRES_DB: testdb
         | 
| 27 | 
            +
                    options: >-
         | 
| 28 | 
            +
                      --health-cmd pg_isready
         | 
| 29 | 
            +
                      --health-interval 10s
         | 
| 30 | 
            +
                      --health-timeout 5s
         | 
| 31 | 
            +
                      --health-retries 5
         | 
| 32 | 
            +
             | 
| 33 | 
            +
             | 
| 34 | 
            +
                runs-on: ubuntu-latest
         | 
| 35 | 
            +
                name: OS Ruby ${{matrix.ruby}} database ${{matrix.database}}
         | 
| 36 | 
            +
                container: ruby:${{matrix.ruby}}
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                steps:
         | 
| 39 | 
            +
                - uses: actions/checkout@v3
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                - name: Show Ruby Version
         | 
| 42 | 
            +
                  run: |
         | 
| 43 | 
            +
                    ruby -v
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                - name: Install psql
         | 
| 46 | 
            +
                  run: |
         | 
| 47 | 
            +
                    apt-get update
         | 
| 48 | 
            +
                    apt-get install -y postgresql-client
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                - name: Show PostgreSQL version and time
         | 
| 51 | 
            +
                  env:
         | 
| 52 | 
            +
                    PGPASSWORD: secret
         | 
| 53 | 
            +
                  run: |
         | 
| 54 | 
            +
                    echo "SELECT version()" | psql -h database -U username testdb
         | 
| 55 | 
            +
                    echo "SELECT CURRENT_TIME" | psql -h database -U username testdb
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                - name: Setup
         | 
| 58 | 
            +
                  run: |
         | 
| 59 | 
            +
                    ./bin/setup
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                - name: run tsdb
         | 
| 62 | 
            +
                  run: ./bin/tsdb postgres://username:secret@database:5432/testdb --stats
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                - name: Test setup
         | 
| 65 | 
            +
                  run: |
         | 
| 66 | 
            +
                    echo PG_URI_TEST="postgres://username:secret@database:5432/testdb" > .env
         | 
| 67 | 
            +
                    cat .env
         | 
| 68 | 
            +
                    bundle exec rake test:setup
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                - name: Test
         | 
| 71 | 
            +
                  run: bundle exec rake
         | 
| 72 | 
            +
             | 
    
        data/.travis.yml
    CHANGED
    
    
    
        data/Gemfile.lock
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            PATH
         | 
| 2 2 | 
             
              remote: .
         | 
| 3 3 | 
             
              specs:
         | 
| 4 | 
            -
                timescaledb (0.2. | 
| 4 | 
            +
                timescaledb (0.2.6)
         | 
| 5 5 | 
             
                  activerecord
         | 
| 6 6 | 
             
                  activesupport
         | 
| 7 7 | 
             
                  pg (~> 1.2)
         | 
| @@ -33,7 +33,7 @@ GEM | |
| 33 33 | 
             
                  concurrent-ruby (~> 1.0)
         | 
| 34 34 | 
             
                method_source (1.0.0)
         | 
| 35 35 | 
             
                minitest (5.14.4)
         | 
| 36 | 
            -
                pg (1.4. | 
| 36 | 
            +
                pg (1.4.5)
         | 
| 37 37 | 
             
                pry (0.14.1)
         | 
| 38 38 | 
             
                  coderay (~> 1.1)
         | 
| 39 39 | 
             
                  method_source (~> 1.0)
         | 
    
        data/Gemfile.scenic.lock
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            PATH
         | 
| 2 2 | 
             
              remote: .
         | 
| 3 3 | 
             
              specs:
         | 
| 4 | 
            -
                timescaledb (0.2. | 
| 4 | 
            +
                timescaledb (0.2.6)
         | 
| 5 5 | 
             
                  activerecord
         | 
| 6 6 | 
             
                  activesupport
         | 
| 7 7 | 
             
                  pg (~> 1.2)
         | 
| @@ -56,9 +56,7 @@ GEM | |
| 56 56 | 
             
                nokogiri (1.12.5)
         | 
| 57 57 | 
             
                  mini_portile2 (~> 2.6.1)
         | 
| 58 58 | 
             
                  racc (~> 1.4)
         | 
| 59 | 
            -
                 | 
| 60 | 
            -
                  racc (~> 1.4)
         | 
| 61 | 
            -
                pg (1.4.4)
         | 
| 59 | 
            +
                pg (1.4.5)
         | 
| 62 60 | 
             
                pry (0.14.1)
         | 
| 63 61 | 
             
                  coderay (~> 1.1)
         | 
| 64 62 | 
             
                  method_source (~> 1.0)
         | 
    
        data/lib/timescaledb/chunk.rb
    CHANGED
    
    
    
        data/lib/timescaledb/job.rb
    CHANGED
    
    
| @@ -4,7 +4,12 @@ require 'active_record/connection_adapters/postgresql_adapter' | |
| 4 4 | 
             
            module Timescaledb
         | 
| 5 5 | 
             
              # Migration helpers can help you to setup hypertables by default.
         | 
| 6 6 | 
             
              module MigrationHelpers
         | 
| 7 | 
            -
                # create_table  | 
| 7 | 
            +
                # `create_table` accepts a `hypertable` argument with options for creating
         | 
| 8 | 
            +
                # a TimescaleDB hypertable.
         | 
| 9 | 
            +
                #
         | 
| 10 | 
            +
                # See https://docs.timescale.com/api/latest/hypertable/create_hypertable/#optional-arguments
         | 
| 11 | 
            +
                # for additional options supported by the plugin.
         | 
| 12 | 
            +
                #
         | 
| 8 13 | 
             
                # @example
         | 
| 9 14 | 
             
                #  options = {
         | 
| 10 15 | 
             
                #    time_column: 'created_at',
         | 
| @@ -27,15 +32,29 @@ module Timescaledb | |
| 27 32 | 
             
                # Setup hypertable from options
         | 
| 28 33 | 
             
                # @see create_table with the hypertable options.
         | 
| 29 34 | 
             
                def create_hypertable(table_name,
         | 
| 30 | 
            -
             | 
| 31 | 
            -
             | 
| 32 | 
            -
             | 
| 33 | 
            -
             | 
| 34 | 
            -
             | 
| 35 | 
            -
             | 
| 35 | 
            +
                                      time_column: 'created_at',
         | 
| 36 | 
            +
                                      chunk_time_interval: '1 week',
         | 
| 37 | 
            +
                                      compress_segmentby: nil,
         | 
| 38 | 
            +
                                      compress_orderby: 'created_at',
         | 
| 39 | 
            +
                                      compression_interval: nil,
         | 
| 40 | 
            +
                                      partition_column: nil,
         | 
| 41 | 
            +
                                      number_partitions: nil,
         | 
| 42 | 
            +
                                      **hypertable_options)
         | 
| 36 43 |  | 
| 37 44 | 
             
                  ActiveRecord::Base.logger = Logger.new(STDOUT)
         | 
| 38 | 
            -
             | 
| 45 | 
            +
             | 
| 46 | 
            +
                  options = ["chunk_time_interval => INTERVAL '#{chunk_time_interval}'"]
         | 
| 47 | 
            +
                  options += hypertable_options.map { |k, v| "#{k} => #{quote(v)}" }
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                  arguments = [
         | 
| 50 | 
            +
                    quote(table_name),
         | 
| 51 | 
            +
                    quote(time_column),
         | 
| 52 | 
            +
                    (quote(partition_column) if partition_column),
         | 
| 53 | 
            +
                    (number_partitions if partition_column),
         | 
| 54 | 
            +
                    *options
         | 
| 55 | 
            +
                  ]
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                  execute "SELECT create_hypertable(#{arguments.compact.join(', ')})"
         | 
| 39 58 |  | 
| 40 59 | 
             
                  if compress_segmentby
         | 
| 41 60 | 
             
                    execute <<~SQL
         | 
| @@ -68,5 +68,5 @@ module Timescaledb | |
| 68 68 | 
             
            end
         | 
| 69 69 |  | 
| 70 70 |  | 
| 71 | 
            +
            Scenic::Adapters::Postgres.include(Timescaledb::Scenic::Extension)
         | 
| 71 72 | 
             
            ActiveRecord::ConnectionAdapters::AbstractAdapter.include(Timescaledb::Scenic::MigrationHelpers)
         | 
| 72 | 
            -
            Scenic::Adapters::Postgres.prepend(Timescaledb::Scenic::Extension)
         | 
| @@ -5,31 +5,24 @@ module Timescaledb | |
| 5 5 | 
             
              module SchemaDumper
         | 
| 6 6 | 
             
                def tables(stream)
         | 
| 7 7 | 
             
                  super # This will call #table for each table in the database
         | 
| 8 | 
            -
                  views(stream) unless defined?(Scenic) # Don't call this twice if we're using Scenic
         | 
| 9 8 |  | 
| 10 9 | 
             
                  return unless Timescaledb::Hypertable.table_exists?
         | 
| 11 10 |  | 
| 12 11 | 
             
                  timescale_hypertables(stream)
         | 
| 13 12 | 
             
                  timescale_retention_policies(stream)
         | 
| 14 | 
            -
                end
         | 
| 15 | 
            -
             | 
| 16 | 
            -
                def views(stream)
         | 
| 17 | 
            -
                  return unless Timescaledb::ContinuousAggregates.table_exists?
         | 
| 18 | 
            -
             | 
| 19 13 | 
             
                  timescale_continuous_aggregates(stream) # Define these before any Scenic views that might use them
         | 
| 20 | 
            -
                  super if defined?(super)
         | 
| 21 14 | 
             
                end
         | 
| 22 15 |  | 
| 23 16 | 
             
                def timescale_hypertables(stream)
         | 
| 24 | 
            -
                  stream.puts # Insert a blank line above the hypertable definitions, for readability
         | 
| 25 | 
            -
             | 
| 26 17 | 
             
                  sorted_hypertables.each do |hypertable|
         | 
| 27 | 
            -
             | 
| 18 | 
            +
                    timescale_hypertable(hypertable, stream)
         | 
| 28 19 | 
             
                  end
         | 
| 29 20 | 
             
                end
         | 
| 30 21 |  | 
| 31 22 | 
             
                def timescale_retention_policies(stream)
         | 
| 32 | 
            -
                   | 
| 23 | 
            +
                  if sorted_hypertables.any? { |hypertable| hypertable.jobs.exists?(proc_name: "policy_retention") }
         | 
| 24 | 
            +
                    stream.puts # Insert a blank line above the retention policies, for readability
         | 
| 25 | 
            +
                  end
         | 
| 33 26 |  | 
| 34 27 | 
             
                  sorted_hypertables.each do |hypertable|
         | 
| 35 28 | 
             
                    timescale_retention_policy(hypertable, stream)
         | 
| @@ -39,13 +32,18 @@ module Timescaledb | |
| 39 32 | 
             
                private
         | 
| 40 33 |  | 
| 41 34 | 
             
                def timescale_hypertable(hypertable, stream)
         | 
| 42 | 
            -
                   | 
| 43 | 
            -
             | 
| 44 | 
            -
             | 
| 45 | 
            -
                     | 
| 46 | 
            -
             | 
| 47 | 
            -
             | 
| 48 | 
            -
             | 
| 35 | 
            +
                  time = hypertable.main_dimension
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                  options = {
         | 
| 38 | 
            +
                    time_column: time.column_name,
         | 
| 39 | 
            +
                    chunk_time_interval: time.time_interval.inspect,
         | 
| 40 | 
            +
                    **timescale_compression_settings_for(hypertable),
         | 
| 41 | 
            +
                    **timescale_space_partition_for(hypertable),
         | 
| 42 | 
            +
                    **timescale_index_options_for(hypertable)
         | 
| 43 | 
            +
                  }
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                  options = options.map { |k, v| "#{k}: #{v.to_json}" }.join(", ")
         | 
| 46 | 
            +
                  stream.puts %Q[  create_hypertable "#{hypertable.hypertable_name}", #{options}]
         | 
| 49 47 | 
             
                end
         | 
| 50 48 |  | 
| 51 49 | 
             
                def timescale_retention_policy(hypertable, stream)
         | 
| @@ -56,21 +54,64 @@ module Timescaledb | |
| 56 54 |  | 
| 57 55 | 
             
                def timescale_compression_settings_for(hypertable)
         | 
| 58 56 | 
             
                  compression_settings = hypertable.compression_settings.each_with_object({}) do |setting, compression_settings|
         | 
| 59 | 
            -
                     | 
| 57 | 
            +
                    # It's possible to configure compression so that it is segmented by multiple
         | 
| 58 | 
            +
                    # columns. To make sure we capture that correctly, we'll treat them as an array.
         | 
| 59 | 
            +
                    compression_settings[:compress_segmentby] ||= []
         | 
| 60 | 
            +
                    compression_settings[:compress_orderby] ||= []
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                    compression_settings[:compress_segmentby] << setting.attname if setting.segmentby_column_index
         | 
| 60 63 |  | 
| 61 64 | 
             
                    if setting.orderby_column_index
         | 
| 62 | 
            -
                       | 
| 63 | 
            -
             | 
| 65 | 
            +
                      if setting.orderby_asc
         | 
| 66 | 
            +
                        direction = "ASC"
         | 
| 67 | 
            +
                        if setting.orderby_nullsfirst
         | 
| 68 | 
            +
                          direction += " NULLS FIRST"
         | 
| 69 | 
            +
                        end
         | 
| 70 | 
            +
                      else
         | 
| 71 | 
            +
                        direction = "DESC"
         | 
| 72 | 
            +
                        if !setting.orderby_nullsfirst
         | 
| 73 | 
            +
                          direction += " NULLS LAST"
         | 
| 74 | 
            +
                        end
         | 
| 75 | 
            +
                      end
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                      compression_settings[:compress_orderby] << "#{setting.attname} #{direction}"
         | 
| 64 78 | 
             
                    end
         | 
| 65 79 | 
             
                  end
         | 
| 66 80 |  | 
| 67 81 | 
             
                  hypertable.jobs.compression.each do |job|
         | 
| 68 82 | 
             
                    compression_settings[:compression_interval] = job.config["compress_after"]
         | 
| 69 83 | 
             
                  end
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                  # Pack the compression setting arrays into a comma-separated string instead.
         | 
| 86 | 
            +
                  if compression_settings[:compress_segmentby]
         | 
| 87 | 
            +
                    compression_settings[:compress_segmentby] = compression_settings[:compress_segmentby].join(", ")
         | 
| 88 | 
            +
                  end
         | 
| 89 | 
            +
                  if compression_settings[:compress_orderby]
         | 
| 90 | 
            +
                    compression_settings[:compress_orderby] = compression_settings[:compress_orderby].join(", ")
         | 
| 91 | 
            +
                  end
         | 
| 92 | 
            +
             | 
| 70 93 | 
             
                  compression_settings
         | 
| 71 94 | 
             
                end
         | 
| 72 95 |  | 
| 96 | 
            +
                def timescale_space_partition_for(hypertable)
         | 
| 97 | 
            +
                  return {} unless hypertable.dimensions.length > 1
         | 
| 98 | 
            +
             | 
| 99 | 
            +
                  space = hypertable.dimensions.last
         | 
| 100 | 
            +
                  {partition_column: space.column_name, number_partitions: space.num_partitions}
         | 
| 101 | 
            +
                end
         | 
| 102 | 
            +
             | 
| 103 | 
            +
                def timescale_index_options_for(hypertable)
         | 
| 104 | 
            +
                  time = hypertable.main_dimension
         | 
| 105 | 
            +
                  if @connection.indexes(hypertable.hypertable_name).any? { |i| i.columns == [time.column_name] }
         | 
| 106 | 
            +
                    {}
         | 
| 107 | 
            +
                  else
         | 
| 108 | 
            +
                    {create_default_indexes: false}
         | 
| 109 | 
            +
                  end
         | 
| 110 | 
            +
                end
         | 
| 111 | 
            +
             | 
| 73 112 | 
             
                def timescale_continuous_aggregates(stream)
         | 
| 113 | 
            +
                  return unless Timescaledb::ContinuousAggregates.table_exists?
         | 
| 114 | 
            +
             | 
| 74 115 | 
             
                  Timescaledb::ContinuousAggregates.all.each do |aggregate|
         | 
| 75 116 | 
             
                    opts = if (refresh_policy = aggregate.jobs.refresh_continuous_aggregate.first)
         | 
| 76 117 | 
             
                             interval = timescale_interval(refresh_policy.schedule_interval)
         | 
| @@ -95,6 +136,7 @@ module Timescaledb | |
| 95 136 |  | 
| 96 137 | 
             
                  "INTERVAL '#{value}'"
         | 
| 97 138 | 
             
                end
         | 
| 139 | 
            +
             | 
| 98 140 | 
             
                def sorted_hypertables
         | 
| 99 141 | 
             
                  @sorted_hypertables ||= Timescaledb::Hypertable.order(:hypertable_name).to_a
         | 
| 100 142 | 
             
                end
         | 
    
        data/lib/timescaledb/version.rb
    CHANGED
    
    
    
        data/lib/timescaledb.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: timescaledb
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.2. | 
| 4 | 
            +
              version: 0.2.6
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Jônatas Davi Paganini
         | 
| 8 8 | 
             
            autorequire:
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date:  | 
| 11 | 
            +
            date: 2023-02-03 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: pg
         | 
| @@ -144,6 +144,7 @@ executables: | |
| 144 144 | 
             
            extensions: []
         | 
| 145 145 | 
             
            extra_rdoc_files: []
         | 
| 146 146 | 
             
            files:
         | 
| 147 | 
            +
            - ".github/workflows/ci.yml"
         | 
| 147 148 | 
             
            - ".gitignore"
         | 
| 148 149 | 
             
            - ".rspec"
         | 
| 149 150 | 
             
            - ".ruby-version"
         | 
| @@ -240,6 +241,7 @@ files: | |
| 240 241 | 
             
            - lib/timescaledb/acts_as_hypertable.rb
         | 
| 241 242 | 
             
            - lib/timescaledb/acts_as_hypertable/core.rb
         | 
| 242 243 | 
             
            - lib/timescaledb/acts_as_time_vector.rb
         | 
| 244 | 
            +
            - lib/timescaledb/application_record.rb
         | 
| 243 245 | 
             
            - lib/timescaledb/chunk.rb
         | 
| 244 246 | 
             
            - lib/timescaledb/compression_settings.rb
         | 
| 245 247 | 
             
            - lib/timescaledb/continuous_aggregates.rb
         |