homeq 1.1.4
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +103 -0
- data/COPYING +348 -0
- data/README.rdoc +64 -0
- data/Rakefile +131 -0
- data/bin/hq +6 -0
- data/config/boot.rb +224 -0
- data/config/databases/frontbase.yml +28 -0
- data/config/databases/mysql.yml +54 -0
- data/config/databases/oracle.yml +39 -0
- data/config/databases/postgresql.yml +48 -0
- data/config/databases/sqlite2.yml +16 -0
- data/config/databases/sqlite3.yml +19 -0
- data/config/environment.rb +20 -0
- data/config/environments/development.cfg +35 -0
- data/config/environments/production.cfg +35 -0
- data/config/environments/test.cfg +35 -0
- data/config/generators/job/templates/job.rb.erb +20 -0
- data/config/generators/message/templates/messages/MESSAGE.proto.erb +12 -0
- data/config/generators/model/templates/models/MODEL.rb.erb +3 -0
- data/config/generators/service/templates/services/SERVICE.rb.erb +43 -0
- data/config/homeq.cfg +35 -0
- data/extras/consumer.rb +85 -0
- data/extras/homeq.cfg +49 -0
- data/extras/hqd.rb +33 -0
- data/extras/producer.rb +79 -0
- data/extras/simple_consumer.rb +53 -0
- data/lib/homeq/base/base.rb +44 -0
- data/lib/homeq/base/commando.rb +81 -0
- data/lib/homeq/base/config.rb +99 -0
- data/lib/homeq/base/exception.rb +48 -0
- data/lib/homeq/base/histogram.rb +141 -0
- data/lib/homeq/base/logger.rb +185 -0
- data/lib/homeq/base/ohash.rb +297 -0
- data/lib/homeq/base/options.rb +171 -0
- data/lib/homeq/base/poolable.rb +100 -0
- data/lib/homeq/base/system.rb +446 -0
- data/lib/homeq/cli.rb +35 -0
- data/lib/homeq/cp/commands.rb +71 -0
- data/lib/homeq/cp/connection.rb +97 -0
- data/lib/homeq/cp/cp.rb +30 -0
- data/lib/homeq/cp/server.rb +105 -0
- data/lib/homeq/sobs/client.rb +119 -0
- data/lib/homeq/sobs/connection.rb +635 -0
- data/lib/homeq/sobs/foreman.rb +237 -0
- data/lib/homeq/sobs/job.rb +66 -0
- data/lib/homeq/sobs/message.rb +49 -0
- data/lib/homeq/sobs/queue.rb +224 -0
- data/lib/homeq/sobs/sender.rb +150 -0
- data/lib/homeq/sobs/server.rb +654 -0
- data/lib/homeq/sobs/sobs.rb +45 -0
- data/lib/homeq/sobs/topology.rb +111 -0
- data/lib/homeq.rb +106 -0
- data/lib/tasks/Rakefile +49 -0
- data/lib/tasks/database.rake +387 -0
- data/lib/tasks/gem.rake +9 -0
- data/lib/tasks/generate.rake +192 -0
- data/lib/tasks/hq.rake +171 -0
- data/lib/tasks/testing.rake +95 -0
- data/lib/tasks/utility.rb +17 -0
- data/script/console.rb +45 -0
- data/script/generate +7 -0
- data/test/unittest.rb +51 -0
- metadata +222 -0
@@ -0,0 +1,111 @@
|
|
1
|
+
#############################################################################
|
2
|
+
#
|
3
|
+
# $Id: topology.rb 48 2008-11-19 05:11:59Z colin $
|
4
|
+
#
|
5
|
+
# Author:: Colin Steele (colin@colinsteele.org)
|
6
|
+
# Homepage::
|
7
|
+
#
|
8
|
+
# TODO: info
|
9
|
+
#
|
10
|
+
#----------------------------------------------------------------------------
|
11
|
+
#
|
12
|
+
# Copyright (C) 2008 by Colin Steele. All Rights Reserved.
|
13
|
+
# colin@colinsteele.org
|
14
|
+
#
|
15
|
+
# This program is free software; you can redistribute it and/or modify
|
16
|
+
# it under the terms of either: 1) the GNU General Public License
|
17
|
+
# as published by the Free Software Foundation; either version 2 of the
|
18
|
+
# License, or (at your option) any later version; or 2) Ruby's License.
|
19
|
+
#
|
20
|
+
# See the file COPYING for complete licensing information.
|
21
|
+
#
|
22
|
+
#---------------------------------------------------------------------------
|
23
|
+
#
|
24
|
+
#
|
25
|
+
#############################################################################
|
26
|
+
|
27
|
+
require 'yaml'
|
28
|
+
|
29
|
+
module HomeQ
|
30
|
+
|
31
|
+
module SOBS
|
32
|
+
|
33
|
+
module Topology
|
34
|
+
|
35
|
+
# Make our configuration available.
|
36
|
+
module HomeQ::Base::Commando::InstanceMethods
|
37
|
+
def topology
|
38
|
+
if block_given?
|
39
|
+
yield
|
40
|
+
else
|
41
|
+
sys.topology
|
42
|
+
end
|
43
|
+
end
|
44
|
+
def queue(queuename, &block)
|
45
|
+
sys.topology.queue(queuename) { |q|
|
46
|
+
q.instance_eval(&block)
|
47
|
+
}
|
48
|
+
end
|
49
|
+
document_command "topology", "Get/set queue topology"
|
50
|
+
document_command "queue(name) {}", "Configure queue topology"
|
51
|
+
end
|
52
|
+
|
53
|
+
class Topology
|
54
|
+
attr :queues, false
|
55
|
+
attr :connections, false
|
56
|
+
def initialize
|
57
|
+
@queues = {}
|
58
|
+
@connections = {}
|
59
|
+
end
|
60
|
+
def queue(name)
|
61
|
+
@current_queue = name
|
62
|
+
yield self
|
63
|
+
@current_queue = nil
|
64
|
+
end
|
65
|
+
def located_at(host, port, hostname='localhost')
|
66
|
+
@queues[@current_queue] = [@current_queue, host, port, hostname]
|
67
|
+
end
|
68
|
+
def connect(other_queue, mode=SOBS::Queue::READ_WRITE, threshold=nil)
|
69
|
+
@connections[@current_queue] ||= []
|
70
|
+
@connections[@current_queue] << [other_queue, mode, threshold]
|
71
|
+
end
|
72
|
+
def reads_from(other_queue, refuse_threshold = nil)
|
73
|
+
connect(other_queue, SOBS::Queue::READ_ONLY, refuse_threshold)
|
74
|
+
end
|
75
|
+
def writes_to(other_queue, refuse_threshold = nil)
|
76
|
+
connect(other_queue, SOBS::Queue::WRITE_ONLY, refuse_threshold)
|
77
|
+
end
|
78
|
+
def read_write(other_queue, refuse_threshold = nil)
|
79
|
+
connect(other_queue, SOBS::Queue::READ_WRITE, refuse_threshold)
|
80
|
+
end
|
81
|
+
def [](name)
|
82
|
+
@queues[name]
|
83
|
+
end
|
84
|
+
def connections(name)
|
85
|
+
@connections[name] || []
|
86
|
+
end
|
87
|
+
def to_s
|
88
|
+
str = ""
|
89
|
+
@queues.each { |name, tuple|
|
90
|
+
queue_name, host, port, hostname = tuple
|
91
|
+
str << "#{name} #{host} #{port} #{hostname}\n"
|
92
|
+
next unless @connections[name]
|
93
|
+
@connections[name].each { |other_queue, mode, threshold|
|
94
|
+
str << " #{mode.upcase} #{other_queue} #{threshold}\n"
|
95
|
+
}
|
96
|
+
}
|
97
|
+
str
|
98
|
+
end
|
99
|
+
def to_yaml
|
100
|
+
YAML.dump({
|
101
|
+
'queues' => @queues,
|
102
|
+
'connections' => @connections
|
103
|
+
})
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
end # Topology
|
108
|
+
|
109
|
+
end # SOBS
|
110
|
+
|
111
|
+
end # HomeQ
|
data/lib/homeq.rb
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
#############################################################################
|
2
|
+
#
|
3
|
+
# $Id: homeq.rb 45 2008-10-24 20:36:21Z colin $
|
4
|
+
#
|
5
|
+
# Author:: Colin Steele (colin@colinsteele.org)
|
6
|
+
# Homepage::
|
7
|
+
#
|
8
|
+
# TODO: info
|
9
|
+
#
|
10
|
+
#----------------------------------------------------------------------------
|
11
|
+
#
|
12
|
+
# Copyright (C) 2008 by Colin Steele. All Rights Reserved.
|
13
|
+
# colin@colinsteele.org
|
14
|
+
#
|
15
|
+
# This program is free software; you can redistribute it and/or modify
|
16
|
+
# it under the terms of either: 1) the GNU General Public License
|
17
|
+
# as published by the Free Software Foundation; either version 2 of the
|
18
|
+
# License, or (at your option) any later version; or 2) Ruby's License.
|
19
|
+
#
|
20
|
+
# See the file COPYING for complete licensing information.
|
21
|
+
#
|
22
|
+
#---------------------------------------------------------------------------
|
23
|
+
#
|
24
|
+
#
|
25
|
+
#############################################################################
|
26
|
+
|
27
|
+
require 'strscan'
|
28
|
+
require 'singleton'
|
29
|
+
require 'yaml'
|
30
|
+
|
31
|
+
HOMEQ_VERSION = "1.1.4" unless defined?(HOMEQ_VERSION)
|
32
|
+
unless defined?(HOMEQ_ROOT)
|
33
|
+
HOMEQ_ROOT = File.expand_path("#{File.dirname(__FILE__)}/..")
|
34
|
+
end
|
35
|
+
HOMEQ_ENV = (ENV['HOMEQ_ENV'] || 'production') unless defined?(HOMEQ_ENV)
|
36
|
+
|
37
|
+
module HomeQ
|
38
|
+
VERSION = HOMEQ_VERSION
|
39
|
+
def self.included(base)
|
40
|
+
base.class_eval {
|
41
|
+
include(HomeQ::HQ)
|
42
|
+
include(HomeQ::Base::Configuration)
|
43
|
+
include(HomeQ::Base::Logging)
|
44
|
+
}
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.calculated_homeq_env
|
48
|
+
if defined?(HOMEQ_APP_ROOT)
|
49
|
+
require "#{HOMEQ_APP_ROOT}/config/environment"
|
50
|
+
else
|
51
|
+
require 'config/environment'
|
52
|
+
end
|
53
|
+
|
54
|
+
options = HomeQ::Base::Options::Options.instance.options
|
55
|
+
sys = HomeQ::Base::System.instance
|
56
|
+
|
57
|
+
options.log_level = 'fatal'
|
58
|
+
options.foreground = true
|
59
|
+
options.queue_name = '__'
|
60
|
+
|
61
|
+
env = nil
|
62
|
+
sys.start {
|
63
|
+
env = HOMEQ_ENV
|
64
|
+
EM.next_tick {
|
65
|
+
sys.stop
|
66
|
+
}
|
67
|
+
}
|
68
|
+
env
|
69
|
+
end
|
70
|
+
|
71
|
+
def self.calculated_homeq_topology
|
72
|
+
if defined?(HOMEQ_APP_ROOT)
|
73
|
+
require "#{HOMEQ_APP_ROOT}/config/environment"
|
74
|
+
else
|
75
|
+
require 'config/environment'
|
76
|
+
end
|
77
|
+
|
78
|
+
options = HomeQ::Base::Options::Options.instance.options
|
79
|
+
sys = HomeQ::Base::System.instance
|
80
|
+
|
81
|
+
if sys.topology.queues.any?
|
82
|
+
return sys.topology
|
83
|
+
end
|
84
|
+
|
85
|
+
options.log_level = 'fatal'
|
86
|
+
options.foreground = true
|
87
|
+
options.queue_name = '__'
|
88
|
+
topology = nil
|
89
|
+
sys.start {
|
90
|
+
topology = sys.topology
|
91
|
+
sys.stop
|
92
|
+
}
|
93
|
+
topology
|
94
|
+
end
|
95
|
+
|
96
|
+
def self.queue_list_for_host_from_topology(some_hostname = `hostname`.chomp)
|
97
|
+
queues_for_this_host = []
|
98
|
+
self.
|
99
|
+
calculated_homeq_topology.queues.
|
100
|
+
values.each { |queue_name, host, port, hostname|
|
101
|
+
queues_for_this_host << queue_name if hostname == some_hostname
|
102
|
+
}
|
103
|
+
queues_for_this_host
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
data/lib/tasks/Rakefile
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
#############################################################################
|
3
|
+
#
|
4
|
+
# Author:: Colin Steele (colin@colinsteele.org)
|
5
|
+
#
|
6
|
+
#############################################################################
|
7
|
+
|
8
|
+
require 'rubygems'
|
9
|
+
require 'rake'
|
10
|
+
|
11
|
+
require File.join(File.dirname(__FILE__), '/config/environment')
|
12
|
+
|
13
|
+
require 'rake/testtask'
|
14
|
+
require 'rake/rdoctask'
|
15
|
+
|
16
|
+
# load custom tasks
|
17
|
+
Dir["#{HOMEQ_APP_ROOT}/lib/tasks/**/*.rake"].sort.each { |ext| load ext }
|
18
|
+
|
19
|
+
task :default => [:test]
|
20
|
+
|
21
|
+
desc "Load HOMEQ environment"
|
22
|
+
task (:environment) do
|
23
|
+
require File.join(File.dirname(__FILE__), '/config/environment')
|
24
|
+
end
|
25
|
+
|
26
|
+
desc "Recreate the CHANGELOG"
|
27
|
+
task(:changelog) do
|
28
|
+
rm 'CHANGELOG', :force => true
|
29
|
+
touch 'CHANGELOG'
|
30
|
+
puts %x[svn2cl.sh]
|
31
|
+
end
|
32
|
+
|
33
|
+
Rake::RDocTask.new do |rd|
|
34
|
+
rd.main = "README"
|
35
|
+
rd.rdoc_files.include("README", "lib/**/*.rb", "app/**/*.rb")
|
36
|
+
rd.rdoc_dir = 'doc'
|
37
|
+
rd.title = ''
|
38
|
+
rd.options << '--line-numbers'
|
39
|
+
rd.options << '--inline-source'
|
40
|
+
rd.options << '--main' << 'README'
|
41
|
+
end
|
42
|
+
|
43
|
+
desc "Recreate message classes from proto definitions"
|
44
|
+
task(:messages => Dir['app/messages/*.proto']) do |t|
|
45
|
+
cd 'app/messages'
|
46
|
+
t.prerequisites.each { |f|
|
47
|
+
sh "rprotoc -o wire #{File.basename(f)}"
|
48
|
+
}
|
49
|
+
end
|
@@ -0,0 +1,387 @@
|
|
1
|
+
namespace :db do
|
2
|
+
namespace :create do
|
3
|
+
desc 'Create all the local databases defined in config/database.yml'
|
4
|
+
task :all => :environment do
|
5
|
+
ActiveRecord::Base.configurations.each_value do |config|
|
6
|
+
# Skip entries that don't have a database key, such as the first entry here:
|
7
|
+
#
|
8
|
+
# defaults: &defaults
|
9
|
+
# adapter: mysql
|
10
|
+
# username: root
|
11
|
+
# password:
|
12
|
+
# host: localhost
|
13
|
+
#
|
14
|
+
# development:
|
15
|
+
# database: blog_development
|
16
|
+
# <<: *defaults
|
17
|
+
next unless config['database']
|
18
|
+
# Only connect to local databases
|
19
|
+
local_database?(config) { create_database(config) }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
desc 'Create the database defined in config/database.yml for the current HOMEQ_ENV'
|
25
|
+
task :create => :environment do
|
26
|
+
create_database(ActiveRecord::Base.configurations[HOMEQ_ENV])
|
27
|
+
end
|
28
|
+
|
29
|
+
def create_database(config)
|
30
|
+
begin
|
31
|
+
ActiveRecord::Base.establish_connection(config)
|
32
|
+
ActiveRecord::Base.connection
|
33
|
+
rescue
|
34
|
+
case config['adapter']
|
35
|
+
when 'mysql'
|
36
|
+
@charset = ENV['CHARSET'] || 'utf8'
|
37
|
+
@collation = ENV['COLLATION'] || 'utf8_general_ci'
|
38
|
+
begin
|
39
|
+
ActiveRecord::Base.establish_connection(config.merge('database' => nil))
|
40
|
+
ActiveRecord::Base.connection.create_database(config['database'], :charset => (config['charset'] || @charset), :collation => (config['collation'] || @collation))
|
41
|
+
ActiveRecord::Base.establish_connection(config)
|
42
|
+
rescue
|
43
|
+
$stderr.puts "Couldn't create database for #{config.inspect}, charset: #{config['charset'] || @charset}, collation: #{config['collation'] || @collation} (if you set the charset manually, make sure you have a matching collation)"
|
44
|
+
end
|
45
|
+
when 'postgresql'
|
46
|
+
@encoding = config[:encoding] || ENV['CHARSET'] || 'utf8'
|
47
|
+
begin
|
48
|
+
ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres', 'schema_search_path' => 'public'))
|
49
|
+
ActiveRecord::Base.connection.create_database(config['database'], config.merge('encoding' => @encoding))
|
50
|
+
ActiveRecord::Base.establish_connection(config)
|
51
|
+
rescue
|
52
|
+
$stderr.puts $!, *($!.backtrace)
|
53
|
+
$stderr.puts "Couldn't create database for #{config.inspect}"
|
54
|
+
end
|
55
|
+
when 'sqlite'
|
56
|
+
`sqlite "#{config['database']}"`
|
57
|
+
when 'sqlite3'
|
58
|
+
`sqlite3 "#{config['database']}"`
|
59
|
+
end
|
60
|
+
else
|
61
|
+
$stderr.puts "#{config['database']} already exists"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
namespace :drop do
|
66
|
+
desc 'Drops all the local databases defined in config/database.yml'
|
67
|
+
task :all => :environment do
|
68
|
+
ActiveRecord::Base.configurations.each_value do |config|
|
69
|
+
# Skip entries that don't have a database key
|
70
|
+
next unless config['database']
|
71
|
+
# Only connect to local databases
|
72
|
+
local_database?(config) { drop_database(config) }
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
desc 'Drops the database for the current HOMEQ_ENV'
|
78
|
+
task :drop => :environment do
|
79
|
+
config = ActiveRecord::Base.configurations[HOMEQ_ENV || 'development']
|
80
|
+
begin
|
81
|
+
drop_database(config)
|
82
|
+
rescue Exception => e
|
83
|
+
puts "Couldn't drop #{config['database']} : #{e.inspect}"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def local_database?(config, &block)
|
88
|
+
if %w( 127.0.0.1 localhost ).include?(config['host']) || config['host'].blank?
|
89
|
+
yield
|
90
|
+
else
|
91
|
+
puts "This task only modifies local databases. #{config['database']} is on a remote host."
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
|
96
|
+
desc "Migrate the database through scripts in db/migrate. Target specific version with VERSION=x. Turn off output with VERBOSE=false."
|
97
|
+
task :migrate => :environment do
|
98
|
+
ActiveRecord::Migration.verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true
|
99
|
+
ActiveRecord::Migrator.migrate("db/migrate/", ENV["VERSION"] ? ENV["VERSION"].to_i : nil)
|
100
|
+
Rake::Task["db:schema:dump"].invoke if ActiveRecord::Base.schema_format == :ruby
|
101
|
+
end
|
102
|
+
|
103
|
+
namespace :migrate do
|
104
|
+
desc 'Rollbacks the database one migration and re migrate up. If you want to rollback more than one step, define STEP=x'
|
105
|
+
task :redo => [ 'db:rollback', 'db:migrate' ]
|
106
|
+
|
107
|
+
desc 'Resets your database using your migrations for the current environment'
|
108
|
+
task :reset => ["db:drop", "db:create", "db:migrate"]
|
109
|
+
|
110
|
+
desc 'Runs the "up" for a given migration VERSION.'
|
111
|
+
task :up => :environment do
|
112
|
+
version = ENV["VERSION"] ? ENV["VERSION"].to_i : nil
|
113
|
+
raise "VERSION is required" unless version
|
114
|
+
ActiveRecord::Migrator.run(:up, "db/migrate/", version)
|
115
|
+
Rake::Task["db:schema:dump"].invoke if ActiveRecord::Base.schema_format == :ruby
|
116
|
+
end
|
117
|
+
|
118
|
+
desc 'Runs the "down" for a given migration VERSION.'
|
119
|
+
task :down => :environment do
|
120
|
+
version = ENV["VERSION"] ? ENV["VERSION"].to_i : nil
|
121
|
+
raise "VERSION is required" unless version
|
122
|
+
ActiveRecord::Migrator.run(:down, "db/migrate/", version)
|
123
|
+
Rake::Task["db:schema:dump"].invoke if ActiveRecord::Base.schema_format == :ruby
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
desc 'Rolls the schema back to the previous version. Specify the number of steps with STEP=n'
|
128
|
+
task :rollback => :environment do
|
129
|
+
step = ENV['STEP'] ? ENV['STEP'].to_i : 1
|
130
|
+
ActiveRecord::Migrator.rollback('db/migrate/', step)
|
131
|
+
Rake::Task["db:schema:dump"].invoke if ActiveRecord::Base.schema_format == :ruby
|
132
|
+
end
|
133
|
+
|
134
|
+
desc 'Drops and recreates the database from db/schema.rb for the current environment.'
|
135
|
+
task :reset => ['db:drop', 'db:create', 'db:schema:load']
|
136
|
+
|
137
|
+
desc "Retrieves the charset for the current environment's database"
|
138
|
+
task :charset => :environment do
|
139
|
+
config = ActiveRecord::Base.configurations[HOMEQ_ENV || 'development']
|
140
|
+
case config['adapter']
|
141
|
+
when 'mysql'
|
142
|
+
ActiveRecord::Base.establish_connection(config)
|
143
|
+
puts ActiveRecord::Base.connection.charset
|
144
|
+
else
|
145
|
+
puts 'sorry, your database adapter is not supported yet, feel free to submit a patch'
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
desc "Retrieves the collation for the current environment's database"
|
150
|
+
task :collation => :environment do
|
151
|
+
config = ActiveRecord::Base.configurations[HOMEQ_ENV || 'development']
|
152
|
+
case config['adapter']
|
153
|
+
when 'mysql'
|
154
|
+
ActiveRecord::Base.establish_connection(config)
|
155
|
+
puts ActiveRecord::Base.connection.collation
|
156
|
+
else
|
157
|
+
puts 'sorry, your database adapter is not supported yet, feel free to submit a patch'
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
desc "Retrieves the current schema version number"
|
162
|
+
task :version => :environment do
|
163
|
+
puts "Current version: #{ActiveRecord::Migrator.current_version}"
|
164
|
+
end
|
165
|
+
|
166
|
+
desc "Raises an error if there are pending migrations"
|
167
|
+
task :abort_if_pending_migrations => :environment do
|
168
|
+
if defined? ActiveRecord
|
169
|
+
pending_migrations = ActiveRecord::Migrator.new(:up, 'db/migrate').pending_migrations
|
170
|
+
|
171
|
+
if pending_migrations.any?
|
172
|
+
puts "You have #{pending_migrations.size} pending migrations:"
|
173
|
+
pending_migrations.each do |pending_migration|
|
174
|
+
puts ' %4d %s' % [pending_migration.version, pending_migration.name]
|
175
|
+
end
|
176
|
+
abort %{Run "rake db:migrate" to update your database then try again.}
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
namespace :fixtures do
|
182
|
+
desc "Load fixtures into the current environment's database. Load specific fixtures using FIXTURES=x,y"
|
183
|
+
task :load => :environment do
|
184
|
+
require 'active_record/fixtures'
|
185
|
+
ActiveRecord::Base.establish_connection(HOMEQ_ENV.to_sym)
|
186
|
+
(ENV['FIXTURES'] ? ENV['FIXTURES'].split(/,/) : Dir.glob(File.join(HOMEQ_APP_ROOT, 'test', 'fixtures', '*.{yml,csv}'))).each do |fixture_file|
|
187
|
+
Fixtures.create_fixtures('test/fixtures', File.basename(fixture_file, '.*'))
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
desc "Search for a fixture given a LABEL or ID."
|
192
|
+
task :identify => :environment do
|
193
|
+
require "active_record/fixtures"
|
194
|
+
|
195
|
+
label, id = ENV["LABEL"], ENV["ID"]
|
196
|
+
raise "LABEL or ID required" if label.blank? && id.blank?
|
197
|
+
|
198
|
+
puts %Q(The fixture ID for "#{label}" is #{Fixtures.identify(label)}.) if label
|
199
|
+
|
200
|
+
Dir["#{HOMEQ_APP_ROOT}/test/fixtures/**/*.yml"].each do |file|
|
201
|
+
if data = YAML::load(ERB.new(IO.read(file)).result)
|
202
|
+
data.keys.each do |key|
|
203
|
+
key_id = Fixtures.identify(key)
|
204
|
+
|
205
|
+
if key == label || key_id == id.to_i
|
206
|
+
puts "#{file}: #{key} (#{key_id})"
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
namespace :schema do
|
215
|
+
desc "Create a db/schema.rb file that can be portably used against any DB supported by AR"
|
216
|
+
task :dump => :environment do
|
217
|
+
require 'active_record/schema_dumper'
|
218
|
+
File.open(ENV['SCHEMA'] || "db/schema.rb", "w") do |file|
|
219
|
+
ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file)
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
desc "Load a schema.rb file into the database"
|
224
|
+
task :load => :environment do
|
225
|
+
file = ENV['SCHEMA'] || "db/schema.rb"
|
226
|
+
load(file)
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
namespace :structure do
|
231
|
+
desc "Dump the database structure to a SQL file"
|
232
|
+
task :dump => :environment do
|
233
|
+
abcs = ActiveRecord::Base.configurations
|
234
|
+
case abcs[HOMEQ_ENV]["adapter"]
|
235
|
+
when "mysql", "oci", "oracle"
|
236
|
+
ActiveRecord::Base.establish_connection(abcs[HOMEQ_ENV])
|
237
|
+
File.open("db/#{HOMEQ_ENV}_structure.sql", "w+") { |f| f << ActiveRecord::Base.connection.structure_dump }
|
238
|
+
when "postgresql"
|
239
|
+
ENV['PGHOST'] = abcs[HOMEQ_ENV]["host"] if abcs[HOMEQ_ENV]["host"]
|
240
|
+
ENV['PGPORT'] = abcs[HOMEQ_ENV]["port"].to_s if abcs[HOMEQ_ENV]["port"]
|
241
|
+
ENV['PGPASSWORD'] = abcs[HOMEQ_ENV]["password"].to_s if abcs[HOMEQ_ENV]["password"]
|
242
|
+
search_path = abcs[HOMEQ_ENV]["schema_search_path"]
|
243
|
+
search_path = "--schema=#{search_path}" if search_path
|
244
|
+
`pg_dump -i -U "#{abcs[HOMEQ_ENV]["username"]}" -s -x -O -f db/#{HOMEQ_ENV}_structure.sql #{search_path} #{abcs[HOMEQ_ENV]["database"]}`
|
245
|
+
raise "Error dumping database" if $?.exitstatus == 1
|
246
|
+
when "sqlite", "sqlite3"
|
247
|
+
dbfile = abcs[HOMEQ_ENV]["database"] || abcs[HOMEQ_ENV]["dbfile"]
|
248
|
+
`#{abcs[HOMEQ_ENV]["adapter"]} #{dbfile} .schema > db/#{HOMEQ_ENV}_structure.sql`
|
249
|
+
when "sqlserver"
|
250
|
+
`scptxfr /s #{abcs[HOMEQ_ENV]["host"]} /d #{abcs[HOMEQ_ENV]["database"]} /I /f db\\#{HOMEQ_ENV}_structure.sql /q /A /r`
|
251
|
+
`scptxfr /s #{abcs[HOMEQ_ENV]["host"]} /d #{abcs[HOMEQ_ENV]["database"]} /I /F db\ /q /A /r`
|
252
|
+
when "firebird"
|
253
|
+
set_firebird_env(abcs[HOMEQ_ENV])
|
254
|
+
db_string = firebird_db_string(abcs[HOMEQ_ENV])
|
255
|
+
sh "isql -a #{db_string} > db/#{HOMEQ_ENV}_structure.sql"
|
256
|
+
else
|
257
|
+
raise "Task not supported by '#{abcs["test"]["adapter"]}'"
|
258
|
+
end
|
259
|
+
|
260
|
+
if ActiveRecord::Base.connection.supports_migrations?
|
261
|
+
File.open("db/#{HOMEQ_ENV}_structure.sql", "a") { |f| f << ActiveRecord::Base.connection.dump_schema_information }
|
262
|
+
end
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
namespace :test do
|
267
|
+
desc "Recreate the test database from the current environment's database schema"
|
268
|
+
task :clone => %w(db:schema:dump db:test:purge) do
|
269
|
+
ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations['test'])
|
270
|
+
ActiveRecord::Schema.verbose = false
|
271
|
+
Rake::Task["db:schema:load"].invoke
|
272
|
+
end
|
273
|
+
|
274
|
+
|
275
|
+
desc "Recreate the test databases from the development structure"
|
276
|
+
task :clone_structure => [ "db:structure:dump", "db:test:purge" ] do
|
277
|
+
abcs = ActiveRecord::Base.configurations
|
278
|
+
case abcs["test"]["adapter"]
|
279
|
+
when "mysql"
|
280
|
+
ActiveRecord::Base.establish_connection(:test)
|
281
|
+
ActiveRecord::Base.connection.execute('SET foreign_key_checks = 0')
|
282
|
+
IO.readlines("db/#{HOMEQ_ENV}_structure.sql").join.split("\n\n").each do |table|
|
283
|
+
ActiveRecord::Base.connection.execute(table)
|
284
|
+
end
|
285
|
+
when "postgresql"
|
286
|
+
ENV['PGHOST'] = abcs["test"]["host"] if abcs["test"]["host"]
|
287
|
+
ENV['PGPORT'] = abcs["test"]["port"].to_s if abcs["test"]["port"]
|
288
|
+
ENV['PGPASSWORD'] = abcs["test"]["password"].to_s if abcs["test"]["password"]
|
289
|
+
`psql -U "#{abcs["test"]["username"]}" -f db/#{HOMEQ_ENV}_structure.sql #{abcs["test"]["database"]}`
|
290
|
+
when "sqlite", "sqlite3"
|
291
|
+
dbfile = abcs["test"]["database"] || abcs["test"]["dbfile"]
|
292
|
+
`#{abcs["test"]["adapter"]} #{dbfile} < db/#{HOMEQ_ENV}_structure.sql`
|
293
|
+
when "sqlserver"
|
294
|
+
`osql -E -S #{abcs["test"]["host"]} -d #{abcs["test"]["database"]} -i db\\#{HOMEQ_ENV}_structure.sql`
|
295
|
+
when "oci", "oracle"
|
296
|
+
ActiveRecord::Base.establish_connection(:test)
|
297
|
+
IO.readlines("db/#{HOMEQ_ENV}_structure.sql").join.split(";\n\n").each do |ddl|
|
298
|
+
ActiveRecord::Base.connection.execute(ddl)
|
299
|
+
end
|
300
|
+
when "firebird"
|
301
|
+
set_firebird_env(abcs["test"])
|
302
|
+
db_string = firebird_db_string(abcs["test"])
|
303
|
+
sh "isql -i db/#{HOMEQ_ENV}_structure.sql #{db_string}"
|
304
|
+
else
|
305
|
+
raise "Task not supported by '#{abcs["test"]["adapter"]}'"
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
desc "Empty the test database"
|
310
|
+
task :purge => :environment do
|
311
|
+
abcs = ActiveRecord::Base.configurations
|
312
|
+
case abcs["test"]["adapter"]
|
313
|
+
when "mysql"
|
314
|
+
ActiveRecord::Base.establish_connection(:test)
|
315
|
+
ActiveRecord::Base.connection.recreate_database(abcs["test"]["database"])
|
316
|
+
when "postgresql"
|
317
|
+
ActiveRecord::Base.clear_active_connections!
|
318
|
+
drop_database(abcs['test'])
|
319
|
+
create_database(abcs['test'])
|
320
|
+
when "sqlite","sqlite3"
|
321
|
+
dbfile = abcs["test"]["database"] || abcs["test"]["dbfile"]
|
322
|
+
File.delete(dbfile) if File.exist?(dbfile)
|
323
|
+
when "sqlserver"
|
324
|
+
dropfkscript = "#{abcs["test"]["host"]}.#{abcs["test"]["database"]}.DP1".gsub(/\\/,'-')
|
325
|
+
`osql -E -S #{abcs["test"]["host"]} -d #{abcs["test"]["database"]} -i db\\#{dropfkscript}`
|
326
|
+
`osql -E -S #{abcs["test"]["host"]} -d #{abcs["test"]["database"]} -i db\\#{HOMEQ_ENV}_structure.sql`
|
327
|
+
when "oci", "oracle"
|
328
|
+
ActiveRecord::Base.establish_connection(:test)
|
329
|
+
ActiveRecord::Base.connection.structure_drop.split(";\n\n").each do |ddl|
|
330
|
+
ActiveRecord::Base.connection.execute(ddl)
|
331
|
+
end
|
332
|
+
when "firebird"
|
333
|
+
ActiveRecord::Base.establish_connection(:test)
|
334
|
+
ActiveRecord::Base.connection.recreate_database!
|
335
|
+
else
|
336
|
+
raise "Task not supported by '#{abcs["test"]["adapter"]}'"
|
337
|
+
end
|
338
|
+
end
|
339
|
+
|
340
|
+
desc 'Prepare the test database and load the schema'
|
341
|
+
task :prepare => %w(environment db:abort_if_pending_migrations) do
|
342
|
+
if defined?(ActiveRecord) && !ActiveRecord::Base.configurations.blank?
|
343
|
+
Rake::Task[{ :sql => "db:test:clone_structure", :ruby => "db:test:clone" }[ActiveRecord::Base.schema_format]].invoke
|
344
|
+
end
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
348
|
+
namespace :sessions do
|
349
|
+
desc "Creates a sessions migration for use with CGI::Session::ActiveRecordStore"
|
350
|
+
task :create => :environment do
|
351
|
+
raise "Task unavailable to this database (no migration support)" unless ActiveRecord::Base.connection.supports_migrations?
|
352
|
+
require 'rails_generator'
|
353
|
+
require 'rails_generator/scripts/generate'
|
354
|
+
Rails::Generator::Scripts::Generate.new.run(["session_migration", ENV["MIGRATION"] || "CreateSessions"])
|
355
|
+
end
|
356
|
+
|
357
|
+
desc "Clear the sessions table"
|
358
|
+
task :clear => :environment do
|
359
|
+
ActiveRecord::Base.connection.execute "DELETE FROM #{session_table_name}"
|
360
|
+
end
|
361
|
+
end
|
362
|
+
end
|
363
|
+
|
364
|
+
def drop_database(config)
|
365
|
+
case config['adapter']
|
366
|
+
when 'mysql'
|
367
|
+
ActiveRecord::Base.connection.drop_database config['database']
|
368
|
+
when /^sqlite/
|
369
|
+
FileUtils.rm(File.join(HOMEQ_APP_ROOT, config['database']))
|
370
|
+
when 'postgresql'
|
371
|
+
ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres', 'schema_search_path' => 'public'))
|
372
|
+
ActiveRecord::Base.connection.drop_database config['database']
|
373
|
+
end
|
374
|
+
end
|
375
|
+
|
376
|
+
def session_table_name
|
377
|
+
ActiveRecord::Base.pluralize_table_names ? :sessions : :session
|
378
|
+
end
|
379
|
+
|
380
|
+
def set_firebird_env(config)
|
381
|
+
ENV["ISC_USER"] = config["username"].to_s if config["username"]
|
382
|
+
ENV["ISC_PASSWORD"] = config["password"].to_s if config["password"]
|
383
|
+
end
|
384
|
+
|
385
|
+
def firebird_db_string(config)
|
386
|
+
FireRuby::Database.db_string_for(config.symbolize_keys)
|
387
|
+
end
|
data/lib/tasks/gem.rake
ADDED