conventional_models 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +4 -2
- data/Gemfile.lock +24 -12
- data/features/cmconsole.feature +3 -3
- data/features/conventional_models.feature +3 -3
- data/features/multiple_databases.feature +43 -0
- data/features/output_model_code.feature +1 -1
- data/features/step_definitions/multiple_databases.rb +4 -0
- data/features/support/env.rb +5 -1
- data/lib/conventional_models.rb +4 -13
- data/lib/conventional_models/{conventions.rb → config.rb} +16 -3
- data/lib/conventional_models/database.rb +25 -9
- data/lib/conventional_models/table.rb +12 -8
- data/lib/conventional_models/version.rb +1 -1
- data/spec/conventional_models/cli_spec.rb +10 -10
- data/spec/conventional_models/{conventions_spec.rb → config_spec.rb} +21 -7
- data/spec/conventional_models/database_spec.rb +33 -41
- data/spec/conventional_models/option_parser_spec.rb +2 -2
- data/spec/conventional_models/options_spec.rb +2 -2
- data/spec/conventional_models/table_spec.rb +19 -21
- data/spec/conventional_models_spec.rb +12 -36
- metadata +43 -53
- data/.document +0 -5
- data/.gitignore +0 -22
- data/Rakefile +0 -86
- data/VERSION +0 -1
- data/conventional_models.gemspec +0 -97
- data/spec/spec.opts +0 -1
data/Gemfile
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
source :gemcutter
|
2
2
|
|
3
3
|
group :features do
|
4
|
-
gem "cucumber", "0.
|
5
|
-
gem "aruba"
|
4
|
+
gem "cucumber", "0.7.2"
|
5
|
+
gem "aruba"
|
6
|
+
gem "open4"
|
6
7
|
end
|
7
8
|
|
8
9
|
group :specs do
|
@@ -12,6 +13,7 @@ end
|
|
12
13
|
group :development do
|
13
14
|
gem "jeweler"
|
14
15
|
gem "rake"
|
16
|
+
gem "ZenTest"
|
15
17
|
end
|
16
18
|
|
17
19
|
gem "activerecord", "2.3.5"
|
data/Gemfile.lock
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
---
|
2
2
|
dependencies:
|
3
|
+
ZenTest:
|
4
|
+
group:
|
5
|
+
- :development
|
6
|
+
version: ">= 0"
|
3
7
|
activerecord:
|
4
8
|
group:
|
5
9
|
- :default
|
@@ -19,7 +23,7 @@ dependencies:
|
|
19
23
|
aruba:
|
20
24
|
group:
|
21
25
|
- :features
|
22
|
-
version:
|
26
|
+
version: ">= 0"
|
23
27
|
jeweler:
|
24
28
|
group:
|
25
29
|
- :development
|
@@ -27,43 +31,51 @@ dependencies:
|
|
27
31
|
cucumber:
|
28
32
|
group:
|
29
33
|
- :features
|
30
|
-
version: = 0.
|
34
|
+
version: = 0.7.2
|
35
|
+
open4:
|
36
|
+
group:
|
37
|
+
- :features
|
38
|
+
version: ">= 0"
|
31
39
|
specs:
|
32
40
|
- rake:
|
33
41
|
version: 0.8.7
|
42
|
+
- ZenTest:
|
43
|
+
version: 4.3.1
|
34
44
|
- activesupport:
|
35
45
|
version: 2.3.5
|
36
46
|
- activerecord:
|
37
47
|
version: 2.3.5
|
38
48
|
- aruba:
|
39
|
-
version: 0.1.
|
49
|
+
version: 0.1.9
|
40
50
|
- builder:
|
41
51
|
version: 2.1.2
|
52
|
+
- bundler:
|
53
|
+
version: 0.9.24
|
42
54
|
- diff-lcs:
|
43
55
|
version: 1.1.2
|
56
|
+
- trollop:
|
57
|
+
version: 1.16.2
|
58
|
+
- gherkin:
|
59
|
+
version: 1.0.25
|
44
60
|
- json_pure:
|
45
|
-
version: 1.
|
46
|
-
- polyglot:
|
47
|
-
version: 0.3.1
|
61
|
+
version: 1.4.3
|
48
62
|
- term-ansicolor:
|
49
63
|
version: 1.0.5
|
50
|
-
- treetop:
|
51
|
-
version: 1.4.5
|
52
64
|
- cucumber:
|
53
|
-
version: 0.
|
65
|
+
version: 0.7.2
|
54
66
|
- gemcutter:
|
55
67
|
version: 0.5.0
|
56
68
|
- git:
|
57
69
|
version: 1.2.5
|
58
|
-
- rubyforge:
|
59
|
-
version: 2.0.4
|
60
70
|
- jeweler:
|
61
71
|
version: 1.4.0
|
72
|
+
- open4:
|
73
|
+
version: 1.0.1
|
62
74
|
- rspec:
|
63
75
|
version: 1.3.0
|
64
76
|
- sqlite3-ruby:
|
65
77
|
version: 1.2.5
|
66
|
-
hash:
|
78
|
+
hash: 49b2ba6893f5940e80f19c400ec7f4a2d38964a5
|
67
79
|
sources:
|
68
80
|
- Rubygems:
|
69
81
|
uri: http://gemcutter.org
|
data/features/cmconsole.feature
CHANGED
@@ -9,7 +9,7 @@ Feature: Cmconsole
|
|
9
9
|
"""
|
10
10
|
development:
|
11
11
|
adapter: sqlite3
|
12
|
-
database:
|
12
|
+
database: development.sqlite
|
13
13
|
pool: 5
|
14
14
|
timeout: 5000
|
15
15
|
|
@@ -26,8 +26,8 @@ Feature: Cmconsole
|
|
26
26
|
timeout: 5000
|
27
27
|
"""
|
28
28
|
And a table "pages"
|
29
|
-
When I run "../../bin/cmconsole"
|
30
|
-
Then I should see ">> "
|
29
|
+
When I run "../../bin/cmconsole" as child "irb"
|
30
|
+
Then I should see ">> " from child "irb"
|
31
31
|
|
32
32
|
|
33
33
|
|
@@ -10,7 +10,7 @@ Feature: ConventionalModels
|
|
10
10
|
$:.unshift("../../lib")
|
11
11
|
require 'rubygems'
|
12
12
|
require 'active_record'
|
13
|
-
ActiveRecord::Base.establish_connection(:database => '
|
13
|
+
ActiveRecord::Base.establish_connection(:database => 'development.sqlite', :adapter => 'sqlite3')
|
14
14
|
require 'conventional_models'
|
15
15
|
ConventionalModels.configure
|
16
16
|
puts "Number of records: #{<model_name>.count}"
|
@@ -30,7 +30,7 @@ Feature: ConventionalModels
|
|
30
30
|
$:.unshift("../../lib")
|
31
31
|
require 'rubygems'
|
32
32
|
require 'active_record'
|
33
|
-
ActiveRecord::Base.establish_connection(:database => '
|
33
|
+
ActiveRecord::Base.establish_connection(:database => 'development.sqlite', :adapter => 'sqlite3')
|
34
34
|
require 'conventional_models'
|
35
35
|
ConventionalModels.configure
|
36
36
|
puts "Number of records: #{<model_name>.count}"
|
@@ -58,7 +58,7 @@ Feature: ConventionalModels
|
|
58
58
|
$:.unshift("../../lib")
|
59
59
|
require 'rubygems'
|
60
60
|
require 'active_record'
|
61
|
-
ActiveRecord::Base.establish_connection(:database => '
|
61
|
+
ActiveRecord::Base.establish_connection(:database => 'development.sqlite', :adapter => 'sqlite3')
|
62
62
|
require 'conventional_models'
|
63
63
|
ConventionalModels.configure do
|
64
64
|
primary_key_name "Id"
|
@@ -0,0 +1,43 @@
|
|
1
|
+
Feature: Multiple database connection
|
2
|
+
In order to transfer data between databases
|
3
|
+
As a user
|
4
|
+
I want to be able to connect and generate models for multiple databases
|
5
|
+
|
6
|
+
Scenario: Connect to multiple database
|
7
|
+
Given a table "pages" in "development"
|
8
|
+
And a table "pages" in "test"
|
9
|
+
And a file named "my_script.rb" with:
|
10
|
+
"""
|
11
|
+
$:.unshift("../../lib")
|
12
|
+
require 'rubygems'
|
13
|
+
require 'active_record'
|
14
|
+
ActiveRecord::Base.establish_connection(:database => 'development.sqlite', :adapter => 'sqlite3')
|
15
|
+
require 'conventional_models'
|
16
|
+
config = {
|
17
|
+
"development" => {
|
18
|
+
"database" => 'development.sqlite',
|
19
|
+
"adapter" => 'sqlite3'
|
20
|
+
},
|
21
|
+
"test" => {
|
22
|
+
"database" => 'test.sqlite',
|
23
|
+
"adapter" => 'sqlite3'
|
24
|
+
}
|
25
|
+
}
|
26
|
+
ConventionalModels.configure do
|
27
|
+
connection config["development"]
|
28
|
+
module_name "Development"
|
29
|
+
end
|
30
|
+
ConventionalModels.configure do
|
31
|
+
connection config["test"]
|
32
|
+
module_name "Test"
|
33
|
+
end
|
34
|
+
puts ConventionalModels.model_code
|
35
|
+
Development::Page.create!
|
36
|
+
Development::Page.create!
|
37
|
+
Test::Page.create!
|
38
|
+
puts "Number of development records: #{Development::Page.count}"
|
39
|
+
puts "Number of production records: #{Test::Page.count}"
|
40
|
+
"""
|
41
|
+
When I run "ruby my_script.rb"
|
42
|
+
Then I should see "Number of development records: 2"
|
43
|
+
Then I should see "Number of production records: 1"
|
@@ -18,7 +18,7 @@ Feature: Output model code
|
|
18
18
|
$:.unshift("../../lib")
|
19
19
|
require 'rubygems'
|
20
20
|
require 'active_record'
|
21
|
-
ActiveRecord::Base.establish_connection(:database => '
|
21
|
+
ActiveRecord::Base.establish_connection(:database => 'development.sqlite', :adapter => 'sqlite3')
|
22
22
|
require 'conventional_models'
|
23
23
|
ConventionalModels.configure do
|
24
24
|
primary_key_name "Id"
|
data/features/support/env.rb
CHANGED
@@ -9,6 +9,10 @@ require 'active_record'
|
|
9
9
|
Before do
|
10
10
|
config = {
|
11
11
|
"development" => {
|
12
|
+
"database" => 'tmp/aruba/development.sqlite',
|
13
|
+
"adapter" => 'sqlite3'
|
14
|
+
},
|
15
|
+
"test" => {
|
12
16
|
"database" => 'tmp/aruba/test.sqlite',
|
13
17
|
"adapter" => 'sqlite3'
|
14
18
|
}
|
@@ -18,6 +22,6 @@ Before do
|
|
18
22
|
|
19
23
|
system "mkdir -p tmp"
|
20
24
|
system "mkdir -p tmp/aruba"
|
21
|
-
system 'rm -f tmp/aruba/
|
25
|
+
system 'rm -f tmp/aruba/development.sqlite'
|
22
26
|
ActiveRecord::Base.establish_connection(config["development"])
|
23
27
|
end
|
data/lib/conventional_models.rb
CHANGED
@@ -2,7 +2,7 @@ require 'rubygems'
|
|
2
2
|
require 'active_record'
|
3
3
|
require 'active_support'
|
4
4
|
require 'conventional_models/version'
|
5
|
-
require 'conventional_models/
|
5
|
+
require 'conventional_models/config'
|
6
6
|
require 'conventional_models/database'
|
7
7
|
require 'conventional_models/table'
|
8
8
|
require 'conventional_models/column'
|
@@ -16,12 +16,9 @@ require 'irb/completion'
|
|
16
16
|
module ConventionalModels
|
17
17
|
@@database = nil
|
18
18
|
|
19
|
-
def self.configure(&block)
|
20
|
-
@@
|
21
|
-
|
22
|
-
remove(@@database)
|
23
|
-
end
|
24
|
-
@@database = Database.new(@@conventions)
|
19
|
+
def self.configure(config=nil, &block)
|
20
|
+
@@config = Config.new(&block)
|
21
|
+
@@database = Database.new(@@config)
|
25
22
|
run_code @@database.code
|
26
23
|
end
|
27
24
|
|
@@ -48,10 +45,4 @@ module ConventionalModels
|
|
48
45
|
ActiveRecord::Base.configurations = config
|
49
46
|
ActiveRecord::Base.establish_connection(config[environment])
|
50
47
|
end
|
51
|
-
|
52
|
-
def self.remove(database)
|
53
|
-
database.tables.map{|t| t.class_name.to_sym}.each do |class_sym|
|
54
|
-
Object.send(:remove_const, class_sym)
|
55
|
-
end
|
56
|
-
end
|
57
48
|
end
|
@@ -1,12 +1,12 @@
|
|
1
1
|
module ConventionalModels
|
2
|
-
class
|
2
|
+
class Config
|
3
3
|
def initialize(&block)
|
4
4
|
builder = Builder.new(self)
|
5
5
|
builder.instance_eval(&block) if block
|
6
6
|
end
|
7
7
|
|
8
|
-
attr_accessor :ignored_tables, :primary_key_name, :class_name,
|
9
|
-
:belongs_to_matcher, :belongs_to_name
|
8
|
+
attr_accessor :ignored_tables, :primary_key_name, :class_name, :base_class,
|
9
|
+
:belongs_to_matcher, :belongs_to_name, :connection, :module_name
|
10
10
|
|
11
11
|
class Builder
|
12
12
|
def initialize(config)
|
@@ -16,6 +16,7 @@ module ConventionalModels
|
|
16
16
|
primary_key_name "id"
|
17
17
|
class_name {|table_name| table_name.singularize.camelize}
|
18
18
|
ignore_tables "schema_migrations", "sqlite_sequence", "sysdiagrams"
|
19
|
+
base_class "::ActiveRecord::Base"
|
19
20
|
end
|
20
21
|
|
21
22
|
def ignore_tables(*tables)
|
@@ -37,6 +38,18 @@ module ConventionalModels
|
|
37
38
|
def class_name(&block)
|
38
39
|
@config.class_name = block
|
39
40
|
end
|
41
|
+
|
42
|
+
def connection(conn)
|
43
|
+
@config.connection = conn
|
44
|
+
end
|
45
|
+
|
46
|
+
def module_name(name)
|
47
|
+
@config.module_name = name
|
48
|
+
end
|
49
|
+
|
50
|
+
def base_class(name)
|
51
|
+
@config.base_class = name
|
52
|
+
end
|
40
53
|
end
|
41
54
|
end
|
42
55
|
|
@@ -4,9 +4,25 @@ module ConventionalModels
|
|
4
4
|
class Database
|
5
5
|
attr_accessor :tables
|
6
6
|
|
7
|
-
def initialize(
|
8
|
-
|
9
|
-
|
7
|
+
def initialize(config)
|
8
|
+
if config.connection.nil?
|
9
|
+
@connection = ::ActiveRecord::Base.connection
|
10
|
+
else
|
11
|
+
base_class_code = []
|
12
|
+
base_class_code << "module ::#{config.module_name}"
|
13
|
+
base_class_code << " class Base < ActiveRecord::Base;"
|
14
|
+
base_class_code << " @abstract_class = true;"
|
15
|
+
base_class_code << " end;"
|
16
|
+
base_class_code << "end"
|
17
|
+
eval base_class_code.join
|
18
|
+
@base_class = "::#{config.module_name}::Base".constantize
|
19
|
+
@base_class.class_eval do
|
20
|
+
establish_connection config.connection
|
21
|
+
end
|
22
|
+
config.base_class = @base_class
|
23
|
+
@connection = @base_class.connection
|
24
|
+
end
|
25
|
+
@config = config
|
10
26
|
@tables = []
|
11
27
|
apply_conventions
|
12
28
|
end
|
@@ -26,22 +42,22 @@ module ConventionalModels
|
|
26
42
|
|
27
43
|
protected
|
28
44
|
def apply_conventions
|
29
|
-
@connection.tables.select{|table| !@
|
30
|
-
@tables << Table.new(table, @connection.columns(table), @
|
45
|
+
@connection.tables.select{|table| !@config.ignored_tables.include? table}.each do |table|
|
46
|
+
@tables << Table.new(table, @connection.columns(table), @config)
|
31
47
|
end
|
32
48
|
|
33
49
|
@tables.each do |table|
|
34
50
|
table.belongs_to_names.each do |belongs_to|
|
35
|
-
name = @
|
36
|
-
has_many_table = @tables.select{|t| t.class_name == @
|
51
|
+
name = @config.belongs_to_name.call(belongs_to)
|
52
|
+
has_many_table = @tables.select{|t| t.class_name == @config.class_name.call(name)}.first
|
37
53
|
if has_many_table
|
38
54
|
unconventions = []
|
39
55
|
unless table.conventional_name?
|
40
56
|
unconventions << ":class_name => '#{table.class_name}'"
|
41
57
|
unconventions << ":foreign_key => '#{belongs_to.name}'"
|
42
58
|
end
|
43
|
-
unless @
|
44
|
-
unconventions << ":primary_key => '#{@
|
59
|
+
unless @config.primary_key_name == "id"
|
60
|
+
unconventions << ":primary_key => '#{@config.primary_key_name}'"
|
45
61
|
end
|
46
62
|
|
47
63
|
has_many_table.lines << ["has_many :#{table.name.tableize}", "#{unconventions.join(", ")}"].select do |convention|
|
@@ -7,7 +7,7 @@ module ConventionalModels
|
|
7
7
|
@columns = columns
|
8
8
|
@lines = []
|
9
9
|
@belongs_to_names = []
|
10
|
-
@
|
10
|
+
@config = conventions
|
11
11
|
|
12
12
|
apply_conventions
|
13
13
|
end
|
@@ -17,7 +17,7 @@ module ConventionalModels
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def code
|
20
|
-
"class ::#{@
|
20
|
+
"class ::#{@class_name} < #{@config.base_class}\n#{@lines.map{|l| " #{l}"}.join("\n")}\nend"
|
21
21
|
end
|
22
22
|
|
23
23
|
def conventional_name?
|
@@ -27,17 +27,21 @@ module ConventionalModels
|
|
27
27
|
protected
|
28
28
|
|
29
29
|
def apply_conventions
|
30
|
-
@class_name = @
|
31
|
-
|
32
|
-
|
30
|
+
@class_name = @config.class_name.call(@name)
|
31
|
+
|
32
|
+
unless @config.module_name.nil?
|
33
|
+
@class_name = "#{@config.module_name}::#{@class_name}"
|
34
|
+
end
|
35
|
+
|
36
|
+
@lines << "set_primary_key \"#{@config.primary_key_name}\"" unless @config.primary_key_name == "id"
|
33
37
|
|
34
38
|
@lines << "set_table_name \"#{@name}\"" unless @name.tableize == @name
|
35
39
|
|
36
40
|
@columns.each do |column|
|
37
|
-
if @
|
38
|
-
name = @
|
41
|
+
if @config.belongs_to_matcher.call(column)
|
42
|
+
name = @config.belongs_to_name.call(column)
|
39
43
|
@belongs_to_names << column
|
40
|
-
@lines << "belongs_to :#{name.underscore}, :class_name => '#{@
|
44
|
+
@lines << "belongs_to :#{name.underscore}, :class_name => '#{@config.class_name.call(name)}'"
|
41
45
|
end
|
42
46
|
end
|
43
47
|
end
|
@@ -2,11 +2,11 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
|
2
2
|
|
3
3
|
module ConventionalModels
|
4
4
|
describe CLI do
|
5
|
+
let(:option_parser) { mock(OptionParser, :options => @options) }
|
5
6
|
before(:each) do
|
6
7
|
@args = []
|
7
8
|
@options = Options.new
|
8
|
-
|
9
|
-
OptionParser.stub(:new).and_return(@option_parser)
|
9
|
+
OptionParser.stub(:new).and_return(option_parser)
|
10
10
|
File.stub(:exists?).with(@options.config).and_return(true)
|
11
11
|
end
|
12
12
|
|
@@ -29,9 +29,9 @@ module ConventionalModels
|
|
29
29
|
@cli.run
|
30
30
|
end
|
31
31
|
|
32
|
-
|
32
|
+
context "with parsed options" do
|
33
33
|
before(:each) do
|
34
|
-
|
34
|
+
option_parser.stub(:parsed_options?).and_return(true)
|
35
35
|
ConventionalModels.stub(:configure)
|
36
36
|
ConventionalModels.stub(:model_code)
|
37
37
|
ConventionalModels.stub(:configure_active_record)
|
@@ -43,7 +43,7 @@ module ConventionalModels
|
|
43
43
|
run
|
44
44
|
end
|
45
45
|
|
46
|
-
|
46
|
+
context "when config doesnt exist" do
|
47
47
|
before(:each) do
|
48
48
|
File.stub(:exists?).with(@options.config).and_return(false)
|
49
49
|
end
|
@@ -75,7 +75,7 @@ module ConventionalModels
|
|
75
75
|
run
|
76
76
|
end
|
77
77
|
|
78
|
-
|
78
|
+
context "with skip-configure option" do
|
79
79
|
it "does not call configure" do
|
80
80
|
@options.skip_configure = true
|
81
81
|
ConventionalModels.should_not_receive(:configure)
|
@@ -83,7 +83,7 @@ module ConventionalModels
|
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
86
|
-
|
86
|
+
context "with help option" do
|
87
87
|
it "outputs help" do
|
88
88
|
RDoc.should_receive(:usage)
|
89
89
|
@options.output_help = true
|
@@ -92,7 +92,7 @@ module ConventionalModels
|
|
92
92
|
end
|
93
93
|
end
|
94
94
|
|
95
|
-
|
95
|
+
context "with output version option" do
|
96
96
|
it "outputs the version" do
|
97
97
|
@options.output_version = true
|
98
98
|
ConventionalModels.should_not_receive(:configure_active_record)
|
@@ -102,10 +102,10 @@ module ConventionalModels
|
|
102
102
|
end
|
103
103
|
end
|
104
104
|
|
105
|
-
|
105
|
+
context "with invalid options" do
|
106
106
|
it "prints usage" do
|
107
107
|
RDoc.should_receive(:usage).with('usage')
|
108
|
-
|
108
|
+
option_parser.stub(:parsed_options?).and_return(false)
|
109
109
|
run
|
110
110
|
end
|
111
111
|
end
|