homeq 1.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. data/CHANGELOG +103 -0
  2. data/COPYING +348 -0
  3. data/README.rdoc +64 -0
  4. data/Rakefile +131 -0
  5. data/bin/hq +6 -0
  6. data/config/boot.rb +224 -0
  7. data/config/databases/frontbase.yml +28 -0
  8. data/config/databases/mysql.yml +54 -0
  9. data/config/databases/oracle.yml +39 -0
  10. data/config/databases/postgresql.yml +48 -0
  11. data/config/databases/sqlite2.yml +16 -0
  12. data/config/databases/sqlite3.yml +19 -0
  13. data/config/environment.rb +20 -0
  14. data/config/environments/development.cfg +35 -0
  15. data/config/environments/production.cfg +35 -0
  16. data/config/environments/test.cfg +35 -0
  17. data/config/generators/job/templates/job.rb.erb +20 -0
  18. data/config/generators/message/templates/messages/MESSAGE.proto.erb +12 -0
  19. data/config/generators/model/templates/models/MODEL.rb.erb +3 -0
  20. data/config/generators/service/templates/services/SERVICE.rb.erb +43 -0
  21. data/config/homeq.cfg +35 -0
  22. data/extras/consumer.rb +85 -0
  23. data/extras/homeq.cfg +49 -0
  24. data/extras/hqd.rb +33 -0
  25. data/extras/producer.rb +79 -0
  26. data/extras/simple_consumer.rb +53 -0
  27. data/lib/homeq/base/base.rb +44 -0
  28. data/lib/homeq/base/commando.rb +81 -0
  29. data/lib/homeq/base/config.rb +99 -0
  30. data/lib/homeq/base/exception.rb +48 -0
  31. data/lib/homeq/base/histogram.rb +141 -0
  32. data/lib/homeq/base/logger.rb +185 -0
  33. data/lib/homeq/base/ohash.rb +297 -0
  34. data/lib/homeq/base/options.rb +171 -0
  35. data/lib/homeq/base/poolable.rb +100 -0
  36. data/lib/homeq/base/system.rb +446 -0
  37. data/lib/homeq/cli.rb +35 -0
  38. data/lib/homeq/cp/commands.rb +71 -0
  39. data/lib/homeq/cp/connection.rb +97 -0
  40. data/lib/homeq/cp/cp.rb +30 -0
  41. data/lib/homeq/cp/server.rb +105 -0
  42. data/lib/homeq/sobs/client.rb +119 -0
  43. data/lib/homeq/sobs/connection.rb +635 -0
  44. data/lib/homeq/sobs/foreman.rb +237 -0
  45. data/lib/homeq/sobs/job.rb +66 -0
  46. data/lib/homeq/sobs/message.rb +49 -0
  47. data/lib/homeq/sobs/queue.rb +224 -0
  48. data/lib/homeq/sobs/sender.rb +150 -0
  49. data/lib/homeq/sobs/server.rb +654 -0
  50. data/lib/homeq/sobs/sobs.rb +45 -0
  51. data/lib/homeq/sobs/topology.rb +111 -0
  52. data/lib/homeq.rb +106 -0
  53. data/lib/tasks/Rakefile +49 -0
  54. data/lib/tasks/database.rake +387 -0
  55. data/lib/tasks/gem.rake +9 -0
  56. data/lib/tasks/generate.rake +192 -0
  57. data/lib/tasks/hq.rake +171 -0
  58. data/lib/tasks/testing.rake +95 -0
  59. data/lib/tasks/utility.rb +17 -0
  60. data/script/console.rb +45 -0
  61. data/script/generate +7 -0
  62. data/test/unittest.rb +51 -0
  63. 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
@@ -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
@@ -0,0 +1,9 @@
1
+ namespace :gem do
2
+ desc "install a gem into vendor/gems"
3
+ task :install do
4
+ if ENV["name"].nil?
5
+ STDERR.puts "Usage: rake gem:install name=the_gem_name"; exit 1
6
+ end
7
+ sh "gem install #{ENV['name']} --install-dir=vendor/gems --no-rdoc --no-ri"
8
+ end
9
+ end