dumbo 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.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +61 -0
- data/Rakefile +9 -0
- data/bin/dumbo +58 -0
- data/config/boot.rb +15 -0
- data/config/database.yml +31 -0
- data/dumbo.gemspec +31 -0
- data/lib/dumbo.rb +21 -0
- data/lib/dumbo/aggregate.rb +57 -0
- data/lib/dumbo/base_type.rb +71 -0
- data/lib/dumbo/cast.rb +49 -0
- data/lib/dumbo/composite_type.rb +31 -0
- data/lib/dumbo/db_task.rb +57 -0
- data/lib/dumbo/dependency_resolver.rb +105 -0
- data/lib/dumbo/enum_type.rb +28 -0
- data/lib/dumbo/extension.rb +73 -0
- data/lib/dumbo/extension_migrator.rb +66 -0
- data/lib/dumbo/extension_version.rb +25 -0
- data/lib/dumbo/function.rb +101 -0
- data/lib/dumbo/operator.rb +74 -0
- data/lib/dumbo/pg_object.rb +80 -0
- data/lib/dumbo/rake_task.rb +121 -0
- data/lib/dumbo/range_type.rb +43 -0
- data/lib/dumbo/type.rb +31 -0
- data/lib/dumbo/version.rb +3 -0
- data/lib/tasks/db.rake +52 -0
- data/lib/tasks/dumbo.rake +23 -0
- data/spec/Makefile +6 -0
- data/spec/aggregate_spec.rb +41 -0
- data/spec/cast_spec.rb +20 -0
- data/spec/dumbo_sample--0.0.1.sql +5 -0
- data/spec/dumbo_sample--0.0.2.sql +5 -0
- data/spec/dumbo_sample.control +5 -0
- data/spec/extension_migrator_spec.rb +40 -0
- data/spec/extension_spec.rb +19 -0
- data/spec/operator_spec.rb +42 -0
- data/spec/spec_helper.rb +28 -0
- data/spec/support/sql_helper.rb +23 -0
- data/spec/type_spec.rb +95 -0
- data/template/Gemfile +3 -0
- data/template/Makefile.erb +6 -0
- data/template/Rakefile +15 -0
- data/template/config/database.yml.erb +31 -0
- data/template/spec/sample_spec.rb.erb +13 -0
- data/template/sql/sample.sql +5 -0
- metadata +230 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8c38d6d2545804ea840a234c51c3d912fc2988a3
|
4
|
+
data.tar.gz: a1ace87c6b8469126e95a1eb94f9a503bcd93483
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6043bb12bfee32add950dd79093d41c3ea70732028749ccf8db79413d2e2219e8b3d5b197695255c4cba3d24ce4e38b3e3a2bdfc83522095ba9b85466fbf4623
|
7
|
+
data.tar.gz: ac5757b0c2dee69ecd5c0d962d3e0f4557b1937b5c08f63c0d3d3210134ef11975803a675e01f2770df35e250865e1331404577a42b246d8043406492394c778
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Manuel Kniep
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
# Dumbo
|
2
|
+
|
3
|
+
postgres extension with fun
|
4
|
+
|
5
|
+

|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
gem 'dumbo'
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install dumbo
|
20
|
+
|
21
|
+
## Getting Started
|
22
|
+
|
23
|
+
At the command prompt, create a new extension:
|
24
|
+
|
25
|
+
dumbo new myextention
|
26
|
+
|
27
|
+
where "myextention" is the extension name.
|
28
|
+
|
29
|
+
Change directory to myextention to start hacking:
|
30
|
+
|
31
|
+
cd myapp
|
32
|
+
|
33
|
+
As a stating point take a look at the sample function in
|
34
|
+
|
35
|
+
sql/sample.sql
|
36
|
+
|
37
|
+
and the corresponding test file
|
38
|
+
|
39
|
+
spec/sample_spec.rb
|
40
|
+
|
41
|
+
build the extension and run the specs
|
42
|
+
|
43
|
+
rake
|
44
|
+
|
45
|
+
if you start working on a new version run
|
46
|
+
|
47
|
+
rake dumbo:new_version [level]
|
48
|
+
|
49
|
+
where level is new version level (major, minor patch)
|
50
|
+
|
51
|
+
when you are done you can create the migration files with
|
52
|
+
|
53
|
+
rake dumbo:migrations
|
54
|
+
|
55
|
+
## Contributing
|
56
|
+
|
57
|
+
1. Fork it ( http://github.com/adeven/dumbo/fork )
|
58
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
59
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
60
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
61
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/bin/dumbo
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'thor'
|
3
|
+
require 'thor/group'
|
4
|
+
require 'erubis'
|
5
|
+
require 'fileutils'
|
6
|
+
|
7
|
+
module Cli
|
8
|
+
class Dumbo < Thor
|
9
|
+
|
10
|
+
desc "new name", "creates a new extension skeleton"
|
11
|
+
|
12
|
+
def new(name, initial_version='0.0.1')
|
13
|
+
FileUtils.mkdir_p("#{name}/sql")
|
14
|
+
FileUtils.mkdir_p("#{name}/src")
|
15
|
+
FileUtils.mkdir_p("#{name}/spec/support")
|
16
|
+
FileUtils.mkdir_p("#{name}/config")
|
17
|
+
FileUtils.mkdir_p("#{name}/lib/tasks")
|
18
|
+
|
19
|
+
spec_helper = Dir.glob(File.expand_path('../../spec/spec_helper.rb', __FILE__))
|
20
|
+
spec_helper += Dir.glob(File.expand_path('../../spec/support', __FILE__))
|
21
|
+
|
22
|
+
FileUtils.cp_r spec_helper, "#{name}/spec/"
|
23
|
+
|
24
|
+
FileUtils.cp File.expand_path('../../config/boot.rb', __FILE__), "#{name}/config/"
|
25
|
+
|
26
|
+
template_path = File.expand_path('../../template', __FILE__)
|
27
|
+
|
28
|
+
Dir.glob(File.expand_path('../../template/**/*', __FILE__)).each do |template|
|
29
|
+
pathname = Pathname.new(template)
|
30
|
+
dest_name = pathname.relative_path_from Pathname.new(template_path)
|
31
|
+
|
32
|
+
if pathname.directory?
|
33
|
+
FileUtils.mkdir_p("#{name}/#{dest_name}")
|
34
|
+
next
|
35
|
+
end
|
36
|
+
|
37
|
+
if dest_name.extname =='.erb'
|
38
|
+
eruby = Erubis::Eruby.new(File.read(template))
|
39
|
+
File.open("#{name}/#{dest_name.sub_ext('')}",'w') do |f|
|
40
|
+
f.puts eruby.result({ext_name: name})
|
41
|
+
end
|
42
|
+
else
|
43
|
+
FileUtils.cp template, "#{name}/#{dest_name}"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
File.open("#{name}/#{name}.control",'w') do |f|
|
48
|
+
f.puts "# #{name} extension"
|
49
|
+
f.puts "comment = 'my awesome extension'"
|
50
|
+
f.puts "default_version = '#{initial_version}'"
|
51
|
+
f.puts "relocatable = true"
|
52
|
+
f.puts "requires = ''"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
Cli::Dumbo.start(ARGV)
|
data/config/boot.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
$:.unshift File.expand_path('../..', __FILE__)
|
2
|
+
|
3
|
+
# Set up gems listed in the Gemfile.
|
4
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
|
5
|
+
ENV['DUMBO_ENV'] ||= 'development'
|
6
|
+
|
7
|
+
require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
|
8
|
+
Bundler.require(:default, ENV['DUMBO_ENV'].to_sym)
|
9
|
+
|
10
|
+
def db_config
|
11
|
+
@config ||= YAML.load_file('config/database.yml')
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
ActiveRecord::Base.establish_connection db_config[ENV['DUMBO_ENV']]
|
data/config/database.yml
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# general postgres settings
|
2
|
+
# Connect on a TCP socket. Omitted by default since the client uses a
|
3
|
+
# domain socket that doesn't need configuration. Windows does not have
|
4
|
+
# domain sockets, so uncomment these lines.
|
5
|
+
# host: localhost
|
6
|
+
# port: 5432
|
7
|
+
|
8
|
+
# Schema search path. The server defaults to $user,public
|
9
|
+
# schema_search_path: myapp,sharedapp,public
|
10
|
+
|
11
|
+
# Minimum log levels, in increasing order:
|
12
|
+
# debug5, debug4, debug3, debug2, debug1,
|
13
|
+
# log, notice, warning, error, fatal, and panic
|
14
|
+
# The server defaults to notice.
|
15
|
+
# min_messages: warning
|
16
|
+
|
17
|
+
postgres: &postgres
|
18
|
+
adapter: postgresql
|
19
|
+
encoding: utf8
|
20
|
+
pool: 5
|
21
|
+
username: postgres
|
22
|
+
password:
|
23
|
+
host: localhost
|
24
|
+
|
25
|
+
development:
|
26
|
+
<<: *postgres
|
27
|
+
database: dumbo_development
|
28
|
+
|
29
|
+
test:
|
30
|
+
<<: *postgres
|
31
|
+
database: dumbo_test
|
data/dumbo.gemspec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'dumbo/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "dumbo"
|
8
|
+
spec.version = Dumbo::VERSION
|
9
|
+
spec.authors = ["Manuel Kniep"]
|
10
|
+
spec.email = ["m.kniep@web.de"]
|
11
|
+
spec.summary = %q{postgres extension with fun}
|
12
|
+
spec.homepage = "https://github.com/adjust/dumbo"
|
13
|
+
spec.license = "MIT"
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0")
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
|
20
|
+
spec.add_dependency "rake"
|
21
|
+
spec.add_dependency 'erubis'
|
22
|
+
spec.add_dependency 'rspec', '~> 2.14.0'
|
23
|
+
spec.add_dependency'factory_girl', '~> 4.0'
|
24
|
+
spec.add_dependency 'activerecord'
|
25
|
+
spec.add_dependency 'pg', '> 0.17'
|
26
|
+
|
27
|
+
spec.add_dependency 'thor'
|
28
|
+
spec.add_dependency 'activesupport'
|
29
|
+
|
30
|
+
spec.add_dependency "bundler", "~> 1.5"
|
31
|
+
end
|
data/lib/dumbo.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
require "dumbo/version"
|
3
|
+
require "dumbo/pg_object"
|
4
|
+
require "dumbo/type"
|
5
|
+
require "dumbo/function"
|
6
|
+
require "dumbo/cast"
|
7
|
+
require "dumbo/base_type"
|
8
|
+
require "dumbo/aggregate"
|
9
|
+
require "dumbo/composite_type"
|
10
|
+
require "dumbo/dependency_resolver"
|
11
|
+
require "dumbo/enum_type"
|
12
|
+
require "dumbo/extension"
|
13
|
+
require "dumbo/extension_migrator"
|
14
|
+
require "dumbo/extension_version"
|
15
|
+
require "dumbo/operator"
|
16
|
+
require "dumbo/range_type"
|
17
|
+
require "dumbo/version"
|
18
|
+
|
19
|
+
module Dumbo
|
20
|
+
# Your code goes here...
|
21
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Dumbo
|
2
|
+
class Aggregate < PgObject
|
3
|
+
attr_accessor :name, :sfunc, :transname, :ffunc, :input_data_type, :state_data_type,
|
4
|
+
:initial_condition, :sort_operator
|
5
|
+
|
6
|
+
def load_attributes
|
7
|
+
result = execute <<-SQL
|
8
|
+
SELECT
|
9
|
+
proname AS name,
|
10
|
+
pg_get_function_arguments(pr.oid) AS input_data_type,
|
11
|
+
aggtransfn AS sfunc,
|
12
|
+
aggfinalfn AS ffunc,
|
13
|
+
agginitval AS initial_condition,
|
14
|
+
op.oprname AS sort_operator,
|
15
|
+
proargtypes,
|
16
|
+
aggtranstype AS state_data_type , proacl,
|
17
|
+
CASE WHEN (tt.typlen = -1 AND tt.typelem != 0) THEN (SELECT at.typname FROM pg_type at WHERE at.oid = tt.typelem) || '[]' ELSE tt.typname END as state_data_type,
|
18
|
+
prorettype AS aggfinaltype,
|
19
|
+
--CASE WHEN (tf.typlen = -1 AND tf.typelem != 0) THEN (SELECT at.typname FROM pg_type at WHERE at.oid = tf.typelem) || '[]' ELSE tf.typname END as ffunc,
|
20
|
+
description,
|
21
|
+
(SELECT array_agg(label) FROM pg_seclabels sl1 WHERE sl1.objoid=aggfnoid) AS labels,
|
22
|
+
(SELECT array_agg(provider) FROM pg_seclabels sl2 WHERE sl2.objoid=aggfnoid) AS providers, oprname, opn.nspname as oprnsp
|
23
|
+
FROM pg_aggregate ag
|
24
|
+
LEFT OUTER JOIN pg_operator op ON op.oid=aggsortop
|
25
|
+
LEFT OUTER JOIN pg_namespace opn ON opn.oid=op.oprnamespace
|
26
|
+
JOIN pg_proc pr ON pr.oid = ag.aggfnoid
|
27
|
+
JOIN pg_type tt on tt.oid=aggtranstype
|
28
|
+
JOIN pg_type tf on tf.oid=prorettype
|
29
|
+
LEFT OUTER JOIN pg_description des ON (des.objoid=aggfnoid::oid AND des.classoid='pg_aggregate'::regclass)
|
30
|
+
WHERE aggfnoid = #{oid}
|
31
|
+
SQL
|
32
|
+
|
33
|
+
result.first.each do |k,v|
|
34
|
+
send("#{k}=",v) rescue nil
|
35
|
+
end
|
36
|
+
|
37
|
+
result.first
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
def to_sql
|
42
|
+
attributes = []
|
43
|
+
attributes << "SFUNC = #{sfunc}"
|
44
|
+
attributes << "STYPE = #{state_data_type}"
|
45
|
+
attributes << "FINALFUNC = #{ffunc}" if ffunc && ffunc != '-'
|
46
|
+
attributes << "INITCOND = '#{initial_condition}'" if initial_condition
|
47
|
+
attributes << "SORTOP = #{sort_operator}" if sort_operator
|
48
|
+
|
49
|
+
<<-SQL.gsub(/^ {6}/, '')
|
50
|
+
CREATE AGGREGATE #{name}(#{input_data_type}) (
|
51
|
+
#{attributes.join(",\n ")}
|
52
|
+
);
|
53
|
+
SQL
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module Dumbo
|
2
|
+
class BaseType < Type
|
3
|
+
attr_accessor :input_function,
|
4
|
+
:output_function,
|
5
|
+
:receive_function,
|
6
|
+
:send_function,
|
7
|
+
:analyze_function,
|
8
|
+
:category,
|
9
|
+
:default,
|
10
|
+
:alignment,
|
11
|
+
:storage,
|
12
|
+
:type,
|
13
|
+
:internallength,
|
14
|
+
:attribute_name,
|
15
|
+
:typrelid
|
16
|
+
|
17
|
+
def load_attributes
|
18
|
+
sql = <<-SQL
|
19
|
+
SELECT
|
20
|
+
t.typname AS name,
|
21
|
+
t.typinput AS input_function,
|
22
|
+
t.typoutput AS output_function,
|
23
|
+
t.typreceive AS receive_function,
|
24
|
+
t.typsend AS send_function,
|
25
|
+
t.typanalyze AS analyze_function,
|
26
|
+
t.typcategory AS category,
|
27
|
+
t.typdefault AS default,
|
28
|
+
t.typrelid,
|
29
|
+
CASE WHEN t.typalign = 'i' THEN 'int' WHEN t.typalign = 'c' THEN 'char' WHEN t.typalign = 's' THEN 'short' WHEN t.typalign = 'd' THEN 'double' ELSE NULL END AS alignment,
|
30
|
+
CASE WHEN t.typstorage = 'p' THEN 'PLAIN' WHEN t.typstorage = 'e' THEN 'EXTENDED' WHEN t.typstorage = 'm' THEN 'MAIN' WHEN t.typstorage = 'x' THEN 'EXTENDED' ELSE NULL END AS storage,
|
31
|
+
t.typtype AS type,
|
32
|
+
t.typlen AS internallength,
|
33
|
+
format_type(t.oid, null) AS alias, e.typname as element,
|
34
|
+
description, ct.oid AS taboid,
|
35
|
+
(SELECT array_agg(label) FROM pg_seclabels sl1 WHERE sl1.objoid=t.oid) AS labels,
|
36
|
+
(SELECT array_agg(provider) FROM pg_seclabels sl2 WHERE sl2.objoid=t.oid) AS providers
|
37
|
+
FROM pg_type t
|
38
|
+
LEFT OUTER JOIN pg_type e ON e.oid=t.typelem
|
39
|
+
LEFT OUTER JOIN pg_class ct ON ct.oid = t.typrelid AND ct.relkind <> 'c'
|
40
|
+
LEFT OUTER JOIN pg_description des ON (des.objoid=t.oid AND des.classoid='pg_type'::regclass)
|
41
|
+
WHERE t.typtype != 'd' AND t.typnamespace = 2200::oid
|
42
|
+
AND ct.oid IS NULL
|
43
|
+
AND t.oid = #{oid}
|
44
|
+
SQL
|
45
|
+
|
46
|
+
result = execute sql
|
47
|
+
result.first.each do |k,v|
|
48
|
+
send("#{k}=",v) rescue nil
|
49
|
+
end
|
50
|
+
|
51
|
+
result.first
|
52
|
+
end
|
53
|
+
|
54
|
+
def to_sql
|
55
|
+
<<-SQL.gsub(/^ {8}/, '')
|
56
|
+
CREATE TYPE #{name}(
|
57
|
+
INPUT=#{input_function},
|
58
|
+
OUTPUT=#{output_function},
|
59
|
+
RECEIVE=#{receive_function},
|
60
|
+
SEND=#{send_function},
|
61
|
+
ANALYZE=#{analyze_function},
|
62
|
+
CATEGORY='#{category}',
|
63
|
+
DEFAULT='#{default}',
|
64
|
+
INTERNALLENGTH=#{internallength},
|
65
|
+
ALIGNMENT=#{alignment},
|
66
|
+
STORAGE=#{storage}
|
67
|
+
);
|
68
|
+
SQL
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
data/lib/dumbo/cast.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
module Dumbo
|
2
|
+
class Cast < PgObject
|
3
|
+
attr_accessor :source_type, :target_type, :function_name, :argument_type, :context
|
4
|
+
identfied_by :source_type, :target_type
|
5
|
+
|
6
|
+
def load_attributes
|
7
|
+
result = execute <<-SQL
|
8
|
+
SELECT
|
9
|
+
format_type(st.oid,NULL) AS source_type,
|
10
|
+
format_type(st.oid,NULL) AS argument_type,
|
11
|
+
format_type(tt.oid,tt.typtypmod) AS target_type,
|
12
|
+
proname AS function_name,
|
13
|
+
CASE WHEN ca.castcontext = 'e' THEN NULL
|
14
|
+
WHEN ca.castcontext = 'a' THEN 'ASSIGNMENT'
|
15
|
+
ELSE 'IMPLICIT'
|
16
|
+
END AS context
|
17
|
+
|
18
|
+
FROM pg_cast ca
|
19
|
+
JOIN pg_type st ON st.oid=castsource
|
20
|
+
JOIN pg_type tt ON tt.oid=casttarget
|
21
|
+
LEFT JOIN pg_proc pr ON pr.oid=castfunc
|
22
|
+
LEFT OUTER JOIN pg_description des ON (des.objoid=ca.oid AND des.objsubid=0 AND des.classoid='pg_cast'::regclass)
|
23
|
+
WHERE ca.oid = #{oid}
|
24
|
+
SQL
|
25
|
+
|
26
|
+
result.first.each do |k,v|
|
27
|
+
send("#{k}=",v) rescue nil
|
28
|
+
end
|
29
|
+
|
30
|
+
result.first
|
31
|
+
end
|
32
|
+
|
33
|
+
def drop
|
34
|
+
"DROP CAST (#{source_type} AS #{target_type})"
|
35
|
+
end
|
36
|
+
|
37
|
+
def to_sql
|
38
|
+
attributes = []
|
39
|
+
attributes << "WITH FUNCTION #{function_name}(#{source_type})" if function_name
|
40
|
+
attributes << "WITHOUT FUNCTION" unless function_name
|
41
|
+
attributes << context if context
|
42
|
+
|
43
|
+
<<-SQL.gsub(/^ {6}/, '')
|
44
|
+
CREATE CAST (#{source_type} AS #{target_type})
|
45
|
+
#{attributes.join("\nAS ")};
|
46
|
+
SQL
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|