spectacles 0.0.2

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,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: []