litestack 0.4.1 → 0.4.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/.standard.yml +3 -0
  3. data/BENCHMARKS.md +23 -7
  4. data/CHANGELOG.md +35 -0
  5. data/Gemfile +1 -7
  6. data/README.md +124 -6
  7. data/ROADMAP.md +45 -0
  8. data/Rakefile +3 -1
  9. data/WHYLITESTACK.md +1 -1
  10. data/assets/litecache_metrics.png +0 -0
  11. data/assets/litedb_metrics.png +0 -0
  12. data/assets/litemetric_logo_teal.png +0 -0
  13. data/assets/litesearch_logo_teal.png +0 -0
  14. data/bench/bench.rb +17 -10
  15. data/bench/bench_cache_rails.rb +45 -14
  16. data/bench/bench_cache_raw.rb +44 -28
  17. data/bench/bench_jobs_rails.rb +18 -12
  18. data/bench/bench_jobs_raw.rb +17 -10
  19. data/bench/bench_queue.rb +4 -6
  20. data/bench/rails_job.rb +5 -7
  21. data/bench/skjob.rb +4 -4
  22. data/bench/uljob.rb +6 -6
  23. data/bin/liteboard +2 -1
  24. data/lib/action_cable/subscription_adapter/litecable.rb +5 -8
  25. data/lib/active_job/queue_adapters/litejob_adapter.rb +6 -8
  26. data/lib/active_record/connection_adapters/litedb_adapter.rb +72 -84
  27. data/lib/active_support/cache/litecache.rb +61 -41
  28. data/lib/generators/litestack/install/install_generator.rb +3 -3
  29. data/lib/generators/litestack/install/templates/cable.yml +0 -3
  30. data/lib/generators/litestack/install/templates/database.yml +7 -1
  31. data/lib/litestack/liteboard/liteboard.rb +269 -149
  32. data/lib/litestack/litecable.rb +41 -37
  33. data/lib/litestack/litecable.sql.yml +22 -11
  34. data/lib/litestack/litecache.rb +118 -93
  35. data/lib/litestack/litecache.sql.yml +83 -22
  36. data/lib/litestack/litecache.yml +1 -1
  37. data/lib/litestack/litedb.rb +35 -40
  38. data/lib/litestack/litejob.rb +30 -29
  39. data/lib/litestack/litejobqueue.rb +63 -65
  40. data/lib/litestack/litemetric.rb +80 -92
  41. data/lib/litestack/litemetric.sql.yml +244 -234
  42. data/lib/litestack/litemetric_collector.sql.yml +38 -41
  43. data/lib/litestack/litequeue.rb +39 -41
  44. data/lib/litestack/litequeue.sql.yml +39 -31
  45. data/lib/litestack/litescheduler.rb +24 -18
  46. data/lib/litestack/litesearch/index.rb +93 -63
  47. data/lib/litestack/litesearch/model.rb +66 -65
  48. data/lib/litestack/litesearch/schema.rb +53 -56
  49. data/lib/litestack/litesearch/schema_adapters/backed_adapter.rb +46 -50
  50. data/lib/litestack/litesearch/schema_adapters/basic_adapter.rb +44 -35
  51. data/lib/litestack/litesearch/schema_adapters/contentless_adapter.rb +3 -6
  52. data/lib/litestack/litesearch/schema_adapters/standalone_adapter.rb +7 -9
  53. data/lib/litestack/litesearch/schema_adapters.rb +4 -9
  54. data/lib/litestack/litesearch.rb +6 -9
  55. data/lib/litestack/litesupport.rb +78 -87
  56. data/lib/litestack/railtie.rb +1 -1
  57. data/lib/litestack/version.rb +2 -2
  58. data/lib/litestack.rb +6 -4
  59. data/lib/railties/rails/commands/dbconsole.rb +16 -20
  60. data/lib/sequel/adapters/litedb.rb +16 -21
  61. data/lib/sequel/adapters/shared/litedb.rb +168 -168
  62. data/scripts/build_metrics.rb +91 -0
  63. data/scripts/test_cable.rb +30 -0
  64. data/scripts/test_job_retry.rb +33 -0
  65. data/scripts/test_metrics.rb +60 -0
  66. data/template.rb +2 -2
  67. metadata +115 -7
@@ -1,17 +1,17 @@
1
- require 'redis'
2
- require 'sqlite3'
3
- require_relative './bench'
1
+ require "redis"
2
+ require "sqlite3"
3
+ require_relative "./bench"
4
4
 
5
- #require 'polyphony'
6
- require 'async/scheduler'
5
+ # require 'polyphony'
6
+ require "async/scheduler"
7
7
 
8
8
  Fiber.set_scheduler Async::Scheduler.new
9
9
  Fiber.scheduler.run
10
10
 
11
- require_relative '../lib/litestack/litecache'
12
- #require 'litestack'
11
+ require_relative "../lib/litestack/litecache"
12
+ # require 'litestack'
13
13
 
14
- cache = Litecache.new({path: '../db/cache.db'}) # default settings
14
+ cache = Litecache.new #({path: "../db/cache.db"}) # default settings
15
15
  redis = Redis.new # default settings
16
16
 
17
17
  values = []
@@ -21,13 +21,13 @@ count.times { keys << random_str(10) }
21
21
 
22
22
  [10, 100, 1000, 10000].each do |size|
23
23
  count.times do
24
- values << random_str(size)
24
+ values << random_str(size)
25
25
  end
26
-
26
+
27
27
  random_keys = keys.shuffle
28
-
28
+
29
29
  GC.compact
30
-
30
+
31
31
  puts "Benchmarks for values of size #{size} bytes"
32
32
  puts "=========================================================="
33
33
  puts "== Writes =="
@@ -35,37 +35,54 @@ count.times { keys << random_str(10) }
35
35
  cache.set(keys[i], values[i])
36
36
  end
37
37
 
38
- #bench("file writes", count) do |i|
39
- # f = File.open("../files/#{keys[i]}.data", 'w+')
40
- # f.write(values[i])
41
- # f.close
42
- #end
43
-
44
-
45
38
  bench("Redis writes", count) do |i|
46
39
  redis.set(keys[i], values[i])
47
40
  end
48
41
 
42
+ puts "== Multi Writes =="
43
+ bench("litecache multi-writes", count/5) do |i|
44
+ idx = i * 5
45
+ payload = {}
46
+ 5.times {|j| payload[keys[idx + j]] = values[idx + j] }
47
+ cache.set_multi(payload)
48
+ end
49
+
50
+ bench("Redis multi-writes", count/5) do |i|
51
+ idx = i * 5
52
+ payload = []
53
+ 5.times {|j| payload << keys[idx + j]; payload << values[idx + j]}
54
+ redis.mset(*payload)
55
+ end
56
+
49
57
  puts "== Reads =="
50
58
  bench("litecache reads", count) do |i|
51
59
  cache.get(random_keys[i])
52
60
  end
53
61
 
54
- #bench("file reads", count) do |i|
55
- # data = File.read("../files/#{keys[i]}.data")
56
- #end
57
-
58
62
  bench("Redis reads", count) do |i|
59
63
  redis.get(random_keys[i])
60
64
  end
65
+
66
+ puts "== Multi Reads =="
67
+ bench("litecache multi-reads", count/5) do |i|
68
+ idx = i * 5
69
+ payload = []
70
+ 5.times {|j| payload << random_keys[idx+j]}
71
+ cache.get_multi(*payload)
72
+ end
73
+
74
+ bench("Redis multi-reads", count/5) do |i|
75
+ idx = i * 5
76
+ payload = []
77
+ 5.times {|j| payload << random_keys[idx+j]}
78
+ redis.mget(*payload)
79
+ end
80
+
61
81
  puts "=========================================================="
62
82
 
63
83
  values = []
64
-
65
-
66
84
  end
67
85
 
68
-
69
86
  cache.set("somekey", 1)
70
87
  redis.set("somekey", 1)
71
88
 
@@ -80,5 +97,4 @@ end
80
97
  cache.clear
81
98
  redis.flushdb
82
99
 
83
- #sleep
84
-
100
+ # sleep
@@ -1,39 +1,45 @@
1
- require './bench'
1
+ require "./bench"
2
2
 
3
- count = ARGV[0].to_i rescue 1000
3
+ count = begin
4
+ ARGV[0].to_i
5
+ rescue
6
+ 1000
7
+ end
4
8
  env = ARGV[1] || "t"
5
- delay = ARGV[2].to_f rescue 0
6
-
9
+ _delay = begin
10
+ ARGV[2].to_f
11
+ rescue
12
+ 0
13
+ end
7
14
 
8
- #ActiveJob::Base.logger = Logger.new(IO::NULL)
15
+ # ActiveJob::Base.logger = Logger.new(IO::NULL)
9
16
 
10
- require './rails_job.rb'
17
+ require "./rails_job"
11
18
 
12
19
  RailsJob.queue_adapter = :sidekiq
13
20
  t = Time.now.to_f
14
- puts "Make sure sidekiq is started with -c ./rails_job.rb"
15
- bench("enqueuing sidekiq jobs", count) do
21
+ puts "Make sure sidekiq is started with -c ./rails_job.rb"
22
+ bench("enqueuing sidekiq jobs", count) do
16
23
  RailsJob.perform_later(count, t)
17
24
  end
18
25
 
19
26
  puts "Don't forget to check the sidekiq log for processing time conclusion"
20
27
 
21
-
22
28
  # Litejob bench
23
29
  ###############
24
30
 
25
31
  if env == "a" # threaded
26
- require 'async/scheduler'
32
+ require "async/scheduler"
27
33
  Fiber.set_scheduler Async::Scheduler.new
28
34
  ActiveSupport::IsolatedExecutionState.isolation_level = :fiber
29
35
  end
30
36
 
31
- require_relative '../lib/active_job/queue_adapters/litejob_adapter'
37
+ require_relative "../lib/active_job/queue_adapters/litejob_adapter"
32
38
  puts Litescheduler.backend
33
39
 
34
40
  RailsJob.queue_adapter = :litejob
35
41
  t = Time.now.to_f
36
- bench("enqueuing litejobs", count) do
42
+ bench("enqueuing litejobs", count) do
37
43
  RailsJob.perform_later(count, t)
38
44
  end
39
45
 
@@ -1,15 +1,23 @@
1
- require './bench'
1
+ require "./bench"
2
2
 
3
- count = ARGV[0].to_i rescue 1000
3
+ count = begin
4
+ ARGV[0].to_i
5
+ rescue
6
+ 1000
7
+ end
4
8
  env = ARGV[1] || "t"
5
- delay = ARGV[2].to_f rescue 0
9
+ delay = begin
10
+ ARGV[2].to_f
11
+ rescue
12
+ 0
13
+ end
6
14
 
7
15
  # Sidekiq bench
8
16
  ###############
9
- require './skjob.rb'
17
+ require "./skjob"
10
18
 
11
19
  t = Process.clock_gettime(Process::CLOCK_MONOTONIC)
12
- puts "make sure sidekiq is started with skjob.rb as the job"
20
+ puts "make sure sidekiq is started with skjob.rb as the job"
13
21
  bench("enqueuing sidekiq jobs", count) do |i|
14
22
  SidekiqJob.perform_async(count, t, delay)
15
23
  end
@@ -20,15 +28,15 @@ puts "Don't forget to check the sidekiq log for processing time conclusion"
20
28
  ###############
21
29
 
22
30
  if env == "t" # threaded
23
- # do nothing
31
+ # do nothing
24
32
  elsif env == "a" # async
25
- require 'async/scheduler'
33
+ require "async/scheduler"
26
34
  Fiber.set_scheduler Async::Scheduler.new
27
35
  end
28
36
 
29
- require './uljob.rb'
37
+ require "./uljob"
30
38
 
31
- STDERR.puts "litejob started in #{Litescheduler.backend} environmnet"
39
+ warn "litejob started in #{Litescheduler.backend} environment"
32
40
 
33
41
  t = Process.clock_gettime(Process::CLOCK_MONOTONIC)
34
42
  bench("enqueuing litejobs", count) do |i|
@@ -40,4 +48,3 @@ puts "Please wait for the benchmark to finish .."
40
48
  Fiber.scheduler.run if env == "a"
41
49
 
42
50
  sleep
43
-
data/bench/bench_queue.rb CHANGED
@@ -1,16 +1,14 @@
1
- require './bench'
2
- require_relative '../lib/litestack'
1
+ require "./bench"
2
+ require_relative "../lib/litestack"
3
3
 
4
4
  count = 1000
5
5
 
6
- q = Litequeue.new({path: '../db/queue.db' })
6
+ q = Litequeue.new({path: "../db/queue.db"})
7
7
 
8
8
  bench("Litequeue enqueue", count) do |i|
9
9
  q.push i.to_s
10
10
  end
11
11
 
12
12
  bench("Litequeue dequeue", count) do |i|
13
- q.pop
13
+ q.pop
14
14
  end
15
-
16
-
data/bench/rails_job.rb CHANGED
@@ -1,18 +1,16 @@
1
- require 'active_job'
1
+ require "active_job"
2
2
 
3
3
  class RailsJob < ActiveJob::Base
4
-
5
4
  queue_as :default
6
5
 
7
6
  @@count = 0
8
-
7
+
9
8
  def perform(count, time)
10
- #sleep 1
11
- @@count += 1
12
- if @@count == count
9
+ # sleep 1
10
+ @@count += 1
11
+ if @@count == count
13
12
  puts "[litejob] Finished in #{Time.now.to_f - time} seconds (#{count / (Time.now.to_f - time)} jps)"
14
13
  @@count = 0
15
14
  end
16
15
  end
17
-
18
16
  end
data/bench/skjob.rb CHANGED
@@ -1,14 +1,14 @@
1
- require 'sidekiq'
1
+ require "sidekiq"
2
2
 
3
3
  class SidekiqJob
4
4
  include Sidekiq::Job
5
5
  @@count = 0
6
6
  def perform(count, time, sleep_interval = nil)
7
- sleep sleep_interval if sleep_interval
7
+ sleep sleep_interval if sleep_interval
8
8
  @@count += 1
9
- if @@count == count
9
+ if @@count == count
10
10
  now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
11
- STDERR.puts "Sidekiq finished in #{now - time} seconds (#{count / (now - time)} jps)"
11
+ warn "Sidekiq finished in #{now - time} seconds (#{count / (now - time)} jps)"
12
12
  @@count = 0
13
13
  end
14
14
  end
data/bench/uljob.rb CHANGED
@@ -1,16 +1,16 @@
1
- require './bench'
2
- require '../lib/litestack/litejob'
1
+ require "./bench"
2
+ require "../lib/litestack/litejob"
3
3
 
4
4
  class MyJob
5
5
  include Litejob
6
6
  @@count = 0
7
- #self.queue = :default
7
+ # self.queue = :default
8
8
  def perform(count, time, sleep_interval = nil)
9
- sleep sleep_interval if sleep_interval
9
+ sleep sleep_interval if sleep_interval
10
10
  @@count += 1
11
- if @@count == count
11
+ if @@count == count
12
12
  now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
13
- STDERR.puts "Litejob finished in #{now - time} seconds (#{count / (now - time)} jps)"
13
+ warn "Litejob finished in #{now - time} seconds (#{count / (now - time)} jps)"
14
14
  end
15
15
  end
16
16
  end
data/bin/liteboard CHANGED
@@ -15,6 +15,7 @@ options = {
15
15
  Port: 9292,
16
16
  Host: 'localhost',
17
17
  environment: 'production',
18
+ pid: 'tmp/pids/liteboard.pid',
18
19
  quiet: false
19
20
  }
20
21
 
@@ -25,7 +26,7 @@ OptionParser.new do |parser|
25
26
  parser.on("-s", "--server SERVER", "use SERVER (e.g. puma/falcon/iodine)") { |v| options[:port] = v }
26
27
  parser.on("-H", "--host HOST", "listen on HOST (default: #{options[:Host]})") { |v| options[:Host] = v }
27
28
  parser.on("-p", "--port PORT", "use PORT (default: #{options[:Port]})") { |v| options[:Port] = v.to_i rescue options[:Port] }
28
- parser.on("-D", "--deamonize", "run in the background") { |v| options[:deamonize] = true }
29
+ parser.on("-D", "--daemonize", "run in the background") { |v| options[:daemonize] = true }
29
30
  parser.on("-E", "--env ENVIRONMENT", "which environment to use (default: #{options[:environment]})") { |v| options[:environment] = v }
30
31
  parser.on("-q", "--quiet", "turn off logging") { |v| options[:quiet] = true }
31
32
  parser.on("-h", "--help", "print this message") do
@@ -1,26 +1,23 @@
1
1
  # frozen_stringe_literal: true
2
2
 
3
- require_relative '../../litestack/litecable'
3
+ require_relative "../../litestack/litecable"
4
4
 
5
5
  module ActionCable
6
6
  module SubscriptionAdapter
7
- class Litecable < ::Litecable# :nodoc:
8
-
7
+ class Litecable < ::Litecable # :nodoc:
9
8
  attr_reader :logger, :server
10
-
9
+
11
10
  prepend ChannelPrefix
12
11
 
13
- def initialize(server, logger=nil)
12
+ def initialize(server, logger = nil)
14
13
  @server = server
15
14
  @logger = server.logger
16
15
  super({config_path: "./config/litecable.yml"})
17
16
  end
18
-
17
+
19
18
  def shutdown
20
19
  close
21
20
  end
22
-
23
21
  end
24
22
  end
25
23
  end
26
-
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../../litestack/litejob.rb'
3
+ require_relative "../../litestack/litejob"
4
4
  require "active_support/core_ext/enumerable"
5
5
  require "active_support/core_ext/array/access"
6
6
  require "active_job"
@@ -12,13 +12,12 @@ module ActiveJob
12
12
  #
13
13
  # Rails.application.config.active_job.queue_adapter = :litejob
14
14
  class LitejobAdapter
15
-
16
- def initialize(options={})
15
+ def initialize(options = {})
17
16
  # we currently don't honour individual options per job class
18
17
  # possible in the future?
19
18
  # Job.options = DEFAULT_OPTIONS.merge(options)
20
19
  end
21
-
20
+
22
21
  def enqueue(job) # :nodoc:
23
22
  Job.queue = job.queue_name
24
23
  Job.perform_async(job.serialize)
@@ -30,14 +29,13 @@ module ActiveJob
30
29
  end
31
30
 
32
31
  class Job # :nodoc:
33
-
34
32
  DEFAULT_OPTIONS = {
35
33
  config_path: "./config/litejob.yml",
36
- logger: nil, # Rails performs its logging already
37
- }
34
+ logger: nil # Rails performs its logging already
35
+ }
38
36
 
39
37
  include ::Litejob
40
-
38
+
41
39
  def perform(job_data)
42
40
  Base.execute job_data
43
41
  end
@@ -1,102 +1,90 @@
1
- require_relative '../../litestack/litedb'
2
- require 'active_record'
3
- require 'active_record/connection_adapters/sqlite3_adapter'
4
- require 'active_record/tasks/sqlite_database_tasks'
1
+ require_relative "../../litestack/litedb"
2
+ require "active_record"
3
+ require "active_record/connection_adapters/sqlite3_adapter"
4
+ require "active_record/tasks/sqlite_database_tasks"
5
5
 
6
6
  module ActiveRecord
7
+ module ConnectionHandling # :nodoc:
8
+ def litedb_connection(config)
9
+ config = config.symbolize_keys
7
10
 
8
- module ConnectionHandling # :nodoc:
9
-
10
- def litedb_connection(config)
11
-
12
- config = config.symbolize_keys
13
-
14
- # Require database.
15
- unless config[:database]
16
- raise ArgumentError, "No database file specified. Missing argument: database"
17
- end
18
-
19
- # Allow database path relative to Rails.root, but only if the database
20
- # path is not the special path that tells sqlite to build a database only
21
- # in memory.
22
- if ":memory:" != config[:database] && !config[:database].to_s.start_with?("file:")
23
- config[:database] = File.expand_path(config[:database], Rails.root) if defined?(Rails.root)
24
- dirname = File.dirname(config[:database])
25
- Dir.mkdir(dirname) unless File.directory?(dirname)
26
- end
27
-
28
- db = ::Litedb.new(
29
- config[:database].to_s,
30
- config.merge(results_as_hash: true)
31
- )
11
+ # Require database.
12
+ unless config[:database]
13
+ raise ArgumentError, "No database file specified. Missing argument: database"
14
+ end
32
15
 
33
- ConnectionAdapters::LitedbAdapter.new(db, logger, nil, config)
34
-
35
- rescue Errno::ENOENT => error
36
- if error.message.include?("No such file or directory")
37
- raise ActiveRecord::NoDatabaseError
38
- else
39
- raise
40
- end
41
- end
42
- end
16
+ # Allow database path relative to Rails.root, but only if the database
17
+ # path is not the special path that tells sqlite to build a database only
18
+ # in memory.
19
+ if config[:database] != ":memory:" && !config[:database].to_s.start_with?("file:")
20
+ config[:database] = File.expand_path(config[:database], Rails.root) if defined?(Rails.root)
21
+ dirname = File.dirname(config[:database])
22
+ Dir.mkdir(dirname) unless File.directory?(dirname)
23
+ end
43
24
 
44
- module ConnectionAdapters # :nodoc:
25
+ db = ::Litedb.new(
26
+ config[:database].to_s,
27
+ config.merge(results_as_hash: true)
28
+ )
29
+
30
+ ConnectionAdapters::LitedbAdapter.new(db, logger, nil, config)
31
+ rescue Errno::ENOENT => error
32
+ if error.message.include?("No such file or directory")
33
+ raise ActiveRecord::NoDatabaseError
34
+ else
35
+ raise
36
+ end
37
+ end
38
+ end
45
39
 
46
- class LitedbAdapter < SQLite3Adapter
40
+ module ConnectionAdapters # :nodoc:
41
+ class LitedbAdapter < SQLite3Adapter
42
+ ADAPTER_NAME = "litedb"
47
43
 
48
- ADAPTER_NAME = "litedb"
49
-
50
- class << self
51
-
52
- def dbconsole(config, options = {})
53
- args = []
44
+ def self.dbconsole(config, options = {})
45
+ args = []
54
46
 
55
- args << "-#{options[:mode]}" if options[:mode]
56
- args << "-header" if options[:header]
57
- args << File.expand_path(config.database, Rails.respond_to?(:root) ? Rails.root : nil)
47
+ args << "-#{options[:mode]}" if options[:mode]
48
+ args << "-header" if options[:header]
49
+ args << File.expand_path(config.database, Rails.respond_to?(:root) ? Rails.root : nil)
58
50
 
59
- find_cmd_and_exec("sqlite3", *args)
60
- end
61
-
51
+ self.find_cmd_and_exec("sqlite3", *args)
62
52
  end
53
+
54
+ NATIVE_DATABASE_TYPES = {
55
+ primary_key: "integer PRIMARY KEY NOT NULL",
56
+ string: {name: "text"},
57
+ text: {name: "text"},
58
+ integer: {name: "integer"},
59
+ float: {name: "real"},
60
+ decimal: {name: "real"},
61
+ datetime: {name: "text"},
62
+ time: {name: "integer"},
63
+ date: {name: "text"},
64
+ binary: {name: "blob"},
65
+ boolean: {name: "integer"},
66
+ json: {name: "text"},
67
+ unixtime: {name: "integer"}
68
+ }
69
+
70
+ private
71
+
72
+ def connect
73
+ @raw_connection = ::Litedb.new(
74
+ @config[:database].to_s,
75
+ @config.merge(results_as_hash: true)
76
+ )
77
+ configure_connection
78
+ end
79
+ end
80
+ end
63
81
 
64
- NATIVE_DATABASE_TYPES = {
65
- primary_key: "integer PRIMARY KEY NOT NULL",
66
- string: { name: "text" },
67
- text: { name: "text" },
68
- integer: { name: "integer" },
69
- float: { name: "real" },
70
- decimal: { name: "real" },
71
- datetime: { name: "text" },
72
- time: { name: "integer" },
73
- date: { name: "text" },
74
- binary: { name: "blob" },
75
- boolean: { name: "integer" },
76
- json: { name: "text" },
77
- unixtime: { name: "integer" }
78
- }
79
-
80
- private
81
-
82
- def connect
83
- @raw_connection = ::Litedb.new(
84
- @config[:database].to_s,
85
- @config.merge(results_as_hash: true)
86
- )
87
- configure_connection
88
- end
89
- end
90
-
91
- end
92
-
93
82
  module Tasks # :nodoc:
94
83
  class LitedbDatabaseTasks < SQLiteDatabaseTasks # :nodoc:
95
84
  end
96
-
85
+
97
86
  module DatabaseTasks
98
87
  register_task(/litedb/, "ActiveRecord::Tasks::LitedbDatabaseTasks")
99
-
100
88
  end
101
- end
89
+ end
102
90
  end