mongify 0.3.1 → 0.9

Sign up to get free protection for your applications and to get access to all the features.
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -1,3 +1,11 @@
1
+ == 0.9 / 08 Feb 2013
2
+ * Changed Mongify Syntax (thanks to tanema)
3
+ * Improved error handling
4
+ * Improved Test output
5
+ * Refactored Commands
6
+ * Updated Gem Requirements
7
+ * Removed depricated calls (from Mongo insert statement)
8
+ * Removed MySql2 dependency (ActiveRecord takes care of that)
1
9
  == 0.3.1 / 21 Jan 2013
2
10
  * README examples updated
3
11
  * README typos fixed.
@@ -1,30 +1,30 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- mongify (0.3.1)
4
+ mongify (0.9)
5
5
  activerecord (>= 3.0.3)
6
6
  activesupport (>= 3.0.3)
7
- bson_ext (>= 1.1.5)
7
+ bson_ext (~> 1.8.2)
8
8
  highline (>= 1.6.1)
9
- mongo (>= 1.1.5)
10
- mysql2
9
+ mongo (~> 1.8.2)
11
10
 
12
11
  GEM
13
12
  remote: http://rubygems.org/
14
13
  specs:
15
- activemodel (3.0.7)
16
- activesupport (= 3.0.7)
14
+ activemodel (3.0.20)
15
+ activesupport (= 3.0.20)
17
16
  builder (~> 2.1.2)
18
17
  i18n (~> 0.5.0)
19
- activerecord (3.0.7)
20
- activemodel (= 3.0.7)
21
- activesupport (= 3.0.7)
22
- arel (~> 2.0.2)
18
+ activerecord (3.0.20)
19
+ activemodel (= 3.0.20)
20
+ activesupport (= 3.0.20)
21
+ arel (~> 2.0.10)
23
22
  tzinfo (~> 0.3.23)
24
- activesupport (3.0.7)
25
- arel (2.0.9)
26
- bson (1.3.0)
27
- bson_ext (1.3.0)
23
+ activesupport (3.0.20)
24
+ arel (2.0.10)
25
+ bson (1.8.2)
26
+ bson_ext (1.8.2)
27
+ bson (~> 1.8.2)
28
28
  builder (2.1.2)
29
29
  cucumber (1.2.1)
30
30
  builder (>= 2.1.2)
@@ -34,13 +34,12 @@ GEM
34
34
  diff-lcs (1.1.3)
35
35
  gherkin (2.11.2)
36
36
  json (>= 1.4.6)
37
- highline (1.6.1)
37
+ highline (1.6.15)
38
38
  i18n (0.5.0)
39
39
  json (1.7.5)
40
40
  mocha (0.9.12)
41
- mongo (1.3.0)
42
- bson (>= 1.3.0)
43
- mysql (2.8.1)
41
+ mongo (1.8.2)
42
+ bson (~> 1.8.2)
44
43
  mysql2 (0.2.7)
45
44
  rake (0.9.2.2)
46
45
  rcov (0.9.9)
@@ -52,10 +51,10 @@ GEM
52
51
  rspec-expectations (2.5.0)
53
52
  diff-lcs (~> 1.1.2)
54
53
  rspec-mocks (2.5.0)
55
- sqlite3 (1.3.3)
54
+ sqlite3 (1.3.7)
56
55
  sqlite3-ruby (1.3.3)
57
56
  sqlite3 (>= 1.3.3)
58
- tzinfo (0.3.26)
57
+ tzinfo (0.3.35)
59
58
  watchr (0.7)
60
59
  yard (0.6.4)
61
60
 
@@ -66,7 +65,7 @@ DEPENDENCIES
66
65
  cucumber (>= 0.10)
67
66
  mocha (>= 0.9.8)
68
67
  mongify!
69
- mysql (>= 2.8.1)
68
+ mysql2 (~> 0.2.7)
70
69
  rake
71
70
  rcov (>= 0.9.9)
72
71
  rspec (>= 2.0)
@@ -35,10 +35,10 @@ Building a config file is as simple as this:
35
35
  host "localhost"
36
36
  database "my_database"
37
37
  end
38
-
38
+
39
39
  You can check your configuration by running
40
- mongify check -c database.config
41
-
40
+ mongify check database.config
41
+
42
42
  ==== Options
43
43
  Currently the only supported option is for the mongodb_connection.
44
44
 
@@ -53,9 +53,9 @@ Currently the only supported option is for the mongodb_connection.
53
53
 
54
54
  ==== Generating a translation
55
55
  If your database is large and complex, it might be a bit too much work to write the translation file by hand. Mongify's translate command can help with this:
56
- mongify translation -c database.config
56
+ mongify translation database.config
57
57
  Or pipe it right into a file by running
58
- mongify translation -c database.config > translation_file.rb
58
+ mongify translation database.config > translation_file.rb
59
59
 
60
60
  ==== Creating a translation
61
61
  Creating a translation is pretty straightforward. It looks something like this:
@@ -86,13 +86,13 @@ Creating a translation is pretty straightforward. It looks something like this:
86
86
  column "created_at", :datetime
87
87
  column "updated_at", :datetime
88
88
  end
89
-
89
+
90
90
  table "preferences", :embed_in => :users, :as => :object do
91
91
  column "id", :key, :as => :string
92
92
  column "user_id", :integer, :references => "users"
93
93
  column "notify_by_email", :boolean
94
94
  end
95
-
95
+
96
96
  table "notes", :embed_in => true, :polymorphic => 'notable' do
97
97
  column "id", :key
98
98
  column "user_id", :integer, :references => "users"
@@ -102,14 +102,14 @@ Creating a translation is pretty straightforward. It looks something like this:
102
102
  column "created_at", :datetime
103
103
  column "updated_at", :datetime
104
104
  end
105
-
105
+
106
106
  Save the file as <tt>"translation_file.rb"</tt> and run the command:
107
107
 
108
- mongify process translation_file.rb -c database.config
109
-
108
+ mongify process database.config translation_file.rb
109
+
110
110
  === Commands
111
111
 
112
- Usage: mongify command [database_translation.rb] [-c database.config]
112
+ Usage: mongify command database_config [database_translation.rb]
113
113
 
114
114
  Commands:
115
115
  "check" or "ck" >> Checks connection for sql and no_sql databases [configuration_file]
@@ -118,15 +118,14 @@ Save the file as <tt>"translation_file.rb"</tt> and run the command:
118
118
 
119
119
  Examples:
120
120
 
121
- mongify translation -c datbase.config
122
- mongify tr -c database.config
123
- mongify check -c database.config
124
- mongify process database_translation.rb -c database.config
121
+ mongify translation datbase.config
122
+ mongify tr database.config
123
+ mongify check database.config
124
+ mongify process database.config database_translation.rb
125
125
 
126
126
  Common options:
127
127
  -h, --help Show this message
128
128
  -v, --version Show version
129
- -c, --config FILE Configuration File to use
130
129
 
131
130
  == Translation Layout and Options
132
131
 
@@ -147,17 +146,17 @@ Table Options are as follow:
147
146
  table "table_name" # Does a straight copy of the table
148
147
  table "table_name", :embed_in => 'users' # Embeds table_name into users, assuming a user_id is present in table_name.
149
148
  # This will also assume you want the table embedded as an array.
150
-
149
+
151
150
  table "table_name", # Embeds table_name into users, linking it via a owner_id
152
151
  :embed_in => 'users', # This will also assume you want the table embedded as an array.
153
- :on => 'owner_id'
154
-
152
+ :on => 'owner_id'
153
+
155
154
  table "table_name", # Embeds table_name into users as a one to one relationship
156
155
  :embed_in => 'users', # This also assumes you have a user_id present in table_name
157
156
  :on => 'owner_id', # You can also specify both :on and :as options when embedding
158
- :as => 'object' # NOTE: If you rename the owner_id column, make sure you
157
+ :as => 'object' # NOTE: If you rename the owner_id column, make sure you
159
158
  # update the :on to the new column name
160
-
159
+
161
160
 
162
161
  table "table_name", :rename_to => 'my_table' # This will allow you to rename the table as it's getting process
163
162
  # Just remember that columns that use :reference need to
@@ -165,14 +164,14 @@ Table Options are as follow:
165
164
 
166
165
  table "table_name", :ignore => true # This will ignore the whole table (like it doesn't exist)
167
166
  # This option is good for tables like: schema_migrations
168
-
167
+
169
168
  table "table_name", # This allows you to specify the table as being polymorphic
170
169
  :polymorphic => 'notable', # and provide the name of the polymorphic relationship.
171
170
  :embed_in => true # Setting embed_in => true allows the relationship to be
172
171
  # embedded directly into the parent class.
173
172
  # If you do not embed it, the polymorphic table will be copied in to
174
173
  # MongoDB and the notable_id will be updated to the new BSON::ObjectID
175
-
174
+
176
175
  table "table_name" do # A table can take a before_save block that will be called just
177
176
  before_save do |row| # before the row is saved to the no sql database.
178
177
  row.admin = row.delete('permission').to_i > 50 # This gives you the ability to do very powerful things like:
@@ -180,9 +179,9 @@ Table Options are as follow:
180
179
  end # some values! Checkout Mongify::Database::DataRow to learn more
181
180
 
182
181
  table "users" do # Here is how to set new ID using the old id
183
- before_save do |row|
184
- row._id = row.delete('pre_mongified_id')
185
- end
182
+ before_save do |row|
183
+ row._id = row.delete('pre_mongified_id')
184
+ end
186
185
  end
187
186
 
188
187
  table "preferences", :embed_in => "users" do # As of version 0.2, embedded tables with a before_save will take an
@@ -203,7 +202,7 @@ Structure for defining a column is as follows:
203
202
 
204
203
  ==== Notes
205
204
 
206
- <em>as of version 0.2:</em>
205
+ <em>as of version 0.2:</em>
207
206
  Leaving a column out when defining a table will result in the column being *ignored*
208
207
 
209
208
  ==== Types
@@ -229,20 +228,20 @@ Before we cover the options, you need to know what types of columns are supporte
229
228
  # NOTE: if you rename the table 'posts', you should set the :references to the new name
230
229
 
231
230
  column "name", :string, :ignore => true # Ignoring a column will make the column NOT copy over to the new database
232
-
233
- column "surname",
234
- :string,
235
- :rename_to => 'last_name' # Rename_to allows you to rename the column
236
-
231
+
232
+ column "surname",
233
+ :string,
234
+ :rename_to => 'last_name' # Rename_to allows you to rename the column
235
+
237
236
  <em>For decimal columns you can specify a few options:</em>
238
237
  column "total", # This is a default conversion setting.
239
238
  :decimal,
240
- :as => 'string'
241
-
239
+ :as => 'string'
240
+
242
241
  column "total", # You can specify to convert your decimal to integer
243
242
  :decimal, # specifying scale will define how many decimal places to keep
244
243
  :as => 'integer', # Example: :scale => 2 will convert 123.4567 to 12346 before saving
245
- :scale => 2
244
+ :scale => 2
246
245
 
247
246
  More documentation can be found at {Mongify::Database::Column}
248
247
 
@@ -11,4 +11,9 @@ require 'mongify/cli'
11
11
 
12
12
  Mongify.root = Dir.pwd
13
13
 
14
- exit Mongify::CLI::Application.new(ARGV).execute!
14
+ begin
15
+ exit Mongify::CLI::Application.new(ARGV).execute!
16
+ rescue Mongify::MongifyError => error
17
+ $stderr.puts "Error: #{error}"
18
+ exit Mongify::CLI::Application.execution_error_status
19
+ end
@@ -5,8 +5,8 @@ Feature: Mongify can be controlled using command-line options
5
5
 
6
6
  Scenario: returns non-zero status on bad options
7
7
  When I run mongify --no-such-option
8
- Then the exit status indicates an error
9
- And it reports the error "Error: invalid option: --no-such-option"
8
+ Then it reports the error "Error: invalid option: --no-such-option"
9
+ And the exit status indicates an error
10
10
  And stdout equals ""
11
11
 
12
12
  Scenario: display the current version number
@@ -19,24 +19,22 @@ Feature: Mongify can be controlled using command-line options
19
19
  Then it succeeds
20
20
  And it reports:
21
21
  """
22
- Usage: mongify command [database_translation.rb] [-c database.config]
23
-
24
- Commands:
25
- "check" or "ck" >> Checks connection for sql and no_sql databases [configuration_file]
26
- "process" or "pr" >> Takes a translation and process it to mongodb [configuration_file, translation_file]
27
- "translation" or "tr" >> Outputs a translation file from a sql connection [configuration_file]
28
-
22
+ Usage: mongify command database.config [database_translation.rb]
23
+
24
+ Commands:
25
+ "check" or "ck" >> Checks connection for sql and no_sql databases [configuration_file]
26
+ "process" or "pr" >> Takes a translation and process it to mongodb [configuration_file, translation_file]
27
+ "translation" or "tr" >> Outputs a translation file from a sql connection [configuration_file]
28
+
29
29
  Examples:
30
-
31
- mongify check -c database.config
32
- mongify translation -c datbase.config > database_translation.rb
33
- mongify process database_translation.rb -c database.config
34
-
30
+
31
+ mongify check database.config
32
+ mongify translation datbase.config > database_translation.rb
33
+ mongify process database.config database_translation.rb
34
+
35
35
  See http://github.com/anlek/mongify for more details
36
36
 
37
37
  Common options:
38
38
  -h, --help Show this message
39
39
  -v, --version Show version
40
- -c, --config FILE Configuration File to use
41
-
42
40
  """
@@ -5,6 +5,6 @@ Feature: Database Translation Output
5
5
 
6
6
  Scenario: Translation Output request
7
7
  Given a database exists
8
- When I run mongify translation -c spec/files/base_configuration.rb
8
+ When I run mongify translation spec/files/base_configuration.rb
9
9
  Then it succeeds
10
10
  And it should print out the database schema
@@ -6,7 +6,7 @@ Feature: Processing a translation
6
6
  Scenario: Process
7
7
  Given a database exists
8
8
  And a blank mongodb
9
- When I run mongify process spec/files/translation.rb -c spec/files/base_configuration.rb
9
+ When I run mongify process spec/files/base_configuration.rb spec/files/translation.rb
10
10
  Then it succeeds
11
11
  And there should be 3 users in mongodb
12
12
  And there should be 3 posts in mongodb
@@ -18,7 +18,7 @@ Feature: Processing a translation
18
18
  Scenario: Processing while modifying embedding parent.
19
19
  Given a database exists
20
20
  And a blank mongodb
21
- When I run mongify process spec/files/embedded_parent_translation.rb -c spec/files/base_configuration.rb
21
+ When I run mongify process spec/files/base_configuration.rb spec/files/embedded_parent_translation.rb
22
22
  Then it succeeds
23
23
  And there should be 3 users in mongodb
24
24
  And the first user's notify_by_email attribute should be true
@@ -7,7 +7,7 @@ Then /^stdout equals "([^\"]*)"$/ do |report|
7
7
  end
8
8
 
9
9
  Then /^it reports:$/ do |report|
10
- @last_stdout.should == report
10
+ @last_stdout.gsub(/\s+/, ' ').strip.should == report.gsub(/\s+/, ' ').strip
11
11
  end
12
12
 
13
13
  Then /^stderr reports:$/ do |report|
@@ -1,7 +1,9 @@
1
1
  require 'mongify'
2
2
 
3
+ require 'mongify/cli/command/version'
4
+ require 'mongify/cli/command/help'
5
+ require 'mongify/cli/command/worker'
6
+
7
+
3
8
  require 'mongify/cli/options'
4
- require 'mongify/cli/version_command'
5
- require 'mongify/cli/help_command'
6
- require 'mongify/cli/worker_command'
7
9
  require 'mongify/cli/application'
@@ -25,7 +25,7 @@ module Mongify
25
25
  def execute!
26
26
  begin
27
27
  cmd = @options.parse
28
- cmd.execute(self)
28
+ return cmd.execute(self)
29
29
  rescue MongifyError => error
30
30
  $stderr.puts "Error: #{error}"
31
31
  report_error
@@ -33,7 +33,6 @@ module Mongify
33
33
  report_error
34
34
  raise error
35
35
  end
36
- return @status
37
36
  end
38
37
 
39
38
  # Sends output to the UI
@@ -0,0 +1,19 @@
1
+ module Mongify
2
+ module CLI
3
+ module Command
4
+ #
5
+ # A command to display usage information for this application.
6
+ #
7
+ class Help
8
+ def initialize(parser)
9
+ @parser = parser
10
+ end
11
+ #Executes the help command
12
+ def execute(view)
13
+ view.output(@parser.to_s)
14
+ view.report_success
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,20 @@
1
+ require 'mongify/version'
2
+ module Mongify
3
+ module CLI
4
+ module Command
5
+ #
6
+ # A command to report the application's current version number.
7
+ #
8
+ class Version
9
+ def initialize(progname)
10
+ @progname = progname
11
+ end
12
+ #Executes version command
13
+ def execute(view)
14
+ view.output("#{@progname} #{Mongify::VERSION}\n")
15
+ view.report_success
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,101 @@
1
+ module Mongify
2
+ module CLI
3
+ module Command
4
+ #
5
+ # A command to run the different commands in the application (related to Mongifying).
6
+ #
7
+ class Worker
8
+ attr_accessor :view
9
+
10
+ # A hash of available commands
11
+ # Including description, additional shortcuts to run the commands and requirements to run the command
12
+ AVAILABLE_COMMANDS = {
13
+ :check => {:commands => ['check', 'ck'], :description => "Checks connection for sql and no_sql databases", :required => [:configuration_file]},
14
+ :translation => {:commands => ['translation', 'tr'], :description => "Outputs a translation file from a sql connection", :required => [:configuration_file]},
15
+ :process => {:commands => ['process', 'pr'], :description => "Takes a translation and process it to mongodb", :required => [:configuration_file, :translation_file]}
16
+ }
17
+
18
+ # Prints out a nice display of the list of commands
19
+ def self.list_commands
20
+ [].tap do |commands|
21
+ AVAILABLE_COMMANDS.each do |key, obj|
22
+ commands << "#{obj[:commands].map{|w| %["#{w}"]}.to_sentence(:two_words_connector => ' or ', :last_word_connector => ', or ').ljust(25)} >> #{obj[:description]}#{ " [#{obj[:required].join(', ')}]" if obj[:required]}"
23
+ end
24
+ end.sort
25
+ end
26
+
27
+ # Finds a command array by any of the shortcut commands
28
+ def self.find_command(command)
29
+ AVAILABLE_COMMANDS.each do |key, options|
30
+ return [key, options] if(options[:commands].include?(command.to_s.downcase))
31
+ end
32
+ 'unknown'
33
+ end
34
+
35
+ def initialize(command, config=nil, translation_file=nil, parser="")
36
+ @command = command.to_s.downcase
37
+ @config = config
38
+ @translation_file = translation_file
39
+ @parser = parser
40
+ end
41
+
42
+ #Executes the worked based on a given command
43
+ def execute(view)
44
+ self.view = view
45
+
46
+ current_command, command_options = find_command
47
+
48
+ if command_options
49
+ #FIXME: Should parse configuration file in this action, (when I know it's required)
50
+ raise ConfigurationFileNotFound, "Database Configuration file is missing or cannot be found" if command_options[:required] && command_options[:required].include?(:configuration_file) && @config.nil?
51
+ if command_options[:required] && command_options[:required].include?(:translation_file)
52
+ raise TranslationFileNotFound, "Translation file is required for command '#{current_command}'" unless @translation_file
53
+ raise TranslationFileNotFound, "Unable to find Translation File at #{@translation_file}" unless File.exists?(@translation_file)
54
+ @translation = Translation.parse(@translation_file)
55
+ end
56
+ end
57
+
58
+ case current_command
59
+ when :translation
60
+ check_connections
61
+ view.output(Mongify::Translation.load(@config.sql_connection).print)
62
+ when :check
63
+ view.output("SQL connection works") if check_sql_connection
64
+ view.output("NoSQL connection works") if check_nosql_connection
65
+ when :process
66
+ check_connections
67
+ @translation.process(@config.sql_connection, @config.no_sql_connection)
68
+ else
69
+ view.output("Unknown action #{@command}\n\n#{@parser}")
70
+ return view.report_error
71
+ end
72
+ view.report_success
73
+ end
74
+
75
+ # Passes find command to parent class
76
+ def find_command(command=@command)
77
+ self.class.find_command(command)
78
+ end
79
+
80
+ #######
81
+ private
82
+ #######
83
+
84
+ # Checks both sql and no sql connection
85
+ def check_connections
86
+ check_sql_connection && check_nosql_connection
87
+ end
88
+
89
+ # Checks sql connection if it's valid and has_connection?
90
+ def check_sql_connection
91
+ @config.sql_connection.valid? && @config.sql_connection.has_connection?
92
+ end
93
+
94
+ # Checks no sql connection if it's valid and has_connection?
95
+ def check_nosql_connection
96
+ @config.no_sql_connection.valid? && @config.no_sql_connection.has_connection?
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end