schema_monkey 0.4.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (29) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +16 -3
  3. data/lib/schema_monkey.rb +28 -33
  4. data/lib/schema_monkey/core_extensions.rb +23 -0
  5. data/lib/schema_monkey/{active_record → core_extensions/active_record}/base.rb +4 -4
  6. data/lib/schema_monkey/{active_record → core_extensions/active_record}/connection_adapters/abstract_adapter.rb +3 -3
  7. data/lib/schema_monkey/{active_record → core_extensions/active_record}/connection_adapters/mysql2_adapter.rb +8 -8
  8. data/lib/schema_monkey/core_extensions/active_record/connection_adapters/postgresql_adapter.rb +30 -0
  9. data/lib/schema_monkey/{active_record → core_extensions/active_record}/connection_adapters/schema_statements.rb +9 -10
  10. data/lib/schema_monkey/{active_record → core_extensions/active_record}/connection_adapters/sqlite3_adapter.rb +8 -8
  11. data/lib/schema_monkey/{active_record → core_extensions/active_record}/connection_adapters/table_definition.rb +5 -5
  12. data/lib/schema_monkey/{active_record → core_extensions/active_record}/migration/command_recorder.rb +2 -2
  13. data/lib/schema_monkey/{active_record → core_extensions/active_record}/schema_dumper.rb +5 -5
  14. data/lib/schema_monkey/core_extensions/middleware.rb +62 -0
  15. data/lib/schema_monkey/tool.rb +43 -0
  16. data/lib/schema_monkey/{client.rb → tool/client.rb} +18 -12
  17. data/lib/schema_monkey/tool/errors.rb +4 -0
  18. data/lib/schema_monkey/{module.rb → tool/module.rb} +9 -2
  19. data/lib/schema_monkey/tool/monkey.rb +46 -0
  20. data/lib/schema_monkey/{rake.rb → tool/rake.rb} +1 -1
  21. data/lib/schema_monkey/tool/stack.rb +90 -0
  22. data/lib/schema_monkey/{tasks → tool/tasks}/insert.rake +0 -0
  23. data/lib/schema_monkey/version.rb +1 -1
  24. data/schema_monkey.gemspec +0 -1
  25. data/spec/middleware_spec.rb +95 -0
  26. data/spec/spec_helper.rb +6 -1
  27. metadata +23 -30
  28. data/lib/schema_monkey/active_record/connection_adapters/postgresql_adapter.rb +0 -30
  29. data/lib/schema_monkey/middleware.rb +0 -117
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 79b4b171241c85efd322e1110d21c832a3496ed8
4
- data.tar.gz: ffd34501fbe45a95ed29750639c4e1dca540e6f0
3
+ metadata.gz: 63717b66e73fd1bf6bd109a53e4a9923e47067b2
4
+ data.tar.gz: 86c7b56f67c7b9c54a816e90f6e4309e1d766e20
5
5
  SHA512:
6
- metadata.gz: 46d478aa24930337a10ce7fa4d672246fa6b6eb2c2ff214ed78eaa09ba6a8c84b751cdb6ba270bbc5efd0a14a4bcf7d262c0bb5ed8d045a361295d133488d9b0
7
- data.tar.gz: 4cc5f36af665873d97bc8d8a1e502d8b1564cb79e60597708fd11a97745f6dfd3d3866eeb5aefa09e5a4459ecfa8c6afce2119189d4643c8a84c36393ebeeea0
6
+ metadata.gz: 0146db8b1769a7b59f797bae5960c003f6cf59296681d381af3356e2f1c6d7e4dbe9223e36167dff098e1a0c2846131655a87f2ad5780cae0b5a0c4c8ae355ce
7
+ data.tar.gz: 140723e774bd68a0356bd64d041eaa8035c535f06b3ded87bbd2d642be72899f09a7babaefbdb449c5c2e35b225bbe5313fcb225b7169f5fa67e1dd4c0d1efc6
data/README.md CHANGED
@@ -11,7 +11,6 @@ SchemaMonkey is a behind-the-scenes gem to facilitate writing extensions to Acti
11
11
 
12
12
  * A convention-based protocol for `include`'ing custom modules into ActiveRecord. You just define your modules and SchemaMonkey will automatically include them in the right places.
13
13
 
14
- * (If you're using Rails) It takes care of setting up a Railtie appropriately to invoke the extensions.
15
14
 
16
15
  The middleware interface has two benefits: it provides a clean API so that the gem or aplication code doesn't need to monkey-patch ActiveRecord (SchemaMonkey does all the monkey-patching for you), and it lets multiple client gems operate in parallel without concern about conflicting monkey-patches.
17
16
 
@@ -30,6 +29,14 @@ gem "schema_monkey", "~> <MAJOR>.<MINOR>", ">= <MAJOR>.<MINOR>.<PATCH>"
30
29
 
31
30
  SchemaMonkey follows semantic versioning; it's a good idea to explicitly use the `~>` and `>=` dependencies to make sure your gem's clients don't accidentally pull in a version of SchemaMonkey that your gem isn't compatible with.
32
31
 
32
+ To use with a rails app, also include
33
+
34
+ ```ruby
35
+ gem "schema_monkey_rails"
36
+ ```
37
+
38
+ which creates a Railtie to insert SchemaMonkey appropriately into the rails stack.
39
+
33
40
  ## Compatibility
34
41
 
35
42
  SchemaMonkey is tested on:
@@ -44,7 +51,7 @@ SchemaMonkey is tested on:
44
51
  ## Usage
45
52
 
46
53
 
47
- **Sorry -- no real documentation yet. Too much is still in flux.**
54
+ **Sorry -- no real documentation yet. See examples in [schema_plus_indexes](https://github/SchemaPlus/schema_plus_indexes) and [schema_plus_pg_indexes](https://github/SchemaPlus/schema_plus_pg_indexes)**
48
55
 
49
56
 
50
57
 
@@ -55,7 +62,13 @@ the standard protocol: fork, feature branch, develop, push, and issue pull reque
55
62
 
56
63
  Some things to know about to help you develop and test:
57
64
 
58
- * **Ugh -- not many specs yet. SchemaMonkey is currently tested indirectly by testing the client gems that use it. Working on it...**
65
+ * SchemaMonkey is a wrapper around two subparts:
66
+
67
+ * `SchemaMonkey::Tool` provides the convention-based mechanism for registering clients that extend ActiveRecord using `include`'s and middleware.
68
+
69
+ * `SchemaMonkey::CoreExtensions` defines the ActiveRecord extension API. It is itself just the first client registered with `SchemaMonkey::Tool`. **Ugh. Currently no specs for `SchemaMonkey::CoreExtensions`; testing indirectly by testing the client gems that use it. Working on it...**
70
+
71
+ One day might actually split these into separate gems to decouple their development and testing. And actually the middleware mechanism of `SchemaMonkey::Tool` could be a split out separate gem.
59
72
 
60
73
  * **schema_dev**: SchemaMonkey uses [schema_dev](https://github.com/SchemaPlus/schema_dev) to
61
74
  facilitate running rspec tests on the matrix of ruby, rails, and database
@@ -1,45 +1,40 @@
1
- require 'hash_keyword_args'
2
- require 'its-it'
3
- require 'key_struct'
4
- require 'middleware'
5
- require 'active_record'
6
- require 'active_support/core_ext/string'
7
-
8
- require_relative "schema_monkey/client"
9
- require_relative "schema_monkey/middleware"
10
- require_relative "schema_monkey/module"
11
- require_relative "schema_monkey/active_record/base"
12
- require_relative "schema_monkey/active_record/connection_adapters/abstract_adapter"
13
- require_relative "schema_monkey/active_record/connection_adapters/table_definition"
14
- require_relative 'schema_monkey/active_record/connection_adapters/schema_statements'
15
- require_relative 'schema_monkey/active_record/migration/command_recorder'
16
- require_relative 'schema_monkey/active_record/schema_dumper'
17
- require_relative 'schema_monkey/rake'
1
+ require_relative "schema_monkey/core_extensions"
2
+ require_relative "schema_monkey/tool"
18
3
 
4
+ #
5
+ # Middleware contents will be created dynamically
6
+ #
19
7
  module SchemaMonkey
20
- extend Module
21
-
22
- DBMS = [:PostgreSQL, :Mysql, :SQLite3]
23
-
24
- module ActiveRecord
25
- module ConnectionAdapters
26
- autoload :PostgresqlAdapter, 'schema_monkey/active_record/connection_adapters/postgresql_adapter'
27
- autoload :Mysql2Adapter, 'schema_monkey/active_record/connection_adapters/mysql2_adapter'
28
- autoload :Sqlite3Adapter, 'schema_monkey/active_record/connection_adapters/sqlite3_adapter'
29
- end
8
+ module Middleware
30
9
  end
10
+ end
31
11
 
12
+ #
13
+ # Wrap public API of SchemaMonkey::Tool
14
+ #
15
+ module SchemaMonkey
32
16
  def self.register(mod)
33
- clients << Client.new(mod)
17
+ Tool::register(mod)
34
18
  end
35
19
 
36
- def self.clients
37
- @clients ||= [Client.new(self)]
20
+ def self.insert(opts={})
21
+ Tool::insert(opts)
38
22
  end
39
23
 
40
- def self.insert(opts={})
41
- opts = opts.keyword_args(:dbm)
42
- clients.each &it.insert(dbm: opts.dbm)
24
+ def self.include_once(*args)
25
+ Tool::Module.include_once(*args)
26
+ end
27
+
28
+ module Rake
29
+ def self.insert(*args)
30
+ Tool::Rake::insert(*args)
31
+ end
43
32
  end
44
33
 
34
+ MiddlewareError = Tool::MiddlewareError
45
35
  end
36
+
37
+ #
38
+ # Register CoreExtensions
39
+ #
40
+ SchemaMonkey::Tool.register(SchemaMonkey::CoreExtensions)
@@ -0,0 +1,23 @@
1
+ require 'active_record'
2
+ require 'key_struct'
3
+
4
+ module SchemaMonkey
5
+ module CoreExtensions
6
+ module ActiveRecord
7
+ module ConnectionAdapters
8
+ DIR = Pathname.new(__FILE__).dirname + 'core_extensions/active_record/connection_adapters'
9
+ autoload :PostgresqlAdapter, DIR + 'postgresql_adapter'
10
+ autoload :Mysql2Adapter, DIR + 'mysql2_adapter'
11
+ autoload :Sqlite3Adapter, DIR + 'sqlite3_adapter'
12
+ end
13
+ end
14
+ end
15
+ end
16
+
17
+ require_relative "core_extensions/active_record/base"
18
+ require_relative "core_extensions/active_record/connection_adapters/abstract_adapter"
19
+ require_relative "core_extensions/active_record/connection_adapters/table_definition"
20
+ require_relative 'core_extensions/active_record/connection_adapters/schema_statements'
21
+ require_relative 'core_extensions/active_record/migration/command_recorder'
22
+ require_relative 'core_extensions/active_record/schema_dumper'
23
+ require_relative "core_extensions/middleware"
@@ -1,4 +1,4 @@
1
- module SchemaMonkey
1
+ module SchemaMonkey::CoreExtensions
2
2
  module ActiveRecord
3
3
 
4
4
  module Base
@@ -15,13 +15,13 @@ module SchemaMonkey
15
15
  end
16
16
 
17
17
  def columns_with_schema_monkey
18
- Middleware::Model::Columns.start model: self, columns: [] do |env|
18
+ SchemaMonkey::Middleware::Model::Columns.start(model: self, columns: []) { |env|
19
19
  env.columns += columns_without_schema_monkey
20
- end
20
+ }.columns
21
21
  end
22
22
 
23
23
  def reset_column_information_with_schema_monkey
24
- Middleware::Model::ResetColumnInformation.start model: self do |env|
24
+ SchemaMonkey::Middleware::Model::ResetColumnInformation.start(model: self) do |env|
25
25
  reset_column_information_without_schema_monkey
26
26
  end
27
27
  end
@@ -1,4 +1,4 @@
1
- module SchemaMonkey
1
+ module SchemaMonkey::CoreExtensions
2
2
  module ActiveRecord
3
3
  module ConnectionAdapters
4
4
  module AbstractAdapter
@@ -27,9 +27,9 @@ module SchemaMonkey
27
27
  end
28
28
 
29
29
  def add_column_options_with_schema_monkey!(sql, options)
30
- Middleware::Migration::ColumnOptionsSql.start caller: self, connection: self.instance_variable_get('@conn'), sql: sql, options: options do |env|
30
+ SchemaMonkey::Middleware::Migration::ColumnOptionsSql.start(caller: self, connection: self.instance_variable_get('@conn'), sql: sql, options: options) { |env|
31
31
  add_column_options_without_schema_monkey! env.sql, env.options
32
- end
32
+ }.sql
33
33
  end
34
34
  end
35
35
  end
@@ -1,4 +1,4 @@
1
- module SchemaMonkey
1
+ module SchemaMonkey::CoreExtensions
2
2
  module ActiveRecord
3
3
  module ConnectionAdapters
4
4
  module Mysql2Adapter
@@ -8,21 +8,21 @@ module SchemaMonkey
8
8
  alias_method_chain :indexes, :schema_monkey
9
9
  alias_method_chain :tables, :schema_monkey
10
10
  end
11
- SchemaMonkey.include_once ::ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter, SchemaMonkey::ActiveRecord::ConnectionAdapters::SchemaStatements::Column
12
- SchemaMonkey.include_once ::ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter, SchemaMonkey::ActiveRecord::ConnectionAdapters::SchemaStatements::Reference
13
- SchemaMonkey.include_once ::ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter, SchemaMonkey::ActiveRecord::ConnectionAdapters::SchemaStatements::Index
11
+ SchemaMonkey.include_once ::ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter, SchemaMonkey::CoreExtensions::ActiveRecord::ConnectionAdapters::SchemaStatements::Column
12
+ SchemaMonkey.include_once ::ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter, SchemaMonkey::CoreExtensions::ActiveRecord::ConnectionAdapters::SchemaStatements::Reference
13
+ SchemaMonkey.include_once ::ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter, SchemaMonkey::CoreExtensions::ActiveRecord::ConnectionAdapters::SchemaStatements::Index
14
14
  end
15
15
 
16
16
  def indexes_with_schema_monkey(table_name, query_name=nil)
17
- Middleware::Query::Indexes.start connection: self, table_name: table_name, query_name: query_name, index_definitions: [] do |env|
17
+ SchemaMonkey::Middleware::Query::Indexes.start(connection: self, table_name: table_name, query_name: query_name, index_definitions: []) { |env|
18
18
  env.index_definitions += indexes_without_schema_monkey env.table_name, env.query_name
19
- end
19
+ }.index_definitions
20
20
  end
21
21
 
22
22
  def tables_with_schema_monkey(query_name=nil, database=nil, like=nil)
23
- Middleware::Query::Tables.start connection: self, query_name: query_name, database: database, like: like, tables: [] do |env|
23
+ SchemaMonkey::Middleware::Query::Tables.start(connection: self, query_name: query_name, database: database, like: like, tables: []) { |env|
24
24
  env.tables += tables_without_schema_monkey env.query_name, env.database, env.like
25
- end
25
+ }.tables
26
26
  end
27
27
  end
28
28
  end
@@ -0,0 +1,30 @@
1
+ module SchemaMonkey::CoreExtensions
2
+ module ActiveRecord
3
+ module ConnectionAdapters
4
+ module PostgresqlAdapter
5
+
6
+ def self.included(base)
7
+ base.class_eval do
8
+ alias_method_chain :exec_cache, :schema_monkey
9
+ alias_method_chain :indexes, :schema_monkey
10
+ end
11
+ SchemaMonkey.include_once ::ActiveRecord::ConnectionAdapters::SchemaStatements, SchemaMonkey::CoreExtensions::ActiveRecord::ConnectionAdapters::SchemaStatements::Reference
12
+ SchemaMonkey.include_once ::ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaStatements, SchemaMonkey::CoreExtensions::ActiveRecord::ConnectionAdapters::SchemaStatements::Column
13
+ SchemaMonkey.include_once ::ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaStatements, SchemaMonkey::CoreExtensions::ActiveRecord::ConnectionAdapters::SchemaStatements::Index
14
+ end
15
+
16
+ def exec_cache_with_schema_monkey(sql, name, binds)
17
+ SchemaMonkey::Middleware::Query::ExecCache.start(connection: self, sql: sql, name: name, binds: binds) { |env|
18
+ env.result = exec_cache_without_schema_monkey(env.sql, env.name, env.binds)
19
+ }.result
20
+ end
21
+
22
+ def indexes_with_schema_monkey(table_name, query_name=nil)
23
+ SchemaMonkey::Middleware::Query::Indexes.start(connection: self, table_name: table_name, query_name: query_name, index_definitions: []) { |env|
24
+ env.index_definitions += indexes_without_schema_monkey env.table_name, env.query_name
25
+ }.index_definitions
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -1,4 +1,4 @@
1
- module SchemaMonkey
1
+ module SchemaMonkey::CoreExtensions
2
2
  module ActiveRecord
3
3
  module ConnectionAdapters
4
4
  module SchemaStatements
@@ -13,13 +13,12 @@ module SchemaMonkey
13
13
  end
14
14
  end
15
15
 
16
+ IndexComponentsSql = KeyStruct[:name, :type, :columns, :options, :algorithm, :using]
17
+
16
18
  def add_index_options_with_schema_monkey(table_name, column_names, options={})
17
- cache = []
18
- Middleware::Migration::IndexComponentsSql.start connection: self, table_name: table_name, column_names: Array.wrap(column_names), options: options.deep_dup do |env|
19
- cache << env
19
+ env = SchemaMonkey::Middleware::Migration::IndexComponentsSql.start(connection: self, table_name: table_name, column_names: Array.wrap(column_names), options: options.deep_dup, sql: IndexComponentsSql.new) { |env|
20
20
  env.sql.name, env.sql.type, env.sql.columns, env.sql.options, env.sql.algorithm, env.sql.using = add_index_options_without_schema_monkey(env.table_name, env.column_names, env.options)
21
- end
22
- env = cache[0]
21
+ }
23
22
  [env.sql.name, env.sql.type, env.sql.columns, env.sql.options, env.sql.algorithm, env.sql.using]
24
23
  end
25
24
 
@@ -38,13 +37,13 @@ module SchemaMonkey
38
37
  end
39
38
 
40
39
  def add_column_with_schema_monkey(table_name, name, type, options = {})
41
- Middleware::Migration::Column.start caller: self, operation: :add, table_name: table_name, column_name: name, type: type, options: options.deep_dup do |env|
40
+ SchemaMonkey::Middleware::Migration::Column.start(caller: self, operation: :add, table_name: table_name, column_name: name, type: type, options: options.deep_dup) do |env|
42
41
  add_column_without_schema_monkey env.table_name, env.column_name, env.type, env.options
43
42
  end
44
43
  end
45
44
 
46
45
  def change_column_with_schema_monkey(table_name, name, type, options = {})
47
- Middleware::Migration::Column.start caller: self, operation: :change, table_name: table_name, column_name: name, type: type, options: options.deep_dup do |env|
46
+ SchemaMonkey::Middleware::Migration::Column.start(caller: self, operation: :change, table_name: table_name, column_name: name, type: type, options: options.deep_dup) do |env|
48
47
  change_column_without_schema_monkey env.table_name, env.column_name, env.type, env.options
49
48
  end
50
49
  end
@@ -57,7 +56,7 @@ module SchemaMonkey
57
56
  end
58
57
  end
59
58
  def add_reference_with_schema_monkey(table_name, name, options = {})
60
- Middleware::Migration::Column.start caller: self, operation: :add, table_name: table_name, column_name: "#{name}_id", type: :reference, options: options.deep_dup do |env|
59
+ SchemaMonkey::Middleware::Migration::Column.start(caller: self, operation: :add, table_name: table_name, column_name: "#{name}_id", type: :reference, options: options.deep_dup) do |env|
61
60
  add_reference_without_schema_monkey env.table_name, env.column_name.sub(/_id$/, ''), env.options
62
61
  end
63
62
  end
@@ -72,7 +71,7 @@ module SchemaMonkey
72
71
  def add_index_with_schema_monkey(*args)
73
72
  options = args.extract_options!
74
73
  table_name, column_names = args
75
- Middleware::Migration::Index.start caller: self, operation: :add, table_name: table_name, column_names: column_names, options: options.deep_dup do |env|
74
+ SchemaMonkey::Middleware::Migration::Index.start(caller: self, operation: :add, table_name: table_name, column_names: column_names, options: options.deep_dup) do |env|
76
75
  add_index_without_schema_monkey env.table_name, env.column_names, env.options
77
76
  end
78
77
  end
@@ -1,4 +1,4 @@
1
- module SchemaMonkey
1
+ module SchemaMonkey::CoreExtensions
2
2
  module ActiveRecord
3
3
  module ConnectionAdapters
4
4
  module Sqlite3Adapter
@@ -8,21 +8,21 @@ module SchemaMonkey
8
8
  alias_method_chain :indexes, :schema_monkey
9
9
  alias_method_chain :tables, :schema_monkey
10
10
  end
11
- SchemaMonkey.include_once ::ActiveRecord::ConnectionAdapters::SchemaStatements, SchemaMonkey::ActiveRecord::ConnectionAdapters::SchemaStatements::Column
12
- SchemaMonkey.include_once ::ActiveRecord::ConnectionAdapters::SchemaStatements, SchemaMonkey::ActiveRecord::ConnectionAdapters::SchemaStatements::Reference
13
- SchemaMonkey.include_once ::ActiveRecord::ConnectionAdapters::SchemaStatements, SchemaMonkey::ActiveRecord::ConnectionAdapters::SchemaStatements::Index
11
+ SchemaMonkey.include_once ::ActiveRecord::ConnectionAdapters::SchemaStatements, SchemaMonkey::CoreExtensions::ActiveRecord::ConnectionAdapters::SchemaStatements::Column
12
+ SchemaMonkey.include_once ::ActiveRecord::ConnectionAdapters::SchemaStatements, SchemaMonkey::CoreExtensions::ActiveRecord::ConnectionAdapters::SchemaStatements::Reference
13
+ SchemaMonkey.include_once ::ActiveRecord::ConnectionAdapters::SchemaStatements, SchemaMonkey::CoreExtensions::ActiveRecord::ConnectionAdapters::SchemaStatements::Index
14
14
  end
15
15
 
16
16
  def indexes_with_schema_monkey(table_name, query_name=nil)
17
- Middleware::Query::Indexes.start connection: self, table_name: table_name, query_name: query_name, index_definitions: [] do |env|
17
+ SchemaMonkey::Middleware::Query::Indexes.start(connection: self, table_name: table_name, query_name: query_name, index_definitions: []) { |env|
18
18
  env.index_definitions += indexes_without_schema_monkey env.table_name, env.query_name
19
- end
19
+ }.index_definitions
20
20
  end
21
21
 
22
22
  def tables_with_schema_monkey(query_name=nil, table_name=nil)
23
- Middleware::Query::Tables.start connection: self, query_name: query_name, table_name: table_name, tables: [] do |env|
23
+ SchemaMonkey::Middleware::Query::Tables.start(connection: self, query_name: query_name, table_name: table_name, tables: []) { |env|
24
24
  env.tables += tables_without_schema_monkey env.query_name, env.table_name
25
- end
25
+ }.tables
26
26
  end
27
27
 
28
28
  end
@@ -1,4 +1,4 @@
1
- module SchemaMonkey
1
+ module SchemaMonkey::CoreExtensions
2
2
  module ActiveRecord
3
3
  module ConnectionAdapters
4
4
  module TableDefinition
@@ -12,19 +12,19 @@ module SchemaMonkey
12
12
  end
13
13
 
14
14
  def column_with_schema_monkey(name, type, options = {})
15
- Middleware::Migration::Column.start caller: self, operation: :define, table_name: self.name, column_name: name, type: type, options: options.deep_dup do |env|
15
+ SchemaMonkey::Middleware::Migration::Column.start(caller: self, operation: :define, table_name: self.name, column_name: name, type: type, options: options.deep_dup) do |env|
16
16
  column_without_schema_monkey env.column_name, env.type, env.options
17
17
  end
18
18
  end
19
19
 
20
20
  def references_with_schema_monkey(name, options = {})
21
- Middleware::Migration::Column.start caller: self, operation: :define, table_name: self.name, column_name: "#{name}_id", type: :reference, options: options.deep_dup do |env|
21
+ SchemaMonkey::Middleware::Migration::Column.start(caller: self, operation: :define, table_name: self.name, column_name: "#{name}_id", type: :reference, options: options.deep_dup) do |env|
22
22
  references_without_schema_monkey env.column_name.sub(/_id$/, ''), env.options
23
23
  end
24
24
  end
25
25
 
26
26
  def belongs_to_with_schema_monkey(name, options = {})
27
- Middleware::Migration::Column.start caller: self, operation: :define, table_name: self.name, column_name: "#{name}_id", type: :reference, options: options.deep_dup do |env|
27
+ SchemaMonkey::Middleware::Migration::Column.start(caller: self, operation: :define, table_name: self.name, column_name: "#{name}_id", type: :reference, options: options.deep_dup) do |env|
28
28
  belongs_to_without_schema_monkey env.column_name.sub(/_id$/, ''), env.options
29
29
  end
30
30
  end
@@ -32,7 +32,7 @@ module SchemaMonkey
32
32
  def index_with_schema_monkey(*args)
33
33
  options = args.extract_options!
34
34
  column_name = args.first
35
- Middleware::Migration::Index.start caller: self, operation: :define, table_name: self.name, column_names: column_name, options: options.deep_dup do |env|
35
+ SchemaMonkey::Middleware::Migration::Index.start(caller: self, operation: :define, table_name: self.name, column_names: column_name, options: options.deep_dup) do |env|
36
36
  index_without_schema_monkey env.column_names, env.options
37
37
  end
38
38
  end
@@ -1,4 +1,4 @@
1
- module SchemaMonkey
1
+ module SchemaMonkey::CoreExtensions
2
2
  module ActiveRecord
3
3
  module Migration
4
4
  module CommandRecorder
@@ -9,7 +9,7 @@ module SchemaMonkey
9
9
  end
10
10
 
11
11
  def add_column_with_schema_monkey(table_name, column_name, type, options = {})
12
- Middleware::Migration::Column.start caller: self, operation: :record, table_name: table_name, column_name: column_name, type: type, options: options.deep_dup do |env|
12
+ SchemaMonkey::Middleware::Migration::Column.start(caller: self, operation: :record, table_name: table_name, column_name: column_name, type: type, options: options.deep_dup) do |env|
13
13
  add_column_without_schema_monkey env.table_name, env.column_name, env.type, env.options
14
14
  end
15
15
  end
@@ -1,7 +1,7 @@
1
1
  require 'ostruct'
2
2
  require 'tsort'
3
3
 
4
- module SchemaMonkey
4
+ module SchemaMonkey::CoreExtensions
5
5
  module ActiveRecord
6
6
  module SchemaDumper
7
7
 
@@ -157,7 +157,7 @@ module SchemaMonkey
157
157
  end
158
158
 
159
159
  def extensions_with_schema_monkey(_)
160
- Middleware::Dumper::Extensions.start dumper: self, connection: @connection, dump: @dump, extensions: @dump.extensions do |env|
160
+ SchemaMonkey::Middleware::Dumper::Extensions.start(dumper: self, connection: @connection, dump: @dump, extensions: @dump.extensions) do |env|
161
161
  stream = StringIO.new
162
162
  extensions_without_schema_monkey(stream)
163
163
  env.dump.extensions << stream.string unless stream.string.blank?
@@ -165,13 +165,13 @@ module SchemaMonkey
165
165
  end
166
166
 
167
167
  def tables_with_schema_monkey(_)
168
- Middleware::Dumper::Tables.start dumper: self, connection: @connection, dump: @dump do |env|
168
+ SchemaMonkey::Middleware::Dumper::Tables.start(dumper: self, connection: @connection, dump: @dump) do |env|
169
169
  tables_without_schema_monkey(nil)
170
170
  end
171
171
  end
172
172
 
173
173
  def table_with_schema_monkey(table, _)
174
- Middleware::Dumper::Table.start dumper: self, connection: @connection, dump: @dump, table: @dump.tables[table] = Dump::Table.new(name: table) do |env|
174
+ SchemaMonkey::Middleware::Dumper::Table.start(dumper: self, connection: @connection, dump: @dump, table: @dump.tables[table] = Dump::Table.new(name: table)) do |env|
175
175
  stream = StringIO.new
176
176
  table_without_schema_monkey(env.table.name, stream)
177
177
  m = stream.string.match %r{
@@ -204,7 +204,7 @@ module SchemaMonkey
204
204
  end
205
205
 
206
206
  def indexes_with_schema_monkey(table, _)
207
- Middleware::Dumper::Indexes.start dumper: self, connection: @connection, dump: @dump, table: @dump.tables[table] do |env|
207
+ SchemaMonkey::Middleware::Dumper::Indexes.start(dumper: self, connection: @connection, dump: @dump, table: @dump.tables[table]) do |env|
208
208
  stream = StringIO.new
209
209
  indexes_without_schema_monkey(env.table.name, stream)
210
210
  env.table.indexes += stream.string.split("\n").map { |string|
@@ -0,0 +1,62 @@
1
+ module SchemaMonkey::CoreExtensions
2
+ module Middleware
3
+ module Query
4
+ module ExecCache
5
+ ENV = [:connection, :sql, :name, :binds, :result]
6
+ end
7
+
8
+ module Tables
9
+ # :database and :like are only for mysql
10
+ # :table_name is only for sqlite3
11
+ ENV = [:connection, :query_name, :table_name, :database, :like, :tables]
12
+ end
13
+
14
+ module Indexes
15
+ ENV = [:connection, :table_name, :query_name, :index_definitions]
16
+ end
17
+ end
18
+
19
+ module Migration
20
+ module Column
21
+ ENV = [:caller, :operation, :table_name, :column_name, :type, :options]
22
+ end
23
+
24
+ module ColumnOptionsSql
25
+ ENV = [:caller, :connection, :sql, :options]
26
+ end
27
+
28
+ module Index
29
+ ENV = [:caller, :operation, :table_name, :column_names, :options]
30
+ end
31
+
32
+ module IndexComponentsSql
33
+ ENV = [:connection, :table_name, :column_names, :options, :sql]
34
+ end
35
+ end
36
+
37
+ module Dumper
38
+ module Extensions
39
+ ENV = [:dumper, :connection, :dump, :extensions]
40
+ end
41
+ module Tables
42
+ ENV = [:dumper, :connection, :dump]
43
+ end
44
+ module Table
45
+ ENV = [:dumper, :connection, :dump, :table]
46
+ end
47
+ module Indexes
48
+ ENV = [:dumper, :connection, :dump, :table]
49
+ end
50
+ end
51
+
52
+ module Model
53
+ module Columns
54
+ ENV = [:model, :columns]
55
+ end
56
+ module ResetColumnInformation
57
+ ENV = [:model]
58
+ end
59
+ end
60
+
61
+ end
62
+ end
@@ -0,0 +1,43 @@
1
+ require 'hash_keyword_args'
2
+ require 'its-it'
3
+ require 'key_struct'
4
+ require 'active_support/core_ext/string'
5
+
6
+ require_relative "tool/client"
7
+ require_relative "tool/errors"
8
+ require_relative "tool/module"
9
+ require_relative "tool/monkey"
10
+ require_relative "tool/stack"
11
+ require_relative 'tool/rake'
12
+
13
+ module SchemaMonkey
14
+ module Tool
15
+
16
+ DBMS = [:PostgreSQL, :Mysql, :SQLite3]
17
+
18
+ def self.register(mod)
19
+ monkey.register(mod)
20
+ end
21
+
22
+ def self.insert(opts={})
23
+ monkey.insert(opts)
24
+ end
25
+
26
+ private
27
+
28
+ def self.monkey
29
+ @monkey ||= Monkey.new
30
+ end
31
+
32
+ def self.reset_for_rspec
33
+ @monkey = nil
34
+ self.reset_middleware
35
+ end
36
+
37
+ def self.reset_middleware
38
+ SchemaMonkey.send :remove_const, :Middleware
39
+ SchemaMonkey.send :const_set, :Middleware, ::Module.new
40
+ end
41
+
42
+ end
43
+ end
@@ -1,6 +1,9 @@
1
- module SchemaMonkey
1
+ module SchemaMonkey::Tool
2
2
  class Client
3
- def initialize(mod)
3
+ attr_reader :monkey
4
+
5
+ def initialize(monkey, mod)
6
+ @monkey = monkey
4
7
  @root = mod
5
8
  @inserted = {}
6
9
  end
@@ -14,23 +17,27 @@ module SchemaMonkey
14
17
 
15
18
  def include_modules(opts={})
16
19
  opts = opts.keyword_args(:dbm)
20
+ # Kernel.warn "--- include modules for #{@root}, dbm=#{opts.dbm.inspect}"
17
21
  find_modules(:ActiveRecord, dbm: opts.dbm).each do |mod|
18
22
  next if mod.is_a? Class
19
23
  component = mod.to_s.sub(/^#{@root}::ActiveRecord::/, '')
20
24
  component = component.gsub(/#{opts.dbm}/i, opts.dbm.to_s) if opts.dbm # canonicalize case
21
- next unless base = Module.get_const(::ActiveRecord, component)
22
- # Kernel.warn "including #{mod}"
25
+ next unless base = Module.const_lookup(::ActiveRecord, component)
26
+ # Kernel.warn "including #{mod} (dbm=#{opts.dbm})"
23
27
  Module.include_once base, mod
24
28
  end
25
29
  end
26
30
 
27
31
  def insert_middleware(opts={})
28
32
  opts = opts.keyword_args(:dbm)
29
- find_modules(:Middleware, dbm: opts.dbm, and_self: true).each do |mod|
33
+ find_modules(:Middleware, dbm: opts.dbm).each do |mod|
30
34
  next if @inserted[mod]
31
- next unless mod.respond_to? :insert
32
- # Kernel.warn "inserting #{mod}"
33
- mod.insert
35
+
36
+ stack_path = mod.to_s.sub(/^#{@root}::Middleware::/, '')
37
+ stack_path = stack_path.split('::').reject(&it =~/\b#{opts.dbm}\b/i).join('::') if opts.dbm
38
+
39
+ monkey.insert_middleware_hook(mod, stack_path: stack_path) unless stack_path.empty?
40
+
34
41
  @inserted[mod] = true
35
42
  end
36
43
  end
@@ -38,19 +45,18 @@ module SchemaMonkey
38
45
  private
39
46
 
40
47
  def find_modules(container, opts={})
41
- opts = opts.keyword_args(dbm: nil, and_self: nil)
42
- return [] unless (container = Module.get_const(@root, container))
48
+ opts = opts.keyword_args(dbm: nil)
49
+ return [] unless (container = Module.const_lookup @root, container)
43
50
 
44
51
  if opts.dbm
45
52
  accept = /\b#{opts.dbm}/i
46
53
  reject = nil
47
54
  else
48
55
  accept = nil
49
- reject = /\b#{SchemaMonkey::DBMS.join('|')}/i
56
+ reject = /\b(#{DBMS.join('|')})/i
50
57
  end
51
58
 
52
59
  modules = []
53
- modules << container if opts.and_self
54
60
  modules += Module.descendants(container, can_load: accept)
55
61
  modules.select!(&it.to_s =~ accept) if accept
56
62
  modules.reject!(&it.to_s =~ reject) if reject
@@ -0,0 +1,4 @@
1
+ module SchemaMonkey::Tool
2
+ class MiddlewareError < Exception
3
+ end
4
+ end
@@ -1,4 +1,4 @@
1
- module SchemaMonkey
1
+ module SchemaMonkey::Tool
2
2
  module Module
3
3
  extend self
4
4
 
@@ -9,7 +9,7 @@ module SchemaMonkey
9
9
  # ruby 2.* supports mod.const_get("Component::Path") but ruby 1.9.3
10
10
  # doesn't. And neither has an option to return nil rather than raising
11
11
  # a NameError
12
- def get_const(mod, name)
12
+ def const_lookup(mod, name)
13
13
  name.to_s.split('::').map(&:to_sym).each do |component|
14
14
  begin
15
15
  mod = mod.const_get(component, false)
@@ -29,5 +29,12 @@ module SchemaMonkey
29
29
  children + children.flat_map {|c| descendants(c, can_load: opts.can_load) }
30
30
  end
31
31
 
32
+ def mkpath(mod, path)
33
+ path.split('::').each do |component|
34
+ mod = const_lookup(mod, component) || mod.const_set(component, ::Module.new)
35
+ end
36
+ mod
37
+ end
38
+
32
39
  end
33
40
  end
@@ -0,0 +1,46 @@
1
+ module SchemaMonkey::Tool
2
+
3
+ # The main manager for the monkey patches. Singleton instance
4
+ # created by SchemaMonkey.monkey
5
+
6
+ class Monkey
7
+
8
+ attr_reader :clients, :stacks
9
+
10
+ def initialize
11
+ @clients = []
12
+ end
13
+
14
+ def register(mod)
15
+ clients << Client.new(self, mod)
16
+ end
17
+
18
+ def insert(opts={})
19
+ opts = opts.keyword_args(:dbm)
20
+ clients.each &it.insert(dbm: opts.dbm)
21
+ end
22
+
23
+ def insert_middleware_hook(mod, opts={})
24
+ opts = opts.keyword_args(stack_path: :required)
25
+
26
+ return unless Stack.is_hook?(mod)
27
+
28
+ stack = Module.const_lookup SchemaMonkey::Middleware, opts.stack_path
29
+ env = Module.const_lookup mod, "ENV"
30
+
31
+ case
32
+ when stack && env
33
+ raise MiddlewareError, "#{mod}::ENV: stack #{stack} is already defined"
34
+ when !stack && !env
35
+ raise MiddlewareError, "#{mod}: No stack #{SchemaMonkey::Middleware}::#{opts.stack_path}"
36
+ when !stack && env
37
+ stack = Module.mkpath SchemaMonkey::Middleware, opts.stack_path
38
+ stack.send :extend, Stack::StartMethod
39
+ stack.send :stack=, Stack.new(module: stack, env: env)
40
+ end
41
+
42
+ stack.stack.append(mod)
43
+ end
44
+
45
+ end
46
+ end
@@ -1,4 +1,4 @@
1
- module SchemaMonkey
1
+ module SchemaMonkey::Tool
2
2
  module Rake
3
3
  TASKS_PATH = Pathname.new(__FILE__).dirname + "tasks"
4
4
 
@@ -0,0 +1,90 @@
1
+ module SchemaMonkey::Tool
2
+ class Stack
3
+ def initialize(opts={})
4
+ opts = opts.keyword_args(module: :required, env: :required)
5
+ @module = opts.module
6
+ @env_class = @module.const_set "Env", KeyStruct[*opts.env]
7
+ @hooks = []
8
+ end
9
+
10
+ def self.is_hook?(mod)
11
+ return true if (mod.instance_methods & [:before, :around, :after, :implementation]).any?
12
+ return true if Module.const_lookup mod, "ENV"
13
+ false
14
+ end
15
+
16
+ def append(mod)
17
+ hook = Hook.new(self, mod)
18
+ @hooks.last._next = hook if @hooks.any?
19
+ @hooks << hook
20
+ end
21
+
22
+ def start(env_opts, &implementation)
23
+ env = @env_class.new(env_opts)
24
+ @implementation = implementation
25
+
26
+ @hooks.each do |hook|
27
+ hook.before env if hook.respond_to? :before
28
+ end
29
+
30
+ @hooks.first._call(env)
31
+
32
+ @hooks.each do |hook|
33
+ hook.after env if hook.respond_to? :after
34
+ end
35
+
36
+ env
37
+ end
38
+
39
+ def call_implementation(env)
40
+ if hook = @hooks.select(&it.respond_to?(:implementation)).last
41
+ hook.implementation(env)
42
+ elsif @implementation
43
+ @implementation.call env
44
+ else
45
+ raise MiddlewareError, "No implementation for middleware stack #{@module}"
46
+ end
47
+ end
48
+
49
+ class Hook
50
+ attr_accessor :_next
51
+
52
+ def initialize(stack, mod)
53
+ @stack = stack
54
+ singleton_class.send :include, mod
55
+ end
56
+
57
+ def _call(env)
58
+ if respond_to? :around
59
+ around(env) { |env|
60
+ _continue env
61
+ }
62
+ else
63
+ _continue env
64
+ end
65
+ end
66
+
67
+ def _continue(env)
68
+ if self._next
69
+ self._next._call(env)
70
+ else
71
+ @stack.call_implementation(env)
72
+ end
73
+ end
74
+ end
75
+
76
+ module StartMethod
77
+ attr_reader :stack
78
+
79
+ def start(env, &block)
80
+ stack.start(env, &block)
81
+ end
82
+
83
+ private
84
+
85
+ def stack=(stack)
86
+ @stack = stack
87
+ end
88
+ end
89
+ end
90
+ end
@@ -1,3 +1,3 @@
1
1
  module SchemaMonkey
2
- VERSION = "0.4.1"
2
+ VERSION = "1.0.0"
3
3
  end
@@ -22,7 +22,6 @@ Gem::Specification.new do |spec|
22
22
  spec.add_dependency "hash_keyword_args"
23
23
  spec.add_dependency "its-it"
24
24
  spec.add_dependency "key_struct"
25
- spec.add_dependency "middleware", "~> 0.1"
26
25
 
27
26
  spec.add_development_dependency "bundler", "~> 1.7"
28
27
  spec.add_development_dependency "rake", "~> 10.0"
@@ -0,0 +1,95 @@
1
+ require 'spec_helper'
2
+
3
+ describe SchemaMonkey::Middleware do
4
+
5
+ When(:insertion) { SchemaMonkey.insert }
6
+
7
+ context "with stack registered" do
8
+
9
+ Given { SchemaMonkey.register make_definition }
10
+
11
+ Then { expect(defined?(SchemaMonkey::Middleware::Group::Stack)).to be_truthy }
12
+
13
+ context "when start with no implementation" do
14
+
15
+ When(:env) { SchemaMonkey::Middleware::Group::Stack.start result: [] }
16
+
17
+ Then { expect(env).to have_failed(SchemaMonkey::MiddlewareError, /implementation/) }
18
+ end
19
+
20
+ context "when start with inline implementation" do
21
+
22
+ When(:env) { SchemaMonkey::Middleware::Group::Stack.start result: [] { |env| env.result << :inline } }
23
+
24
+ Then { expect(env.result).to eq [:inline] }
25
+
26
+ context "if register client1" do
27
+
28
+ Given { SchemaMonkey.register make_client(1) }
29
+
30
+ Then { expect(env.result).to eq [:before1, :around_pre1, :implementation1, :around_post1, :after1 ] }
31
+
32
+ context "if register client2" do
33
+
34
+ Given { SchemaMonkey.register make_client(2) }
35
+
36
+ Then { expect(env.result).to eq [:before1, :before2, :around_pre1, :around_pre2, :implementation2, :around_post2, :around_post1, :after1, :after2 ] }
37
+ end
38
+ end
39
+ end
40
+
41
+ context "if register again" do
42
+ Given { SchemaMonkey.register make_definition }
43
+ Then { expect(insertion).to have_failed(SchemaMonkey::MiddlewareError, /already defined/i) }
44
+ end
45
+ end
46
+
47
+ context "without stack registered" do
48
+ context "if register client1" do
49
+ Given { SchemaMonkey.register make_client(1) }
50
+
51
+ Then { expect(insertion).to have_failed(SchemaMonkey::MiddlewareError, /no stack/i) }
52
+ end
53
+ end
54
+
55
+
56
+ def make_definition
57
+ Module.new.tap(&it.module_eval(<<-END))
58
+ module Middleware
59
+ module Group
60
+ module Stack
61
+ ENV = [:result]
62
+ end
63
+ end
64
+ end
65
+ END
66
+ end
67
+
68
+ def make_client(n)
69
+ Module.new.tap(&it.module_eval(<<-END))
70
+ module Middleware
71
+ module Group
72
+ module Stack
73
+ def before(env)
74
+ env.result << :"before#{n}"
75
+ end
76
+
77
+ def after(env)
78
+ env.result << :"after#{n}"
79
+ end
80
+
81
+ def around(env)
82
+ env.result << :"around_pre#{n}"
83
+ yield env
84
+ env.result << :"around_post#{n}"
85
+ end
86
+
87
+ def implementation(env)
88
+ env.result << :"implementation#{n}"
89
+ end
90
+ end
91
+ end
92
+ end
93
+ END
94
+ end
95
+ end
@@ -1,6 +1,8 @@
1
1
  require 'simplecov'
2
2
  require 'simplecov-gem-profile'
3
- SimpleCov.start "gem"
3
+ SimpleCov.start "gem" do
4
+ add_filter "/tasks/"
5
+ end
4
6
 
5
7
  $LOAD_PATH.unshift(File.dirname(__FILE__))
6
8
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
@@ -17,6 +19,9 @@ Dir[File.dirname(__FILE__) + "/support/**/*.rb"].each {|f| require f}
17
19
 
18
20
  RSpec.configure do |config|
19
21
  config.warnings = true
22
+ config.after(:each) do
23
+ SchemaMonkey::Tool.reset_for_rspec
24
+ end
20
25
  end
21
26
 
22
27
  SimpleCov.command_name "[ruby #{RUBY_VERSION} - ActiveRecord #{::ActiveRecord::VERSION::STRING} - #{ActiveRecord::Base.connection.adapter_name}]"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: schema_monkey
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ronen barzel
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-01 00:00:00.000000000 Z
11
+ date: 2015-02-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -66,20 +66,6 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: middleware
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - "~>"
74
- - !ruby/object:Gem::Version
75
- version: '0.1'
76
- type: :runtime
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - "~>"
81
- - !ruby/object:Gem::Version
82
- version: '0.1'
83
69
  - !ruby/object:Gem::Dependency
84
70
  name: bundler
85
71
  requirement: !ruby/object:Gem::Requirement
@@ -198,24 +184,30 @@ files:
198
184
  - gemfiles/activerecord-4.2/Gemfile.postgresql
199
185
  - gemfiles/activerecord-4.2/Gemfile.sqlite3
200
186
  - lib/schema_monkey.rb
201
- - lib/schema_monkey/active_record/base.rb
202
- - lib/schema_monkey/active_record/connection_adapters/abstract_adapter.rb
203
- - lib/schema_monkey/active_record/connection_adapters/mysql2_adapter.rb
204
- - lib/schema_monkey/active_record/connection_adapters/postgresql_adapter.rb
205
- - lib/schema_monkey/active_record/connection_adapters/schema_statements.rb
206
- - lib/schema_monkey/active_record/connection_adapters/sqlite3_adapter.rb
207
- - lib/schema_monkey/active_record/connection_adapters/table_definition.rb
208
- - lib/schema_monkey/active_record/migration/command_recorder.rb
209
- - lib/schema_monkey/active_record/schema_dumper.rb
210
- - lib/schema_monkey/client.rb
211
- - lib/schema_monkey/middleware.rb
212
- - lib/schema_monkey/module.rb
213
- - lib/schema_monkey/rake.rb
214
- - lib/schema_monkey/tasks/insert.rake
187
+ - lib/schema_monkey/core_extensions.rb
188
+ - lib/schema_monkey/core_extensions/active_record/base.rb
189
+ - lib/schema_monkey/core_extensions/active_record/connection_adapters/abstract_adapter.rb
190
+ - lib/schema_monkey/core_extensions/active_record/connection_adapters/mysql2_adapter.rb
191
+ - lib/schema_monkey/core_extensions/active_record/connection_adapters/postgresql_adapter.rb
192
+ - lib/schema_monkey/core_extensions/active_record/connection_adapters/schema_statements.rb
193
+ - lib/schema_monkey/core_extensions/active_record/connection_adapters/sqlite3_adapter.rb
194
+ - lib/schema_monkey/core_extensions/active_record/connection_adapters/table_definition.rb
195
+ - lib/schema_monkey/core_extensions/active_record/migration/command_recorder.rb
196
+ - lib/schema_monkey/core_extensions/active_record/schema_dumper.rb
197
+ - lib/schema_monkey/core_extensions/middleware.rb
198
+ - lib/schema_monkey/tool.rb
199
+ - lib/schema_monkey/tool/client.rb
200
+ - lib/schema_monkey/tool/errors.rb
201
+ - lib/schema_monkey/tool/module.rb
202
+ - lib/schema_monkey/tool/monkey.rb
203
+ - lib/schema_monkey/tool/rake.rb
204
+ - lib/schema_monkey/tool/stack.rb
205
+ - lib/schema_monkey/tool/tasks/insert.rake
215
206
  - lib/schema_monkey/version.rb
216
207
  - schema_dev.yml
217
208
  - schema_monkey.gemspec
218
209
  - spec/connection_spec.rb
210
+ - spec/middleware_spec.rb
219
211
  - spec/rake_spec.rb
220
212
  - spec/spec_helper.rb
221
213
  homepage: https://github.com/SchemaPlus/schema_monkey
@@ -245,5 +237,6 @@ summary: Provides an internal API and module inclusion protocol to facilitate ad
245
237
  features to ActiveRecord
246
238
  test_files:
247
239
  - spec/connection_spec.rb
240
+ - spec/middleware_spec.rb
248
241
  - spec/rake_spec.rb
249
242
  - spec/spec_helper.rb
@@ -1,30 +0,0 @@
1
- module SchemaMonkey
2
- module ActiveRecord
3
- module ConnectionAdapters
4
- module PostgresqlAdapter
5
-
6
- def self.included(base)
7
- base.class_eval do
8
- alias_method_chain :exec_cache, :schema_monkey
9
- alias_method_chain :indexes, :schema_monkey
10
- end
11
- SchemaMonkey.include_once ::ActiveRecord::ConnectionAdapters::SchemaStatements, SchemaMonkey::ActiveRecord::ConnectionAdapters::SchemaStatements::Reference
12
- SchemaMonkey.include_once ::ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaStatements, SchemaMonkey::ActiveRecord::ConnectionAdapters::SchemaStatements::Column
13
- SchemaMonkey.include_once ::ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaStatements, SchemaMonkey::ActiveRecord::ConnectionAdapters::SchemaStatements::Index
14
- end
15
-
16
- def exec_cache_with_schema_monkey(sql, name, binds)
17
- Middleware::Query::ExecCache.start connection: self, sql: sql, name: name, binds: binds do |env|
18
- exec_cache_without_schema_monkey(env.sql, env.name, env.binds)
19
- end
20
- end
21
-
22
- def indexes_with_schema_monkey(table_name, query_name=nil)
23
- Middleware::Query::Indexes.start connection: self, table_name: table_name, query_name: query_name, index_definitions: [] do |env|
24
- env.index_definitions += indexes_without_schema_monkey env.table_name, env.query_name
25
- end
26
- end
27
- end
28
- end
29
- end
30
- end
@@ -1,117 +0,0 @@
1
- module SchemaMonkey
2
- module Middleware
3
-
4
- class Base
5
- def initialize(app)
6
- @app = app
7
- end
8
- def continue(env)
9
- @app.call env
10
- end
11
- end
12
-
13
- module Stack
14
- def stack
15
- @stack ||= ::Middleware::Builder.new do
16
- use Root
17
- end
18
- end
19
-
20
- def append(middleware)
21
- stack.insert_before(Root, middleware)
22
- end
23
-
24
- def prepend(middleware)
25
- stack.insert(0, middleware)
26
- end
27
-
28
- def start(*args, &block)
29
- env = self.const_get(:Env).new(*args)
30
- env.instance_variable_set('@root', block)
31
- stack.call(env)
32
- end
33
-
34
- class Root < Base
35
- def call(env)
36
- env.instance_variable_get('@root').call(env)
37
- end
38
- end
39
- end
40
-
41
- module Query
42
- module ExecCache
43
- extend Stack
44
- Env = KeyStruct[:connection, :sql, :name, :binds]
45
- end
46
-
47
- module Tables
48
- extend Stack
49
- # :database and :like are only for mysql
50
- # :table_name is only for sqlite3
51
- Env = KeyStruct[:connection, :query_name, :table_name, :database, :like, :tables]
52
- end
53
-
54
- module Indexes
55
- extend Stack
56
- Env = KeyStruct[:connection, :table_name, :query_name, :index_definitions]
57
- end
58
- end
59
-
60
- module Migration
61
-
62
- module Column
63
- extend Stack
64
- Env = KeyStruct[:caller, :operation, :table_name, :column_name, :type, :options]
65
- end
66
-
67
- module ColumnOptionsSql
68
- extend Stack
69
- Env = KeyStruct[:caller, :connection, :sql, :options]
70
- end
71
-
72
- module Index
73
- extend Stack
74
- Env = KeyStruct[:caller, :operation, :table_name, :column_names, :options]
75
- end
76
-
77
- module IndexComponentsSql
78
- extend Stack
79
- Sql = KeyStruct[:name, :type, :columns, :options, :algorithm, :using]
80
- Env = KeyStruct[:connection, :table_name, :column_names, :options, sql: Sql.new]
81
- end
82
-
83
- end
84
-
85
- module Dumper
86
- module Extensions
87
- extend Stack
88
- Env = KeyStruct[:dumper, :connection, :dump, :extensions]
89
- end
90
- module Tables
91
- extend Stack
92
- Env = KeyStruct[:dumper, :connection, :dump]
93
- end
94
- module Table
95
- extend Stack
96
- Env = KeyStruct[:dumper, :connection, :dump, :table]
97
- end
98
- module Indexes
99
- extend Stack
100
- Env = KeyStruct[:dumper, :connection, :dump, :table]
101
- end
102
- end
103
-
104
- module Model
105
- module Columns
106
- extend Stack
107
- Env = KeyStruct[:model, :columns]
108
- end
109
- module ResetColumnInformation
110
- extend Stack
111
- Env = KeyStruct[:model]
112
- end
113
- end
114
-
115
-
116
- end
117
- end