squirm_rails 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 +20 -0
- data/Gemfile +3 -0
- data/Rakefile +18 -0
- data/lib/squirm/rails.rb +23 -0
- data/lib/squirm/rails/active_record_support.rb +33 -0
- data/lib/squirm/rails/connection_pool.rb +22 -0
- data/lib/squirm/rails/functions.sql +11 -0
- data/lib/squirm/rails/generator.rb +11 -0
- data/lib/squirm/rails/squirm.rake +14 -0
- data/lib/squirm/rails/unit_test.rb +15 -0
- data/lib/squirm/rails/version.rb +5 -0
- data/squirm_rails.gemspec +24 -0
- data/test/active_record_support_test.rb +27 -0
- data/test/generator_test.rb +23 -0
- data/test/helper.rb +56 -0
- metadata +108 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'rake/clean'
|
2
|
+
require 'rake/testtask'
|
3
|
+
|
4
|
+
CLEAN.include "pkg", "test/coverage", "doc", "*.gem"
|
5
|
+
|
6
|
+
task default: :test
|
7
|
+
|
8
|
+
task :gem do
|
9
|
+
sh "gem build squirm_rails.gemspec"
|
10
|
+
end
|
11
|
+
|
12
|
+
task :test do
|
13
|
+
Rake::TestTask.new do |t|
|
14
|
+
t.libs << "test"
|
15
|
+
t.test_files = FileList["test/*_test.rb"]
|
16
|
+
t.verbose = false
|
17
|
+
end
|
18
|
+
end
|
data/lib/squirm/rails.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require "squirm"
|
2
|
+
require "squirm/rails/connection_pool"
|
3
|
+
require "squirm/rails/active_record_support"
|
4
|
+
|
5
|
+
module Squirm
|
6
|
+
module Rails
|
7
|
+
|
8
|
+
class Railtie < ::Rails::Railtie
|
9
|
+
initializer "squirm.setup" do
|
10
|
+
Squirm.connect pool: ConnectionPool.new
|
11
|
+
ActiveRecord::Base.extend ActiveRecordSupport
|
12
|
+
end
|
13
|
+
|
14
|
+
rake_tasks do
|
15
|
+
load File.expand_path("../rails/squirm.rake", __FILE__)
|
16
|
+
end
|
17
|
+
|
18
|
+
generators do
|
19
|
+
require File.expand_path("../rails/generator", __FILE__)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Squirm
|
2
|
+
|
3
|
+
module Rails
|
4
|
+
|
5
|
+
# Support for working with procedures inside Active Record models. This
|
6
|
+
# exists primarily to ensure that stored procedure calls are done inside the
|
7
|
+
# same connection used by the AR model, to avoid transaction opacity issues
|
8
|
+
# that could arise if AR and Squirm are used different connections.
|
9
|
+
module ActiveRecordSupport
|
10
|
+
|
11
|
+
def procedure(name, options = {}, &block)
|
12
|
+
name = options[:as] || name
|
13
|
+
|
14
|
+
self.class_eval(<<-EOM, __FILE__, __LINE__ + 1)
|
15
|
+
@@__squirm ||= {}
|
16
|
+
@@__squirm[:#{name}] = Squirm.procedure("#{name}")
|
17
|
+
|
18
|
+
def self.#{name}(options = {})
|
19
|
+
Squirm.use(connection.raw_connection) do
|
20
|
+
@@__squirm[:#{name}].call(options)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def #{name}(options = {})
|
25
|
+
proc_args = @@__squirm[:#{name}].arguments
|
26
|
+
args = proc_args.inject({}) {|m, o| m[o] ||= try(o); m}
|
27
|
+
self.class.#{name}(args.merge(options))
|
28
|
+
end
|
29
|
+
EOM
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Squirm
|
2
|
+
module Rails
|
3
|
+
class ConnectionPool
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@pool = ActiveRecord::Base.connection_pool
|
7
|
+
@map = {}
|
8
|
+
end
|
9
|
+
|
10
|
+
def checkout
|
11
|
+
conn = @pool.checkout
|
12
|
+
raw_connection = conn.raw_connection
|
13
|
+
@map[raw_connection.object_id] = conn
|
14
|
+
raw_connection
|
15
|
+
end
|
16
|
+
|
17
|
+
def checkin(raw_connection)
|
18
|
+
@pool.checkin @map[raw_connection.object_id]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
/*
|
2
|
+
This is the functions.sql file used by Squirm-Rails. Define your Postgres stored
|
3
|
+
procedures in this file and they will be loaded at the end of any calls to the
|
4
|
+
db:schema:load Rake task.
|
5
|
+
*/
|
6
|
+
|
7
|
+
CREATE OR REPLACE FUNCTION hello_world() RETURNS TEXT AS $$
|
8
|
+
BEGIN
|
9
|
+
RETURN 'hello world!';
|
10
|
+
END;
|
11
|
+
$$ LANGUAGE 'PLPGSQL'
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require "rails/generators"
|
2
|
+
|
3
|
+
module Squirm
|
4
|
+
class Install < ::Rails::Generators::Base
|
5
|
+
source_root File.dirname(__FILE__)
|
6
|
+
def install_functions
|
7
|
+
copy_file "functions.sql", "db/functions.sql"
|
8
|
+
copy_file "unit_test.rb", "test/unit/stored_procedures/hello_world_test.rb"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
namespace :db do
|
2
|
+
namespace :functions do
|
3
|
+
task :load => :environment do
|
4
|
+
functions = File.read(Rails.root.join("db", "functions.sql"))
|
5
|
+
ActiveRecord::Base.connection.execute functions
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
namespace :schema do
|
10
|
+
task :load do
|
11
|
+
Rake::Task["db:functions:load"].invoke
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module StoredProcedureTests
|
4
|
+
|
5
|
+
class HelloWorldTest < ActiveSupport::TestCase
|
6
|
+
def setup
|
7
|
+
@procedure = Squirm.procedure "hello_world"
|
8
|
+
end
|
9
|
+
|
10
|
+
test "hello_world should emit a greeting" do
|
11
|
+
assert_equal "hello world!", @procedure.call
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require File.expand_path("../lib/squirm/rails/version", __FILE__)
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = "squirm_rails"
|
5
|
+
s.version = Squirm::Rails::VERSION
|
6
|
+
s.platform = Gem::Platform::RUBY
|
7
|
+
s.authors = ["Norman Clarke"]
|
8
|
+
s.email = ["norman@njclarke.com"]
|
9
|
+
s.homepage = "http://github.com/bvision/squirm_rails"
|
10
|
+
s.summary = %q{"Easily use and manage Postgres stored procedures with Active Record."}
|
11
|
+
s.description = %q{"Squirm facilitates using Postgres stored procedures with Active Record."}
|
12
|
+
s.bindir = "bin"
|
13
|
+
s.files = `git ls-files`.split("\n")
|
14
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
15
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
16
|
+
s.require_paths = ["lib"]
|
17
|
+
s.required_ruby_version = ">= 1.9"
|
18
|
+
|
19
|
+
s.add_development_dependency "minitest"
|
20
|
+
s.add_runtime_dependency "squirm", ">= 0.0.6"
|
21
|
+
s.add_runtime_dependency "activerecord", ">= 3.0.0"
|
22
|
+
s.add_runtime_dependency "railties"
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require File.expand_path("../helper", __FILE__)
|
2
|
+
|
3
|
+
class ActiveRecordSupportTest < MiniTest::Unit::TestCase
|
4
|
+
test "#procedure should define an instance method that invokes a procuedure of the same name" do
|
5
|
+
model_class = Class.new(Person) do
|
6
|
+
procedure "hello_world"
|
7
|
+
end
|
8
|
+
assert model_class.public_instance_methods.include? :hello_world
|
9
|
+
assert_equal "hello world!", model_class.new.hello_world
|
10
|
+
end
|
11
|
+
|
12
|
+
test "#procedure should define class method that invokes a procuedure of the same name" do
|
13
|
+
model_class = Class.new(Person) do
|
14
|
+
procedure "hello_world"
|
15
|
+
end
|
16
|
+
assert model_class.public_methods.include? :hello_world
|
17
|
+
assert_equal "hello world!", model_class.hello_world
|
18
|
+
end
|
19
|
+
|
20
|
+
test "#procedure should pass instance variables matching procedure argument names" do
|
21
|
+
model_class = Class.new(Person) do
|
22
|
+
procedure "return_name_and_email"
|
23
|
+
end
|
24
|
+
person = model_class.new name: "foo", email: "bar"
|
25
|
+
assert_equal "foo bar", person.return_name_and_email
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require File.expand_path("../helper", __FILE__)
|
2
|
+
|
3
|
+
class SquirmRailsGeneratorTest < Rails::Generators::TestCase
|
4
|
+
|
5
|
+
tests Squirm::Install
|
6
|
+
destination File.expand_path("../../tmp", __FILE__)
|
7
|
+
|
8
|
+
setup :prepare_destination
|
9
|
+
|
10
|
+
def teardown
|
11
|
+
FileUtils.rm_rf self.destination_root
|
12
|
+
end
|
13
|
+
|
14
|
+
test "should generate functions.sql" do
|
15
|
+
run_generator
|
16
|
+
assert_file "db/functions.sql"
|
17
|
+
end
|
18
|
+
|
19
|
+
test "should generate unit test" do
|
20
|
+
run_generator
|
21
|
+
assert_file "test/unit/stored_procedures/hello_world_test.rb"
|
22
|
+
end
|
23
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
if ENV["COVERAGE"]
|
2
|
+
require 'simplecov'
|
3
|
+
SimpleCov.start do
|
4
|
+
add_filter "/spec/"
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
require "bundler/setup"
|
9
|
+
require "minitest/unit"
|
10
|
+
require 'minitest/autorun'
|
11
|
+
|
12
|
+
require "active_record"
|
13
|
+
require "rails"
|
14
|
+
|
15
|
+
ActiveRecord::Base.establish_connection \
|
16
|
+
:adapter => "postgresql",
|
17
|
+
:host => "localhost",
|
18
|
+
:database => "squirm_test",
|
19
|
+
:pool_size => 2
|
20
|
+
|
21
|
+
# $VERBOSE = true
|
22
|
+
|
23
|
+
require "squirm/rails"
|
24
|
+
require "squirm/rails/generator"
|
25
|
+
|
26
|
+
ActiveRecord::Base.extend Squirm::Rails::ActiveRecordSupport
|
27
|
+
|
28
|
+
Squirm.connect pool: Squirm::Rails::ConnectionPool.new
|
29
|
+
|
30
|
+
Squirm do
|
31
|
+
exec "DROP TABLE IF EXISTS people"
|
32
|
+
exec "CREATE TABLE people(id SERIAL, name VARCHAR(126), email VARCHAR(128))"
|
33
|
+
exec %q{
|
34
|
+
CREATE OR REPLACE FUNCTION hello_world() RETURNS TEXT AS $$
|
35
|
+
BEGIN
|
36
|
+
RETURN 'hello world!';
|
37
|
+
END;
|
38
|
+
$$ LANGUAGE 'PLPGSQL'
|
39
|
+
}
|
40
|
+
exec %q{
|
41
|
+
CREATE OR REPLACE FUNCTION return_name_and_email(_name text, _email text) RETURNS TEXT AS $$
|
42
|
+
BEGIN
|
43
|
+
RETURN _name || ' ' || _email;
|
44
|
+
END;
|
45
|
+
$$ LANGUAGE 'PLPGSQL'
|
46
|
+
}
|
47
|
+
end
|
48
|
+
|
49
|
+
class Module
|
50
|
+
def test(name, &block)
|
51
|
+
define_method("test_#{name.gsub(/[^a-z0-9']/i, "_")}".to_sym, &block)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
class Person < ActiveRecord::Base
|
56
|
+
end
|
metadata
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: squirm_rails
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Norman Clarke
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-12-27 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: minitest
|
16
|
+
requirement: &70309450323300 !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: *70309450323300
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: squirm
|
27
|
+
requirement: &70309450322460 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 0.0.6
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70309450322460
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: activerecord
|
38
|
+
requirement: &70309450321680 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 3.0.0
|
44
|
+
type: :runtime
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70309450321680
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: railties
|
49
|
+
requirement: &70309450337060 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :runtime
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70309450337060
|
58
|
+
description: ! '"Squirm facilitates using Postgres stored procedures with Active Record."'
|
59
|
+
email:
|
60
|
+
- norman@njclarke.com
|
61
|
+
executables: []
|
62
|
+
extensions: []
|
63
|
+
extra_rdoc_files: []
|
64
|
+
files:
|
65
|
+
- .gitignore
|
66
|
+
- Gemfile
|
67
|
+
- Rakefile
|
68
|
+
- lib/squirm/rails.rb
|
69
|
+
- lib/squirm/rails/active_record_support.rb
|
70
|
+
- lib/squirm/rails/connection_pool.rb
|
71
|
+
- lib/squirm/rails/functions.sql
|
72
|
+
- lib/squirm/rails/generator.rb
|
73
|
+
- lib/squirm/rails/squirm.rake
|
74
|
+
- lib/squirm/rails/unit_test.rb
|
75
|
+
- lib/squirm/rails/version.rb
|
76
|
+
- squirm_rails.gemspec
|
77
|
+
- test/active_record_support_test.rb
|
78
|
+
- test/generator_test.rb
|
79
|
+
- test/helper.rb
|
80
|
+
homepage: http://github.com/bvision/squirm_rails
|
81
|
+
licenses: []
|
82
|
+
post_install_message:
|
83
|
+
rdoc_options: []
|
84
|
+
require_paths:
|
85
|
+
- lib
|
86
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
87
|
+
none: false
|
88
|
+
requirements:
|
89
|
+
- - ! '>='
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '1.9'
|
92
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
93
|
+
none: false
|
94
|
+
requirements:
|
95
|
+
- - ! '>='
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
requirements: []
|
99
|
+
rubyforge_project:
|
100
|
+
rubygems_version: 1.8.10
|
101
|
+
signing_key:
|
102
|
+
specification_version: 3
|
103
|
+
summary: ! '"Easily use and manage Postgres stored procedures with Active Record."'
|
104
|
+
test_files:
|
105
|
+
- test/active_record_support_test.rb
|
106
|
+
- test/generator_test.rb
|
107
|
+
- test/helper.rb
|
108
|
+
has_rdoc:
|