timescaledb 0.2.6 → 0.2.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. data/lib/timescaledb/acts_as_hypertable/core.rb +1 -1
  3. data/lib/timescaledb/database/quoting.rb +12 -0
  4. data/lib/timescaledb/database/schema_statements.rb +168 -0
  5. data/lib/timescaledb/database/types.rb +17 -0
  6. data/lib/timescaledb/database.rb +11 -0
  7. data/lib/timescaledb/toolkit/time_vector.rb +41 -4
  8. data/lib/timescaledb/version.rb +1 -1
  9. metadata +6 -95
  10. data/.github/workflows/ci.yml +0 -72
  11. data/.gitignore +0 -12
  12. data/.rspec +0 -3
  13. data/.ruby-version +0 -1
  14. data/.tool-versions +0 -1
  15. data/.travis.yml +0 -9
  16. data/CODE_OF_CONDUCT.md +0 -74
  17. data/Fastfile +0 -17
  18. data/Gemfile +0 -8
  19. data/Gemfile.lock +0 -75
  20. data/Gemfile.scenic +0 -7
  21. data/Gemfile.scenic.lock +0 -119
  22. data/README.md +0 -490
  23. data/Rakefile +0 -21
  24. data/bin/console +0 -28
  25. data/bin/setup +0 -13
  26. data/docs/command_line.md +0 -178
  27. data/docs/img/lttb_example.png +0 -0
  28. data/docs/img/lttb_sql_vs_ruby.gif +0 -0
  29. data/docs/img/lttb_zoom.gif +0 -0
  30. data/docs/index.md +0 -72
  31. data/docs/migrations.md +0 -76
  32. data/docs/models.md +0 -78
  33. data/docs/toolkit.md +0 -507
  34. data/docs/toolkit_lttb_tutorial.md +0 -557
  35. data/docs/toolkit_lttb_zoom.md +0 -357
  36. data/docs/toolkit_ohlc.md +0 -315
  37. data/docs/videos.md +0 -16
  38. data/examples/all_in_one/all_in_one.rb +0 -94
  39. data/examples/all_in_one/benchmark_comparison.rb +0 -108
  40. data/examples/all_in_one/caggs.rb +0 -93
  41. data/examples/all_in_one/query_data.rb +0 -78
  42. data/examples/ranking/.gitattributes +0 -7
  43. data/examples/ranking/.gitignore +0 -29
  44. data/examples/ranking/.ruby-version +0 -1
  45. data/examples/ranking/Gemfile +0 -33
  46. data/examples/ranking/Gemfile.lock +0 -189
  47. data/examples/ranking/README.md +0 -166
  48. data/examples/ranking/Rakefile +0 -6
  49. data/examples/ranking/app/controllers/application_controller.rb +0 -2
  50. data/examples/ranking/app/controllers/concerns/.keep +0 -0
  51. data/examples/ranking/app/jobs/application_job.rb +0 -7
  52. data/examples/ranking/app/models/application_record.rb +0 -3
  53. data/examples/ranking/app/models/concerns/.keep +0 -0
  54. data/examples/ranking/app/models/game.rb +0 -2
  55. data/examples/ranking/app/models/play.rb +0 -7
  56. data/examples/ranking/bin/bundle +0 -114
  57. data/examples/ranking/bin/rails +0 -4
  58. data/examples/ranking/bin/rake +0 -4
  59. data/examples/ranking/bin/setup +0 -33
  60. data/examples/ranking/config/application.rb +0 -39
  61. data/examples/ranking/config/boot.rb +0 -4
  62. data/examples/ranking/config/credentials.yml.enc +0 -1
  63. data/examples/ranking/config/database.yml +0 -86
  64. data/examples/ranking/config/environment.rb +0 -5
  65. data/examples/ranking/config/environments/development.rb +0 -60
  66. data/examples/ranking/config/environments/production.rb +0 -75
  67. data/examples/ranking/config/environments/test.rb +0 -53
  68. data/examples/ranking/config/initializers/cors.rb +0 -16
  69. data/examples/ranking/config/initializers/filter_parameter_logging.rb +0 -8
  70. data/examples/ranking/config/initializers/inflections.rb +0 -16
  71. data/examples/ranking/config/initializers/timescale.rb +0 -2
  72. data/examples/ranking/config/locales/en.yml +0 -33
  73. data/examples/ranking/config/puma.rb +0 -43
  74. data/examples/ranking/config/routes.rb +0 -6
  75. data/examples/ranking/config/storage.yml +0 -34
  76. data/examples/ranking/config.ru +0 -6
  77. data/examples/ranking/db/migrate/20220209120747_create_games.rb +0 -10
  78. data/examples/ranking/db/migrate/20220209120910_create_plays.rb +0 -19
  79. data/examples/ranking/db/migrate/20220209143347_create_score_per_hours.rb +0 -5
  80. data/examples/ranking/db/schema.rb +0 -47
  81. data/examples/ranking/db/seeds.rb +0 -7
  82. data/examples/ranking/db/views/score_per_hours_v01.sql +0 -7
  83. data/examples/ranking/lib/tasks/.keep +0 -0
  84. data/examples/ranking/log/.keep +0 -0
  85. data/examples/ranking/public/robots.txt +0 -1
  86. data/examples/ranking/storage/.keep +0 -0
  87. data/examples/ranking/tmp/.keep +0 -0
  88. data/examples/ranking/tmp/pids/.keep +0 -0
  89. data/examples/ranking/tmp/storage/.keep +0 -0
  90. data/examples/ranking/vendor/.keep +0 -0
  91. data/examples/toolkit-demo/compare_volatility.rb +0 -104
  92. data/examples/toolkit-demo/lttb/README.md +0 -15
  93. data/examples/toolkit-demo/lttb/lttb.rb +0 -92
  94. data/examples/toolkit-demo/lttb/lttb_sinatra.rb +0 -139
  95. data/examples/toolkit-demo/lttb/lttb_test.rb +0 -21
  96. data/examples/toolkit-demo/lttb/views/index.erb +0 -27
  97. data/examples/toolkit-demo/lttb-zoom/README.md +0 -13
  98. data/examples/toolkit-demo/lttb-zoom/lttb_zoomable.rb +0 -90
  99. data/examples/toolkit-demo/lttb-zoom/views/index.erb +0 -33
  100. data/examples/toolkit-demo/ohlc.rb +0 -175
  101. data/mkdocs.yml +0 -34
  102. data/timescaledb.gemspec +0 -40
@@ -1,94 +0,0 @@
1
- require 'bundler/inline' #require only what you need
2
-
3
- gemfile(true) do
4
- gem 'timescaledb', path: '../..'
5
- gem 'pry'
6
- gem 'faker'
7
- end
8
-
9
- require 'timescaledb'
10
- require 'pp'
11
- require 'pry'
12
- # ruby all_in_one.rb postgres://user:pass@host:port/db_name
13
- ActiveRecord::Base.establish_connection( ARGV.last)
14
-
15
- # Simple example
16
- class Event < ActiveRecord::Base
17
- self.primary_key = nil
18
- acts_as_hypertable
19
- end
20
-
21
- # Setup Hypertable as in a migration
22
- ActiveRecord::Base.connection.instance_exec do
23
- ActiveRecord::Base.logger = Logger.new(STDOUT)
24
-
25
- drop_table(:events, cascade: true) if Event.table_exists?
26
-
27
- hypertable_options = {
28
- time_column: 'created_at',
29
- chunk_time_interval: '1 day',
30
- compress_segmentby: 'identifier',
31
- compression_interval: '7 days'
32
- }
33
-
34
- create_table(:events, id: false, hypertable: hypertable_options) do |t|
35
- t.string :identifier, null: false
36
- t.jsonb :payload
37
- t.timestamps
38
- end
39
- end
40
-
41
- # Create some data just to see how it works
42
- 1.times do
43
- Event.transaction do
44
- Event.create identifier: "sign_up", payload: {"name" => "Eon"}
45
- Event.create identifier: "login", payload: {"email" => "eon@timescale.com"}
46
- Event.create identifier: "click", payload: {"user" => "eon", "path" => "/install/timescaledb"}
47
- Event.create identifier: "scroll", payload: {"user" => "eon", "path" => "/install/timescaledb"}
48
- Event.create identifier: "logout", payload: {"email" => "eon@timescale.com"}
49
- end
50
- end
51
-
52
-
53
- def generate_fake_data(total: 100_000)
54
- time = 1.month.ago
55
- total.times.flat_map do
56
- identifier = %w[sign_up login click scroll logout view]
57
- time = time + rand(60).seconds
58
- {
59
- created_at: time,
60
- updated_at: time,
61
- identifier: identifier.sample,
62
- payload: {
63
- "name" => Faker::Name.name,
64
- "email" => Faker::Internet.email
65
- }
66
- }
67
- end
68
- end
69
-
70
- def supress_logs
71
- ActiveRecord::Base.logger =nil
72
- yield
73
- ActiveRecord::Base.logger = Logger.new(STDOUT)
74
- end
75
-
76
- batch = generate_fake_data total: 10_000
77
- supress_logs do
78
- Event.insert_all(batch, returning: false)
79
- end
80
- # Now let's see what we have in the scopes
81
- Event.last_hour.group(:identifier).count # => {"login"=>2, "click"=>1, "logout"=>1, "sign_up"=>1, "scroll"=>1}
82
-
83
- puts "compressing #{ Event.chunks.count }"
84
- Event.chunks.first.compress!
85
-
86
- puts "detailed size"
87
- pp Event.hypertable.detailed_size
88
-
89
- puts "compression stats"
90
- pp Event.hypertable.compression_stats
91
-
92
- puts "decompressing"
93
- Event.chunks.first.decompress!
94
- Pry.start
@@ -1,108 +0,0 @@
1
- require 'bundler/inline' #require only what you need
2
-
3
- gemfile(true) do
4
- gem 'timescaledb', path: '../..'
5
- gem 'pry'
6
- gem 'faker'
7
- gem 'benchmark-ips', require: "benchmark/ips", git: 'https://github.com/evanphx/benchmark-ips'
8
- end
9
-
10
- require 'pp'
11
- require 'benchmark'
12
- # ruby all_in_one.rb postgres://user:pass@host:port/db_name
13
- ActiveRecord::Base.establish_connection( ARGV.last)
14
-
15
- # Simple example
16
- class Event < ActiveRecord::Base
17
- self.primary_key = nil
18
- acts_as_hypertable
19
-
20
- # If you want to override the automatic assingment of the `created_at ` time series column
21
- def self.timestamp_attributes_for_create_in_model
22
- []
23
- end
24
- def self.timestamp_attributes_for_update_in_model
25
- []
26
- end
27
- end
28
-
29
- class Event2 < ActiveRecord::Base
30
- self.table_name = "events_2"
31
- end
32
-
33
- # Setup Hypertable as in a migration
34
- ActiveRecord::Base.connection.instance_exec do
35
- ActiveRecord::Base.logger = Logger.new(STDOUT)
36
-
37
- drop_table(Event.table_name) if Event.table_exists?
38
- drop_table(Event2.table_name) if Event2.table_exists?
39
-
40
- hypertable_options = {
41
- time_column: 'created_at',
42
- chunk_time_interval: '7 day',
43
- compress_segmentby: 'identifier',
44
- compression_interval: '7 days'
45
- }
46
-
47
- create_table(:events, id: false, hypertable: hypertable_options) do |t|
48
- t.string :identifier, null: false
49
- t.jsonb :payload
50
- t.timestamps
51
- end
52
-
53
- create_table(Event2.table_name) do |t|
54
- t.string :identifier, null: false
55
- t.jsonb :payload
56
- t.timestamps
57
- end
58
- end
59
-
60
- def generate_fake_data(total: 100_000)
61
- time = Time.now
62
- total.times.flat_map do
63
- identifier = %w[sign_up login click scroll logout view]
64
- time = time + rand(60).seconds
65
- {
66
- created_at: time,
67
- updated_at: time,
68
- identifier: identifier.sample,
69
- payload: {
70
- "name" => Faker::Name.name,
71
- "email" => Faker::Internet.email
72
- }
73
- }
74
- end
75
- end
76
-
77
-
78
- def parallel_inserts clazz: nil, size: 5_000, data: nil
79
- limit = 8
80
- threads = []
81
- while (batch = data.shift(size)).any? do
82
- threads << Thread.new(batch) do |batch|
83
- begin
84
- clazz.insert_all(batch, returning: false)
85
- ensure
86
- ActiveRecord::Base.connection.close if ActiveRecord::Base.connection
87
- end
88
- end
89
- if threads.size == limit
90
- threads.each(&:join)
91
- threads = []
92
- end
93
- end
94
- threads.each(&:join)
95
- end
96
-
97
- payloads = nil
98
- ActiveRecord::Base.logger = nil
99
- Benchmark.ips do |x|
100
- x.config(time: 500, warmup: 2)
101
-
102
- x.report("gen data") { payloads = generate_fake_data total: 100_000}
103
- x.report("normal ") { parallel_inserts(data: payloads.dup, clazz: Event2, size: 5000) }
104
- x.report("hyper ") { parallel_inserts(data: payloads.dup, clazz: Event, size: 5000) }
105
- x.compare!
106
- end
107
- ActiveRecord::Base.logger = Logger.new(STDOUT)
108
-
@@ -1,93 +0,0 @@
1
- require 'bundler/inline' #require only what you need
2
-
3
- gemfile(true) do
4
- gem 'timescaledb', path: '../..'
5
- gem 'pry'
6
- end
7
-
8
- require 'pp'
9
- # ruby caggs.rb postgres://user:pass@host:port/db_name
10
- ActiveRecord::Base.establish_connection( ARGV.last)
11
-
12
- class Tick < ActiveRecord::Base
13
- self.table_name = 'ticks'
14
- self.primary_key = nil
15
-
16
- acts_as_hypertable time_column: 'time'
17
-
18
- %w[open high low close].each{|name| attribute name, :decimal}
19
-
20
- scope :ohlc, -> (timeframe='1m') do
21
- select("time_bucket('#{timeframe}', time) as time,
22
- symbol,
23
- FIRST(price, time) as open,
24
- MAX(price) as high,
25
- MIN(price) as low,
26
- LAST(price, time) as close,
27
- SUM(volume) as volume").group("1,2")
28
- end
29
- end
30
-
31
- ActiveRecord::Base.connection.instance_exec do
32
- drop_table(:ticks, force: :cascade) if Tick.table_exists?
33
-
34
- hypertable_options = {
35
- time_column: 'time',
36
- chunk_time_interval: '1 day',
37
- compress_segmentby: 'symbol',
38
- compress_orderby: 'time',
39
- compression_interval: '7 days'
40
- }
41
-
42
- create_table :ticks, hypertable: hypertable_options, id: false do |t|
43
- t.timestamp :time
44
- t.string :symbol
45
- t.decimal :price
46
- t.integer :volume
47
- end
48
- end
49
-
50
- FAANG = %w[META AMZN AAPL NFLX GOOG]
51
- OPERATION = [:+, :-]
52
- RAND_VOLUME = -> { (rand(10) * rand(10)) * 100 }
53
- RAND_CENT = -> { (rand / 50.0).round(2) }
54
-
55
- def generate_fake_data(total: 100)
56
- previous_price = {}
57
- time = Time.now
58
- (total / FAANG.size).times.flat_map do
59
- time += rand(10)
60
- FAANG.map do |symbol|
61
- if previous_price[symbol]
62
- price = previous_price[symbol].send(OPERATION.sample, RAND_CENT.()).round(2)
63
- else
64
- price = 50 + rand(100)
65
- end
66
- payload = { time: time, symbol: symbol, price: price, volume: RAND_VOLUME.() }
67
- previous_price[symbol] = price
68
- payload
69
- end
70
- end
71
- end
72
-
73
- batch = generate_fake_data total: 10_000
74
- ActiveRecord::Base.logger = nil
75
- Tick.insert_all(batch, returning: false)
76
- ActiveRecord::Base.logger = Logger.new(STDOUT)
77
-
78
- ActiveRecord::Base.connection.instance_exec do
79
- create_continuous_aggregates('ohlc_1m', Tick.ohlc('1m'), with_data: true)
80
- end
81
-
82
- class Ohlc1m < ActiveRecord::Base
83
- self.table_name = 'ohlc_1m'
84
- attribute :time, :time
85
- attribute :symbol, :string
86
- %w[open high low close volume].each{|name| attribute name, :decimal}
87
-
88
- def readonly?
89
- true
90
- end
91
- end
92
-
93
- binding.pry
@@ -1,78 +0,0 @@
1
- require 'bundler/inline' #require only what you need
2
-
3
- gemfile(true) do
4
- gem 'timescaledb', path: '../..'
5
- gem 'pry'
6
- gem 'faker'
7
- end
8
-
9
- require 'pp'
10
- # ruby all_in_one.rb postgres://user:pass@host:port/db_name
11
- ActiveRecord::Base.establish_connection( ARGV.last)
12
-
13
- # Simple example
14
- class Event < ActiveRecord::Base
15
- self.primary_key = nil
16
- acts_as_hypertable
17
-
18
- # If you want to override the automatic assingment of the `created_at ` time series column
19
- def self.timestamp_attributes_for_create_in_model
20
- []
21
- end
22
- def self.timestamp_attributes_for_update_in_model
23
- []
24
- end
25
- end
26
-
27
- # Setup Hypertable as in a migration
28
- ActiveRecord::Base.connection.instance_exec do
29
- ActiveRecord::Base.logger = Logger.new(STDOUT)
30
-
31
- drop_table(Event.table_name) if Event.table_exists?
32
-
33
- hypertable_options = {
34
- time_column: 'created_at',
35
- chunk_time_interval: '7 day',
36
- compress_segmentby: 'identifier',
37
- compression_interval: '7 days'
38
- }
39
-
40
- create_table(:events, id: false, hypertable: hypertable_options) do |t|
41
- t.string :identifier, null: false
42
- t.jsonb :payload
43
- t.timestamps
44
- end
45
- end
46
-
47
- def generate_fake_data(total: 100_000)
48
- time = 1.month.ago
49
- total.times.flat_map do
50
- identifier = %w[sign_up login click scroll logout view]
51
- time = time + rand(60).seconds
52
- {
53
- created_at: time,
54
- updated_at: time,
55
- identifier: identifier.sample,
56
- payload: {
57
- "name" => Faker::Name.name,
58
- "email" => Faker::Internet.email
59
- }
60
- }
61
- end
62
- end
63
-
64
-
65
- batch = generate_fake_data total: 10_000
66
- ActiveRecord::Base.logger = nil
67
- Event.insert_all(batch, returning: false)
68
- ActiveRecord::Base.logger = Logger.new(STDOUT)
69
-
70
- pp Event.previous_month.count
71
- pp Event.previous_week.count
72
- pp Event.previous_month.group('identifier').count
73
- pp Event.previous_week.group('identifier').count
74
-
75
- pp Event
76
- .previous_month
77
- .select("time_bucket('1 day', created_at) as time, identifier, count(*)")
78
- .group("1,2").map(&:attributes)
@@ -1,7 +0,0 @@
1
- # See https://git-scm.com/docs/gitattributes for more about git attribute files.
2
-
3
- # Mark the database schema as having been generated.
4
- db/schema.rb linguist-generated
5
-
6
- # Mark any vendored files as having been vendored.
7
- vendor/* linguist-vendored
@@ -1,29 +0,0 @@
1
- # See https://help.github.com/articles/ignoring-files for more about ignoring files.
2
- #
3
- # If you find yourself ignoring temporary files generated by your text editor
4
- # or operating system, you probably want to add a global ignore instead:
5
- # git config --global core.excludesfile '~/.gitignore_global'
6
-
7
- # Ignore bundler config.
8
- /.bundle
9
-
10
- # Ignore all logfiles and tempfiles.
11
- /log/*
12
- /tmp/*
13
- !/log/.keep
14
- !/tmp/.keep
15
-
16
- # Ignore pidfiles, but keep the directory.
17
- /tmp/pids/*
18
- !/tmp/pids/
19
- !/tmp/pids/.keep
20
-
21
- # Ignore uploaded files in development.
22
- /storage/*
23
- !/storage/.keep
24
- /tmp/storage/*
25
- !/tmp/storage/
26
- !/tmp/storage/.keep
27
-
28
- # Ignore master key for decrypting credentials and more.
29
- /config/master.key
@@ -1 +0,0 @@
1
- 2.7.1
@@ -1,33 +0,0 @@
1
- source "https://rubygems.org"
2
- git_source(:github) { |repo| "https://github.com/#{repo}.git" }
3
-
4
- ruby "2.7.1"
5
-
6
- # Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main"
7
- gem "rails", "~> 7.0.2"
8
-
9
- gem "timescaledb", path: "../../"
10
- gem "pg", "~> 1.1"
11
- gem "puma", "~> 5.0"
12
- gem "tzinfo-data", platforms: %i[ mingw mswin x64_mingw jruby ]
13
-
14
- # Reduces boot times through caching; required in config/boot.rb
15
- gem "bootsnap", require: false
16
-
17
- # Use Active Storage variants [https://guides.rubyonrails.org/active_storage_overview.html#transforming-images]
18
- # gem "image_processing", "~> 1.2"
19
-
20
- # Use Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin AJAX possible
21
- # gem "rack-cors"
22
-
23
- group :development, :test do
24
- gem "pry-rails"
25
- end
26
-
27
- group :development do
28
- # Speed up commands on slow machines / big apps [https://github.com/rails/spring]
29
- # gem "spring"
30
- end
31
-
32
-
33
- gem "scenic", "~> 1.5"
@@ -1,189 +0,0 @@
1
- PATH
2
- remote: ../..
3
- specs:
4
- timescaledb (0.1.5)
5
- activerecord
6
- activesupport
7
- pg (~> 1.2)
8
-
9
- GEM
10
- remote: https://rubygems.org/
11
- specs:
12
- actioncable (7.0.2)
13
- actionpack (= 7.0.2)
14
- activesupport (= 7.0.2)
15
- nio4r (~> 2.0)
16
- websocket-driver (>= 0.6.1)
17
- actionmailbox (7.0.2)
18
- actionpack (= 7.0.2)
19
- activejob (= 7.0.2)
20
- activerecord (= 7.0.2)
21
- activestorage (= 7.0.2)
22
- activesupport (= 7.0.2)
23
- mail (>= 2.7.1)
24
- net-imap
25
- net-pop
26
- net-smtp
27
- actionmailer (7.0.2)
28
- actionpack (= 7.0.2)
29
- actionview (= 7.0.2)
30
- activejob (= 7.0.2)
31
- activesupport (= 7.0.2)
32
- mail (~> 2.5, >= 2.5.4)
33
- net-imap
34
- net-pop
35
- net-smtp
36
- rails-dom-testing (~> 2.0)
37
- actionpack (7.0.2)
38
- actionview (= 7.0.2)
39
- activesupport (= 7.0.2)
40
- rack (~> 2.0, >= 2.2.0)
41
- rack-test (>= 0.6.3)
42
- rails-dom-testing (~> 2.0)
43
- rails-html-sanitizer (~> 1.0, >= 1.2.0)
44
- actiontext (7.0.2)
45
- actionpack (= 7.0.2)
46
- activerecord (= 7.0.2)
47
- activestorage (= 7.0.2)
48
- activesupport (= 7.0.2)
49
- globalid (>= 0.6.0)
50
- nokogiri (>= 1.8.5)
51
- actionview (7.0.2)
52
- activesupport (= 7.0.2)
53
- builder (~> 3.1)
54
- erubi (~> 1.4)
55
- rails-dom-testing (~> 2.0)
56
- rails-html-sanitizer (~> 1.1, >= 1.2.0)
57
- activejob (7.0.2)
58
- activesupport (= 7.0.2)
59
- globalid (>= 0.3.6)
60
- activemodel (7.0.2)
61
- activesupport (= 7.0.2)
62
- activerecord (7.0.2)
63
- activemodel (= 7.0.2)
64
- activesupport (= 7.0.2)
65
- activestorage (7.0.2)
66
- actionpack (= 7.0.2)
67
- activejob (= 7.0.2)
68
- activerecord (= 7.0.2)
69
- activesupport (= 7.0.2)
70
- marcel (~> 1.0)
71
- mini_mime (>= 1.1.0)
72
- activesupport (7.0.2)
73
- concurrent-ruby (~> 1.0, >= 1.0.2)
74
- i18n (>= 1.6, < 2)
75
- minitest (>= 5.1)
76
- tzinfo (~> 2.0)
77
- bootsnap (1.10.3)
78
- msgpack (~> 1.2)
79
- builder (3.2.4)
80
- coderay (1.1.3)
81
- concurrent-ruby (1.1.9)
82
- crass (1.0.6)
83
- digest (3.1.0)
84
- erubi (1.10.0)
85
- globalid (1.0.0)
86
- activesupport (>= 5.0)
87
- i18n (1.9.1)
88
- concurrent-ruby (~> 1.0)
89
- io-wait (0.2.1)
90
- loofah (2.13.0)
91
- crass (~> 1.0.2)
92
- nokogiri (>= 1.5.9)
93
- mail (2.7.1)
94
- mini_mime (>= 0.1.1)
95
- marcel (1.0.2)
96
- method_source (1.0.0)
97
- mini_mime (1.1.2)
98
- mini_portile2 (2.7.1)
99
- minitest (5.15.0)
100
- msgpack (1.4.4)
101
- net-imap (0.2.3)
102
- digest
103
- net-protocol
104
- strscan
105
- net-pop (0.1.1)
106
- digest
107
- net-protocol
108
- timeout
109
- net-protocol (0.1.2)
110
- io-wait
111
- timeout
112
- net-smtp (0.3.1)
113
- digest
114
- net-protocol
115
- timeout
116
- nio4r (2.5.8)
117
- nokogiri (1.13.1)
118
- mini_portile2 (~> 2.7.0)
119
- racc (~> 1.4)
120
- pg (1.3.1)
121
- pry (0.14.1)
122
- coderay (~> 1.1)
123
- method_source (~> 1.0)
124
- pry-rails (0.3.9)
125
- pry (>= 0.10.4)
126
- puma (5.6.1)
127
- nio4r (~> 2.0)
128
- racc (1.6.0)
129
- rack (2.2.3)
130
- rack-test (1.1.0)
131
- rack (>= 1.0, < 3)
132
- rails (7.0.2)
133
- actioncable (= 7.0.2)
134
- actionmailbox (= 7.0.2)
135
- actionmailer (= 7.0.2)
136
- actionpack (= 7.0.2)
137
- actiontext (= 7.0.2)
138
- actionview (= 7.0.2)
139
- activejob (= 7.0.2)
140
- activemodel (= 7.0.2)
141
- activerecord (= 7.0.2)
142
- activestorage (= 7.0.2)
143
- activesupport (= 7.0.2)
144
- bundler (>= 1.15.0)
145
- railties (= 7.0.2)
146
- rails-dom-testing (2.0.3)
147
- activesupport (>= 4.2.0)
148
- nokogiri (>= 1.6)
149
- rails-html-sanitizer (1.4.2)
150
- loofah (~> 2.3)
151
- railties (7.0.2)
152
- actionpack (= 7.0.2)
153
- activesupport (= 7.0.2)
154
- method_source
155
- rake (>= 12.2)
156
- thor (~> 1.0)
157
- zeitwerk (~> 2.5)
158
- rake (13.0.6)
159
- scenic (1.5.5)
160
- activerecord (>= 4.0.0)
161
- railties (>= 4.0.0)
162
- strscan (3.0.1)
163
- thor (1.2.1)
164
- timeout (0.2.0)
165
- tzinfo (2.0.4)
166
- concurrent-ruby (~> 1.0)
167
- websocket-driver (0.7.5)
168
- websocket-extensions (>= 0.1.0)
169
- websocket-extensions (0.1.5)
170
- zeitwerk (2.5.4)
171
-
172
- PLATFORMS
173
- ruby
174
-
175
- DEPENDENCIES
176
- bootsnap
177
- pg (~> 1.1)
178
- pry-rails
179
- puma (~> 5.0)
180
- rails (~> 7.0.2)
181
- scenic (~> 1.5)
182
- timescaledb!
183
- tzinfo-data
184
-
185
- RUBY VERSION
186
- ruby 2.7.1p83
187
-
188
- BUNDLED WITH
189
- 2.1.4