pg_saurus 2.2.1 → 2.3.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 +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.
|