wraithdb 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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: []