sequel-schema-sharding 0.5.1 → 0.6.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
2
  SHA1:
3
- metadata.gz: e8da54e7c94ed8f3eda67c2be550c95aa722bfd3
4
- data.tar.gz: 047620efbb7536b0a187b50e3d276d46539012e9
3
+ metadata.gz: fa175ac4af8322937a21fda859150649e9872091
4
+ data.tar.gz: dc40633aa45cc01bd5747610db19dffc2cd80463
5
5
  SHA512:
6
- metadata.gz: 21e6938c04438c694bd04173cf53a0b7bd9d3c6677b4477909908e750e279e3b97b39984992d94feff45f7969775b1b5224ff8d2cb17aaa2e1ae41c276eb6b88
7
- data.tar.gz: 8b67577bcdf9dd92391d78a6bafca000724560e96fa11b2ceec025cbc22ceb2d0fb15a585d365d0e1bc39cc5ed5eaadf2edebbda67dddc6da4e5f60d5df40cc1
6
+ metadata.gz: 767a816353d1ecc7ed2052c2e8885f5a19e79aac06d47e77ca92043a532c409862350b50a40310cc292c97a4757d0a9fffaf91a85f1d7eea34f183d6c49a6a58
7
+ data.tar.gz: e4404c3e64c7883212fbbcecf49ef585a6c6544d16264e9c1633c9eedd7069691a6895b42152c26ca78bb3ee988b194557b0ffdec400b78ce257069260c64f0e
@@ -1,12 +1,13 @@
1
+ require 'logger'
2
+ require 'sequel'
1
3
  require 'sequel/schema-sharding/version'
2
4
  require 'sequel/schema-sharding/configuration'
3
5
  require 'sequel/schema-sharding/connection_manager'
4
6
  require 'sequel/schema-sharding/database_manager'
5
7
  require 'sequel/schema-sharding/ring'
6
8
  require 'sequel/schema-sharding/finder'
7
- require 'sequel/schema-sharding/sequel_ext'
9
+ require 'sequel/schema-sharding/monkey_patching'
8
10
  require 'sequel/schema-sharding/model'
9
- require 'logger'
10
11
  require 'sequel/schema-sharding/logger_proxy'
11
12
 
12
13
  module Sequel
@@ -56,13 +56,11 @@ module Sequel
56
56
 
57
57
  def create_shards
58
58
  config.table_names.each do |table_name|
59
- config.logical_shard_configs(table_name).each_pair do |shard_number, physical_shard|
60
- schema_name = connection_manager.schema_for(table_name, shard_number)
61
- Sequel::SchemaSharding.logger.info "Creating schema #{schema_name} on #{physical_shard}.."
62
- connection = connection_manager.master(physical_shard)
59
+ SchemaIterator.new.iterate_on(table_name) do |conn, schema_name, table_name|
60
+ Sequel::SchemaSharding.logger.warn "Creating schema #{schema_name}.."
63
61
 
64
62
  begin
65
- connection.run("CREATE SCHEMA #{schema_name}")
63
+ conn.run("CREATE SCHEMA #{schema_name}")
66
64
  rescue Sequel::DatabaseError => e
67
65
  if e.message.include?('already exists')
68
66
  $stderr.puts "#{schema_name} schema already exists"
@@ -71,26 +69,46 @@ module Sequel
71
69
  end
72
70
  end
73
71
 
74
- connection.run("SET search_path TO #{schema_name}")
75
-
76
- Sequel::Migrator.run(connection, Sequel::SchemaSharding.migration_path + "/#{table_name}", :use_transactions => true)
72
+ migrator_for(conn, schema_name, table_name).run
77
73
  end
78
74
  end
79
75
  end
80
76
 
81
77
  def drop_shards
82
78
  config.table_names.each do |table_name|
83
- config.logical_shard_configs(table_name).each_pair do |shard_number, physical_shard|
84
- schema_name = connection_manager.schema_for(table_name, shard_number)
85
- Sequel::SchemaSharding.logger.info "Dropping schema #{schema_name} on #{physical_shard}.."
86
- connection = connection_manager[physical_shard]
87
- connection.run("DROP SCHEMA #{schema_name} CASCADE")
79
+ SchemaIterator.new.iterate_on(table_name) do |conn, schema_name, table_name|
80
+ Sequel::SchemaSharding.logger.warn "Dropping schema #{schema_name}.."
81
+ conn.run("DROP SCHEMA #{schema_name} CASCADE")
88
82
  end
89
83
  end
90
84
  end
91
85
 
86
+ def migrate(table_name, migration_options = {})
87
+ SchemaIterator.new.iterate_on(table_name) do |conn, schema_name, table_name|
88
+ Sequel::SchemaSharding.logger.warn "Migrating #{table_name} in schema #{schema_name}.."
89
+ migrator_for(conn, schema_name, table_name, migration_options).run
90
+ end
91
+ end
92
+
93
+ def rollback(table_name, migration_options = {})
94
+ SchemaIterator.new.iterate_on(table_name) do |conn, schema_name, table_name|
95
+ Sequel::SchemaSharding.logger.warn "Rolling back #{table_name} in schema #{schema_name}.."
96
+ migrator = migrator_for(conn, schema_name, table_name, {direction: :down}.merge(migration_options))
97
+ # :((((((((((((((((((((((
98
+ migrator.instance_variable_set(:@target, migrator.current - 1)
99
+ migrator.instance_variable_set(:@direction, :down)
100
+ migrator.run
101
+ end
102
+ end
103
+
92
104
  private
93
105
 
106
+ def migrator_for(connection, schema, table_name, options = {})
107
+ path = Sequel::SchemaSharding.migration_path + "/#{table_name}"
108
+ connection.migration_current_schema = schema
109
+ Sequel::Migrator.migrator_class(path).new(connection, path, { table: connection.migration_schema_for_table(:schema_info)}.merge(options))
110
+ end
111
+
94
112
  def env
95
113
  config.env
96
114
  end
@@ -105,3 +123,5 @@ module Sequel
105
123
  end
106
124
  end
107
125
  end
126
+
127
+ require 'sequel/schema-sharding/database_manager/schema_iterator'
@@ -0,0 +1,20 @@
1
+ class Sequel::SchemaSharding::DatabaseManager::SchemaIterator
2
+ def iterate_on(table_name, &block)
3
+ config.logical_shard_configs(table_name).each_pair do |shard_number, physical_shard|
4
+ schema_name = connection_manager.schema_for(table_name, shard_number)
5
+ connection = connection_manager.master(physical_shard)
6
+
7
+ yield connection, schema_name, table_name
8
+ end
9
+ end
10
+
11
+ private
12
+
13
+ def config
14
+ Sequel::SchemaSharding.config
15
+ end
16
+
17
+ def connection_manager
18
+ Sequel::SchemaSharding.connection_manager
19
+ end
20
+ end
@@ -0,0 +1,26 @@
1
+ # These are non-nasty (hopefully) extensions to the sequel
2
+ # migration code to support explicitly passing Postgres schemas.
3
+
4
+ module Sequel
5
+ module SchemaSharding
6
+ module Extensions
7
+ module MigrationsExt
8
+ def self.included(base)
9
+ base.class_eval do
10
+ attr_accessor :migration_current_schema
11
+ end
12
+ end
13
+
14
+ def migration_schema_for_table(table)
15
+ :"#{migration_current_schema}__#{table}"
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ module Sequel
23
+ class Database
24
+ include Sequel::SchemaSharding::Extensions::MigrationsExt
25
+ end
26
+ end
@@ -0,0 +1,16 @@
1
+ module Sequel
2
+ module SchemaSharding
3
+ module Extensions
4
+ module SequelExt
5
+ module ClassMethods
6
+ def db
7
+ return @db if @db
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
14
+
15
+ Sequel::Model.plugin Sequel::SchemaSharding::Extensions::SequelExt
16
+ Sequel::Model.plugin :validation_helpers
@@ -0,0 +1,2 @@
1
+ require 'sequel/schema-sharding/extensions/migrations_ext'
2
+ require 'sequel/schema-sharding/extensions/sequel_ext'
@@ -1,5 +1,5 @@
1
1
  module Sequel
2
2
  module SchemaSharding
3
- VERSION = "0.5.1"
3
+ VERSION = "0.6.0"
4
4
  end
5
5
  end
@@ -1,6 +1,6 @@
1
1
  Sequel.migration do
2
2
  up do
3
- create_table(:artists) do
3
+ create_table(migration_schema_for_table(:artists)) do
4
4
  primary_key :id
5
5
  Integer :artist_id
6
6
  String :name, :null=>false
@@ -1,6 +1,6 @@
1
1
  Sequel.migration do
2
2
  up do
3
- create_table(:boofs) do
3
+ create_table(migration_schema_for_table(:boofs)) do
4
4
  primary_key :id
5
5
  String :name, :null=>false
6
6
  end
@@ -0,0 +1,9 @@
1
+ Sequel.migration do
2
+ up do
3
+ add_index(migration_schema_for_table(:artists), :name, concurrently: true)
4
+ end
5
+
6
+ down do
7
+ drop_index(migration_schema_for_table(:artists), :name, concurrently: true)
8
+ end
9
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe Sequel::SchemaSharding::DatabaseManager::SchemaIterator do
4
+ subject { Sequel::SchemaSharding::DatabaseManager::SchemaIterator.new }
5
+
6
+ describe '#iterate_on' do
7
+ let(:expector) { stub }
8
+
9
+ it 'calls the given block with the connection, schema, and table name for each shard' do
10
+ expector.expects(:boom).times(20).with(kind_of(Sequel::Database), kind_of(String), 'artists')
11
+
12
+ subject.iterate_on('artists') do |*args|
13
+ expector.boom(*args)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -121,4 +121,37 @@ describe Sequel::SchemaSharding::DatabaseManager, type: :manager, sharded: true
121
121
  end
122
122
  end
123
123
  end
124
+
125
+ describe 'schema migrations' do
126
+ before(:each) do
127
+ @manager.create_databases
128
+ @manager.create_shards
129
+ end
130
+
131
+ before do
132
+ Sequel::SchemaSharding.migration_path = "spec/fixtures/db/other_migrate"
133
+ end
134
+
135
+ after do
136
+ Sequel::SchemaSharding.migration_path = "spec/fixtures/db/migrate"
137
+ end
138
+
139
+ describe '#migrate' do
140
+ it 'runs migrations against the table on all schemas' do
141
+ expect(DatabaseHelper.index_count('shard1', 'sequel_explosions_artists_01', 'artists', 'name')).to eq(0)
142
+ @manager.migrate('artists', allow_missing_migration_files: true, use_transactions: false, current: 1)
143
+ expect(DatabaseHelper.index_count('shard1', 'sequel_explosions_artists_01', 'artists', 'name')).to eq(1)
144
+ end
145
+ end
146
+
147
+ describe '#rollback' do
148
+ it 'runs migrations against the table on all schemas' do
149
+ expect(DatabaseHelper.index_count('shard1', 'sequel_explosions_artists_01', 'artists', 'name')).to eq(0)
150
+ @manager.migrate('artists', allow_missing_migration_files: true, use_transactions: false, current: 1)
151
+ expect(DatabaseHelper.index_count('shard1', 'sequel_explosions_artists_01', 'artists', 'name')).to eq(1)
152
+ @manager.rollback('artists', allow_missing_migration_files: true, use_transactions: false, current: 1)
153
+ expect(DatabaseHelper.index_count('shard1', 'sequel_explosions_artists_01', 'artists', 'name')).to eq(0)
154
+ end
155
+ end
156
+ end
124
157
  end
@@ -29,6 +29,12 @@ class DatabaseHelper
29
29
  schemas(database).include?(schema)
30
30
  end
31
31
 
32
+ def self.index_count(database, schema, table, column)
33
+ Sequel::SchemaSharding.connection_manager[database]
34
+ .fetch("select * from pg_catalog.pg_indexes where tablename = '#{table}' and schemaname = '#{schema}' and indexdef LIKE '%#{column}%'")
35
+ .count
36
+ end
37
+
32
38
  def self.schemas(database)
33
39
  Sequel::SchemaSharding.connection_manager[database].fetch('select nspname from pg_catalog.pg_namespace;').all.map { |d| d[:nspname] }
34
40
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sequel-schema-sharding
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Henry
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-10-16 00:00:00.000000000 Z
13
+ date: 2013-10-22 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: sequel
@@ -108,19 +108,24 @@ files:
108
108
  - lib/sequel/schema-sharding/configuration.rb
109
109
  - lib/sequel/schema-sharding/connection_manager.rb
110
110
  - lib/sequel/schema-sharding/database_manager.rb
111
+ - lib/sequel/schema-sharding/database_manager/schema_iterator.rb
112
+ - lib/sequel/schema-sharding/extensions/migrations_ext.rb
113
+ - lib/sequel/schema-sharding/extensions/sequel_ext.rb
111
114
  - lib/sequel/schema-sharding/finder.rb
112
115
  - lib/sequel/schema-sharding/logger_proxy.rb
113
116
  - lib/sequel/schema-sharding/model.rb
117
+ - lib/sequel/schema-sharding/monkey_patching.rb
114
118
  - lib/sequel/schema-sharding/ring.rb
115
- - lib/sequel/schema-sharding/sequel_ext.rb
116
119
  - lib/sequel/schema-sharding/version.rb
117
120
  - lib/sequel/tasks/test.rake
118
121
  - sequel-schema-sharding.gemspec
119
122
  - spec/fixtures/db/migrate/artists/001_create_test_table.rb
120
123
  - spec/fixtures/db/migrate/boof/001_create_boof_table.rb
124
+ - spec/fixtures/db/other_migrate/artists/002_create_test_index.rb
121
125
  - spec/fixtures/test_db_config.yml
122
126
  - spec/schema-sharding/configuration_spec.rb
123
127
  - spec/schema-sharding/connection_manager_spec.rb
128
+ - spec/schema-sharding/database_manager/schema_iterator_spec.rb
124
129
  - spec/schema-sharding/database_manager_spec.rb
125
130
  - spec/schema-sharding/finder_spec.rb
126
131
  - spec/schema-sharding/model_spec.rb
@@ -154,9 +159,11 @@ summary: Create horizontally sharded Sequel models with Postgres
154
159
  test_files:
155
160
  - spec/fixtures/db/migrate/artists/001_create_test_table.rb
156
161
  - spec/fixtures/db/migrate/boof/001_create_boof_table.rb
162
+ - spec/fixtures/db/other_migrate/artists/002_create_test_index.rb
157
163
  - spec/fixtures/test_db_config.yml
158
164
  - spec/schema-sharding/configuration_spec.rb
159
165
  - spec/schema-sharding/connection_manager_spec.rb
166
+ - spec/schema-sharding/database_manager/schema_iterator_spec.rb
160
167
  - spec/schema-sharding/database_manager_spec.rb
161
168
  - spec/schema-sharding/finder_spec.rb
162
169
  - spec/schema-sharding/model_spec.rb
@@ -1,14 +0,0 @@
1
- module Sequel
2
- module SchemaSharding
3
- module SequelExt
4
- module ClassMethods
5
- def db
6
- return @db if @db
7
- end
8
- end
9
- end
10
- end
11
- end
12
-
13
- Sequel::Model.plugin Sequel::SchemaSharding::SequelExt
14
- Sequel::Model.plugin :validation_helpers