spectacles 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ .DS_Store
2
+ *.gem
3
+ .bundle
4
+ .rvmrc
5
+ Gemfile.lock
6
+ pkg/*
7
+ specs/*.db
8
+ coverage
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in spectacles.gemspec
4
+ gemspec
5
+
6
+ group :test do
7
+ gem 'simplecov', :require => false
8
+ end
9
+
10
+ group :development do
11
+ gem 'ruby-debug19', :require => "ruby-debug"
12
+ end
data/Rakefile ADDED
@@ -0,0 +1,25 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+
4
+ namespace :test do
5
+ adapters = [:mysql, :mysql2, :postgresql, :sqlite]
6
+ task :all => [:spectacles] + adapters
7
+
8
+ adapters.each do |adapter|
9
+ Rake::TestTask.new(adapter) do |t|
10
+ t.libs.push "lib"
11
+ t.libs.push "specs"
12
+ t.pattern = "specs/adapters/#{t.name}*_spec.rb"
13
+ t.verbose = true
14
+ end
15
+ end
16
+
17
+ Rake::TestTask.new(:spectacles) do |t|
18
+ t.libs.push "lib"
19
+ t.libs.push "specs"
20
+ t.pattern = "specs/spectacles/**/*_spec.rb"
21
+ t.verbose = true
22
+ end
23
+ end
24
+
25
+ task :default => 'test:all'
data/Readme.rdoc ADDED
@@ -0,0 +1,43 @@
1
+ = Spectacles
2
+
3
+ Spectacles adds database view functionality to ActiveRecord. It is heavily inspired by Rails SQL Views (http://github.com/aeden/rails_sql_views/) and built from the ground-up to work with Rails 3+.
4
+
5
+ Spectacles provides the ability to create views in migrations using a similar format to creating tables. It also provides an abstract view class that inherits from ActiveRecord::Base that can be used to create view-backed models.
6
+
7
+ It currently only works with the SQLite and PostgreSQL drivers. MySQL & MySQL2 have a couple of issues that are still being worked out.
8
+
9
+ = Using Spectacles
10
+ Install it
11
+ gem install spectacles # => OR include it in your Gemfile
12
+
13
+ == Migrations
14
+
15
+ Create a migration from an query string:
16
+
17
+ create_view :product_users do
18
+ "SELECT name AS product_name, first_name AS username FROM
19
+ products JOIN users ON users.id = products.user_id"
20
+ end
21
+
22
+
23
+ Create a migration from an ARel object:
24
+
25
+ create_view :product_users do
26
+ Product.select("products.name AS product_name).
27
+ select("users.first_name AS username").
28
+ join(:users)
29
+ end
30
+
31
+ == Models
32
+
33
+ class ProductUser < Spectacles::View
34
+ # Add relationships
35
+
36
+ # Use scopes
37
+
38
+ # Your fancy methods
39
+ end
40
+
41
+ = License
42
+
43
+ Spectacles is licensed under MIT license (Read lib/spectactles.rb for full license)
data/lib/spectacles.rb ADDED
@@ -0,0 +1,42 @@
1
+ # (The MIT License)
2
+ #
3
+ # Copyright (c) 2012 Adam Hutchison, http://github.com/liveh2o
4
+ # Copyright (c) 2012 Brandon Dewitt, http://abrandoned.com
5
+ #
6
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'),
7
+ # to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
+ # and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11
+ #
12
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
14
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
15
+ # IN THE SOFTWARE.
16
+
17
+ require 'active_record'
18
+ require 'active_support/core_ext'
19
+ require 'spectacles/schema_statements'
20
+ require 'spectacles/schema_dumper'
21
+ require 'spectacles/view'
22
+ require 'spectacles/version'
23
+
24
+ ActiveRecord::ConnectionAdapters::AbstractAdapter.class_eval do
25
+ alias_method(:_spectacles_orig_inherited, :inherited) if method_defined?(:inherited)
26
+
27
+ def self.inherited(klass)
28
+ ::Spectacles::load_adapters
29
+ _spectacles_orig_inherited if method_defined?(:_spectacles_orig_inherited)
30
+ end
31
+ end
32
+
33
+ ActiveRecord::SchemaDumper.class_eval do
34
+ alias_method(:_spectacles_orig_trailer, :trailer)
35
+
36
+ def trailer(stream)
37
+ ::Spectacles::SchemaDumper.dump_views(stream, @connection)
38
+ _spectacles_orig_trailer(stream)
39
+ end
40
+ end
41
+
42
+ Spectacles::load_adapters
@@ -0,0 +1,17 @@
1
+ module Spectacles
2
+ module SchemaDumper
3
+ def self.dump_views(stream, connection)
4
+ connection.views.each do |view|
5
+ dump_view(stream, connection, view)
6
+ end
7
+ end
8
+
9
+ def self.dump_view(stream, connection, view_name)
10
+ stream.print <<-CREATEVIEW
11
+ create_view :#{view_name} do
12
+ "#{connection.view_build_query(view_name)}"
13
+ end
14
+ CREATEVIEW
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,18 @@
1
+ require 'spectacles/schema_statements/abstract_adapter'
2
+
3
+ module Spectacles
4
+ SUPPORTED_ADAPTERS = %w( Mysql Mysql2 PostgreSQL SQLServer SQLite )
5
+
6
+ def self.load_adapters
7
+ SUPPORTED_ADAPTERS.each do |db|
8
+ adapter_class = "#{db}Adapter"
9
+
10
+ if ActiveRecord::ConnectionAdapters.const_defined?(adapter_class)
11
+ require "spectacles/schema_statements/#{db.downcase}_adapter"
12
+ ActiveRecord::ConnectionAdapters.const_get(adapter_class).class_eval do
13
+ include Spectacles::SchemaStatements.const_get(adapter_class)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,40 @@
1
+ module Spectacles
2
+ module SchemaStatements
3
+ module AbstractAdapter
4
+ def create_view(view_name, build_query = nil)
5
+ raise "#{self.class} requires a query or block" if build_query.nil? && !block_given?
6
+
7
+ build_query = yield if block_given?
8
+ build_query = build_query.to_sql if build_query.respond_to?(:to_sql)
9
+
10
+ query = create_view_statement(view_name, build_query)
11
+ execute(query)
12
+ end
13
+
14
+ def create_view_statement(view_name, create_query)
15
+ query = "CREATE VIEW ? AS #{create_query}"
16
+ query_array = [query, view_name.to_s]
17
+
18
+ #return ActiveRecord::Base.__send__(:sanitize_sql_array, query_array)
19
+ "CREATE VIEW #{view_name} AS #{create_query}"
20
+ end
21
+
22
+ def drop_view(view_name)
23
+ query = drop_view_statement(view_name)
24
+ execute(query)
25
+ end
26
+
27
+ def drop_view_statement(view_name)
28
+ query = "DROP VIEW IF EXISTS ? "
29
+ query_array = [query, view_name.to_s]
30
+
31
+ #return ActiveRecord::Base.__send__(:sanitize_sql_array, query_array)
32
+ "DROP VIEW IF EXISTS #{view_name} "
33
+ end
34
+
35
+ def views
36
+ raise "Override view for your db adapter in #{self.class}"
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,9 @@
1
+ require 'spectacles/schema_statements/mysql_adapter'
2
+
3
+ module Spectacles
4
+ module SchemaStatements
5
+ module Mysql2Adapter
6
+ include Spectacles::SchemaStatements::MysqlAdapter
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,20 @@
1
+ require 'spectacles/schema_statements/abstract_adapter'
2
+
3
+ module Spectacles
4
+ module SchemaStatements
5
+ module MysqlAdapter
6
+ include Spectacles::SchemaStatements::AbstractAdapter
7
+
8
+ def views(name = nil) #:nodoc:
9
+ execute("SHOW FULL TABLES WHERE TABLE_TYPE='VIEW'").map { |row| row[0] }
10
+ end
11
+
12
+ def view_build_query(view, name = nil)
13
+ row = execute("SHOW CREATE VIEW #{view}", name).first
14
+ return row[1].gsub(/CREATE .*? (AS)+/i, "")
15
+ rescue ActiveRecord::StatementInvalid => e
16
+ raise "No view called #{view} found"
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,37 @@
1
+ require 'spectacles/schema_statements/abstract_adapter'
2
+
3
+ module Spectacles
4
+ module SchemaStatements
5
+ module PostgreSQLAdapter
6
+ include Spectacles::SchemaStatements::AbstractAdapter
7
+
8
+ def views(name = nil) #:nodoc:
9
+ q = <<-SQL
10
+ SELECT table_name, table_type
11
+ FROM information_schema.tables
12
+ WHERE table_schema IN (#{schemas})
13
+ AND table_type = 'VIEW'
14
+ SQL
15
+
16
+ query(q, name).map { |row| row[0] }
17
+ end
18
+
19
+ def view_build_query(view, name = nil)
20
+ q = <<-SQL
21
+ SELECT view_definition
22
+ FROM information_schema.views
23
+ WHERE table_catalog = (SELECT catalog_name FROM information_schema.information_schema_catalog_name)
24
+ AND table_schema IN (#{schemas})
25
+ AND table_name = '#{view}'
26
+ SQL
27
+
28
+ select_value(q, name) or raise "No view called #{view} found"
29
+ end
30
+
31
+ private
32
+ def schemas
33
+ schema_search_path.split(/,/).map { |p| quote(p) }.join(',')
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,33 @@
1
+ require 'spectacles/schema_statements/abstract_adapter'
2
+
3
+ module Spectacles
4
+ module SchemaStatements
5
+ module SQLiteAdapter
6
+ include Spectacles::SchemaStatements::AbstractAdapter
7
+
8
+ def generate_view_query(*columns)
9
+ sql = <<-SQL
10
+ SELECT #{columns.join(',')}
11
+ FROM sqlite_master
12
+ WHERE type = 'view'
13
+ SQL
14
+ end
15
+
16
+ def views #:nodoc:
17
+ sql = generate_view_query(:name)
18
+
19
+ exec_query(sql, "SCHEMA").map do |row|
20
+ row['name']
21
+ end
22
+ end
23
+
24
+ def view_build_query(table_name)
25
+ sql = generate_view_query(:sql)
26
+ sql << " AND name = #{quote_table_name(table_name)}"
27
+
28
+ row = exec_query(sql, "SCHEMA").first
29
+ row['sql'].gsub(/CREATE VIEW .*? AS/i, "")
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,23 @@
1
+ require 'spectacles/schema_statements/abstract_adapter'
2
+
3
+ module Spectacles
4
+ module SchemaStatements
5
+ module SQLServerAdapter
6
+ include Spectacles::SchemaStatements::AbstractAdapter
7
+
8
+ def views(name = nil) #:nodoc:
9
+ select_values("SELECT table_name FROM information_schema.views", name)
10
+ end
11
+
12
+ def view_build_query(view, name = nil)
13
+ q =<<-ENDSQL
14
+ SELECT view_definition FROM information_schema.views
15
+ WHERE table_name = '#{view}'
16
+ ENDSQL
17
+
18
+ q = select_value(q, name) or raise "No view called #{view} found"
19
+ q.gsub(/CREATE VIEW .*? AS/i, "")
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,3 @@
1
+ module Spectacles
2
+ VERSION = "0.0.2"
3
+ end
@@ -0,0 +1,9 @@
1
+ module Spectacles
2
+ class View < ActiveRecord::Base
3
+ self.abstract_class = true
4
+
5
+ def readonly?
6
+ true
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Spectacles::SchemaStatements::Mysql2Adapter" do
4
+ config = {
5
+ :adapter => "mysql2",
6
+ :host => "localhost",
7
+ :username => "root"
8
+ }
9
+
10
+ configure_database(config)
11
+ recreate_database("spectacles_test")
12
+ load_schema
13
+
14
+ it_behaves_like "an adapter", "Mysql2Adapter"
15
+ it_behaves_like "a view model"
16
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Spectacles::SchemaStatements::MysqlAdapter" do
4
+ config = {
5
+ :adapter => "mysql",
6
+ :host => "localhost",
7
+ :username => "root"
8
+ }
9
+ configure_database(config)
10
+ recreate_database("spectacles_test")
11
+ load_schema
12
+
13
+ it_behaves_like "an adapter", "MysqlAdapter"
14
+ it_behaves_like "a view model"
15
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Spectacles::SchemaStatements::PostgreSQLAdapter" do
4
+ config = {
5
+ :adapter => "postgresql",
6
+ :host => "localhost",
7
+ :username => "postgres",
8
+ :database => "postgres",
9
+ :min_messages => "error"
10
+ }
11
+ configure_database(config)
12
+ recreate_database("spectacles_test")
13
+ load_schema
14
+
15
+ it_behaves_like "an adapter", "PostgreSQLAdapter"
16
+ it_behaves_like "a view model"
17
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Spectacles::SchemaStatements::SQLiteAdapter" do
4
+ File.delete(File.expand_path(File.dirname(__FILE__) + "/../test.db")) rescue nil
5
+
6
+ ActiveRecord::Base.establish_connection(
7
+ :adapter => "sqlite3",
8
+ :database => "specs/test.db"
9
+ )
10
+ load_schema
11
+
12
+ it_behaves_like "an adapter", "SQLiteAdapter"
13
+ it_behaves_like "a view model"
14
+ end
@@ -0,0 +1,53 @@
1
+ require 'simplecov'
2
+ SimpleCov.start do
3
+ add_filter "/specs"
4
+ end
5
+
6
+ require 'rubygems'
7
+ require 'bundler'
8
+ Bundler.require(:default, :development, :test)
9
+
10
+ require 'minitest/spec'
11
+ require 'minitest/autorun'
12
+ require 'minitest/pride'
13
+ require 'support/minitest_shared'
14
+ require 'support/minitest_matchers'
15
+ require 'support/schema_statement_examples'
16
+ require 'support/view_examples'
17
+
18
+ class User < ActiveRecord::Base
19
+ has_many :products
20
+ end
21
+
22
+ class Product < ActiveRecord::Base
23
+ belongs_to :user
24
+ end
25
+
26
+ ActiveRecord::Schema.verbose = false
27
+
28
+ def configure_database(config)
29
+ @database_config = config
30
+ end
31
+
32
+ def load_schema
33
+ ActiveRecord::Schema.define(:version => 1) do
34
+ create_table :users do |t|
35
+ t.string :first_name
36
+ t.string :last_name
37
+ end
38
+
39
+ create_table :products do |t|
40
+ t.string :name
41
+ t.integer :value
42
+ t.boolean :available, :default => true
43
+ t.belongs_to :user
44
+ end
45
+ end
46
+ end
47
+
48
+ def recreate_database(database)
49
+ ActiveRecord::Base.establish_connection(@database_config)
50
+ ActiveRecord::Base.connection.drop_database(database) rescue nil
51
+ ActiveRecord::Base.connection.create_database(database)
52
+ ActiveRecord::Base.establish_connection(@database_config.merge(:database => database))
53
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spectacles::SchemaStatements::AbstractAdapter do
4
+ class TestBase
5
+ extend Spectacles::SchemaStatements::AbstractAdapter
6
+ end
7
+
8
+ describe "#create_view" do
9
+ it "throws error when block not given and no build_query" do
10
+ lambda { TestBase.create_view(:view_name) }.must_raise(RuntimeError)
11
+ end
12
+ end
13
+
14
+ describe "#views" do
15
+ it "throws error when accessed on AbstractAdapter" do
16
+ lambda { TestBase.views }.must_raise(RuntimeError)
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spectacles::View do
4
+ it "is an abstract class" do
5
+ Spectacles::View.abstract_class?.must_be true
6
+ end
7
+ end
@@ -0,0 +1,5 @@
1
+ require 'minitest/spec'
2
+
3
+ module MiniTest::Expectations
4
+ infect_an_assertion :assert_equal, :must_be
5
+ end
@@ -0,0 +1,21 @@
1
+ require 'minitest/spec'
2
+
3
+ MiniTest::Spec.class_eval do
4
+ def self.shared_examples
5
+ @shared_examples ||= {}
6
+ end
7
+ end
8
+
9
+ module MiniTest::Spec::SharedExamples
10
+ def shared_examples_for(desc, &block)
11
+ MiniTest::Spec.shared_examples[desc] = block
12
+ end
13
+
14
+ def it_behaves_like(desc, *args)
15
+ self.instance_eval do
16
+ MiniTest::Spec.shared_examples[desc].call(*args)
17
+ end
18
+ end
19
+ end
20
+
21
+ Object.class_eval { include(MiniTest::Spec::SharedExamples) }
@@ -0,0 +1,98 @@
1
+ require 'spec_helper'
2
+
3
+ shared_examples_for "an adapter" do |adapter|
4
+ shared_base = Class.new do
5
+ extend Spectacles::SchemaStatements.const_get(adapter)
6
+ def self.execute(query); query; end
7
+ end
8
+
9
+ describe "ActiveRecord::SchemaDumper#dump" do
10
+ before(:each) do
11
+ ActiveRecord::Base.connection.drop_view(:new_product_users)
12
+
13
+ ActiveRecord::Base.connection.create_view(:new_product_users) do
14
+ "SELECT name AS product_name, first_name AS username FROM
15
+ products JOIN users ON users.id = products.user_id"
16
+ end
17
+ end
18
+
19
+ it "should return create_view in dump stream" do
20
+ stream = StringIO.new
21
+ ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
22
+ stream.string.must_match(/create_view/)
23
+ end
24
+
25
+ it "should return create_view in dump stream" do
26
+ stream = StringIO.new
27
+ ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
28
+
29
+ ActiveRecord::Base.connection.views.each do |view|
30
+ ActiveRecord::Base.connection.drop_view(view)
31
+ end
32
+
33
+ ActiveRecord::Base.connection.tables.each do |table|
34
+ ActiveRecord::Base.connection.drop_table(table)
35
+ end
36
+
37
+ eval(stream.string)
38
+
39
+ ActiveRecord::Base.connection.views.must_include('new_product_users')
40
+ end
41
+ end
42
+
43
+ describe "#create_view" do
44
+ let(:view_name) { :view_name }
45
+
46
+ it "throws error when block not given and no build_query" do
47
+ lambda { shared_base.create_view(view_name) }.must_raise(RuntimeError)
48
+ end
49
+
50
+ describe "view_name" do
51
+ it "takes a symbol as the view_name" do
52
+ shared_base.create_view(view_name.to_sym, Product.scoped).must_match(/#{view_name}/)
53
+ end
54
+
55
+ it "takes a string as the view_name" do
56
+ shared_base.create_view(view_name.to_s, Product.scoped).must_match(/#{view_name}/)
57
+ end
58
+ end
59
+
60
+ describe "build_query" do
61
+ it "uses a string if passed" do
62
+ select_statement = "SELECT * FROM products"
63
+ shared_base.create_view(view_name, select_statement).must_match(/#{Regexp.escape(select_statement)}/)
64
+ end
65
+
66
+ it "uses an Arel::Relation if passed" do
67
+ select_statement = Product.scoped.to_sql
68
+ shared_base.create_view(view_name, Product.scoped).must_match(/#{Regexp.escape(select_statement)}/)
69
+ end
70
+ end
71
+
72
+ describe "block" do
73
+ it "can use an Arel::Relation from the yield" do
74
+ select_statement = Product.scoped.to_sql
75
+ shared_base.create_view(view_name) { Product.scoped }.must_match(/#{Regexp.escape(select_statement)}/)
76
+ end
77
+
78
+ it "can use a String from the yield" do
79
+ select_statement = "SELECT * FROM products"
80
+ shared_base.create_view(view_name) { "SELECT * FROM products" }.must_match(/#{Regexp.escape(select_statement)}/)
81
+ end
82
+ end
83
+ end
84
+
85
+ describe "#drop_view" do
86
+ let(:view_name) { :view_name }
87
+
88
+ describe "view_name" do
89
+ it "takes a symbol as the view_name" do
90
+ shared_base.drop_view(view_name.to_sym).must_match(/#{view_name}/)
91
+ end
92
+
93
+ it "takes a string as the view_name" do
94
+ shared_base.drop_view(view_name.to_s).must_match(/#{view_name}/)
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ shared_examples_for "a view model" do
4
+ ActiveRecord::Base.connection.create_view(:new_product_users) do
5
+ "SELECT name AS product_name, first_name AS username FROM
6
+ products JOIN users ON users.id = products.user_id"
7
+ end
8
+
9
+ class NewProductUser < Spectacles::View
10
+ scope :duck_lovers, where(:product_name => 'Rubber Duck')
11
+ end
12
+
13
+ describe "Spectacles::View" do
14
+ describe "inherited class" do
15
+ it "can has scopes" do
16
+ User.destroy_all
17
+ Product.destroy_all
18
+ @john = User.create(:first_name => 'John', :last_name => 'Doe')
19
+ @john.products.create(:name => 'Rubber Duck', :value => 10)
20
+
21
+ NewProductUser.duck_lovers.first.username.must_be @john.first_name
22
+ end
23
+
24
+ describe "an instance" do
25
+ it "is readonly" do
26
+ NewProductUser.new.readonly?.must_be true
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,31 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "spectacles/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "spectacles"
7
+ s.version = Spectacles::VERSION
8
+ s.authors = ["Adam Hutchison, Brandon Dewitt"]
9
+ s.email = ["liveh2o@gmail.com, brandonsdewitt@gmail.com"]
10
+ s.homepage = "http://github.com/liveh2o/spectacles"
11
+ s.summary = %q{Spectacles (derived from RailsSQLViews) adds database view functionality to ActiveRecord.}
12
+ s.description = %q{Still working out some of the kinks. Almost ready for Prime Time(TM). If you decide to use it and have problems, please report them at github.com/liveh2o/spectactles/issues}
13
+
14
+ s.rubyforge_project = "spectacles"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ # specify any dependencies here; for example:
22
+ s.add_development_dependency "minitest"
23
+ s.add_development_dependency "mysql"
24
+ s.add_development_dependency "mysql2"
25
+ s.add_development_dependency "pg"
26
+ s.add_development_dependency "rake"
27
+ s.add_development_dependency "sqlite3-ruby"
28
+
29
+ s.add_runtime_dependency "activerecord"
30
+ s.add_runtime_dependency "activesupport"
31
+ end
metadata ADDED
@@ -0,0 +1,162 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: spectacles
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Adam Hutchison, Brandon Dewitt
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-02-10 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: minitest
16
+ requirement: &2165825860 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *2165825860
25
+ - !ruby/object:Gem::Dependency
26
+ name: mysql
27
+ requirement: &2165825440 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *2165825440
36
+ - !ruby/object:Gem::Dependency
37
+ name: mysql2
38
+ requirement: &2165825020 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *2165825020
47
+ - !ruby/object:Gem::Dependency
48
+ name: pg
49
+ requirement: &2165824600 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *2165824600
58
+ - !ruby/object:Gem::Dependency
59
+ name: rake
60
+ requirement: &2165824180 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *2165824180
69
+ - !ruby/object:Gem::Dependency
70
+ name: sqlite3-ruby
71
+ requirement: &2165823760 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *2165823760
80
+ - !ruby/object:Gem::Dependency
81
+ name: activerecord
82
+ requirement: &2165823340 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :runtime
89
+ prerelease: false
90
+ version_requirements: *2165823340
91
+ - !ruby/object:Gem::Dependency
92
+ name: activesupport
93
+ requirement: &2165822920 !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ type: :runtime
100
+ prerelease: false
101
+ version_requirements: *2165822920
102
+ description: Still working out some of the kinks. Almost ready for Prime Time(TM).
103
+ If you decide to use it and have problems, please report them at github.com/liveh2o/spectactles/issues
104
+ email:
105
+ - liveh2o@gmail.com, brandonsdewitt@gmail.com
106
+ executables: []
107
+ extensions: []
108
+ extra_rdoc_files: []
109
+ files:
110
+ - .gitignore
111
+ - Gemfile
112
+ - Rakefile
113
+ - Readme.rdoc
114
+ - lib/spectacles.rb
115
+ - lib/spectacles/schema_dumper.rb
116
+ - lib/spectacles/schema_statements.rb
117
+ - lib/spectacles/schema_statements/abstract_adapter.rb
118
+ - lib/spectacles/schema_statements/mysql2_adapter.rb
119
+ - lib/spectacles/schema_statements/mysql_adapter.rb
120
+ - lib/spectacles/schema_statements/postgresql_adapter.rb
121
+ - lib/spectacles/schema_statements/sqlite_adapter.rb
122
+ - lib/spectacles/schema_statements/sqlserver_adapter.rb
123
+ - lib/spectacles/version.rb
124
+ - lib/spectacles/view.rb
125
+ - specs/adapters/mysql2_adapter_spec.rb
126
+ - specs/adapters/mysql_adapter_spec.rb
127
+ - specs/adapters/postgresql_adapter_spec.rb
128
+ - specs/adapters/sqlite_adapter_spec.rb
129
+ - specs/spec_helper.rb
130
+ - specs/spectacles/schema_statements/abstract_adapter_spec.rb
131
+ - specs/spectacles/view_spec.rb
132
+ - specs/support/minitest_matchers.rb
133
+ - specs/support/minitest_shared.rb
134
+ - specs/support/schema_statement_examples.rb
135
+ - specs/support/view_examples.rb
136
+ - spectacles.gemspec
137
+ homepage: http://github.com/liveh2o/spectacles
138
+ licenses: []
139
+ post_install_message:
140
+ rdoc_options: []
141
+ require_paths:
142
+ - lib
143
+ required_ruby_version: !ruby/object:Gem::Requirement
144
+ none: false
145
+ requirements:
146
+ - - ! '>='
147
+ - !ruby/object:Gem::Version
148
+ version: '0'
149
+ required_rubygems_version: !ruby/object:Gem::Requirement
150
+ none: false
151
+ requirements:
152
+ - - ! '>='
153
+ - !ruby/object:Gem::Version
154
+ version: '0'
155
+ requirements: []
156
+ rubyforge_project: spectacles
157
+ rubygems_version: 1.8.15
158
+ signing_key:
159
+ specification_version: 3
160
+ summary: Spectacles (derived from RailsSQLViews) adds database view functionality
161
+ to ActiveRecord.
162
+ test_files: []