wraithdb 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 ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in wraithdb.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,28 @@
1
+
2
+ ©2011 Airbnb, Inc.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ Redistributions of source code must retain the above copyright notice,
8
+ this list of conditions and the following disclaimer.
9
+
10
+ Redistributions in binary form must reproduce the above copyright notice,
11
+ this list of conditions and the following disclaimer in the documentation
12
+ and/or other materials provided with the distribution.
13
+
14
+ Names of the contributors to this software may not be used to endorse or
15
+ promote products derived from this software without specific prior written
16
+ permission.
17
+
18
+ This software is provided by the contributors "as is" and any express or
19
+ implied warranties, including, but not limited to, the implied warranties
20
+ of merchantability and fitness for a particular purpose are disclaimed. In
21
+ no event shall the contributors be liable for any direct, indirect,
22
+ incidental, special, exemplary, or consequential damages (including, but not
23
+ limited to, procurement of substitute goods or services; loss of use, data,
24
+ or profits; or business interruption) however caused and on any theory of
25
+ liability, whether in contract, strict liability, or tort (including
26
+ negligence or otherwise) arising in any way out of the use of this
27
+ software, even if advised of the possibility of such damage.
28
+
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Wraithdb
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'wraithdb'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install wraithdb
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,16 @@
1
+ module ActiveRecord
2
+ class Base
3
+ class << self
4
+ def establish_connection_with_activerecord_import(*args)
5
+ establish_connection_without_activerecord_import(*args)
6
+ begin
7
+ ActiveSupport.run_load_hooks(:active_record_connection_established, connection)
8
+ rescue StandardError => e
9
+ # ActiveImport will not work but this shouldn't be an issue as it's only used in Rake tasks.
10
+ # If the DB is down we won't be importing anything in a rake task anyhow.
11
+ end
12
+ end
13
+ alias establish_connection establish_connection_with_activerecord_import
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,23 @@
1
+ module ActiveRecord
2
+ class Base
3
+ class << self
4
+ # This clobbers the DB Charmer wrapping of relation and does the same thing except
5
+ # it leaves connection resolution to runtime rather than assigning an instance variable
6
+ def relation_with_db_charmer(*args, &block)
7
+ relation_without_db_charmer(*args, &block).tap do |rel|
8
+ begin
9
+ rel.db_charmer_connection = @connection
10
+ rescue StandardError => e
11
+ base = self
12
+ rel.define_singleton_method(:db_charmer_connection) do
13
+ base.connection
14
+ end
15
+ end
16
+ rel.db_charmer_enable_slaves = self.db_charmer_slaves.any?
17
+ rel.db_charmer_connection_is_forced = !db_charmer_top_level_connection?
18
+ end
19
+ end
20
+ alias relation relation_with_db_charmer
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,39 @@
1
+ module ActiveRecord
2
+ class Base
3
+ class << self
4
+ #If we do variable binding inside of where clauses on scopes it needs to work without
5
+ #an actual connection. The implementation provided mirrors the Mysql2Adapter
6
+ def replace_bind_variables_with_wraithdb(statement, values)
7
+ begin
8
+ replace_bind_variables_without_wraithdb
9
+ rescue StandardError => e
10
+ raise e if e.kind_of? PreparedStatementInvalid
11
+ bound = values.dup
12
+ statement.gsub('?') { quote_bound_value(bound.shift, WraithDB::Schema.connection) }
13
+ end
14
+ end
15
+ alias_method_chain :replace_bind_variables, :wraithdb
16
+
17
+ def table_exists_with_wraithdb_columns?
18
+ begin
19
+ table_exists_without_wraithdb_columns?
20
+ rescue StandardError => e
21
+ WraithDB::Schema.tables.has_key?(table_name.to_s)
22
+ end
23
+ end
24
+ alias_method_chain :table_exists?, :wraithdb_columns
25
+
26
+ def columns_with_wraithdb_columns
27
+ begin
28
+ columns_without_wraithdb_columns
29
+ rescue StandardError => e
30
+ columns = WraithDB::Schema.tables[table_name.to_s].columns
31
+ return columns.map {|column|
32
+ WraithDB::Column.new(column)
33
+ }
34
+ end
35
+ end
36
+ alias_method_chain :columns, :wraithdb_columns
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,27 @@
1
+ module Arel
2
+ class Table
3
+ def columns_with_wraithdb
4
+ begin
5
+ columns_without_wraithdb
6
+ rescue StandardError => e
7
+ attributes_for WraithDB::Schema.tables[@name].columns
8
+ end
9
+ end
10
+ alias_method_chain :columns, :wraithdb
11
+
12
+ class << self
13
+ def table_cache_with_wraithdb(engine)
14
+ begin
15
+ table_cache_without_wraithdb(engine)
16
+ rescue StandardError => e
17
+ tables = {}
18
+ WraithDB::Schema.tables.keys.each do |table_name|
19
+ tables[table_name] = true
20
+ end
21
+ tables
22
+ end
23
+ end
24
+ alias_method_chain :table_cache, :wraithdb
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,27 @@
1
+ module ActiveRecord
2
+ module ModelSchema
3
+ module ClassMethods
4
+ def table_exists_with_wraithdb_columns?
5
+ begin
6
+ table_exists_without_wraithdb_columns?
7
+ rescue StandardError => e
8
+ WraithDB.schema.tables.has_key?(table_name.to_s)
9
+ end
10
+ end
11
+ alias_method_chain :table_exists?, :wraithdb_columns
12
+
13
+ def columns_with_wraithdb_columns
14
+ begin
15
+ columns_without_wraithdb_columns
16
+ rescue StandardError => e
17
+ columns = WraithDB.schema.tables[table_name.to_s].columns
18
+ return columns.map {|column|
19
+ WraithDB::Column.new(column)
20
+ }
21
+ end
22
+ end
23
+ alias_method_chain :columns, :wraithdb_columns
24
+ end
25
+ end
26
+ end
27
+
@@ -0,0 +1,43 @@
1
+ module WraithDB
2
+ class Adapter < ActiveRecord::ConnectionAdapters::AbstractAdapter
3
+ attr_reader :tables
4
+
5
+ def initialize
6
+ super(nil)
7
+ @active = true
8
+ @tables = {}
9
+ end
10
+
11
+ def quote(value, column = nil)
12
+ if value.kind_of?(String) && column && column.type == :binary && column.class.respond_to?(:string_to_binary)
13
+ s = column.class.string_to_binary(value).unpack("H*")[0]
14
+ "x'#{s}'"
15
+ elsif value.kind_of?(BigDecimal)
16
+ value.to_s("F")
17
+ else
18
+ super
19
+ end
20
+ end
21
+
22
+ def adapter_name
23
+ 'WraithDB'
24
+ end
25
+
26
+ def support_migrations?
27
+ true
28
+ end
29
+
30
+ def create_table(table_name, options = {})
31
+ table_definition = ActiveRecord::ConnectionAdapters::TableDefinition.new(self)
32
+ table_definition.primary_key(options[:primary_key] || ActiveRecord::Base.get_primary_key(table_name.to_s.singularize)) unless options[:id] == false
33
+
34
+ yield table_definition if block_given?
35
+
36
+ @tables[table_name.to_s] = table_definition
37
+ end
38
+
39
+ def add_index(*args)
40
+ end
41
+
42
+ end
43
+ end
@@ -0,0 +1,16 @@
1
+ module WraithDB
2
+ class Column < ActiveRecord::ConnectionAdapters::Column
3
+ def initialize(column_definition)
4
+ @name = column_definition.name
5
+ @sql_type = nil
6
+ @null = column_definition.null
7
+ @limit = column_definition.limit
8
+ @precision = column_definition.precision
9
+ @scale = column_definition.scale
10
+ @type = (column_definition.type == :primary_key) ? :integer : column_definition.type
11
+ @default = column_definition.default
12
+ @primary = column_definition.type == :primary_key
13
+ @coder = nil
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,39 @@
1
+ module WraithDB
2
+ class Schema < ActiveRecord::Schema
3
+ SCHEMA_REGEX = /^ActiveRecord::Schema.define\(:version => \d+\) do/
4
+ END_REGEX = /^end\s*\z/
5
+
6
+ class << self
7
+ def write(*args)
8
+ # normally this would be noisy like a migration, this makes it quiet
9
+ end
10
+
11
+ def connection
12
+ load
13
+ @connection ||= WraithDB::Adapter.new
14
+ end
15
+
16
+ def tables
17
+ connection.tables
18
+ end
19
+
20
+ def initialize(*args)
21
+ end
22
+
23
+ def load
24
+ return if @loaded
25
+ @loaded = true
26
+ file = ENV['SCHEMA'] || "#{Rails.root}/db/schema.rb"
27
+ source = File.read(file)
28
+ if (source =~ SCHEMA_REGEX && source =~ END_REGEX)
29
+ source.sub!(SCHEMA_REGEX, "")
30
+ source.sub!(END_REGEX, "")
31
+ else
32
+ raise StandardError.new("Invalid format for #{file}.")
33
+ end
34
+
35
+ instance_eval(source)
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,3 @@
1
+ module Wraithdb
2
+ VERSION = "0.0.1"
3
+ end
data/lib/wraithdb.rb ADDED
@@ -0,0 +1,13 @@
1
+ require 'active_record/connection_adapters/abstract/schema_definitions'
2
+ require "wraithdb/version"
3
+ require 'wraithdb/schema'
4
+ require 'wraithdb/column'
5
+ require 'wraithdb/adapter'
6
+
7
+ dir_path = File.expand_path('..', __FILE__)
8
+
9
+ Dir["#{dir_path}/rails/#{Rails.version[0..2]}/**/*.rb"].each {|file| require file}
10
+ Dir["#{dir_path}/gems/**/*.rb"].each { |file|
11
+ gem_name = file.gsub(/.*\/|\..*/, '')
12
+ require file if Gem.loaded_specs.has_key?(gem_name)
13
+ }
data/wraithdb.gemspec ADDED
@@ -0,0 +1,18 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/wraithdb/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Nathan Baxter"]
6
+ gem.email = ["nathan.baxter@airbnb.com"]
7
+ gem.description = %q{WraithDB uses schema.rb as a template to initialize ActiveRecord classes when databases are offline. It does this with minimal overhead, leaving the normal connection object untouched and only interacting with the columns and tables interfaces.}
8
+ gem.summary = %q{Allows Rails to boot in the absence of a working database.}
9
+ gem.homepage = "https://github.com/airbnb/wraithdb"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "wraithdb"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Wraithdb::VERSION
17
+ gem.add_runtime_dependency 'activerecord', '>= 3.0', '<= 3.2'
18
+ end
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: wraithdb
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Nathan Baxter
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-09-26 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: '3.0'
22
+ - - <=
23
+ - !ruby/object:Gem::Version
24
+ version: '3.2'
25
+ type: :runtime
26
+ prerelease: false
27
+ version_requirements: !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '3.0'
33
+ - - <=
34
+ - !ruby/object:Gem::Version
35
+ version: '3.2'
36
+ description: WraithDB uses schema.rb as a template to initialize ActiveRecord classes
37
+ when databases are offline. It does this with minimal overhead, leaving the normal
38
+ connection object untouched and only interacting with the columns and tables interfaces.
39
+ email:
40
+ - nathan.baxter@airbnb.com
41
+ executables: []
42
+ extensions: []
43
+ extra_rdoc_files: []
44
+ files:
45
+ - .gitignore
46
+ - Gemfile
47
+ - LICENSE
48
+ - README.md
49
+ - Rakefile
50
+ - lib/gems/activerecord-import.rb
51
+ - lib/gems/db-charmer.rb
52
+ - lib/rails/3.0/active_record/base.rb
53
+ - lib/rails/3.0/arel/table.rb
54
+ - lib/rails/3.2/active_record/model_schema.rb
55
+ - lib/wraithdb.rb
56
+ - lib/wraithdb/adapter.rb
57
+ - lib/wraithdb/column.rb
58
+ - lib/wraithdb/schema.rb
59
+ - lib/wraithdb/version.rb
60
+ - wraithdb.gemspec
61
+ homepage: https://github.com/airbnb/wraithdb
62
+ licenses: []
63
+ post_install_message:
64
+ rdoc_options: []
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ! '>='
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ! '>='
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ requirements: []
80
+ rubyforge_project:
81
+ rubygems_version: 1.8.24
82
+ signing_key:
83
+ specification_version: 3
84
+ summary: Allows Rails to boot in the absence of a working database.
85
+ test_files: []