squirm 0.0.5 → 0.0.6
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 +1 -0
- data/MIT-LICENSE +11 -12
- data/README.md +2 -14
- data/lib/squirm.rb +3 -4
- data/lib/squirm/core.rb +4 -10
- data/lib/squirm/executor.rb +17 -0
- data/lib/squirm/procedure.rb +4 -4
- data/lib/squirm/version.rb +1 -1
- data/spec/core_spec.rb +27 -0
- data/spec/procedure_spec.rb +13 -6
- metadata +7 -11
- data/lib/squirm/rails.rb +0 -54
- data/lib/squirm/rails/generator.rb +0 -11
- data/lib/squirm/rails/squirm.rake +0 -8
- data/lib/squirm/rails/stored_procedures.sql +0 -11
- data/lib/squirm/rails/unit_test.rb +0 -10
data/.gitignore
CHANGED
data/MIT-LICENSE
CHANGED
@@ -1,19 +1,18 @@
|
|
1
1
|
Copyright (c) 2011 Norman Clarke and Business Vision S.A.
|
2
2
|
|
3
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
4
|
+
this software and associated documentation files (the "Software"), to deal in
|
5
|
+
the Software without restriction, including without limitation the rights to
|
6
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
7
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
8
|
+
subject to the following conditions:
|
9
9
|
|
10
10
|
The above copyright notice and this permission notice shall be included in all
|
11
11
|
copies or substantial portions of the Software.
|
12
12
|
|
13
13
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
SOFTWARE.
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
15
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
16
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
17
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
18
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
@@ -42,23 +42,11 @@ Here's a quick demo of how you might use it:
|
|
42
42
|
id = create.call(email: "johndoe@example.com", name: "John Doe")
|
43
43
|
|
44
44
|
In and of itself, Squirm offers very little, but is meant to be a basic building
|
45
|
-
block for other libraries, such as [Squirm
|
45
|
+
block for other libraries, such as [Squirm Rails](https://github.com/bvision/squirm_rails),
|
46
|
+
which adds stored procedure support to Active Record, or [Squirm
|
46
47
|
Model](https://github.com/bvision/squirm_model), which supplies an Active Model
|
47
48
|
compatible ORM based on stored procedures.
|
48
49
|
|
49
|
-
## Using it with Rails
|
50
|
-
|
51
|
-
Squirm comes with built-in support to make it work seamlessly with Active Record:
|
52
|
-
|
53
|
-
class Person < ActiveRecord::Base
|
54
|
-
procedure :say_hello
|
55
|
-
end
|
56
|
-
|
57
|
-
p = Person.find(23)
|
58
|
-
p.say_hello
|
59
|
-
|
60
|
-
More documentation coming soon.
|
61
|
-
|
62
50
|
## Author
|
63
51
|
|
64
52
|
Norman Clarke <nclarke@bvision.com>
|
data/lib/squirm.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require "squirm/core"
|
2
2
|
require "squirm/pool"
|
3
3
|
require "squirm/procedure"
|
4
|
+
require "squirm/executor"
|
4
5
|
|
5
6
|
=begin
|
6
7
|
Squirm is an experimental anti-ORM for database-loving programmers who want to
|
@@ -68,8 +69,6 @@ end
|
|
68
69
|
|
69
70
|
module Kernel
|
70
71
|
def Squirm(&block)
|
71
|
-
Squirm.
|
72
|
+
Squirm::Executor.eval(&block)
|
72
73
|
end
|
73
|
-
end
|
74
|
-
|
75
|
-
require "squirm/rails" if defined? Rails
|
74
|
+
end
|
data/lib/squirm/core.rb
CHANGED
@@ -6,6 +6,8 @@ module Squirm
|
|
6
6
|
# The core DSL used by Squirm.
|
7
7
|
module Core
|
8
8
|
|
9
|
+
attr :pool
|
10
|
+
|
9
11
|
# Establishes a connection pool.
|
10
12
|
# @param [Hash] options The connection options
|
11
13
|
# @option options [String] :pool Use the given pool rather than Squirm's.
|
@@ -34,8 +36,7 @@ module Squirm
|
|
34
36
|
# Executes the query and passes the result to the block you specify.
|
35
37
|
def exec(*args, &block)
|
36
38
|
if current = Thread.current[:squirm_connection]
|
37
|
-
|
38
|
-
conn.exec(*args, &block)
|
39
|
+
current.exec(*args, &block)
|
39
40
|
else
|
40
41
|
use {|conn| conn.exec(*args, &block)}
|
41
42
|
end
|
@@ -45,12 +46,6 @@ module Squirm
|
|
45
46
|
Procedure.load(*args)
|
46
47
|
end
|
47
48
|
|
48
|
-
# Gets the connection pool.
|
49
|
-
# @return [Squirm::Pool] The connection pool.
|
50
|
-
def pool
|
51
|
-
@pool if defined? @pool
|
52
|
-
end
|
53
|
-
|
54
49
|
# Performs a #use inside a transaction.
|
55
50
|
def transaction
|
56
51
|
use do |connection|
|
@@ -78,8 +73,7 @@ module Squirm
|
|
78
73
|
conn_given = !!conn
|
79
74
|
conn = conn_given ? conn : @pool.checkout
|
80
75
|
begin
|
81
|
-
Thread.current[:squirm_connection] = conn
|
82
|
-
yield conn.respond_to?(:raw_connection) ? conn.raw_connection : conn
|
76
|
+
yield Thread.current[:squirm_connection] = conn
|
83
77
|
ensure
|
84
78
|
Thread.current[:squirm_connection] = nil
|
85
79
|
@pool.checkin conn unless conn_given
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Squirm
|
2
|
+
|
3
|
+
# This class exists simply to provide a space in which to evaluate blocked
|
4
|
+
# passed to the Kernel.Squirm method.
|
5
|
+
class Executor
|
6
|
+
include Core
|
7
|
+
|
8
|
+
def self.eval(&block)
|
9
|
+
executor = new(Squirm.pool)
|
10
|
+
executor.instance_eval(&block)
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(pool)
|
14
|
+
@pool = pool
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/squirm/procedure.rb
CHANGED
@@ -163,14 +163,14 @@ module Squirm
|
|
163
163
|
@hash = self.class.hashify(string)
|
164
164
|
end
|
165
165
|
|
166
|
-
# Formats arguments used to call the stored procedure.
|
166
|
+
# Formats the arguments used to call the stored procedure.
|
167
167
|
#
|
168
|
-
# When given
|
168
|
+
# When given anything other than a hash, the arguments are returned
|
169
169
|
# without modification.
|
170
170
|
#
|
171
|
-
# When given a hash, the return value is an array
|
171
|
+
# When given a hash, the return value is an array of arguments in the
|
172
172
|
# order needed when calling the procedure. Missing values are replaced by
|
173
|
-
# nil
|
173
|
+
# +nil+.
|
174
174
|
#
|
175
175
|
# @example
|
176
176
|
# # Assume a stored procedure with a definition like the following:
|
data/lib/squirm/version.rb
CHANGED
data/spec/core_spec.rb
CHANGED
@@ -10,6 +10,26 @@ describe Squirm do
|
|
10
10
|
assert_equal '"table"', Squirm.quote_ident("table")
|
11
11
|
end
|
12
12
|
|
13
|
+
it "should be a module" do
|
14
|
+
assert Squirm.is_a? Module
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should evaluate a block inside an Executor instance" do
|
18
|
+
assert_raises RuntimeError do
|
19
|
+
Squirm do
|
20
|
+
raise "SUCCESS" if self.class == Squirm::Executor
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "#procedure" do
|
26
|
+
it "should get a procedure instance and load it" do
|
27
|
+
Squirm.connect $squirm_test_connection
|
28
|
+
proc = Squirm.procedure "date", args: "abstime", schema: "pg_catalog"
|
29
|
+
assert proc.kind_of? Squirm::Procedure
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
13
33
|
describe "#connect" do
|
14
34
|
it "should use a pool if given" do
|
15
35
|
pool = OpenStruct.new
|
@@ -53,6 +73,13 @@ describe Squirm do
|
|
53
73
|
end
|
54
74
|
assert_nil Thread.current[:squirm_connection]
|
55
75
|
end
|
76
|
+
|
77
|
+
it "should use connection if given as an argument" do
|
78
|
+
mock = Object.new
|
79
|
+
Squirm.use(mock) do |conn|
|
80
|
+
assert mock == conn
|
81
|
+
end
|
82
|
+
end
|
56
83
|
end
|
57
84
|
|
58
85
|
describe "#exec" do
|
data/spec/procedure_spec.rb
CHANGED
@@ -93,24 +93,31 @@ describe Squirm::Procedure do
|
|
93
93
|
end
|
94
94
|
|
95
95
|
it "should load an overloaded functions if instance was initialized with :args" do
|
96
|
-
assert Squirm::Procedure.new("date", :
|
96
|
+
assert Squirm::Procedure.new("date", args: "abstime", schema: "pg_catalog").load
|
97
97
|
end
|
98
98
|
|
99
99
|
end
|
100
100
|
|
101
|
+
describe "#to_proc" do
|
102
|
+
before {Squirm.connect $squirm_test_connection}
|
103
|
+
|
104
|
+
it "should return a proc which calls the procedure" do
|
105
|
+
proc = Squirm::Procedure.new("date", args: "abstime", schema: "pg_catalog").load.to_proc
|
106
|
+
proc.call("Jan 1, 2011") {|result| assert_instance_of PGresult, result}
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
101
110
|
describe "#call" do
|
102
111
|
|
103
112
|
before {Squirm.connect $squirm_test_connection}
|
104
113
|
|
105
114
|
it "should yield the result to a block if given" do
|
106
|
-
proc = Squirm::Procedure.new("date", :
|
107
|
-
proc.call("Jan 1, 2011")
|
108
|
-
assert_instance_of PGresult, result
|
109
|
-
end
|
115
|
+
proc = Squirm::Procedure.new("date", args: "abstime", schema: "pg_catalog").load
|
116
|
+
proc.call("Jan 1, 2011") {|result| assert_instance_of PGresult, result}
|
110
117
|
end
|
111
118
|
|
112
119
|
it "should return the value of a single-row result" do
|
113
|
-
proc = Squirm::Procedure.new("date", :
|
120
|
+
proc = Squirm::Procedure.new("date", args: "abstime", schema: "pg_catalog").load
|
114
121
|
assert_equal "2011-01-01", proc.call("Jan 1, 2011")
|
115
122
|
end
|
116
123
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: squirm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-12-
|
12
|
+
date: 2011-12-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: minitest
|
16
|
-
requirement: &
|
16
|
+
requirement: &70292131700860 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '2.6'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70292131700860
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: pg
|
27
|
-
requirement: &
|
27
|
+
requirement: &70292131700180 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,7 +32,7 @@ dependencies:
|
|
32
32
|
version: 0.11.0
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70292131700180
|
36
36
|
description: ! '"Squirm is an anti-ORM for database-loving programmers"'
|
37
37
|
email:
|
38
38
|
- norman@njclarke.com
|
@@ -47,14 +47,10 @@ files:
|
|
47
47
|
- Rakefile
|
48
48
|
- lib/squirm.rb
|
49
49
|
- lib/squirm/core.rb
|
50
|
+
- lib/squirm/executor.rb
|
50
51
|
- lib/squirm/pool.rb
|
51
52
|
- lib/squirm/procedure.rb
|
52
53
|
- lib/squirm/procedure.sql
|
53
|
-
- lib/squirm/rails.rb
|
54
|
-
- lib/squirm/rails/generator.rb
|
55
|
-
- lib/squirm/rails/squirm.rake
|
56
|
-
- lib/squirm/rails/stored_procedures.sql
|
57
|
-
- lib/squirm/rails/unit_test.rb
|
58
54
|
- lib/squirm/version.rb
|
59
55
|
- spec/core_spec.rb
|
60
56
|
- spec/helper.rb
|
data/lib/squirm/rails.rb
DELETED
@@ -1,54 +0,0 @@
|
|
1
|
-
module Squirm
|
2
|
-
|
3
|
-
# Support for working with procedures inside Active Record models. This exists
|
4
|
-
# primarily to ensure that stored procedure calls are done inside the same
|
5
|
-
# connection used by the AR model, to avoid transaction opacity issues that
|
6
|
-
# could arise if AR and Squirm are used different connections.
|
7
|
-
module ActiveRecord
|
8
|
-
class Procedure < ::Squirm::Procedure
|
9
|
-
attr_accessor :connector
|
10
|
-
|
11
|
-
def call(*args, &block)
|
12
|
-
Squirm.use(connector.call) do
|
13
|
-
super
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
def self.included(model_class)
|
19
|
-
model_class.extend ClassMethods
|
20
|
-
end
|
21
|
-
|
22
|
-
module ClassMethods
|
23
|
-
def procedure(name, options = {}, &block)
|
24
|
-
self.class_eval(<<-EOM, __FILE__, __LINE__ + 1)
|
25
|
-
@@__squirm ||= {}
|
26
|
-
@@__squirm[:#{name}] = Squirm::ActiveRecord::Procedure.new("#{name}")
|
27
|
-
@@__squirm[:#{name}].connector = ->{connection}
|
28
|
-
@@__squirm[:#{name}].load
|
29
|
-
def #{options[:as] or name}(options = {})
|
30
|
-
options[:id] ||= id if @@__squirm[:#{name}].arguments.hash.has_key?(:id)
|
31
|
-
@@__squirm[:#{name}].call(options)
|
32
|
-
end
|
33
|
-
EOM
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
class Railtie < Rails::Railtie
|
39
|
-
initializer "squirm.setup" do
|
40
|
-
Squirm.connect pool: ::ActiveRecord::Base.connection_pool
|
41
|
-
::ActiveRecord::Base.send :include, Squirm::ActiveRecord
|
42
|
-
end
|
43
|
-
|
44
|
-
rake_tasks do
|
45
|
-
load File.expand_path("../rails/squirm.rake", __FILE__)
|
46
|
-
end
|
47
|
-
|
48
|
-
generators do
|
49
|
-
require File.expand_path("../rails/generator", __FILE__)
|
50
|
-
end
|
51
|
-
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
@@ -1,11 +0,0 @@
|
|
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 "stored_procedures.sql", "db/stored_procedures.sql"
|
8
|
-
copy_file "unit_test.rb", "test/unit/stored_procedures_test.rb"
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|
@@ -1,11 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
This is the stored_procedures.sql file used by Squirm. Define your Postgres
|
3
|
-
stored procedures in this file and they will be loaded at the end of any calls
|
4
|
-
to the 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'
|