rammer 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rammer.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 manishaharidas
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,65 @@
1
+ # Rammer
2
+
3
+ Rammer is a framework dedicated to build high performance Async API servers on top of non-blocking (asynchronous) Ruby web server called Goliath. Rammer APIs are designed on top of REST-like API micro-framework Grape. Rammer is modular and integrates a powerful CLI called Viber to plug in and out its modules.
4
+
5
+ ## Installation
6
+
7
+ Install it yourself as:
8
+
9
+ $ gem install rammer
10
+
11
+ ## Usage
12
+
13
+ * rammer application_name
14
+ * cd application_name
15
+ * bundle install (To install all dependencies)
16
+ * ruby server.rb -vs (To run the Goliath server)
17
+
18
+ To include rammer modules into application use command viber:
19
+
20
+ $ viber module <COMMAND> <MODULE_NAME>
21
+
22
+ COMMAND :
23
+ * -p or -plugin (Plugs in the specified module)
24
+ * -u or -unplug (Unplugs the specified module)
25
+
26
+ MODULE_NAME :
27
+ * authentication (Includes endpoint : sign_up)
28
+ * authorization (Includes endpoint : sign_in, sign_out)
29
+ * oauth (Includes endpoint : register_client, authorize, access_token, token, invalidate_token)
30
+
31
+ Endpoints enabled with respective module:
32
+
33
+ - Authentication
34
+ * sign_up : "Enables user authentication using email, MD5 password and redirect url returning session token."
35
+
36
+ - Authorization
37
+ * sign_in : "Enables user login using credentials returning session token."
38
+ * sign_out : "Enables user logout using credentials by invalidating the session token."
39
+
40
+ - Oauth
41
+ * register_client : "Registers ouath client using credentials returning client details like ID, Secret hash, authorization code."
42
+ * authorize : "Enables functionality for activating authorization page access."
43
+ * access_token : "Returns oauth access token for registered clients to authorized users."
44
+ * token : "Returns bearer token to registered third party clients."
45
+ * invalidate_token : "Invalidated the issued bearer token."
46
+
47
+ ## Contributors
48
+
49
+ This list is open to all. You are all welcome :).
50
+
51
+ * manishaharidas (Manisha Haridas) -
52
+ * Github: https://github.com/manishaharidas
53
+
54
+ ## Comments/Requests
55
+
56
+ If anyone has comments or questions please let me know (qbruby@qburst.com).
57
+ If you have updates or patches or want to contribute I would love to see what you have or want to add.
58
+
59
+
60
+ ## Note on Patches/Pull Requests
61
+
62
+ * Fork the project.
63
+ * Make your feature addition or bug fix.
64
+ * Add tests for it. This is important so I don't break it in a future version unintentionally.
65
+ * Send me a pull request. Bonus points for topic branches.
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/rammer ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rammer'
4
+
5
+ generator = Rammer::Generator.new(*ARGV)
6
+ generator.run
data/bin/viber ADDED
@@ -0,0 +1,73 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rammer'
4
+
5
+ def parse_options
6
+ case ARGV[1]
7
+ when "-p", "-plugin"
8
+ return true
9
+ when "-u", "-unplug"
10
+ return true
11
+ else
12
+ return false
13
+ end
14
+ end
15
+
16
+ def options_message
17
+ STDOUT.puts <<-EOF
18
+ Please include module name
19
+
20
+ Usage:
21
+ viber module #{ARGV[1]}
22
+
23
+ options:
24
+ authentication
25
+ authorization
26
+ oauth
27
+ EOF
28
+ end
29
+
30
+ def execute(module_name,action)
31
+ target_dir = Dir.pwd.split('/',Dir.pwd.count('/')+1).last
32
+ name = target_dir.split.map(&:capitalize)*' '
33
+ case module_name
34
+ when "authentication"
35
+ module_class = "::#{name}::AuthenticationApis"
36
+ when "authorization"
37
+ module_class = "::#{name}::AuthorizationApis"
38
+ when "oauth"
39
+ module_class = "::#{name}::OauthApis"
40
+ end
41
+ options = { :target_dir => target_dir, :module_class => module_class,
42
+ :module_name => module_name, :action => action}
43
+ module_generator = Rammer::ModuleGenerator.new(options)
44
+ module_generator.run
45
+ end
46
+
47
+ case ARGV[0]
48
+ when "module"
49
+ if parse_options
50
+ case ARGV[2]
51
+ when "authentication"
52
+ execute("authentication",ARGV[1])
53
+ when "authorization"
54
+ execute("authorization",ARGV[1])
55
+ when "oauth"
56
+ execute("oauth",ARGV[1])
57
+ else
58
+ options_message
59
+ exit
60
+ end
61
+ else
62
+ STDOUT.puts <<-EOF
63
+ Please provide command options
64
+
65
+ Usage:
66
+ viber module
67
+
68
+ options:
69
+ -p,-plugin :Plugs in rammer specified modules.
70
+ -u,-unplug :Unplugs rammer specified modules.
71
+ EOF
72
+ end
73
+ end
@@ -0,0 +1,3 @@
1
+ module Rammer
2
+ VERSION = "1.1.0"
3
+ end
data/lib/rammer.rb ADDED
@@ -0,0 +1,287 @@
1
+ require "rammer/version"
2
+ require 'fileutils'
3
+ $gem_file_name = "rammer-"+Rammer::VERSION
4
+ module Rammer
5
+
6
+ class Generator
7
+ attr_accessor :target_dir, :project_name, :module_name, :gem_path
8
+ BASE_DIR = ['app', 'app/apis', 'config', 'db', 'db/migrate', 'app/models']
9
+ TEMPLATE_FILES = ['Gemfile','Gemfile.lock','Procfile','Rakefile','server.rb', 'tree.rb']
10
+ def initialize(dir_name)
11
+ self.project_name = dir_name
12
+ if self.project_name.nil? || self.project_name.squeeze.strip == ""
13
+ raise NoGitHubRepoNameGiven
14
+ else
15
+ path = File.split(self.project_name)
16
+
17
+ if path.size > 1
18
+ extracted_directory = File.join(path[0..-1])
19
+ self.project_name = path.last
20
+ end
21
+ end
22
+ self.target_dir = self.project_name
23
+ path = `gem which rammer`
24
+ p self.gem_path = path.split($gem_file_name,2).first
25
+ end
26
+
27
+ def run
28
+ unless File.exists?(target_dir) || File.directory?(target_dir)
29
+ $stdout.puts "Creating goliath application under the directory #{target_dir}"
30
+ FileUtils.mkdir target_dir
31
+ create_base_dirs
32
+ copy_files_to_target
33
+ setup_api_module
34
+ copy_files_to_dir 'application.rb','config'
35
+ copy_files_to_dir 'database.yml','config'
36
+ $stdout.puts "\e[33mRun `bundle install` to install missing gems.\e[0m"
37
+ else
38
+ $stdout.puts "\e[1;31mError:\e[0m The directory #{target_dir} already exists, aborting. Maybe move it out of the way before continuing."
39
+ end
40
+ end
41
+
42
+ private
43
+
44
+ def create_base_dirs
45
+ BASE_DIR.each do |dir|
46
+ FileUtils.mkdir "#{target_dir}/#{dir}"
47
+ $stdout.puts "\e[1;32m \tcreate\e[0m\t#{dir}"
48
+ end
49
+ FileUtils.mkdir "#{target_dir}/app/apis/#{target_dir}"
50
+ $stdout.puts "\e[1;32m \tcreate\e[0m\tapp/apis/#{target_dir}"
51
+ end
52
+
53
+ def setup_api_module
54
+ self.module_name = target_dir.split('_').map(&:capitalize).join('')
55
+ create_api_module
56
+ config_server
57
+ end
58
+
59
+ def create_api_module
60
+ File.open("#{target_dir}/app/apis/#{target_dir}/base.rb", "w") do |f|
61
+ f.write('module ')
62
+ f.puts(module_name)
63
+ f.write("\tclass Base < Grape::API\n\tend\nend")
64
+ end
65
+ $stdout.puts "\e[1;32m \tcreate\e[0m\tapp/apis/#{target_dir}/base.rb"
66
+ end
67
+
68
+ def config_server
69
+ file = File.open("#{target_dir}/server.rb", "r+")
70
+ file.each do |line|
71
+ while line == "\tdef response(env)\n" do
72
+ pos = file.pos
73
+ rest = file.read
74
+ file.seek pos
75
+ file.write("\t\t::")
76
+ file.write(module_name)
77
+ file.write("::Base.call(env)\n")
78
+ file.write(rest)
79
+ return
80
+ end
81
+ end
82
+ $stdout.puts "\e[1;32m \tcreate\e[0m\tserver.rb"
83
+ end
84
+
85
+ def copy_files_to_target
86
+ TEMPLATE_FILES.each do |file|
87
+ source = File.join("#{gem_path}/#{$gem_file_name}/lib/template/",file)
88
+ FileUtils.cp(source,"#{target_dir}")
89
+ $stdout.puts "\e[1;32m \tcreate\e[0m\t#{file}"
90
+ end
91
+ end
92
+
93
+ def copy_files_to_dir(file,destination)
94
+ FileUtils.cp("#{gem_path}/#{$gem_file_name}/lib/template/#{file}","#{target_dir}/#{destination}")
95
+ $stdout.puts "\e[1;32m \tcreate\e[0m\t#{destination}/#{file}"
96
+ end
97
+ end
98
+
99
+ class ModuleGenerator
100
+ attr_accessor :target_dir, :module_class, :options, :module_name, :gem_path, :action
101
+ AUTH_MIGRATE = ['01_create_users.rb','02_create_sessions.rb']
102
+ OAUTH_MIGRATE = ['03_create_owners.rb', '04_create_oauth2_authorizations.rb', '05_create_oauth2_clients.rb']
103
+ AUTH_MODELS = ['user.rb', 'session.rb', 'oauth2_authorization.rb']
104
+ OAUTH_MODELS = ['oauth2_client.rb', 'owner.rb']
105
+ def initialize(options)
106
+ self.options = options
107
+ self.target_dir = options[:target_dir]
108
+ self.module_class = options[:module_class]
109
+ self.module_name = options[:module_name]
110
+ self.action = options[:action]
111
+ path = `gem which rammer`
112
+ self.gem_path = path.split($gem_file_name,2).first
113
+ end
114
+
115
+ def run
116
+ case action
117
+ when "-p","-plugin"
118
+ flag = require_module_to_base
119
+ mount_module unless flag
120
+ copy_module
121
+ create_migrations
122
+ copy_model_files
123
+ add_gems
124
+ oauth_message if module_name == "oauth" && !flag
125
+ when "-u","-unplug"
126
+ unmount_module
127
+ end
128
+ end
129
+
130
+ def mount_module
131
+ file = File.open("#{Dir.pwd}/app/apis/#{target_dir}/base.rb", "r+")
132
+ file.each do |line|
133
+ while line == "\tclass Base < Grape::API\n" do
134
+ pos = file.pos
135
+ rest = file.read
136
+ file.seek pos
137
+ file.write("\t\tmount ")
138
+ file.puts(module_class)
139
+ file.write(rest)
140
+ break
141
+ end
142
+ end
143
+ $stdout.puts "\e[1;35m\tmounted\e[0m\t#{module_class}"
144
+ end
145
+
146
+ def require_module_to_base
147
+ file = File.open("#{Dir.pwd}/app/apis/#{target_dir}/base.rb", "r+")
148
+ file.each do |line|
149
+ while line == "require_relative './modules/#{module_name}_apis'\n" do
150
+ $stdout.puts "\e[33mModule already mounted.\e[0m"
151
+ return true
152
+ end
153
+ end
154
+ File.open("#{Dir.pwd}/app/apis/#{target_dir}/base.rb", "r+") do |f|
155
+ pos = f.pos
156
+ rest = f.read
157
+ f.seek pos
158
+ f.write("require_relative './modules/")
159
+ f.write(module_name)
160
+ f.write("_apis'\n")
161
+ f.write(rest)
162
+ end
163
+ return false
164
+ end
165
+
166
+ def copy_module
167
+ src = "#{gem_path}/#{$gem_file_name}/lib/template/#{module_name}_apis.rb"
168
+ dest = "#{Dir.pwd}/app/apis/#{target_dir}/modules"
169
+ presence = File.exists?("#{dest}/#{module_name}_apis.rb")? true : false
170
+ FileUtils.mkdir dest unless File.exists?(dest)
171
+ FileUtils.cp(src,dest) unless presence
172
+ configure_module_files
173
+ $stdout.puts "\e[1;32m \tcreate\e[0m\tapp/apis/#{target_dir}/modules/#{module_name}_apis.rb" unless presence
174
+ end
175
+
176
+ def create_migrations
177
+ src = "#{gem_path}/#{$gem_file_name}/lib/template"
178
+ dest = "#{Dir.pwd}/db/migrate"
179
+ case module_name
180
+ when "authentication", "authorization"
181
+ common_migrations(src,dest)
182
+ when "oauth"
183
+ common_migrations(src,dest)
184
+ OAUTH_MIGRATE.each do |file|
185
+ presence = File.exists?("#{dest}/#{file}")? true : false
186
+ unless presence
187
+ FileUtils.cp("#{src}/#{file}",dest)
188
+ $stdout.puts "\e[1;32m \tcreate\e[0m\tdb/migrate/#{file}"
189
+ end
190
+ end
191
+ end
192
+ end
193
+
194
+ def common_migrations(src,dest)
195
+ AUTH_MIGRATE.each do |file|
196
+ presence = File.exists?("#{dest}/#{file}")? true : false
197
+ unless presence
198
+ FileUtils.cp("#{src}/#{file}",dest)
199
+ $stdout.puts "\e[1;32m \tcreate\e[0m\tdb/migrate/#{file}"
200
+ end
201
+ end
202
+ end
203
+
204
+ def common_models(src,dest)
205
+ AUTH_MODELS.each do |file|
206
+ presence = File.exists?("#{dest}/#{file}")? true : false
207
+ unless presence
208
+ FileUtils.cp("#{src}/#{file}",dest)
209
+ $stdout.puts "\e[1;32m \tcreate\e[0m\tapp/models/#{file}"
210
+ end
211
+ end
212
+ end
213
+
214
+ def copy_model_files
215
+ src = "#{gem_path}/#{$gem_file_name}/lib/template"
216
+ dest = "#{Dir.pwd}/app/models"
217
+ case module_name
218
+ when "authentication", "authorization"
219
+ common_models(src,dest)
220
+ when "oauth"
221
+ common_models(src,dest)
222
+ OAUTH_MODELS.each do |file|
223
+ presence = File.exists?("#{dest}/#{file}")? true : false
224
+ unless presence
225
+ FileUtils.cp("#{src}/#{file}",dest)
226
+ $stdout.puts "\e[1;32m \tcreate\e[0m\tapp/models/#{file}"
227
+ end
228
+ end
229
+ end
230
+ end
231
+
232
+ def configure_module_files
233
+ file = File.read("#{Dir.pwd}/app/apis/#{target_dir}/modules/#{module_name}_apis.rb")
234
+ replace = file.gsub(/module GrapeGoliath/, "module #{target_dir.split('_').map(&:capitalize)*''}")
235
+ File.open("#{Dir.pwd}/app/apis/#{target_dir}/modules/#{module_name}_apis.rb", "w"){|f|
236
+ f.puts replace
237
+ }
238
+ end
239
+
240
+ def add_gems
241
+ file = File.open("#{Dir.pwd}/Gemfile", "r+")
242
+ file.each do |line|
243
+ while line == "gem 'oauth2'\n" do
244
+ return
245
+ end
246
+ end
247
+ File.open("#{Dir.pwd}/Gemfile", "a+") do |f|
248
+ f.write("gem 'multi_json'\ngem 'oauth2'\ngem 'songkick-oauth2-provider'\ngem 'ruby_regex'\ngem 'oauth'\n")
249
+ end
250
+ $stdout.puts "\e[1;35m \tGemfile\e[0m\tgem 'multi_json'\n\t\tgem 'oauth2'
251
+ \t\tgem 'songkick-oauth2-provider'\n\t\tgem 'ruby_regex'\n\t\tgem 'oauth'\n"
252
+ $stdout.puts "\e[1;32m \trun\e[0m\tbundle install"
253
+ system("bundle install")
254
+ end
255
+
256
+ def unmount_module
257
+ temp_file = "#{Dir.pwd}/app/apis/#{target_dir}/tmp.rb"
258
+ source = "#{Dir.pwd}/app/apis/#{target_dir}/base.rb"
259
+ delete_file = "#{Dir.pwd}/app/apis/#{target_dir}/modules/#{module_name}_apis.rb"
260
+ File.open(temp_file, "w") do |out_file|
261
+ File.foreach(source) do |line|
262
+ unless line == "require_relative './modules/#{module_name}_apis'\n"
263
+ out_file.puts line unless line == "\t\tmount #{module_class}\n"
264
+ end
265
+ end
266
+ FileUtils.mv(temp_file, source)
267
+ end
268
+ if File.exists?(delete_file)
269
+ FileUtils.rm(delete_file)
270
+ $stdout.puts "\e[1;35m\tunmounted\e[0m\t#{module_class}"
271
+ $stdout.puts "\e[1;31m\tdelete\e[0m\t\tapp/apis/#{target_dir}/modules/#{module_name}_apis.rb"
272
+ else
273
+ $stdout.puts "\e[33mModule already unmounted.\e[0m"
274
+ end
275
+ end
276
+
277
+ def oauth_message
278
+ $stdout.puts "\e[33m
279
+ In app/apis/<APP_NAME>/modules/oauth_apis.rb
280
+ Specify redirection url to the respective authorization page into 'redirect_to_url'
281
+ and uncomment the code to enable /oauth/authorize endpoint functionality.
282
+
283
+ \e[0m"
284
+ end
285
+ end
286
+ end
287
+
@@ -0,0 +1,44 @@
1
+ class CreateUsers < ActiveRecord::Migration
2
+ def change
3
+ create_table(:users) do |t|
4
+ t.string :email, :null => false, :default => ""
5
+ t.string :encrypted_password, :null => false, :default => ""
6
+
7
+ ## Recoverable
8
+ t.string :reset_password_token
9
+ t.datetime :reset_password_sent_at
10
+
11
+ ## Rememberable
12
+ t.datetime :remember_created_at
13
+
14
+ ## Trackable
15
+ t.integer :sign_in_count, :default => 0, :null => false
16
+ t.datetime :current_sign_in_at
17
+ t.datetime :last_sign_in_at
18
+ t.string :current_sign_in_ip
19
+ t.string :last_sign_in_ip
20
+
21
+ ## Confirmable
22
+ # t.string :confirmation_token
23
+ # t.datetime :confirmed_at
24
+ # t.datetime :confirmation_sent_at
25
+ # t.string :unconfirmed_email # Only if using reconfirmable
26
+
27
+ ## Lockable
28
+ # t.integer :failed_attempts, :default => 0, :null => false # Only if lock strategy is :failed_attempts
29
+ # t.string :unlock_token # Only if unlock strategy is :email or :both
30
+ # t.datetime :locked_at
31
+
32
+ ## Token authenticatable
33
+ # t.string :authentication_token
34
+
35
+ t.timestamps
36
+ end
37
+
38
+ add_index :users, :email, :unique => true
39
+ add_index :users, :reset_password_token, :unique => true
40
+ # add_index :users, :authentication_token, :unique => true
41
+ # add_index :operators, :confirmation_token, :unique => true
42
+ # add_index :operators, :unlock_token, :unique => true
43
+ end
44
+ end
@@ -0,0 +1,9 @@
1
+ class CreateSessions < ActiveRecord::Migration
2
+ def change
3
+ create_table(:sessions) do |t|
4
+ t.string :user_id
5
+ t.string :session_token
6
+ end
7
+ add_index :sessions, :session_token, :unique => true
8
+ end
9
+ end
@@ -0,0 +1,13 @@
1
+ class CreateOwner < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :owners do |t|
4
+ t.timestamps
5
+ t.string :username
6
+ end
7
+ add_index :owners, [:username]
8
+ end
9
+
10
+ def self.down
11
+ drop_table :owners
12
+ end
13
+ end
@@ -0,0 +1,23 @@
1
+ class CreateOauth2Authorizations < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :oauth2_authorizations do |t|
4
+ t.timestamps
5
+ t.string :oauth2_resource_owner_type
6
+ t.integer :oauth2_resource_owner_id
7
+ t.belongs_to :oauth2_client
8
+ t.string :scope
9
+ t.string :code, :limit => 40
10
+ t.string :access_token, :limit => 40
11
+ t.string :refresh_token, :limit => 40
12
+ t.datetime :expires_at
13
+ end
14
+ add_index :oauth2_authorizations, [:oauth2_client_id, :code]
15
+ add_index :oauth2_authorizations, [:access_token]
16
+ add_index :oauth2_authorizations, [:oauth2_client_id, :access_token], :name => 'access_token_index'
17
+ add_index :oauth2_authorizations, [:oauth2_client_id, :refresh_token], :name => 'refresh_token_index'
18
+ end
19
+
20
+ def self.down
21
+ drop_table :oauth2_authorizations
22
+ end
23
+ end
@@ -0,0 +1,18 @@
1
+ class CreateOauth2Clients < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :oauth2_clients do |t|
4
+ t.string :name
5
+ t.string :client_id
6
+ t.string :client_secret_hash
7
+ t.string :redirect_uri
8
+ t.string :basic_code
9
+ t.timestamps
10
+ end
11
+ add_index :oauth2_clients, :client_id, :unique => true
12
+ end
13
+
14
+ def self.down
15
+ drop_table :oauth2_clients
16
+ end
17
+
18
+ end
@@ -0,0 +1,16 @@
1
+ source "http://rubygems.org"
2
+
3
+
4
+ gem 'pg'
5
+ gem 'em-postgresql-adapter', :git => 'git://github.com/leftbee/em-postgresql-adapter.git'
6
+ gem 'rack-fiber_pool', :require => 'rack/fiber_pool'
7
+ gem 'em-synchrony', :git => 'git://github.com/igrigorik/em-synchrony.git',
8
+ :require => ['em-synchrony', 'em-synchrony/activerecord', 'em-synchrony/mysql2']
9
+
10
+ gem 'grape'
11
+ gem 'goliath'
12
+
13
+ gem "activerecord", "~> 3.1.1"
14
+ gem 'rack-fiber_pool', :require => 'rack/fiber_pool'
15
+ gem "mysql2"
16
+
File without changes
@@ -0,0 +1 @@
1
+ web: bundle exec ruby server.rb -sv -e prod -p $PORT
@@ -0,0 +1,47 @@
1
+ require "rubygems"
2
+ require "bundler/setup"
3
+ require 'em-synchrony/activerecord'
4
+ require 'yaml'
5
+ require 'erb'
6
+
7
+ namespace :db do
8
+ desc "loads database configuration in for other tasks to run"
9
+ task :load_config do
10
+ ActiveRecord::Base.configurations = db_conf
11
+
12
+ # drop and create need to be performed with a connection to the 'postgres' (system) database
13
+ ActiveRecord::Base.establish_connection db_conf["production"].merge('database' => 'postgres',
14
+ 'schema_search_path' => 'public')
15
+ end
16
+
17
+ desc "creates and migrates your database"
18
+ task :setup => :load_config do
19
+ Rake::Task["db:create"].invoke
20
+ Rake::Task["db:migrate"].invoke
21
+ end
22
+
23
+ desc "migrate your database"
24
+ task :migrate do
25
+ ActiveRecord::Base.establish_connection db_conf["production"]
26
+
27
+ ActiveRecord::Migrator.migrate(
28
+ ActiveRecord::Migrator.migrations_paths,
29
+ ENV["VERSION"] ? ENV["VERSION"].to_i : nil
30
+ )
31
+ end
32
+
33
+ desc 'Drops the database'
34
+ task :drop => :load_config do
35
+ ActiveRecord::Base.connection.drop_database db_conf['production']['database']
36
+ end
37
+
38
+ desc 'Creates the database'
39
+ task :create => :load_config do
40
+ ActiveRecord::Base.connection.create_database db_conf['production']['database']
41
+ end
42
+
43
+ end
44
+
45
+ def db_conf
46
+ config = YAML.load(ERB.new(File.read('config/database.yml')).result)
47
+ end
@@ -0,0 +1,21 @@
1
+ require 'uri'
2
+ require 'em-synchrony/activerecord'
3
+ require 'yaml'
4
+ require 'erb'
5
+
6
+ # Sets up database configuration
7
+ db = URI.parse(ENV['DATABASE_URL'] || 'http://localhost')
8
+ if db.scheme == 'postgres' # Heroku environment
9
+ ActiveRecord::Base.establish_connection(
10
+ :adapter => db.scheme == 'postgres' ? 'em_postgresql' : db.scheme,
11
+ :host => db.host,
12
+ :username => db.user,
13
+ :password => db.password,
14
+ :database => db.path[1..-1],
15
+ :encoding => 'utf8'
16
+ )
17
+ else # local environment
18
+ environment = ENV['DATABASE_URL'] ? 'production' : 'development'
19
+ db = YAML.load(ERB.new(File.read('config/database.yml')).result)[environment]
20
+ ActiveRecord::Base.establish_connection(db)
21
+ end