wd_sinatra_active_record 0.0.1
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/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +75 -0
- data/Rakefile +1 -0
- data/lib/wd_sinatra_active_record.rb +69 -0
- data/lib/wd_sinatra_active_record/db.rake +479 -0
- data/lib/wd_sinatra_active_record/version.rb +3 -0
- data/wd_sinatra_active_record.gemspec +21 -0
- metadata +70 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Matt Aimonetti
|
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,75 @@
|
|
1
|
+
# WdSinatraActiveRecord
|
2
|
+
|
3
|
+
Some code to avoid reinventing the wheel every time you want to use
|
4
|
+
ActiveRecord in a WeaselDiesel app backed by Sinatra.
|
5
|
+
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
gem 'wd_sinatra_active_record'
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install wd_sinatra_active_record
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
Add an ActiveRecord `database.yml` file in your config folder and then require this
|
24
|
+
gem in your `app.rb` file.
|
25
|
+
|
26
|
+
The DB settings can be accessed via:
|
27
|
+
|
28
|
+
DBConnector::DB_CONFIG[RACK_ENV]
|
29
|
+
|
30
|
+
If you need a secondary DB connection (to another DB for instance),
|
31
|
+
add a new entry to your `database.yml` config file:
|
32
|
+
|
33
|
+
development:
|
34
|
+
adapter: mysql2
|
35
|
+
encoding: utf8
|
36
|
+
reconnect: true
|
37
|
+
database: app_development
|
38
|
+
pool: 5
|
39
|
+
username: root
|
40
|
+
password:
|
41
|
+
socket: /tmp/mysql.sock
|
42
|
+
|
43
|
+
secondary:
|
44
|
+
adapter: mysql2
|
45
|
+
encoding: utf8
|
46
|
+
reconnect: true
|
47
|
+
database: app_development
|
48
|
+
pool: 5
|
49
|
+
username: root
|
50
|
+
password:
|
51
|
+
socket: /tmp/mysql.sock
|
52
|
+
|
53
|
+
Then in your `app.rb` after requiring this gem:
|
54
|
+
|
55
|
+
|
56
|
+
class SecondaryConnection < ActiveRecord::Base
|
57
|
+
self.abstract_class = true
|
58
|
+
end
|
59
|
+
secondary_config = DBConnector::DB_CONFIG[RACK_ENV]['secondary']
|
60
|
+
SecondaryConnection.establish_connection(secondary_config) unless ENV['DONT_CONNECT']
|
61
|
+
|
62
|
+
Then whichever `ActiveRecord` that needs to connect to the secondary DB
|
63
|
+
can inherit from `SecondaryConnection` instead of `ActiveRecord::Base`.
|
64
|
+
|
65
|
+
|
66
|
+
A rake file with some tasks is also available but I won't support that
|
67
|
+
feature for now.
|
68
|
+
|
69
|
+
## Contributing
|
70
|
+
|
71
|
+
1. Fork it
|
72
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
73
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
74
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
75
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require "wd_sinatra_active_record/version"
|
2
|
+
require 'active_record'
|
3
|
+
|
4
|
+
# Set the default value, feel free to overwrite
|
5
|
+
ActiveRecord::Base.default_timezone = :utc
|
6
|
+
|
7
|
+
|
8
|
+
module WdSinatraActiveRecord
|
9
|
+
|
10
|
+
##### DB Connection ########
|
11
|
+
module DBConnector
|
12
|
+
DB_CONFIG = YAML.load_file(File.join(WDSinatra::AppLoader.root_path, "config", "database.yml"))
|
13
|
+
|
14
|
+
module_function
|
15
|
+
|
16
|
+
def set_db_connection(env=RACK_ENV)
|
17
|
+
# Set the AR logger
|
18
|
+
if Object.const_defined?(:LOGGER)
|
19
|
+
ActiveRecord::Base.logger = LOGGER
|
20
|
+
else
|
21
|
+
ActiveRecord::Base.logger = Logger.new($stdout)
|
22
|
+
end
|
23
|
+
# Establish the DB connection
|
24
|
+
db_file = File.join(WDSinatra::AppLoader.root_path, "config", "database.yml")
|
25
|
+
if File.exist?(db_file)
|
26
|
+
hash_settings = YAML.load_file(db_file)
|
27
|
+
if hash_settings && hash_settings[env]
|
28
|
+
@db_configurations = hash_settings
|
29
|
+
@db_configuration = @db_configurations[env]
|
30
|
+
# overwrite DB name by using an ENV variable
|
31
|
+
if ENV['FORCED_DB_NAME']
|
32
|
+
print "Database name overwritten to be #{ENV['FORCED_DB_NAME']}\n"
|
33
|
+
@db_configurations[env]['database'] = @db_configuration['database'] = ENV['FORCED_DB_NAME']
|
34
|
+
end
|
35
|
+
connect_to_db unless ENV['DONT_CONNECT']
|
36
|
+
else
|
37
|
+
raise "#{db_file} doesn't have an entry for the #{env} environment"
|
38
|
+
end
|
39
|
+
else
|
40
|
+
raise "#{db_file} file missing, can't connect to the DB"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def db_configuration(env=RACK_ENV)
|
45
|
+
old_connect_status = ENV['DONT_CONNECT']
|
46
|
+
set_db_connection(env) unless @db_configuration
|
47
|
+
ENV['DONT_CONNECT'] = old_connect_status
|
48
|
+
@db_configuration
|
49
|
+
end
|
50
|
+
|
51
|
+
def db_configurations
|
52
|
+
db_configuration unless @db_configurations
|
53
|
+
@db_configurations
|
54
|
+
end
|
55
|
+
|
56
|
+
def connect_to_db
|
57
|
+
if @db_configuration
|
58
|
+
connection = ActiveRecord::Base.establish_connection(@db_configuration)
|
59
|
+
else
|
60
|
+
raise "Can't connect without the config previously set"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
DBConnector.set_db_connection
|
67
|
+
DBConnector.connect_to_db unless ENV['DONT_CONNECT']
|
68
|
+
|
69
|
+
end
|
@@ -0,0 +1,479 @@
|
|
1
|
+
# require 'active_support/core_ext/object/inclusion'
|
2
|
+
|
3
|
+
db_namespace = namespace :db do
|
4
|
+
|
5
|
+
task :load_config => :setup_app do
|
6
|
+
require 'active_record'
|
7
|
+
ActiveRecord::Base.configurations = DBConnector.db_configuration
|
8
|
+
ActiveRecord::Migrator.migrations_paths = [File.join(WDSinatra::AppLoader.root_path, 'db/migrate')]
|
9
|
+
end
|
10
|
+
|
11
|
+
desc 'Create the database from config/database.yml for the current RACK_ENV (use db:create:all to create all dbs in the config)'
|
12
|
+
task :create do
|
13
|
+
old_connect_env = ENV['DONT_CONNECT'] ? 'true' : nil
|
14
|
+
ENV['DONT_CONNECT'] = 'true'
|
15
|
+
Rake::Task["db:load_config"].invoke
|
16
|
+
create_database(DBConnector.db_configuration)
|
17
|
+
ENV['DONT_CONNECT'] = old_connect_env
|
18
|
+
end
|
19
|
+
|
20
|
+
def mysql_creation_options(config)
|
21
|
+
@charset = ENV['CHARSET'] || 'utf8'
|
22
|
+
@collation = ENV['COLLATION'] || 'utf8_unicode_ci'
|
23
|
+
{:charset => (config['charset'] || @charset), :collation => (config['collation'] || @collation)}
|
24
|
+
end
|
25
|
+
|
26
|
+
def create_database(config)
|
27
|
+
begin
|
28
|
+
if config['adapter'] =~ /sqlite/
|
29
|
+
if File.exist?(config['database'])
|
30
|
+
$stderr.puts "#{config['database']} already exists"
|
31
|
+
else
|
32
|
+
begin
|
33
|
+
# Create the SQLite database
|
34
|
+
ActiveRecord::Base.establish_connection(config)
|
35
|
+
ActiveRecord::Base.connection
|
36
|
+
rescue Exception => e
|
37
|
+
$stderr.puts e, *(e.backtrace)
|
38
|
+
$stderr.puts "Couldn't create database for #{config.inspect}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
return # Skip the else clause of begin/rescue
|
42
|
+
else
|
43
|
+
ActiveRecord::Base.establish_connection(config)
|
44
|
+
ActiveRecord::Base.connection
|
45
|
+
end
|
46
|
+
rescue
|
47
|
+
case config['adapter']
|
48
|
+
when /mysql/
|
49
|
+
if config['adapter'] =~ /jdbc/
|
50
|
+
#FIXME After Jdbcmysql gives this class
|
51
|
+
require 'active_record/railties/jdbcmysql_error'
|
52
|
+
error_class = ArJdbcMySQL::Error
|
53
|
+
else
|
54
|
+
error_class = config['adapter'] =~ /mysql2/ ? Mysql2::Error : Mysql::Error
|
55
|
+
end
|
56
|
+
access_denied_error = 1045
|
57
|
+
begin
|
58
|
+
ActiveRecord::Base.establish_connection(config.merge('database' => nil))
|
59
|
+
ActiveRecord::Base.connection.create_database(config['database'], mysql_creation_options(config))
|
60
|
+
ActiveRecord::Base.establish_connection(config)
|
61
|
+
rescue error_class => sqlerr
|
62
|
+
if sqlerr.errno == access_denied_error
|
63
|
+
print "#{sqlerr.error}. \nPlease provide the root password for your mysql installation\n>"
|
64
|
+
root_password = $stdin.gets.strip
|
65
|
+
grant_statement = "GRANT ALL PRIVILEGES ON #{config['database']}.* " \
|
66
|
+
"TO '#{config['username']}'@'localhost' " \
|
67
|
+
"IDENTIFIED BY '#{config['password']}' WITH GRANT OPTION;"
|
68
|
+
ActiveRecord::Base.establish_connection(config.merge(
|
69
|
+
'database' => nil, 'username' => 'root', 'password' => root_password))
|
70
|
+
ActiveRecord::Base.connection.create_database(config['database'], mysql_creation_options(config))
|
71
|
+
ActiveRecord::Base.connection.execute grant_statement
|
72
|
+
ActiveRecord::Base.establish_connection(config)
|
73
|
+
else
|
74
|
+
$stderr.puts sqlerr.error
|
75
|
+
$stderr.puts "Couldn't create database for #{config.inspect}, charset: #{config['charset'] || @charset}, collation: #{config['collation'] || @collation}"
|
76
|
+
$stderr.puts "(if you set the charset manually, make sure you have a matching collation)" if config['charset']
|
77
|
+
end
|
78
|
+
end
|
79
|
+
when /postgresql/
|
80
|
+
@encoding = config['encoding'] || ENV['CHARSET'] || 'utf8'
|
81
|
+
begin
|
82
|
+
ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres', 'schema_search_path' => 'public'))
|
83
|
+
ActiveRecord::Base.connection.create_database(config['database'], config.merge('encoding' => @encoding))
|
84
|
+
ActiveRecord::Base.establish_connection(config)
|
85
|
+
rescue Exception => e
|
86
|
+
$stderr.puts e, *(e.backtrace)
|
87
|
+
$stderr.puts "Couldn't create database for #{config.inspect}"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
else
|
91
|
+
# Bug with 1.9.2 Calling return within begin still executes else
|
92
|
+
$stderr.puts "#{config['database']} already exists" unless config['adapter'] =~ /sqlite/
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
desc 'Drops the database for the current RACK_ENV (use db:drop:all to drop all databases)'
|
97
|
+
task :drop do
|
98
|
+
Rake::Task["db:load_config"].invoke
|
99
|
+
config = DBConnector.db_configuration
|
100
|
+
begin
|
101
|
+
drop_database(config)
|
102
|
+
rescue Exception => e
|
103
|
+
$stderr.puts "Couldn't drop #{config['database']} : #{e.inspect}"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def local_database?(config, &block)
|
108
|
+
if config['host'].in?(['127.0.0.1', 'localhost']) || config['host'].blank?
|
109
|
+
yield
|
110
|
+
else
|
111
|
+
$stderr.puts "This task only modifies local databases. #{config['database']} is on a remote host."
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
|
116
|
+
desc "Migrate the database (options: VERSION=x, VERBOSE=false)."
|
117
|
+
task :migrate do
|
118
|
+
Rake::Task[:environment].invoke
|
119
|
+
Rake::Task["db:load_config"].invoke
|
120
|
+
ActiveRecord::Migration.verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true
|
121
|
+
if ActiveRecord::Migrator.migrations_paths.any?{|path| File.exist?(path)} && \
|
122
|
+
ActiveRecord::Migrator.migrations_paths.any?{|path| !Dir.glob("#{path}/*.rb").empty? }
|
123
|
+
ActiveRecord::Migrator.migrate(ActiveRecord::Migrator.migrations_paths, ENV["VERSION"] ? ENV["VERSION"].to_i : nil)
|
124
|
+
db_namespace["schema:dump"].invoke if ActiveRecord::Base.schema_format == :ruby
|
125
|
+
else
|
126
|
+
print "No migration files, will try loading the schema manually by calling $ rack db:schema:load\n"
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
namespace :migrate do
|
131
|
+
# desc 'Rollbacks the database one migration and re migrate up (options: STEP=x, VERSION=x).'
|
132
|
+
task :redo => [:environment, :load_config] do
|
133
|
+
if ENV['VERSION']
|
134
|
+
db_namespace['migrate:down'].invoke
|
135
|
+
db_namespace['migrate:up'].invoke
|
136
|
+
else
|
137
|
+
db_namespace['rollback'].invoke
|
138
|
+
db_namespace['migrate'].invoke
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
# desc 'Resets your database using your migrations for the current environment'
|
143
|
+
task :reset => ['db:drop', 'db:create', 'db:migrate']
|
144
|
+
|
145
|
+
# desc 'Runs the "up" for a given migration VERSION.'
|
146
|
+
task :up => [:environment, :load_config] do
|
147
|
+
version = ENV['VERSION'] ? ENV['VERSION'].to_i : nil
|
148
|
+
raise 'VERSION is required' unless version
|
149
|
+
ActiveRecord::Migrator.run(:up, ActiveRecord::Migrator.migrations_paths, version)
|
150
|
+
db_namespace['schema:dump'].invoke if ActiveRecord::Base.schema_format == :ruby
|
151
|
+
end
|
152
|
+
|
153
|
+
# desc 'Runs the "down" for a given migration VERSION.'
|
154
|
+
task :down => [:environment, :load_config] do
|
155
|
+
version = ENV['VERSION'] ? ENV['VERSION'].to_i : nil
|
156
|
+
raise 'VERSION is required' unless version
|
157
|
+
ActiveRecord::Migrator.run(:down, ActiveRecord::Migrator.migrations_paths, version)
|
158
|
+
db_namespace['schema:dump'].invoke if ActiveRecord::Base.schema_format == :ruby
|
159
|
+
end
|
160
|
+
|
161
|
+
desc 'Display status of migrations'
|
162
|
+
task :status => [:environment, :load_config] do
|
163
|
+
config = DBConnector.db_configuration
|
164
|
+
ActiveRecord::Base.establish_connection(config)
|
165
|
+
unless ActiveRecord::Base.connection.table_exists?(ActiveRecord::Migrator.schema_migrations_table_name)
|
166
|
+
puts 'Schema migrations table does not exist yet.'
|
167
|
+
next # means "return" for rake task
|
168
|
+
end
|
169
|
+
db_list = ActiveRecord::Base.connection.select_values("SELECT version FROM #{ActiveRecord::Migrator.schema_migrations_table_name}")
|
170
|
+
file_list = []
|
171
|
+
Dir.foreach(File.join(WDSinatra::AppLoader.root_path, 'db', 'migrations')) do |file|
|
172
|
+
# only files matching "20091231235959_some_name.rb" pattern
|
173
|
+
if match_data = /^(\d{14})_(.+)\.rb$/.match(file)
|
174
|
+
status = db_list.delete(match_data[1]) ? 'up' : 'down'
|
175
|
+
file_list << [status, match_data[1], match_data[2].humanize]
|
176
|
+
end
|
177
|
+
end
|
178
|
+
db_list.map! do |version|
|
179
|
+
['up', version, '********** NO FILE **********']
|
180
|
+
end
|
181
|
+
# output
|
182
|
+
puts "\ndatabase: #{config['database']}\n\n"
|
183
|
+
puts "#{'Status'.center(8)} #{'Migration ID'.ljust(14)} Migration Name"
|
184
|
+
puts "-" * 50
|
185
|
+
(db_list + file_list).sort_by {|migration| migration[1]}.each do |migration|
|
186
|
+
puts "#{migration[0].center(8)} #{migration[1].ljust(14)} #{migration[2]}"
|
187
|
+
end
|
188
|
+
puts
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
desc 'Rolls the schema back to the previous version (specify steps w/ STEP=n).'
|
193
|
+
task :rollback => [:environment, :load_config] do
|
194
|
+
step = ENV['STEP'] ? ENV['STEP'].to_i : 1
|
195
|
+
ActiveRecord::Migrator.rollback(ActiveRecord::Migrator.migrations_paths, step)
|
196
|
+
db_namespace['schema:dump'].invoke if ActiveRecord::Base.schema_format == :ruby
|
197
|
+
end
|
198
|
+
|
199
|
+
# desc 'Pushes the schema to the next version (specify steps w/ STEP=n).'
|
200
|
+
task :forward => [:environment, :load_config] do
|
201
|
+
step = ENV['STEP'] ? ENV['STEP'].to_i : 1
|
202
|
+
ActiveRecord::Migrator.forward(ActiveRecord::Migrator.migrations_paths, step)
|
203
|
+
db_namespace['schema:dump'].invoke if ActiveRecord::Base.schema_format == :ruby
|
204
|
+
end
|
205
|
+
|
206
|
+
# desc 'Drops and recreates the database from db/schema.rb for the current environment and loads the seeds.'
|
207
|
+
task :reset => [ 'db:drop', 'db:setup' ]
|
208
|
+
|
209
|
+
# desc "Retrieves the charset for the current environment's database"
|
210
|
+
task :charset => :setup_app do
|
211
|
+
config = DBConnector.db_configuration
|
212
|
+
case config['adapter']
|
213
|
+
when /mysql/
|
214
|
+
ActiveRecord::Base.establish_connection(config)
|
215
|
+
puts ActiveRecord::Base.connection.charset
|
216
|
+
when /postgresql/
|
217
|
+
ActiveRecord::Base.establish_connection(config)
|
218
|
+
puts ActiveRecord::Base.connection.encoding
|
219
|
+
when /sqlite/
|
220
|
+
ActiveRecord::Base.establish_connection(config)
|
221
|
+
puts ActiveRecord::Base.connection.encoding
|
222
|
+
else
|
223
|
+
$stderr.puts 'sorry, your database adapter is not supported yet, feel free to submit a patch'
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
# desc "Retrieves the collation for the current environment's database"
|
228
|
+
task :collation => :setup_app do
|
229
|
+
config = DBConnector.db_configuration
|
230
|
+
case config['adapter']
|
231
|
+
when /mysql/
|
232
|
+
ActiveRecord::Base.establish_connection(config)
|
233
|
+
puts ActiveRecord::Base.connection.collation
|
234
|
+
else
|
235
|
+
$stderr.puts 'sorry, your database adapter is not supported yet, feel free to submit a patch'
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
desc 'Retrieves the current schema version number'
|
240
|
+
task :version => :setup_app do
|
241
|
+
puts "Current version: #{ActiveRecord::Migrator.current_version}"
|
242
|
+
end
|
243
|
+
|
244
|
+
# desc "Raises an error if there are pending migrations"
|
245
|
+
task :abort_if_pending_migrations => [:environment, :setup_app] do
|
246
|
+
if defined? ActiveRecord
|
247
|
+
pending_migrations = ActiveRecord::Migrator.new(:up, ActiveRecord::Migrator.migrations_paths).pending_migrations
|
248
|
+
|
249
|
+
if pending_migrations.any?
|
250
|
+
puts "You have #{pending_migrations.size} pending migrations:"
|
251
|
+
pending_migrations.each do |pending_migration|
|
252
|
+
puts ' %4d %s' % [pending_migration.version, pending_migration.name]
|
253
|
+
end
|
254
|
+
abort %{Run "rake db:migrate" to update your database then try again.}
|
255
|
+
end
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
desc 'Create the database, load the schema, and initialize with the seed data (use db:reset to also drop the db first)'
|
260
|
+
task :setup => [ 'db:create', 'db:schema:load', 'db:seed' ]
|
261
|
+
|
262
|
+
desc 'Load the seed data from db/seeds.rb'
|
263
|
+
task :seed do
|
264
|
+
old_no_redis = ENV['NO_REDIS'] ? 'true' : nil
|
265
|
+
ENV['NO_REDIS'] = 'true'
|
266
|
+
Rake::Task[:environment].invoke
|
267
|
+
Rake::Task["db:abort_if_pending_migrations"].invoke
|
268
|
+
seed = File.join(WDSinatra::AppLoader.root_path, "db", "seed.rb")
|
269
|
+
if File.exist?(seed)
|
270
|
+
puts "seeding #{seed}"
|
271
|
+
load seed
|
272
|
+
else
|
273
|
+
puts "Seed file: #{seed} is missing"
|
274
|
+
end
|
275
|
+
ENV['NO_REDIS'] = old_no_redis
|
276
|
+
end
|
277
|
+
|
278
|
+
namespace :fixtures do
|
279
|
+
desc "Load fixtures into the current environment's database. Load specific fixtures using FIXTURES=x,y. Load from subdirectory in test/fixtures using FIXTURES_DIR=z. Specify an alternative path (eg. spec/fixtures) using FIXTURES_PATH=spec/fixtures."
|
280
|
+
task :load => :setup_app do
|
281
|
+
require 'active_record/fixtures'
|
282
|
+
|
283
|
+
ActiveRecord::Base.establish_connection(RACK_ENV)
|
284
|
+
base_dir = File.join [WDSinatra::AppLoader.root_path, ENV['FIXTURES_PATH'] || %w{test fixtures}].flatten
|
285
|
+
fixtures_dir = File.join [base_dir, ENV['FIXTURES_DIR']].compact
|
286
|
+
|
287
|
+
(ENV['FIXTURES'] ? ENV['FIXTURES'].split(/,/) : Dir["#{fixtures_dir}/**/*.{yml,csv}"].map {|f| f[(fixtures_dir.size + 1)..-5] }).each do |fixture_file|
|
288
|
+
ActiveRecord::Fixtures.create_fixtures(fixtures_dir, fixture_file)
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
# desc "Search for a fixture given a LABEL or ID. Specify an alternative path (eg. spec/fixtures) using FIXTURES_PATH=spec/fixtures."
|
293
|
+
task :identify => :setup_app do
|
294
|
+
require 'active_record/fixtures'
|
295
|
+
|
296
|
+
label, id = ENV['LABEL'], ENV['ID']
|
297
|
+
raise 'LABEL or ID required' if label.blank? && id.blank?
|
298
|
+
|
299
|
+
puts %Q(The fixture ID for "#{label}" is #{ActiveRecord::Fixtures.identify(label)}.) if label
|
300
|
+
|
301
|
+
base_dir = ENV['FIXTURES_PATH'] ? File.join(WDSinatra::AppLoader.root_path, ENV['FIXTURES_PATH']) : File.join(WDSinatra::AppLoader.root_path, 'test', 'fixtures')
|
302
|
+
Dir["#{base_dir}/**/*.yml"].each do |file|
|
303
|
+
if data = YAML::load(ERB.new(IO.read(file)).result)
|
304
|
+
data.keys.each do |key|
|
305
|
+
key_id = ActiveRecord::Fixtures.identify(key)
|
306
|
+
|
307
|
+
if key == label || key_id == id.to_i
|
308
|
+
puts "#{file}: #{key} (#{key_id})"
|
309
|
+
end
|
310
|
+
end
|
311
|
+
end
|
312
|
+
end
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
namespace :schema do
|
317
|
+
desc 'Create a db/schema.rb file that can be portably used against any DB supported by AR'
|
318
|
+
task :dump => :load_config do
|
319
|
+
require 'active_record/schema_dumper'
|
320
|
+
filename = ENV['SCHEMA'] || "#{WDSinatra::AppLoader.root_path}/db/schema.rb"
|
321
|
+
File.open(filename, "w:utf-8") do |file|
|
322
|
+
ActiveRecord::Base.establish_connection(DBConnector.db_configuration)
|
323
|
+
ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file)
|
324
|
+
end
|
325
|
+
db_namespace['schema:dump'].reenable
|
326
|
+
end
|
327
|
+
|
328
|
+
desc 'Load a schema.rb file into the database'
|
329
|
+
task :load do
|
330
|
+
root = File.expand_path('../..', File.dirname(__FILE__))
|
331
|
+
WDSinatra::AppLoader.console(root)
|
332
|
+
file = ENV['SCHEMA'] || "#{WDSinatra::AppLoader.root_path}/db/schema.rb"
|
333
|
+
if File.exists?(file)
|
334
|
+
load(file)
|
335
|
+
else
|
336
|
+
abort %{#{file} doesn't exist yet. Run "rake db:migrate" to create it then try again. If you do not intend to use a database, you should instead alter #{WDSinatra::AppLoader.root_path}/config/application.rb to limit the frameworks that will be loaded}
|
337
|
+
end
|
338
|
+
end
|
339
|
+
end
|
340
|
+
|
341
|
+
namespace :structure do
|
342
|
+
desc 'Dump the database structure to an SQL file'
|
343
|
+
task :dump => :setup_app do
|
344
|
+
abcs = DBConnector.db_configuration
|
345
|
+
case abcs[RACK_ENV]['adapter']
|
346
|
+
when /mysql/, 'oci', 'oracle'
|
347
|
+
ActiveRecord::Base.establish_connection(config)
|
348
|
+
File.open("#{WDSinatra::AppLoader.root_path}/db/#{RACK_ENV}_structure.sql", "w+") { |f| f << ActiveRecord::Base.connection.structure_dump }
|
349
|
+
when /postgresql/
|
350
|
+
ENV['PGHOST'] = abcs[RACK_ENV]['host'] if abcs[RACK_ENV]['host']
|
351
|
+
ENV['PGPORT'] = abcs[RACK_ENV]["port"].to_s if abcs[RACK_ENV]['port']
|
352
|
+
ENV['PGPASSWORD'] = abcs[RACK_ENV]['password'].to_s if abcs[RACK_ENV]['password']
|
353
|
+
search_path = abcs[RACK_ENV]['schema_search_path']
|
354
|
+
unless search_path.blank?
|
355
|
+
search_path = search_path.split(",").map{|search_path_part| "--schema=#{search_path_part.strip}" }.join(" ")
|
356
|
+
end
|
357
|
+
`pg_dump -i -U "#{abcs[RACK_ENV]['username']}" -s -x -O -f db/#{RACK_ENV}_structure.sql #{search_path} #{abcs[RACK_ENV]['database']}`
|
358
|
+
raise 'Error dumping database' if $?.exitstatus == 1
|
359
|
+
when /sqlite/
|
360
|
+
dbfile = abcs[RACK_ENV]['database'] || abcs[RACK_ENV]['dbfile']
|
361
|
+
`sqlite3 #{dbfile} .schema > db/#{RACK_ENV}_structure.sql`
|
362
|
+
when 'sqlserver'
|
363
|
+
`smoscript -s #{abcs[RACK_ENV]['host']} -d #{abcs[RACK_ENV]['database']} -u #{abcs[RACK_ENV]['username']} -p #{abcs[RACK_ENV]['password']} -f db\\#{RACK_ENV}_structure.sql -A -U`
|
364
|
+
when "firebird"
|
365
|
+
set_firebird_env(abcs[RACK_ENV])
|
366
|
+
db_string = firebird_db_string(abcs[RACK_ENV])
|
367
|
+
sh "isql -a #{db_string} > #{WDSinatra::AppLoader.root_path}/db/#{RACK_ENV}_structure.sql"
|
368
|
+
else
|
369
|
+
raise "Task not supported by '#{abcs[RACK_ENV]["adapter"]}'"
|
370
|
+
end
|
371
|
+
|
372
|
+
if ActiveRecord::Base.connection.supports_migrations?
|
373
|
+
File.open("#{WDSinatra::AppLoader.root_path}/db/#{RACK_ENV}_structure.sql", "a") { |f| f << ActiveRecord::Base.connection.dump_schema_information }
|
374
|
+
end
|
375
|
+
end
|
376
|
+
end
|
377
|
+
|
378
|
+
namespace :test do
|
379
|
+
# desc "Recreate the test database from the current schema.rb"
|
380
|
+
task :load => 'db:test:purge' do
|
381
|
+
ActiveRecord::Base.establish_connection(DBConnector.db_configuration('test'))
|
382
|
+
ActiveRecord::Schema.verbose = false
|
383
|
+
db_namespace['schema:load'].invoke
|
384
|
+
end
|
385
|
+
|
386
|
+
# desc "Recreate the test database from the current environment's database schema"
|
387
|
+
task :clone => %w(db:schema:dump db:test:load)
|
388
|
+
|
389
|
+
# desc "Recreate the test databases from the development structure"
|
390
|
+
task :clone_structure => [ 'db:structure:dump', 'db:test:purge' ] do
|
391
|
+
abcs = ActiveRecord::Base.configurations
|
392
|
+
case abcs['test']['adapter']
|
393
|
+
when /mysql/
|
394
|
+
ActiveRecord::Base.establish_connection(:test)
|
395
|
+
ActiveRecord::Base.connection.execute('SET foreign_key_checks = 0')
|
396
|
+
IO.readlines("#{WDSinatra::AppLoader.root_path}/db/#{RACK_ENV}_structure.sql").join.split("\n\n").each do |table|
|
397
|
+
ActiveRecord::Base.connection.execute(table)
|
398
|
+
end
|
399
|
+
when /postgresql/
|
400
|
+
ENV['PGHOST'] = abcs['test']['host'] if abcs['test']['host']
|
401
|
+
ENV['PGPORT'] = abcs['test']['port'].to_s if abcs['test']['port']
|
402
|
+
ENV['PGPASSWORD'] = abcs['test']['password'].to_s if abcs['test']['password']
|
403
|
+
`psql -U "#{abcs['test']['username']}" -f #{WDSinatra::AppLoader.root_path}/db/#{RACK_ENV}_structure.sql #{abcs['test']['database']} #{abcs['test']['template']}`
|
404
|
+
when /sqlite/
|
405
|
+
dbfile = abcs['test']['database'] || abcs['test']['dbfile']
|
406
|
+
`sqlite3 #{dbfile} < #{WDSinatra::AppLoader.root_path}/db/#{RACK_ENV}_structure.sql`
|
407
|
+
when 'sqlserver'
|
408
|
+
`sqlcmd -S #{abcs['test']['host']} -d #{abcs['test']['database']} -U #{abcs['test']['username']} -P #{abcs['test']['password']} -i db\\#{RACK_ENV}_structure.sql`
|
409
|
+
when 'oci', 'oracle'
|
410
|
+
ActiveRecord::Base.establish_connection(:test)
|
411
|
+
IO.readlines("#{WDSinatra::AppLoader.root_path}/db/#{RACK_ENV}_structure.sql").join.split(";\n\n").each do |ddl|
|
412
|
+
ActiveRecord::Base.connection.execute(ddl)
|
413
|
+
end
|
414
|
+
when 'firebird'
|
415
|
+
set_firebird_env(abcs['test'])
|
416
|
+
db_string = firebird_db_string(abcs['test'])
|
417
|
+
sh "isql -i #{WDSinatra::AppLoader.root_path}/db/#{RACK_ENV}_structure.sql #{db_string}"
|
418
|
+
else
|
419
|
+
raise "Task not supported by '#{abcs['test']['adapter']}'"
|
420
|
+
end
|
421
|
+
end
|
422
|
+
|
423
|
+
# desc "Empty the test database"
|
424
|
+
task :purge => :setup_app do
|
425
|
+
abcs = DBConnector.db_configuration('test')
|
426
|
+
case abcs['adapter']
|
427
|
+
when /mysql/
|
428
|
+
ActiveRecord::Base.establish_connection(abcs)
|
429
|
+
ActiveRecord::Base.connection.recreate_database(abcs['database'], mysql_creation_options(abcs))
|
430
|
+
when /postgresql/
|
431
|
+
ActiveRecord::Base.clear_active_connections!
|
432
|
+
drop_database(abcs)
|
433
|
+
create_database(abcs)
|
434
|
+
when /sqlite/
|
435
|
+
dbfile = abcs['database'] || abcs['dbfile']
|
436
|
+
File.delete(dbfile) if File.exist?(dbfile)
|
437
|
+
when 'sqlserver'
|
438
|
+
test = abcs.deep_dup
|
439
|
+
test_database = test['database']
|
440
|
+
test['database'] = 'master'
|
441
|
+
ActiveRecord::Base.establish_connection(test)
|
442
|
+
ActiveRecord::Base.connection.recreate_database!(test_database)
|
443
|
+
else
|
444
|
+
raise "Task not supported by '#{abcs['adapter']}'"
|
445
|
+
end
|
446
|
+
end
|
447
|
+
|
448
|
+
# desc 'Check for pending migrations and load the test schema'
|
449
|
+
task :prepare => 'db:abort_if_pending_migrations' do
|
450
|
+
if defined?(ActiveRecord) && !ActiveRecord::Base.configurations.blank?
|
451
|
+
db_namespace[{ :sql => 'test:clone_structure', :ruby => 'test:load' }[ActiveRecord::Base.schema_format]].invoke
|
452
|
+
end
|
453
|
+
end
|
454
|
+
end
|
455
|
+
|
456
|
+
end
|
457
|
+
|
458
|
+
task 'test:prepare' => 'db:test:prepare'
|
459
|
+
|
460
|
+
def drop_database(config)
|
461
|
+
case config['adapter']
|
462
|
+
when /mysql/
|
463
|
+
ActiveRecord::Base.establish_connection(config)
|
464
|
+
ActiveRecord::Base.connection.drop_database config['database']
|
465
|
+
when /sqlite/
|
466
|
+
require 'pathname'
|
467
|
+
path = Pathname.new(config['database'])
|
468
|
+
file = path.absolute? ? path.to_s : File.join(WDSinatra::AppLoader.root_path, path)
|
469
|
+
|
470
|
+
FileUtils.rm(file) if File.exist?(file)
|
471
|
+
when /postgresql/
|
472
|
+
ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres', 'schema_search_path' => 'public'))
|
473
|
+
ActiveRecord::Base.connection.drop_database config['database']
|
474
|
+
end
|
475
|
+
end
|
476
|
+
|
477
|
+
def session_table_name
|
478
|
+
ActiveRecord::SessionStore::Session.table_name
|
479
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'wd_sinatra_active_record/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "wd_sinatra_active_record"
|
8
|
+
gem.version = WdSinatraActiveRecord::VERSION
|
9
|
+
gem.authors = ["Matt Aimonetti"]
|
10
|
+
gem.email = ["mattaimonetti@gmail.com"]
|
11
|
+
gem.description = %q{Basics to use ActiveRecord with WD Sinatra.}
|
12
|
+
gem.summary = %q{Provides a way to get started with ActiveRecord and WeaselDiesel on Sinatra.}
|
13
|
+
gem.homepage = ""
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.add_dependency "activerecord"
|
21
|
+
end
|
metadata
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: wd_sinatra_active_record
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Matt Aimonetti
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-11-14 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: activerecord
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
description: Basics to use ActiveRecord with WD Sinatra.
|
31
|
+
email:
|
32
|
+
- mattaimonetti@gmail.com
|
33
|
+
executables: []
|
34
|
+
extensions: []
|
35
|
+
extra_rdoc_files: []
|
36
|
+
files:
|
37
|
+
- .gitignore
|
38
|
+
- Gemfile
|
39
|
+
- LICENSE.txt
|
40
|
+
- README.md
|
41
|
+
- Rakefile
|
42
|
+
- lib/wd_sinatra_active_record.rb
|
43
|
+
- lib/wd_sinatra_active_record/db.rake
|
44
|
+
- lib/wd_sinatra_active_record/version.rb
|
45
|
+
- wd_sinatra_active_record.gemspec
|
46
|
+
homepage: ''
|
47
|
+
licenses: []
|
48
|
+
post_install_message:
|
49
|
+
rdoc_options: []
|
50
|
+
require_paths:
|
51
|
+
- lib
|
52
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ! '>='
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '0'
|
58
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
59
|
+
none: false
|
60
|
+
requirements:
|
61
|
+
- - ! '>='
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '0'
|
64
|
+
requirements: []
|
65
|
+
rubyforge_project:
|
66
|
+
rubygems_version: 1.8.24
|
67
|
+
signing_key:
|
68
|
+
specification_version: 3
|
69
|
+
summary: Provides a way to get started with ActiveRecord and WeaselDiesel on Sinatra.
|
70
|
+
test_files: []
|