partitioner_pg 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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