rammer 1.1.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.
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