database_introspection 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fd6b1e340f5f576df0fdc03f994f376069ace956
4
- data.tar.gz: 0401ddeac82d36e2a54c214cea8cf9c303db3322
3
+ metadata.gz: 25c5d7a4888eafde894853b452a714f634b652ae
4
+ data.tar.gz: eb2e2cedbe5a5ff900049ba10fd485a1ed70e9bb
5
5
  SHA512:
6
- metadata.gz: 7452dd3c478d085d73c1ad3245fd75e5440814be8c8b0d464e182ee63afadebbe31626ed3e3cd080c74c5fd12a74d4d3a189abf4490ff28218c991b622e0938f
7
- data.tar.gz: 4292876722bf17e645aaefc7fafd33021a7ecc6ceb239248a1449b78c8f0b504ea69200c274663e3a3baabd66f6aae1dc92060abdea8bf7972e8329f4889233b
6
+ metadata.gz: 76cee6c4b5202dceb394f5efd85f67928d173b73ab52aa7d6bfd2eb2be6c6adb6fb131cd822f9655b977efddc2d303ea8ebe55c42648db9921a29015b7c5086b
7
+ data.tar.gz: 69824f5c5e775c980fe1081f48c83a02c3f88a4ca812c5643ea9ba25221f5eee1152e606a350816316607775b2ff1d908c885b3ab3c7710a6bd14be845dee8cd
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Database Introspection
2
2
 
3
- This gem will introspect the database and create __dynamically__ ActiveRecord::Base descendants that can be used by your application, including some Rails associations helper methods.
3
+ [This gem][gemref] will introspect the database and create __dynamically__ ActiveRecord::Base descendants that can be used by your application, including some Rails associations helper methods.
4
4
 
5
5
  It is intended to be primarily used within rails applications but nothing prevents you to use standalone, provided the fact you are already connected to a database.
6
6
  This gem does a bit the reverse action of what you do with Rails generator, when you want to generate the database from you migrations.
@@ -20,6 +20,8 @@ Or install it yourself as:
20
20
 
21
21
  $ gem install database_introspection
22
22
 
23
+ Classes documentation is available [here](http://rubydoc.info/gems/database_introspection/0.1.0/frames)
24
+
23
25
  ## Usage
24
26
 
25
27
  ### Basic database introspection
@@ -86,7 +88,7 @@ DynamicModel::ManagedDomains::AnotherDomain
86
88
 
87
89
  The classes generated will actually have some behaviour added by extending the module `DynamicModel::ActiveRecordExtension` to basically be aware of the domain they belong to.
88
90
 
89
- ### Database relationships
91
+ ### Table relationships
90
92
 
91
93
  Provided you follow the standard rails rules for ids, for example:
92
94
 
@@ -105,3 +107,6 @@ if `user_defined_table1` contains `user_defined_table2_id` or simply `table2_id`
105
107
  3. Commit your changes (`git commit -am 'Add some feature'`)
106
108
  4. Push to the branch (`git push origin my-new-feature`)
107
109
  5. Create new Pull Request
110
+
111
+
112
+ [gemref]: https://rubygems.org/gems/database_introspection "Rails Database Introspection gem"
@@ -2,29 +2,62 @@ require 'active_record'
2
2
 
3
3
  module DynamicModel
4
4
 
5
+ @domain_analyser ||= {}
6
+
5
7
  # Creates ActiveRecord::Base descendants from the database.
6
8
  # ActiveRecord descendant classes are dynamically created from database introspection in their own namespace
7
9
  # (DynamicModel::<NameSpace>::) The name of the module NameSpace is derived from table_prefix.
8
10
  def self.introspect_database(table_prefix = :user_defined, base_class = ActiveRecord::Base)
11
+ if table_prefix.class == Array
12
+ table_prefix.each {|p| self.introspect_database p, base_class}
13
+ return
14
+ end
9
15
  table_prefix = table_prefix.to_s
10
- @domain_analyser ||= {}
11
-
12
- # Confines Activerecord classes into a module named from table_prefix
13
- @domain_analyser[table_prefix] ||= DynamicModel::TablesAnalyser.new table_prefix, base_class
14
- klasses = @domain_analyser[table_prefix].scan_database
15
- relation_analyser = RelationsAnalyser.new klasses
16
- relation_analyser.run
16
+ analyse_domain table_prefix, base_class
17
17
  end
18
18
 
19
19
  # Creates a new table with auto numbered id in the database with the name prefix provided
20
20
  # by creating a live migration.
21
21
  # If block is provided it will behave like create_table method for migrations, allowing
22
22
  # to create any other column.
23
- def self.add_table(scoped_table_name, table_prefix: :user_defined, &block)
23
+ def self.add_table(scoped_table_name, table_prefix: :user_defined, base_class: ActiveRecord::Base, &block)
24
+ for_action_on_table(scoped_table_name, table_prefix) do |table_prefix, real_table_name|
25
+ Migration::create_for "#{table_prefix}_#{real_table_name}", &block
26
+ end
27
+ ensure
28
+ analyse_domain table_prefix, base_class
29
+ end
30
+
31
+
32
+ # Modifies a table in the database with the name prefix provided by creating a live migration.
33
+ # If block is provided it will behave like create_table method for migrations, allowing
34
+ # to create any other column.
35
+ def self.alter_table(scoped_table_name, table_prefix: :user_defined, base_class: ActiveRecord::Base, &block)
36
+ raise "Missing block parameter" unless block_given?
37
+ for_action_on_table(scoped_table_name, table_prefix) do |table_prefix, real_table_name|
38
+ Migration::update_for "#{table_prefix}_#{real_table_name}", &block
39
+ end
40
+ ensure
41
+ analyse_domain table_prefix, base_class
42
+ end
43
+
44
+ private
45
+
46
+ def self.for_action_on_table(scoped_table_name, table_prefix)
47
+ raise "Missing block parameter" unless block_given?
24
48
  scoped_table_name = scoped_table_name.to_s
25
49
  table_prefix = table_prefix.to_s
26
50
  real_table_name = scoped_table_name.underscore.pluralize
27
- Migration::create_with "#{table_prefix}_#{real_table_name}", &block
51
+ yield table_prefix, real_table_name
52
+ end
53
+
54
+ def self.analyse_domain(table_prefix, base_class)
55
+ # Confines Activerecord classes into a module named from table_prefix
56
+ @domain_analyser[table_prefix] ||= DynamicModel::TablesAnalyser.new table_prefix, base_class
57
+ raise "You cannot change the base class for a domain" unless @domain_analyser[table_prefix].base_class == base_class
58
+ klasses = @domain_analyser[table_prefix].scan_database
59
+ relation_analyser = RelationsAnalyser.new klasses
60
+ relation_analyser.run
28
61
  end
29
62
 
30
63
 
@@ -25,13 +25,17 @@ module DynamicModel::ActiveRecordExtension
25
25
  end
26
26
 
27
27
  def name_space
28
- self.name.gsub( /DynamicModel::ManagedDomains::([^:]+)::.*$/, "\\1") .underscore
28
+ self.name.gsub(/DynamicModel::ManagedDomains::([^:]+)::.*$/, "\\1") .underscore
29
29
  end
30
30
 
31
31
  def list_name
32
32
  self.name.gsub( /^.*::([^:]+)$/, "\\1") .underscore.pluralize
33
33
  end
34
34
 
35
+ def alter(&block)
36
+ self.domain.alter_table(self.list_name, &block)
37
+ end
38
+
35
39
  end
36
40
 
37
41
  include InstanceMethods
@@ -22,6 +22,10 @@ module DynamicModel::DomainExtension
22
22
  DynamicModel.add_table scoped_table_name, table_prefix: prefix, &block
23
23
  end
24
24
 
25
+ def alter_table(scoped_table_name, &block)
26
+ DynamicModel.alter_table scoped_table_name, table_prefix: prefix, &block
27
+ end
28
+
25
29
  def model_class(scoped_table_name)
26
30
  Hash[scoped_table_names.zip model_classes][scoped_table_name]
27
31
  end
@@ -1,6 +1,6 @@
1
1
  require 'active_record'
2
2
  class DynamicModel::Migration < ActiveRecord::Migration
3
- def self.create_with(name, &block)
3
+ def self.create_for(name, &block)
4
4
  create_table name.to_sym do |t|
5
5
  block.call(t) if block_given?
6
6
  begin
@@ -10,4 +10,11 @@ class DynamicModel::Migration < ActiveRecord::Migration
10
10
  end
11
11
  end
12
12
  end
13
+
14
+ def self.update_for(name, &block)
15
+ change_table name.to_sym do |t|
16
+ block.call(t) if block_given?
17
+ end
18
+ end
19
+
13
20
  end
@@ -2,7 +2,7 @@ require 'active_record'
2
2
 
3
3
  class DynamicModel::TablesAnalyser
4
4
 
5
- attr_reader :domain, :klasses_analysed
5
+ attr_reader :domain, :base_class, :klasses_analysed
6
6
 
7
7
  def initialize(domain, base_class = ActiveRecord::Base)
8
8
  @domain = domain
@@ -28,13 +28,15 @@ class DynamicModel::TablesAnalyser
28
28
  if @domain_module.constants.include? short_model_name.to_sym
29
29
  klass = @domain_module.const_get short_model_name
30
30
  puts "Found #{klass.name} that already handles #{table_name}"
31
+ klass.reset_column_information
31
32
  else
32
33
  klass = @domain_module.const_set short_model_name, Class.new(@base_class)
33
34
  puts "Created #{klass.name} to handle #{table_name}"
34
35
  # Adds some class methods
35
36
  klass.send :include, DynamicModel::ActiveRecordExtension
36
37
  end
37
-
38
+ # Disables STI
39
+ klass.inheritance_column = nil
38
40
  # Maps the class to the correct table
39
41
  klass.table_name = table_name
40
42
  # Adds attributes accessible for mass assign
@@ -1,3 +1,3 @@
1
1
  module DatabaseIntrospection
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: database_introspection
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - L.Briais
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-05-18 00:00:00.000000000 Z
11
+ date: 2013-05-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler