partitioner_pg 0.1.0 → 0.2.0

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
- SHA1:
3
- metadata.gz: b4fb71f05532ad74b92aed33d82c8ba773818fb6
4
- data.tar.gz: bac1502e2523fc7a3819feb15f427883d02cba79
2
+ SHA256:
3
+ metadata.gz: e30a831e9e29196be95988158811a18398422ae7bd0ad6301906778f4f1fcd0a
4
+ data.tar.gz: 134c8445b3610c98365fca4b0a066ef668b368592b4094c53479acca5961ef33
5
5
  SHA512:
6
- metadata.gz: ae342aa32bef1f79728cf5e4e8d700362f1b0f576e7b4bd9e82cbbee679f4d582cecee4a535c16ada96cbab5fa03a78c4cb066b7e33355dee4e4ac523819d5d5
7
- data.tar.gz: b0b9b211ae6db60edda1cb7cebf2f379fb3158dfdde81cc1d0f8c784330b817df80c386539cceaed43761a2a6680e5a150780fce6e08dbf68e3df17ac75537c6
6
+ metadata.gz: 7630fafde31ad687310dfce98bfa55719cf52038ec6a293be0bf484b875d0902f782d038ab188e8bfe823ac7f07f5d60295a476ad520d5d35e02ec71f5be2e6b
7
+ data.tar.gz: 2c940f85492295a3eb8cd23bc324c397991cd6bebacb0a360f7b07fcb3419bdd18defbf25f3f228e9a20c9ddf656b1d5ae3550b63d6222e3cf485d258bda7a71
data/README.md CHANGED
@@ -1,36 +1,79 @@
1
- # Partitioner
1
+ # PartitionerPg
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/partitioner`. To experiment with that code, run `bin/console` for an interactive prompt.
4
-
5
- TODO: Delete this and the text above, and describe your gem
3
+ It's a gem for a partitioning Postgresql tables in Ruby on Rails.
4
+ Now gem can help you with partitioning tables by months. New table for each month.
6
5
 
7
6
  ## Installation
8
7
 
9
8
  Add this line to your application's Gemfile:
10
9
 
11
10
  ```ruby
12
- gem 'partitioner'
11
+ gem 'partitioner_pg'
13
12
  ```
14
13
 
15
- And then execute:
16
-
17
- $ bundle
18
-
19
- Or install it yourself as:
20
-
21
- $ gem install partitioner
22
-
23
14
  ## Usage
24
15
 
25
- TODO: Write usage instructions here
26
-
27
- ## Development
16
+ 1) Include PartitionerPg into your model: `include PartitionerPg`. Also, you can specify parting column and some indexes.
17
+ Example:
18
+ ```ruby
19
+ class YourModelName < ActiveRecord::Base
20
+ include PartitionerPg
21
+
22
+ # Point date or datetime column which will be used for monthly partitioning. Optional (:created_at uses by default)
23
+ def self.parting_column
24
+ :date
25
+ end
26
+
27
+ # List of indexes. Names of indexes will be generated by active migration. Optional.
28
+ def self.partition_table_indexes
29
+ [
30
+ %w[column1 column2]
31
+ ]
32
+ end
33
+
34
+ # Map of indexes. Full name of named index will be generated as "index_[partition_name]_[name_of_index_from_map]". Optional.
35
+ def self.partition_table_named_indexes
36
+ {
37
+ :three_cols => %w[column1 column2 column3]
38
+ }
39
+ end
40
+
41
+ # List of unique indexes. Names of indexes wiil be generated by active migration. Optional.
42
+ def self.partition_table_unique_indexes
43
+ [
44
+ %w[column1 column2 column3 column4]
45
+ ]
46
+ end
47
+
48
+ # Map of named unique indexes. Optional.
49
+ def self.partition_table_named_unique_indexes
50
+ {
51
+ :uniq => %w[column5 column6 column7]
52
+ }
53
+ end
54
+ end
55
+ ```
56
+ 2) Create migration and add some instructions to it. Generate migration:
28
57
 
29
- After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
58
+ ```
59
+ rails g migration make_partitioning_of_you_table
60
+ ```
30
61
 
31
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
62
+ add instructions to migration:
32
63
 
33
- ## Contributing
64
+ ```ruby
65
+ class YouMigrationClassName
66
+ def change
67
+ YourModel.create_partitioning_by_month_trigger_sql
68
+ YourModel.create_month_table
69
+ YourModel.create_next_month_table
70
+ end
71
+ end
72
+ ```
34
73
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/partitioner. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
74
+ 3) For correct work you need to create next partition every month.
75
+ We recommend you to create a rake task and run it once a month by crontab. Code for a rake task:
36
76
 
77
+ ```ruby
78
+ YourModel.create_next_month_table
79
+ ```
@@ -12,12 +12,18 @@ module PartitionerPg
12
12
  def create_month_table(date=Date.today)
13
13
  date_start = date.at_beginning_of_month
14
14
  date_end = date.at_beginning_of_month.next_month
15
- sql = "CREATE TABLE IF NOT EXISTS #{name_of_partition_table(date)} (
16
- CHECK ( created_at >= DATE('#{date_start}') AND created_at < DATE('#{date_end}') )
15
+ partition_table_name = name_of_partition_table(date)
16
+ sql = "CREATE TABLE IF NOT EXISTS #{partition_table_name} (
17
+ CHECK ( #{parting_column} >= DATE('#{date_start}') AND #{parting_column} < DATE('#{date_end}') )
17
18
  ) INHERITS (#{table_name});"
18
19
  execute_sql(sql)
19
- sql = "ALTER TABLE #{name_of_partition_table(date)} ADD PRIMARY KEY (id);"
20
+ sql = "ALTER TABLE #{partition_table_name} ADD PRIMARY KEY (id);"
20
21
  execute_sql(sql)
22
+
23
+ create_partition_indexes(partition_table_name)
24
+ create_partition_named_indexes(partition_table_name)
25
+ create_partition_unique_indexes(partition_table_name)
26
+ create_partition_named_unique_indexes(partition_table_name)
21
27
  end
22
28
 
23
29
  def drop_month_table(date=Date.today)
@@ -33,8 +39,8 @@ module PartitionerPg
33
39
  curM varchar(2);
34
40
  tbl varchar(30);
35
41
  BEGIN
36
- select cast(DATE_PART('year', new.created_at) as varchar) into curY;
37
- select lpad(cast(DATE_PART('month', new.created_at) as varchar), 2, '0') into curM;
42
+ select cast(DATE_PART('year', new.#{parting_column}) as varchar) into curY;
43
+ select lpad(cast(DATE_PART('month', new.#{parting_column}) as varchar), 2, '0') into curM;
38
44
  tbl := '#{table_name}_y' || curY || 'm' || curM;
39
45
  EXECUTE format('INSERT into %I values ($1.*);', tbl) USING NEW;
40
46
  return NEW;
@@ -72,9 +78,76 @@ module PartitionerPg
72
78
  DROP FUNCTION #{table_name}_delete_trigger();"
73
79
  end
74
80
 
81
+ def create_partition_indexes(partition_table_name)
82
+ custom_indexes = partition_table_indexes.presence
83
+ return unless custom_indexes
84
+
85
+ custom_indexes.each { |custom_index| create_custom_index(partition_table_name, custom_index) }
86
+ end
87
+
88
+ def create_partition_named_indexes(partition_table_name)
89
+ custom_indexes = partition_table_named_indexes.presence
90
+ return unless custom_indexes
91
+
92
+ custom_indexes.map{|name, custom_index|
93
+ index_name = "index_#{partition_table_name}_#{name}"
94
+ create_custom_named_index(partition_table_name, custom_index, index_name)
95
+ }
96
+ end
97
+
98
+ def create_partition_unique_indexes(partition_table_name)
99
+ custom_unique_indexes = partition_table_unique_indexes.presence
100
+ return unless custom_unique_indexes
101
+
102
+ custom_unique_indexes.each { |custom_index| create_custom_index(partition_table_name, custom_index, true) }
103
+ end
104
+
105
+ def create_partition_named_unique_indexes(partition_table_name)
106
+ custom_indexes = partition_table_named_unique_indexes.presence
107
+ return unless custom_indexes
108
+
109
+ custom_indexes.map{|name, custom_index|
110
+ index_name = "index_#{partition_table_name}_#{name}"
111
+ create_custom_named_index(partition_table_name, custom_index, index_name, true)
112
+ }
113
+ end
114
+
115
+ def create_custom_index(table_name, index_fields, is_unique = false)
116
+ ActiveRecord::Migration.add_index table_name, index_fields, unique: is_unique
117
+ end
118
+
119
+ def create_custom_named_index(table_name, index_fields, name, is_unique = false)
120
+ ActiveRecord::Migration.add_index table_name, index_fields, name: name, unique: is_unique
121
+ end
122
+
75
123
  def name_of_partition_table(date=Date.today)
76
124
  date.strftime("#{table_name}_y%Ym%m")
77
125
  end
126
+
127
+ # Template method
128
+ # Column which will determine partition for row (must be date or datetime type). Default value is :created_at
129
+ def parting_column
130
+ :created_at
131
+ end
132
+
133
+ # Template method
134
+ def partition_table_indexes
135
+ #
136
+ end
137
+
138
+ def partition_table_named_indexes
139
+ #
140
+ end
141
+
142
+ # Template method
143
+ def partition_table_unique_indexes
144
+ #
145
+ end
146
+
147
+ # Template method
148
+ def partition_table_named_unique_indexes
149
+ #
150
+ end
78
151
  end
79
152
  end
80
153
  end
@@ -1,3 +1,3 @@
1
1
  module PartitionerPg
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: partitioner_pg
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aleksander Nikulin
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-08-24 00:00:00.000000000 Z
11
+ date: 2018-04-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -76,7 +76,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
76
76
  version: '0'
77
77
  requirements: []
78
78
  rubyforge_project:
79
- rubygems_version: 2.5.2
79
+ rubygems_version: 2.7.3
80
80
  signing_key:
81
81
  specification_version: 4
82
82
  summary: Gem for a partitoning PG tables