schema_monkey 0.4.1 → 1.0.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.
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