timescaledb 0.2.1 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/Fastfile +17 -0
  3. data/Gemfile.lock +2 -2
  4. data/README.md +41 -9
  5. data/bin/console +1 -1
  6. data/bin/tsdb +2 -2
  7. data/docs/command_line.md +178 -0
  8. data/docs/img/lttb_example.png +0 -0
  9. data/docs/img/lttb_sql_vs_ruby.gif +0 -0
  10. data/docs/img/lttb_zoom.gif +0 -0
  11. data/docs/index.md +61 -0
  12. data/docs/migrations.md +69 -0
  13. data/docs/models.md +78 -0
  14. data/docs/toolkit.md +394 -0
  15. data/docs/toolkit_lttb_tutorial.md +557 -0
  16. data/docs/toolkit_lttb_zoom.md +357 -0
  17. data/docs/videos.md +16 -0
  18. data/examples/all_in_one/all_in_one.rb +39 -5
  19. data/examples/all_in_one/benchmark_comparison.rb +108 -0
  20. data/examples/all_in_one/caggs.rb +93 -0
  21. data/examples/all_in_one/query_data.rb +78 -0
  22. data/examples/toolkit-demo/compare_volatility.rb +64 -0
  23. data/examples/toolkit-demo/lttb/README.md +15 -0
  24. data/examples/toolkit-demo/lttb/lttb.rb +92 -0
  25. data/examples/toolkit-demo/lttb/lttb_sinatra.rb +139 -0
  26. data/examples/toolkit-demo/lttb/lttb_test.rb +21 -0
  27. data/examples/toolkit-demo/lttb/views/index.erb +27 -0
  28. data/examples/toolkit-demo/lttb-zoom/README.md +13 -0
  29. data/examples/toolkit-demo/lttb-zoom/lttb_zoomable.rb +90 -0
  30. data/examples/toolkit-demo/lttb-zoom/views/index.erb +33 -0
  31. data/lib/timescaledb/acts_as_time_vector.rb +18 -0
  32. data/lib/timescaledb/dimensions.rb +1 -0
  33. data/lib/timescaledb/hypertable.rb +5 -1
  34. data/lib/timescaledb/job_stats.rb +1 -0
  35. data/lib/timescaledb/migration_helpers.rb +11 -0
  36. data/lib/timescaledb/schema_dumper.rb +1 -1
  37. data/lib/timescaledb/stats_report.rb +1 -1
  38. data/lib/timescaledb/toolkit/helpers.rb +20 -0
  39. data/lib/timescaledb/toolkit/time_vector.rb +66 -0
  40. data/lib/timescaledb/toolkit.rb +3 -0
  41. data/lib/timescaledb/version.rb +1 -1
  42. data/lib/timescaledb.rb +1 -0
  43. data/mkdocs.yml +33 -0
  44. metadata +31 -4
  45. data/examples/all_in_one/Gemfile +0 -11
  46. data/examples/all_in_one/Gemfile.lock +0 -51
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d1fef5df000abb1cc12f56397a1e18f452bf35c061260cf403809db25954451a
4
- data.tar.gz: d00d7d94a33b52475a6e5415e7bab669be079f62b165abdb666764a907e34dc6
3
+ metadata.gz: 0367f44853d1cd4845a905e4692691baca381b739f9fb35f6a2aa471f350c946
4
+ data.tar.gz: b6bd9df57b80f6570f341f4842949092b367da03c5e9ba2edae6df6826288729
5
5
  SHA512:
6
- metadata.gz: 1b814e74e3403c5a0e12ed8d3e115aff9a44e67cf0eff46a94b396e5511c0ce7a316808b1cc563890e27892383e1d0c3358c97abb8f9f49577bc5c8b01fc3fe6
7
- data.tar.gz: ac250f31153249745e7db4ce3b7d7bbacaa25934dd7915a5a4b2aaf02595b5332344b890d1ee7a759b193f75c554bf101b7e0c492104f539edf7fa094fba133e
6
+ metadata.gz: 4e02cd458d020baeaa3658c20f6b502970f36772ef10f62162ad1028ad3ef7ab36943909815d3d6d04776d6cbbd8047f4705bfacbcc9315b89adaf516e54365c
7
+ data.tar.gz: 83f647f7814cf797155f599a3403e6641ea09edf6334f49f65279bed90c290686554b533eab852345367a0c76cf5f9a88d318d419fa46c9534aebb28a8922858
data/Fastfile ADDED
@@ -0,0 +1,17 @@
1
+
2
+ # Use `fast .version_up` to rewrite the version file
3
+ Fast.shortcut :version_up do
4
+ rewrite_file('(casgn nil VERSION (str _)', 'lib/timescaledb/version.rb') do |node|
5
+ target = node.children.last.loc.expression
6
+ pieces = target.source.split('.').map(&:to_i)
7
+ pieces.reverse.each_with_index do |fragment, i|
8
+ if fragment < 9
9
+ pieces[-(i + 1)] = fragment + 1
10
+ break
11
+ else
12
+ pieces[-(i + 1)] = 0
13
+ end
14
+ end
15
+ replace(target, "'#{pieces.join('.')}'")
16
+ end
17
+ end
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- timescaledb (0.2.1)
4
+ timescaledb (0.2.3)
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.3.1)
36
+ pg (1.4.4)
37
37
  pry (0.14.1)
38
38
  coderay (~> 1.1)
39
39
  method_source (~> 1.0)
data/README.md CHANGED
@@ -29,7 +29,7 @@ tsdb postgres://<user>@localhost:5432/<dbname> --stats
29
29
  Or just check the stats:
30
30
 
31
31
  ```bash
32
- tsdb "postgres://jonatasdp@localhost:5432/timescaledb_test" --stats
32
+ tsdb "postgres://<user>@localhost:5432/timescaledb_test" --stats
33
33
  ```
34
34
 
35
35
  These is a sample output from database example with almost no data:
@@ -53,13 +53,13 @@ as the example of database.
53
53
 
54
54
 
55
55
  ```bash
56
- psql postgres://jonatasdp@localhost:5432/playground -f caggs.sql
56
+ psql postgres://<user>@localhost:5432/playground -f caggs.sql
57
57
  ```
58
58
 
59
59
  Then use `tsdb` in the command line with the same URI and `--stats`:
60
60
 
61
61
  ```bash
62
- tsdb postgres://jonatasdp@localhost:5432/playground --stats
62
+ tsdb postgres://<user>@localhost:5432/playground --stats
63
63
  {:hypertables=>
64
64
  {:count=>1,
65
65
  :uncompressed=>1,
@@ -80,7 +80,7 @@ the context has a hypertable named `ticks` and a view named `ohlc_1m`.
80
80
 
81
81
 
82
82
  ```ruby
83
- tsdb postgres://jonatasdp@localhost:5432/playground --console
83
+ tsdb postgres://<user>@localhost:5432/playground --console
84
84
  pry(Timescale)>
85
85
  ```
86
86
 
@@ -223,6 +223,19 @@ You can check the [all_in_one.rb](examples/all_in_one/all_in_one.rb) example tha
223
223
  6. Check chunk status
224
224
  7. Decompress a chunk
225
225
 
226
+ ### Toolkit
227
+
228
+ Toolkit contains a lot of extra features to analyse data more deeply directly in
229
+ the SQL. There are a few examples in the [examples/toolkit-demo](examples/toolkit-demo)
230
+ folder that can let you benchmark and see the differences between implementing
231
+ the algorithm directly in Ruby or directly in SQL using the [Timescaledb
232
+ Toolkit](https://github.com/timescale/timescaledb-toolkit) extension.
233
+
234
+ For now you can benchmark and compare:
235
+
236
+ 1. [volatility](examples/toolkit-demo/compare_volatility.rb) algorithm.
237
+ 2. [lttb](examples/toolkit-demo/lttb/lttb_sinatra.rb) algorithm.
238
+
226
239
  ### Testing
227
240
 
228
241
  If you need some inspiration for how are you going to test your hypertables,
@@ -360,7 +373,17 @@ To get compression settings for all hypertables: `Timescaledb.compression_settin
360
373
 
361
374
  ### Scopes
362
375
 
363
- When you enable ActsAsHypertable on your model, we include a couple default scopes. They are:
376
+ The `acts_as_hypertable` macro can be very useful to generate some extra scopes
377
+ for you. Example of a weather condition:
378
+
379
+ ```ruby
380
+ class Condition < ActiveRecord::Base
381
+ acts_as_hypertable time_column: "time"
382
+ end
383
+ ```
384
+
385
+ Through the [ActsAsHypertable](./lib/timescaledb/acts_as_hypertable) on the model,
386
+ a few scopes are created based on the `time_column` argument:
364
387
 
365
388
  | Scope name | What they return |
366
389
  |------------------------|---------------------------------------|
@@ -374,6 +397,16 @@ When you enable ActsAsHypertable on your model, we include a couple default scop
374
397
 
375
398
  All time-related scopes respect your application's timezone.
376
399
 
400
+ When you enable ActsAsTimeVector on your model, we include a couple default scopes. They are:
401
+
402
+ ```ruby
403
+ class Condition < ActiveRecord::Base
404
+ acts_as_time_vector time_column: "time",
405
+ value_column: "temperature",
406
+ segment_by: "device_id"
407
+ end
408
+ ```
409
+
377
410
  ## RSpec Hooks
378
411
 
379
412
  In case you want to use TimescaleDB on a Rails environment, you may have some
@@ -422,7 +455,7 @@ You can put some postgres URI directly as a parameter of
422
455
  `tsdb`. Here is an example from the console:
423
456
 
424
457
  ```bash
425
- tsdb "postgres://jonatasdp@localhost:5432/timescaledb_test"
458
+ tsdb "postgres://<user>@localhost:5432/timescaledb_test"
426
459
  ```
427
460
 
428
461
  ## More resources
@@ -442,12 +475,11 @@ You can watch all episodes here:
442
475
 
443
476
  Here is a list of functions that would be great to have:
444
477
 
445
- - [ ] Dump and Restore Timescale metadata - Like db/schema.rb but for Timescale configuration.
446
478
  - [ ] Add data nodes support
447
479
 
448
480
  ## Contributing
449
481
 
450
- Bug reports and pull requests are welcome on GitHub at https://github.com/jonatas/timescale. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/jonatas/timescale/blob/master/CODE_OF_CONDUCT.md).
482
+ Bug reports and pull requests are welcome on GitHub at https://github.com/jonatas/timescaledb. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/jonatas/timescaledb/blob/master/CODE_OF_CONDUCT.md).
451
483
 
452
484
  ## License
453
485
 
@@ -455,4 +487,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
455
487
 
456
488
  ## Code of Conduct
457
489
 
458
- Everyone interacting in the Timescale project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/jonatas/timescale/blob/master/CODE_OF_CONDUCT.md).
490
+ Everyone interacting in the Timescale project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/jonatas/timescaledb/blob/master/CODE_OF_CONDUCT.md).
data/bin/console CHANGED
@@ -25,4 +25,4 @@ Timescaledb::Hypertable.find_each do |hypertable|
25
25
  end
26
26
 
27
27
  require "pry"
28
- Pry.start(Timescale)
28
+ Pry.start(Timescaledb)
data/bin/tsdb CHANGED
@@ -9,7 +9,7 @@ Timescaledb::Hypertable.find_each do |hypertable|
9
9
  class_name = hypertable.hypertable_name.singularize.camelize
10
10
  model = Class.new(ActiveRecord::Base) do
11
11
  self.table_name = hypertable.hypertable_name
12
- acts_as_hypertable
12
+ acts_as_hypertable time_column: hypertable.main_dimension.column_name
13
13
  end
14
14
  Timescaledb.const_set(class_name, model)
15
15
  end
@@ -44,5 +44,5 @@ if ARGV.index("--stats")
44
44
  end
45
45
 
46
46
  if ARGV.index("--console")
47
- Pry.start(Timescale)
47
+ Pry.start(Timescaledb)
48
48
  end
@@ -0,0 +1,178 @@
1
+ # Command line application
2
+
3
+ When you install the gem locally, a new command line application named `tsdb` will be available on your command line.
4
+
5
+ ## The `tsdb` CLI
6
+
7
+ It accepts a Postgresql URI and some extra flags that can help you to get more info from your TimescaleDB server:
8
+
9
+ ```bash
10
+ tsdb <uri> --stats
11
+ ```
12
+
13
+ Where the `<uri>` is replaced with params from your connection like:
14
+
15
+ ```bash
16
+ tsdb postgres://<user>@localhost:5432/<dbname> --stats
17
+ ```
18
+
19
+ Or merely check the stats:
20
+
21
+ ```bash
22
+ tsdb "postgres://<user>@localhost:5432/timescaledb_test" --stats
23
+ ```
24
+
25
+ Here is a sample output from a database example with almost no data:
26
+
27
+ ```ruby
28
+ {:hypertables=>
29
+ {:count=>3,
30
+ :uncompressed=>2,
31
+ :chunks=>{:total=>1, :compressed=>0, :uncompressed=>1},
32
+ :size=>{:befoe_compressing=>"80 KB", :after_compressing=>"0 Bytes"}},
33
+ :continuous_aggregates=>{:count=>1},
34
+ :jobs_stats=>[{:success=>nil, :runs=>nil, :failures=>nil}]}
35
+ ```
36
+
37
+ To start a interactive ruby/[pry](https://github.com/pry/pry) console use `--console`:
38
+ The console will dynamically create models for all hypertables that it finds
39
+ in the database.
40
+
41
+ Let's consider the [caggs.sql](https://gist.github.com/jonatas/95573ad8744994094ec9f284150004f9#file-caggs-sql) as the example of a database.
42
+
43
+
44
+ ```bash
45
+ psql postgres://<user>@localhost:5432/playground -f caggs.sql
46
+ ```
47
+
48
+ Then use `tsdb` in the command line with the same URI and `--stats`:
49
+
50
+ ```ruby
51
+ tsdb postgres://<user>@localhost:5432/playground --stats
52
+ {:hypertables=>
53
+ {:count=>1,
54
+ :uncompressed=>1,
55
+ :approximate_row_count=>{"ticks"=>352},
56
+ :chunks=>{:total=>1, :compressed=>0, :uncompressed=>1},
57
+ :size=>{:uncompressed=>"88 KB", :compressed=>"0 Bytes"}},
58
+ :continuous_aggregates=>{:total=>1},
59
+ :jobs_stats=>[{:success=>nil, :runs=>nil, :failures=>nil}]}
60
+ ```
61
+
62
+ To have some interactive playground with the actual database using ruby, just
63
+ try the same command before changing from `--stats` to `--console`:
64
+
65
+ ### tsdb --console
66
+
67
+ We are using the same database from the previous example for this context which contains a hypertable named `ticks` and a view called `ohlc_1m`.
68
+
69
+
70
+ ```ruby
71
+ tsdb postgres://<user>@localhost:5432/playground --console
72
+ pry(Timescale)>
73
+ ```
74
+
75
+ The `tsdb` CLI will automatically create ActiveRecord models for hypertables and the continuous aggregates views.
76
+
77
+ ```ruby
78
+ Tick
79
+ => Timescaledb::Tick(time: datetime, symbol: string, price: decimal, volume: integer)
80
+ ```
81
+
82
+ Note that it's only created for this session and will never cache in the
83
+ library or any other place.
84
+
85
+ In this case, the `Tick` model comes from the `ticks` hypertable found in the database.
86
+ It contains several methods inherited from the `acts_as_hypertable` macro.
87
+
88
+ Let's start with the `.hypertable` method.
89
+
90
+ ```ruby
91
+ Tick.hypertable
92
+ => #<Timescaledb::Hypertable:0x00007fe99c258900
93
+ hypertable_schema: "public",
94
+ hypertable_name: "ticks",
95
+ owner: "jonatasdp",
96
+ num_dimensions: 1,
97
+ num_chunks: 1,
98
+ compression_enabled: false,
99
+ is_distributed: false,
100
+ replication_factor: nil,
101
+ data_nodes: nil,
102
+ tablespaces: nil>
103
+ ```
104
+
105
+ The core of the hypertables is the fragmentation of the data into chunks, the child tables that distribute the data. You can check all chunks directly from the hypertable relation.
106
+
107
+ ```ruby
108
+ Tick.hypertable.chunks
109
+ unknown OID 2206: failed to recognize type of 'primary_dimension_type'. It will cast as a String.
110
+ => [#<Timescaledb::Chunk:0x00007fe99c31b068
111
+ hypertable_schema: "public",
112
+ hypertable_name: "ticks",
113
+ chunk_schema: "_timescaledb_internal",
114
+ chunk_name: "_hyper_33_17_chunk",
115
+ primary_dimension: "time",
116
+ primary_dimension_type: "timestamp without time zone",
117
+ range_start: 1999-12-30 00:00:00 +0000,
118
+ range_end: 2000-01-06 00:00:00 +0000,
119
+ range_start_integer: nil,
120
+ range_end_integer: nil,
121
+ is_compressed: false,
122
+ chunk_tablespace: nil,
123
+ data_nodes: nil>]
124
+ ```
125
+
126
+ > Chunks are created by partitioning the hypertable data into one
127
+ > (or potentially multiple) dimensions. All hypertables are partitions by the
128
+ > values belonging to a time column, which may be in timestamp, date, or
129
+ > various integer forms. If the time partitioning interval is one day,
130
+ > for example, then rows with timestamps that belong to the same day are co-located
131
+ > within the same chunk, while rows belonging to different days belong to different chunks.
132
+ > Learn more [here](https://docs.timescale.com/timescaledb/latest/overview/core-concepts/hypertables-and-chunks/).
133
+
134
+ Another core concept of TimescaleDB is compression. With data partitioned, it
135
+ becomes very convenient to compress and decompress chunks independently.
136
+
137
+ ```ruby
138
+ Tick.hypertable.chunks.first.compress!
139
+ ActiveRecord::StatementInvalid: PG::FeatureNotSupported: ERROR: compression not enabled on "ticks"
140
+ DETAIL: It is not possible to compress chunks on a hypertable that does not have compression enabled.
141
+ HINT: Enable compression using ALTER TABLE with the timescaledb.compress option.
142
+ ```
143
+
144
+ As compression is not enabled, let's do it by executing plain SQL directly from the actual context. To borrow a connection, let's use the Tick object.
145
+
146
+ ```ruby
147
+ Tick.connection.execute("ALTER TABLE ticks SET (timescaledb.compress)") # => PG_OK
148
+ ```
149
+
150
+ And now, it's possible to compress and decompress:
151
+
152
+ ```ruby
153
+ Tick.hypertable.chunks.first.compress!
154
+ Tick.hypertable.chunks.first.decompress!
155
+ ```
156
+ Learn more about TimescaleDB compression [here](https://docs.timescale.com/timescaledb/latest/overview/core-concepts/compression/).
157
+
158
+ The `ohlc_1m` view is also available as an ActiveRecord:
159
+
160
+ ```ruby
161
+ Ohlc1m
162
+ => Timescaledb::Ohlc1m(bucket: datetime, symbol: string, open: decimal, high: decimal, low: decimal, close: decimal, volume: integer)
163
+ ```
164
+
165
+ And you can run any query as you do with regular active record queries.
166
+
167
+ ```ruby
168
+ Ohlc1m.order(bucket: :desc).last
169
+ => #<Timescaledb::Ohlc1m:0x00007fe99c2c38e0
170
+ bucket: 2000-01-01 00:00:00 UTC,
171
+ symbol: "SYMBOL",
172
+ open: 0.13e2,
173
+ high: 0.3e2,
174
+ low: 0.1e1,
175
+ close: 0.1e2,
176
+ volume: 27600>
177
+ ```
178
+
Binary file
Binary file
Binary file
data/docs/index.md ADDED
@@ -0,0 +1,61 @@
1
+ # The TimescaleDB Ruby Gem
2
+
3
+ Welcome to the TimescaleDB gem! To experiment with the code, start installing the
4
+ gem:
5
+
6
+ ## Installing
7
+
8
+ You can install the gem locally:
9
+
10
+ ```bash
11
+ gem install timescaledb
12
+ ```
13
+
14
+ Or require it directly in the Gemfile of your project:
15
+
16
+ ```ruby
17
+ gem "timescaledb"
18
+ ```
19
+
20
+ ## Features
21
+
22
+ * The model can use the [acts_as_hypertable](https://github.com/jonatas/timescaledb/tree/master/lib/timescaledb/acts_as_hypertable.rb) macro. Check more on [models](models) documentation.
23
+ * The ActiveRecord [migrations](migrations) can use the [create_table](https://github.com/jonatas/timescaledb/tree/master/lib/timescaledb/migration_helpers.rb) supporting the `hypertable` keyword. It's also enabling you to add retention and continuous aggregates policies
24
+ * A standalone `create_hypertable` macro is also allowed in the migrations.
25
+ * Testing also becomes easier as the [schema dumper](https://github.com/jonatas/timescaledb/tree/master/lib/timescaledb/schema_dumper.rb) will automatically introduce the hypertables to all environments.
26
+ * It also contains a [scenic extension](https://github.com/jonatas/timescaledb/tree/master/lib/timescaledb/scenic/extension.rb) to work with [scenic views](https://github.com/scenic-views/scenic) as it's a wide adoption in the community.
27
+ * The gem is also packed with a [command line utility](command_line) that makes it easier to navigate in your database with Pry and all your hypertables available in a Ruby style.
28
+
29
+ ## Examples
30
+
31
+ The [all_in_one](https://github.com/jonatas/timescaledb/tree/master/examples/all_in_one/all_in_one.rb) example shows:
32
+
33
+ 1. Create a hypertable with compression settings
34
+ 2. Insert data
35
+ 3. Run some queries
36
+ 4. Check chunk size per model
37
+ 5. Compress a chunk
38
+ 6. Check chunk status
39
+ 7. Decompress a chunk
40
+
41
+ The [ranking](https://github.com/jonatas/timescaledb/tree/master/examples/ranking) example shows how to configure a Rails app and navigate all the features available.
42
+
43
+ ## Extra resources
44
+
45
+ If you need extra help, please join the fantastic [timescale community](https://www.timescale.com/community)
46
+ or ask your question on [StackOverflow](https://stackoverflow.com/questions/tagged/timescaledb) using the `#timescaledb` tag.
47
+
48
+ If you want to go deeper in the library, the [videos](videos) links to all
49
+ live-coding sessions showed how [@jonatasdp](https://twitter.com/jonatasdp) built the gem.
50
+
51
+ ## Contributing
52
+
53
+ Bug reports and pull requests are welcome on GitHub at https://github.com/jonatas/timescaledb. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/jonatas/timescaledb/blob/master/CODE_OF_CONDUCT.md).
54
+
55
+ ## License
56
+
57
+ The gem is available as open source under the [MIT License](https://opensource.org/licenses/MIT).
58
+
59
+ ## Code of Conduct
60
+
61
+ Everyone interacting in the Timescale project's codebases, issue trackers, chat rooms, and mailing lists is expected to follow the [code of conduct](https://github.com/jonatas/timescaledb/blob/master/CODE_OF_CONDUCT.md).
@@ -0,0 +1,69 @@
1
+ # ActiveRecord migrations helpers for Timescale
2
+
3
+ Create table is now with the `hypertable` keyword allowing to pass a few options
4
+ to the function call while also using the `create_table` method:
5
+
6
+ ## create_table with the `:hypertable` option
7
+
8
+ ```ruby
9
+ hypertable_options = {
10
+ time_column: 'created_at',
11
+ chunk_time_interval: '1 min',
12
+ compress_segmentby: 'identifier',
13
+ compression_interval: '7 days'
14
+ }
15
+
16
+ create_table(:events, id: false, hypertable: hypertable_options) do |t|
17
+ t.string :identifier, null: false
18
+ t.jsonb :payload
19
+ t.timestamps
20
+ end
21
+ ```
22
+
23
+ ## The `create_continuous_aggregate` helper
24
+
25
+ This example shows a ticks table grouping ticks as OHLCV histograms for every
26
+ minute.
27
+
28
+ ```ruby
29
+ hypertable_options = {
30
+ time_column: 'created_at',
31
+ chunk_time_interval: '1 min',
32
+ compress_segmentby: 'symbol',
33
+ compress_orderby: 'created_at',
34
+ compression_interval: '7 days'
35
+ }
36
+ create_table :ticks, hypertable: hypertable_options, id: false do |t|
37
+ t.string :symbol
38
+ t.decimal :price
39
+ t.integer :volume
40
+ t.timestamps
41
+ end
42
+ Tick = Class.new(ActiveRecord::Base) do
43
+ self.table_name = 'ticks'
44
+ self.primary_key = 'symbol'
45
+ acts_as_hypertable
46
+ end
47
+
48
+ query = Tick.select(<<~QUERY)
49
+ time_bucket('1m', created_at) as time,
50
+ symbol,
51
+ FIRST(price, created_at) as open,
52
+ MAX(price) as high,
53
+ MIN(price) as low,
54
+ LAST(price, created_at) as close,
55
+ SUM(volume) as volume").group("1,2")
56
+ QUERY
57
+
58
+ options = {
59
+ with_data: false,
60
+ refresh_policies: {
61
+ start_offset: "INTERVAL '1 month'",
62
+ end_offset: "INTERVAL '1 minute'",
63
+ schedule_interval: "INTERVAL '1 minute'"
64
+ }
65
+ }
66
+
67
+ create_continuous_aggregate('ohlc_1m', query, **options)
68
+ ```
69
+
data/docs/models.md ADDED
@@ -0,0 +1,78 @@
1
+ # Models
2
+
3
+ The ActiveRecord is the default ORM in the Ruby community. We have introduced a macro that helps you to inject the behavior as other libraries do in the Rails ecosystem.
4
+
5
+ ## The `acts_as_hypertable` macro
6
+
7
+ You can declare a Rails model as a Hypertable by invoking the `acts_as_hypertable` macro. This macro extends your existing model with timescaledb-related functionality.
8
+ model:
9
+
10
+ ```ruby
11
+ class Event < ActiveRecord::Base
12
+ acts_as_hypertable
13
+ end
14
+ ```
15
+
16
+ By default, ActsAsHypertable assumes a record's _time_column_ is called `created_at`.
17
+
18
+ ### Options
19
+
20
+ If you are using a different time_column name, you can specify it as follows when invoking the `acts_as_hypertable` macro:
21
+
22
+ ```ruby
23
+ class Event < ActiveRecord::Base
24
+ acts_as_hypertable time_column :timestamp
25
+ end
26
+ ```
27
+
28
+ ### Chunks
29
+
30
+ To get all the chunks from a model's hypertable, you can use `.chunks`.
31
+
32
+ ```ruby
33
+ Event.chunks # => [#<Timescaledb::Chunk>, ...]
34
+ ```
35
+
36
+ ### Hypertable metadata
37
+
38
+ To get the models' hypertable metadata, you can use `.hypertable`.
39
+
40
+ ```ruby
41
+ Event.hypertable # => #<Timescaledb::Hypertable>
42
+ ```
43
+
44
+ To get hypertable metadata for all hypertables: `Timescaledb.hypertables`.
45
+
46
+ ### Compression Settings
47
+
48
+ Compression settings are accessible through the hypertable.
49
+
50
+ ```ruby
51
+ Event.hypertable.compression_settings # => [#<Timescaledb::CompressionSettings>, ...]
52
+ ```
53
+
54
+ To get compression settings for all hypertables: `Timescaledb.compression_settings`.
55
+
56
+ ### Scopes
57
+
58
+ When you enable ActsAsHypertable on your model, we include a few default scopes. They are:
59
+
60
+ | Scope name | What they return |
61
+ |------------------------|---------------------------------------|
62
+ | `Model.previous_month` | Records created in the previous month |
63
+ | `Model.previous_week` | Records created in the previous week |
64
+ | `Model.this_month` | Records created this month |
65
+ | `Model.this_week` | Records created this week |
66
+ | `Model.yesterday` | Records created yesterday |
67
+ | `Model.today` | Records created today |
68
+ | `Model.last_hour` | Records created in the last hour |
69
+
70
+ All time-related scopes respect your application's timezone.
71
+
72
+
73
+ ## Scenic integration
74
+
75
+ The [Scenic](https://github.com/scenic-views/scenic) gem is easy to
76
+ manage database view definitions for a Rails application. Unfortunately, TimescaleDB's continuous aggregates are more complex than regular PostgreSQL views, and the schema dumper included with Scenic can't dump a complete definition.
77
+
78
+ This gem automatically configures Scenic to use a `Timescaledb::Scenic::Adapter.` which will correctly handle schema dumping.