pg_saurus 2.2.1 → 2.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.markdown +28 -2
- data/lib/pg_saurus/connection_adapters.rb +1 -0
- data/lib/pg_saurus/connection_adapters/abstract_adapter.rb +2 -0
- data/lib/pg_saurus/connection_adapters/abstract_adapter/function_methods.rb +24 -0
- data/lib/pg_saurus/connection_adapters/function_definition.rb +10 -0
- data/lib/pg_saurus/connection_adapters/postgresql_adapter.rb +2 -0
- data/lib/pg_saurus/connection_adapters/postgresql_adapter/function_methods.rb +109 -0
- data/lib/pg_saurus/migration/command_recorder.rb +2 -0
- data/lib/pg_saurus/migration/command_recorder/function_methods.rb +23 -0
- data/lib/pg_saurus/schema_dumper.rb +4 -1
- data/lib/pg_saurus/schema_dumper/function_methods.rb +24 -0
- data/lib/pg_saurus/version.rb +1 -1
- metadata +14 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3e759d3f6f18831227c70d8d5609d0545053a3ec
|
4
|
+
data.tar.gz: 6bacd12ec585be568ad2863c9cc7dedb112b97fd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 66c2279cce0676edd0084721a66ef4faf325df16e43e77649b9cc0bf95bf6a41af41f43c645d14d711656ed1159c9ff80dec6e95b7ec450ee5f97fb257e3c910
|
7
|
+
data.tar.gz: 8d33063a06e25aaf16868674bee9c2c9811237ac82d2519c78cccdbdc45837027aba1fb18376ed495a3f460a23608b3eb0257944ec28cc1e95f03a59eec87f6f
|
data/README.markdown
CHANGED
@@ -310,6 +310,32 @@ PgSaurus.configre do |config|
|
|
310
310
|
end
|
311
311
|
```
|
312
312
|
|
313
|
+
## Functions
|
314
|
+
|
315
|
+
You can create, list, and drop functions.
|
316
|
+
|
317
|
+
### Examples
|
318
|
+
|
319
|
+
```ruby
|
320
|
+
pets_not_empty_function = <<-SQL
|
321
|
+
BEGIN
|
322
|
+
IF (SELECT COUNT(*) FROM pets) > 0
|
323
|
+
THEN
|
324
|
+
RETURN true;
|
325
|
+
ELSE
|
326
|
+
RETURN false;
|
327
|
+
END IF;
|
328
|
+
END;
|
329
|
+
SQL
|
330
|
+
|
331
|
+
create_function 'pets_not_empty()', :boolean, pets_not_empty_function, schema: 'public'
|
332
|
+
functions.any?{ |function| function.name == 'public.pets_not_empty()' }
|
333
|
+
# => true
|
334
|
+
drop_function 'pets_not_empty()'
|
335
|
+
functions.any?{ |function| function.name == 'public.pets_not_empty()' }
|
336
|
+
# => false
|
337
|
+
```
|
338
|
+
|
313
339
|
## Tools
|
314
340
|
|
315
341
|
PgSaurus::Tools provides a number of useful methods:
|
@@ -357,14 +383,14 @@ Support for JRuby:
|
|
357
383
|
## Credits
|
358
384
|
|
359
385
|
* [Potapov Sergey](https://github.com/greyblake) - schema support
|
360
|
-
* [Arthur Shagall](https://github.com/albertosaurus) - thanks for [pg_comment](https://github.com/albertosaurus/pg_comment)
|
386
|
+
* [Arthur Shagall](https://github.com/albertosaurus) - function support - and thanks for [pg_comment](https://github.com/albertosaurus/pg_comment)
|
361
387
|
* [Matthew Higgins](https://github.com/matthuhiggins) - thanks for [foreigner](https://github.com/matthuhiggins/foreigner), which was used as a base for the foreign key support
|
362
388
|
* [Artem Ignatyev](https://github.com/cryo28) - extension modules load/unload support
|
363
389
|
* [Marcelo Silveira](https://github.com/mhfs) - thanks for rails partial index support that was backported into this gem
|
364
390
|
|
365
391
|
## Copyright and License
|
366
392
|
|
367
|
-
* Copyright (c)
|
393
|
+
* Copyright (c) 2015 HornsAndHooves.
|
368
394
|
* Initial foreign key code taken from foreigner, Copyright (c) 2009 Matthew Higgins
|
369
395
|
* pg_comment Copyright (c) 2011 Arthur Shagall
|
370
396
|
* Partial index Copyright (c) 2012 Marcelo Silveira
|
@@ -7,11 +7,13 @@ module PgSaurus::ConnectionAdapters::AbstractAdapter
|
|
7
7
|
autoload :ForeignerMethods
|
8
8
|
autoload :SchemaMethods
|
9
9
|
autoload :IndexMethods
|
10
|
+
autoload :FunctionMethods
|
10
11
|
|
11
12
|
include CommentMethods
|
12
13
|
include ForeignerMethods
|
13
14
|
include SchemaMethods
|
14
15
|
include IndexMethods
|
16
|
+
include FunctionMethods
|
15
17
|
|
16
18
|
included do
|
17
19
|
alias_method_chain :create_table, :schema_option
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# Adapter definitions for DB functions.
|
2
|
+
module PgSaurus::ConnectionAdapters::AbstractAdapter::FunctionMethods
|
3
|
+
|
4
|
+
# :nodoc
|
5
|
+
def supports_functions?
|
6
|
+
false
|
7
|
+
end
|
8
|
+
|
9
|
+
# Create a database function.
|
10
|
+
def create_function(function_name, returning, definition, options = {})
|
11
|
+
|
12
|
+
end
|
13
|
+
|
14
|
+
# Delete the database function.
|
15
|
+
def drop_function(function_name, options)
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
# Return the listing of currently defined DB functions.
|
20
|
+
def functions
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
@@ -12,6 +12,7 @@ module PgSaurus::ConnectionAdapters::PostgreSQLAdapter
|
|
12
12
|
autoload :IndexMethods, 'pg_saurus/connection_adapters/postgresql_adapter/index_methods'
|
13
13
|
autoload :TranslateException, 'pg_saurus/connection_adapters/postgresql_adapter/translate_exception'
|
14
14
|
autoload :ViewMethods, 'pg_saurus/connection_adapters/postgresql_adapter/view_methods'
|
15
|
+
autoload :FunctionMethods, 'pg_saurus/connection_adapters/postgresql_adapter/function_methods'
|
15
16
|
|
16
17
|
include ExtensionMethods
|
17
18
|
include SchemaMethods
|
@@ -20,6 +21,7 @@ module PgSaurus::ConnectionAdapters::PostgreSQLAdapter
|
|
20
21
|
include IndexMethods
|
21
22
|
include TranslateException
|
22
23
|
include ViewMethods
|
24
|
+
include FunctionMethods
|
23
25
|
|
24
26
|
included do
|
25
27
|
alias_method_chain :tables, :non_public_schema_tables
|
@@ -0,0 +1,109 @@
|
|
1
|
+
# Methods to extend {ActiveRecord::ConnectionAdapters::PostgreSQLAdapter}
|
2
|
+
# to support database functions.
|
3
|
+
module PgSaurus::ConnectionAdapters::PostgreSQLAdapter::FunctionMethods
|
4
|
+
|
5
|
+
# Return +true+.
|
6
|
+
def supports_functions?
|
7
|
+
true
|
8
|
+
end
|
9
|
+
|
10
|
+
# Return a list of defined DB functions. Ignore function definitions that can't be parsed.
|
11
|
+
def functions
|
12
|
+
res = select_all <<-SQL
|
13
|
+
SELECT n.nspname AS "Schema",
|
14
|
+
p.proname AS "Name",
|
15
|
+
pg_catalog.pg_get_function_result(p.oid) AS "Returning",
|
16
|
+
CASE
|
17
|
+
WHEN p.proisagg THEN 'agg'
|
18
|
+
WHEN p.proiswindow THEN 'window'
|
19
|
+
WHEN p.prorettype = 'pg_catalog.trigger'::pg_catalog.regtype
|
20
|
+
THEN 'trigger'
|
21
|
+
ELSE 'normal'
|
22
|
+
END AS "Type",
|
23
|
+
p.oid AS "Oid"
|
24
|
+
FROM pg_catalog.pg_proc p
|
25
|
+
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace
|
26
|
+
WHERE pg_catalog.pg_function_is_visible(p.oid)
|
27
|
+
AND n.nspname <> 'pg_catalog'
|
28
|
+
AND n.nspname <> 'information_schema'
|
29
|
+
ORDER BY 1, 2, 3, 4;
|
30
|
+
SQL
|
31
|
+
res.inject([]) do |buffer, row|
|
32
|
+
returning = row['Returning']
|
33
|
+
function_type = row['Type']
|
34
|
+
oid = row['Oid']
|
35
|
+
|
36
|
+
function_str = select_value("SELECT pg_get_functiondef(#{oid});")
|
37
|
+
|
38
|
+
name = parse_function_name(function_str)
|
39
|
+
language = parse_function_language(function_str)
|
40
|
+
definition = parse_function_definition(function_str)
|
41
|
+
|
42
|
+
if definition
|
43
|
+
buffer << ::PgSaurus::ConnectionAdapters::FunctionDefinition.new(name,
|
44
|
+
returning,
|
45
|
+
definition.strip,
|
46
|
+
function_type,
|
47
|
+
language,
|
48
|
+
oid)
|
49
|
+
end
|
50
|
+
buffer
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Create a new database function.
|
55
|
+
def create_function(function_name, returning, definition, options = {})
|
56
|
+
|
57
|
+
function_name = full_function_name(function_name, options)
|
58
|
+
language = options[:language] || 'plpgsql'
|
59
|
+
replace = if options[:replace] == false
|
60
|
+
''
|
61
|
+
else
|
62
|
+
'OR REPLACE '
|
63
|
+
end
|
64
|
+
|
65
|
+
sql = <<-SQL.gsub(/^[ ]{6}/, "")
|
66
|
+
CREATE #{replace}FUNCTION #{function_name}
|
67
|
+
RETURNS #{returning}
|
68
|
+
LANGUAGE #{language}
|
69
|
+
AS $function$
|
70
|
+
#{definition.strip}
|
71
|
+
$function$
|
72
|
+
SQL
|
73
|
+
|
74
|
+
execute(sql)
|
75
|
+
end
|
76
|
+
|
77
|
+
# Drop the given database function.
|
78
|
+
def drop_function(function_name, options = {})
|
79
|
+
function_name = full_function_name(function_name, options)
|
80
|
+
|
81
|
+
execute "DROP FUNCTION #{function_name}"
|
82
|
+
end
|
83
|
+
|
84
|
+
# Retrieve the function name from the function SQL.
|
85
|
+
def parse_function_name(function_str)
|
86
|
+
function_str.split("\n").find { |line| line =~ /^CREATE[\s\S]+FUNCTION/ }.split(' ').last
|
87
|
+
end
|
88
|
+
private :parse_function_name
|
89
|
+
|
90
|
+
# Retrieve the function language from the function SQL.
|
91
|
+
def parse_function_language(function_str)
|
92
|
+
function_str.split("\n").find { |line| line =~ /LANGUAGE/ }.split(' ').last
|
93
|
+
end
|
94
|
+
private :parse_function_language
|
95
|
+
|
96
|
+
# Retrieve the function definition from the function SQL.
|
97
|
+
def parse_function_definition(function_str)
|
98
|
+
function_str[/#{Regexp.escape("AS $function$\n")}(.*?)#{Regexp.escape("$function$")}/m, 1]
|
99
|
+
end
|
100
|
+
private :parse_function_definition
|
101
|
+
|
102
|
+
# Write out the fully qualified function name if the :schema option is passed.
|
103
|
+
def full_function_name(function_name, options)
|
104
|
+
schema = options[:schema]
|
105
|
+
function_name = "#{schema}.#{function_name}" if schema
|
106
|
+
function_name
|
107
|
+
end
|
108
|
+
private :full_function_name
|
109
|
+
end
|
@@ -8,10 +8,12 @@ module PgSaurus::Migration::CommandRecorder
|
|
8
8
|
autoload :CommentMethods
|
9
9
|
autoload :ForeignerMethods
|
10
10
|
autoload :ViewMethods
|
11
|
+
autoload :FunctionMethods
|
11
12
|
|
12
13
|
include ExtensionMethods
|
13
14
|
include SchemaMethods
|
14
15
|
include CommentMethods
|
15
16
|
include ForeignerMethods
|
16
17
|
include ViewMethods
|
18
|
+
include FunctionMethods
|
17
19
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# Methods to extend ActiveRecord::Migration::CommandRecorder to
|
2
|
+
# support comments feature.
|
3
|
+
module PgSaurus::Migration::CommandRecorder::FunctionMethods
|
4
|
+
|
5
|
+
# :nodoc
|
6
|
+
def create_function(*args)
|
7
|
+
record :create_function, *args
|
8
|
+
end
|
9
|
+
|
10
|
+
# :nodoc
|
11
|
+
def drop_function(*args)
|
12
|
+
record :drop_function, *args
|
13
|
+
end
|
14
|
+
|
15
|
+
# :nodoc
|
16
|
+
def invert_create_function(args)
|
17
|
+
function_name = args.first
|
18
|
+
schema = args.last[:schema]
|
19
|
+
|
20
|
+
[:drop_function, [function_name, { schema: schema }]]
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -10,19 +10,22 @@ module PgSaurus::SchemaDumper
|
|
10
10
|
autoload :SchemaMethods
|
11
11
|
autoload :ForeignerMethods
|
12
12
|
autoload :ViewMethods
|
13
|
+
autoload :FunctionMethods
|
13
14
|
|
14
15
|
include ExtensionMethods
|
15
16
|
include CommentMethods
|
16
17
|
include SchemaMethods
|
17
18
|
include ForeignerMethods
|
18
19
|
include ViewMethods
|
20
|
+
include FunctionMethods
|
19
21
|
|
20
22
|
included do
|
21
23
|
alias_method_chain :header, :schemas
|
22
24
|
alias_method_chain :header, :extensions
|
23
25
|
|
24
26
|
alias_method_chain :tables, :views
|
25
|
-
alias_method_chain :tables, :comments
|
26
27
|
alias_method_chain :tables, :foreign_keys
|
28
|
+
alias_method_chain :tables, :functions
|
29
|
+
alias_method_chain :tables, :comments
|
27
30
|
end
|
28
31
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# Support for dumping database functions.
|
2
|
+
module PgSaurus::SchemaDumper::FunctionMethods
|
3
|
+
|
4
|
+
# :nodoc
|
5
|
+
def tables_with_functions(stream)
|
6
|
+
tables_without_functions(stream)
|
7
|
+
|
8
|
+
dump_functions stream
|
9
|
+
|
10
|
+
stream
|
11
|
+
end
|
12
|
+
|
13
|
+
# Writes out a command to create each detected function.
|
14
|
+
def dump_functions(stream)
|
15
|
+
@connection.functions.each do |function|
|
16
|
+
statement = " create_function '#{function.name}', :#{function.returning}, <<-FUNCTION_DEFINITION.gsub(/^[\s]{4}/, '')"
|
17
|
+
statement << "\n#{function.definition.split("\n").map{|line| " #{line}" }.join("\n")}"
|
18
|
+
statement << "\n FUNCTION_DEFINITION\n\n"
|
19
|
+
|
20
|
+
stream.puts statement
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
data/lib/pg_saurus/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pg_saurus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Potapov Sergey
|
@@ -13,7 +13,7 @@ authors:
|
|
13
13
|
autorequire:
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
|
-
date:
|
16
|
+
date: 2015-07-14 00:00:00.000000000 Z
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
19
19
|
name: pg
|
@@ -33,6 +33,9 @@ dependencies:
|
|
33
33
|
name: rails
|
34
34
|
requirement: !ruby/object:Gem::Requirement
|
35
35
|
requirements:
|
36
|
+
- - "<"
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '4.2'
|
36
39
|
- - "~>"
|
37
40
|
- !ruby/object:Gem::Version
|
38
41
|
version: '4.0'
|
@@ -40,6 +43,9 @@ dependencies:
|
|
40
43
|
prerelease: false
|
41
44
|
version_requirements: !ruby/object:Gem::Requirement
|
42
45
|
requirements:
|
46
|
+
- - "<"
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '4.2'
|
43
49
|
- - "~>"
|
44
50
|
- !ruby/object:Gem::Version
|
45
51
|
version: '4.0'
|
@@ -168,14 +174,17 @@ files:
|
|
168
174
|
- lib/pg_saurus/connection_adapters/abstract_adapter.rb
|
169
175
|
- lib/pg_saurus/connection_adapters/abstract_adapter/comment_methods.rb
|
170
176
|
- lib/pg_saurus/connection_adapters/abstract_adapter/foreigner_methods.rb
|
177
|
+
- lib/pg_saurus/connection_adapters/abstract_adapter/function_methods.rb
|
171
178
|
- lib/pg_saurus/connection_adapters/abstract_adapter/index_methods.rb
|
172
179
|
- lib/pg_saurus/connection_adapters/abstract_adapter/schema_methods.rb
|
173
180
|
- lib/pg_saurus/connection_adapters/foreign_key_definition.rb
|
181
|
+
- lib/pg_saurus/connection_adapters/function_definition.rb
|
174
182
|
- lib/pg_saurus/connection_adapters/index_definition.rb
|
175
183
|
- lib/pg_saurus/connection_adapters/postgresql_adapter.rb
|
176
184
|
- lib/pg_saurus/connection_adapters/postgresql_adapter/comment_methods.rb
|
177
185
|
- lib/pg_saurus/connection_adapters/postgresql_adapter/extension_methods.rb
|
178
186
|
- lib/pg_saurus/connection_adapters/postgresql_adapter/foreigner_methods.rb
|
187
|
+
- lib/pg_saurus/connection_adapters/postgresql_adapter/function_methods.rb
|
179
188
|
- lib/pg_saurus/connection_adapters/postgresql_adapter/index_methods.rb
|
180
189
|
- lib/pg_saurus/connection_adapters/postgresql_adapter/schema_methods.rb
|
181
190
|
- lib/pg_saurus/connection_adapters/postgresql_adapter/translate_exception.rb
|
@@ -191,6 +200,7 @@ files:
|
|
191
200
|
- lib/pg_saurus/migration/command_recorder/comment_methods.rb
|
192
201
|
- lib/pg_saurus/migration/command_recorder/extension_methods.rb
|
193
202
|
- lib/pg_saurus/migration/command_recorder/foreigner_methods.rb
|
203
|
+
- lib/pg_saurus/migration/command_recorder/function_methods.rb
|
194
204
|
- lib/pg_saurus/migration/command_recorder/schema_methods.rb
|
195
205
|
- lib/pg_saurus/migration/command_recorder/view_methods.rb
|
196
206
|
- lib/pg_saurus/migration/set_role_method.rb
|
@@ -198,6 +208,7 @@ files:
|
|
198
208
|
- lib/pg_saurus/schema_dumper/comment_methods.rb
|
199
209
|
- lib/pg_saurus/schema_dumper/extension_methods.rb
|
200
210
|
- lib/pg_saurus/schema_dumper/foreigner_methods.rb
|
211
|
+
- lib/pg_saurus/schema_dumper/function_methods.rb
|
201
212
|
- lib/pg_saurus/schema_dumper/schema_methods.rb
|
202
213
|
- lib/pg_saurus/schema_dumper/view_methods.rb
|
203
214
|
- lib/pg_saurus/tools.rb
|
@@ -223,7 +234,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
223
234
|
version: '0'
|
224
235
|
requirements: []
|
225
236
|
rubyforge_project:
|
226
|
-
rubygems_version: 2.
|
237
|
+
rubygems_version: 2.4.3
|
227
238
|
signing_key:
|
228
239
|
specification_version: 4
|
229
240
|
summary: ActiveRecord extensions for PostgreSQL.
|