activerecord_postgresql_procedures 0.0.2

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a73f8bb2dfb762712b1c8882c87106ed5015b944
4
+ data.tar.gz: 1b1715557f0b6058cf8fea739a78037ff431bf29
5
+ SHA512:
6
+ metadata.gz: 2b8af5e65162e33569a18306bb7cdfa48cbe0bd912c5a0369a5101b7b861b84699d9cb89c0668f620319a641f9cb97dccd538f79347a900787af6512b5cc1d2c
7
+ data.tar.gz: d0a64dccda163842a7aed6173ff55395ea01a167333ee1da8e8a7bad021775cd5303827ef070b72ad38a1b31faa026dcc5630eb87b42f4274d31cb8a8f543d37
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2014 Tomáš Kuča
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,23 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'ActiverecordPostgresqlProcedures'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.rdoc')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+
18
+
19
+
20
+
21
+
22
+ Bundler::GemHelper.install_tasks
23
+
@@ -0,0 +1,12 @@
1
+
2
+ require 'active_record'
3
+ require 'active_record/connection_adapters/postgresql/schema_statements'
4
+ require 'active_record/connection_adapters/postgresql_adapter'
5
+
6
+ require 'activerecord_postgresql_procedures/schema_statements'
7
+ require 'activerecord_postgresql_procedures/postgresql_adapter'
8
+
9
+ module ActiverecordPostgresqlProcedures
10
+ end
11
+
12
+
@@ -0,0 +1,53 @@
1
+ module ActiveRecord
2
+ module ConnectionAdapters
3
+ class PostgreSQLAdapter < AbstractAdapter
4
+
5
+ # Returns the list of a table's or procedure's column names, data types, and default values.
6
+ def column_definitions(name) # :nodoc:
7
+ if procedure_exists?(name)
8
+ procedure_column_definitions(name)
9
+ else
10
+ table_column_definitions(name)
11
+ end
12
+ end
13
+
14
+ # Returns the list of a table's column names, data types, and default values.
15
+ #
16
+ # Query implementation notes:
17
+ # - format_type includes the column size constraint, e.g. varchar(50)
18
+ # - ::regclass is a function that gives the id for a table name
19
+ def table_column_definitions(name)
20
+ exec_query(<<-SQL, 'SCHEMA').rows
21
+ SELECT a.attname, format_type(a.atttypid, a.atttypmod),
22
+ pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod
23
+ FROM
24
+ pg_attribute a
25
+ LEFT JOIN pg_attrdef d ON a.attrelid = d.adrelid AND a.attnum = d.adnum
26
+ WHERE
27
+ a.attrelid = '#{quote_table_name(name)}'::regclass
28
+ AND a.attnum > 0 AND NOT a.attisdropped
29
+ ORDER BY a.attnum
30
+ SQL
31
+ end
32
+
33
+ # Returns the list of procedure's column names, data types, and default values.
34
+ def procedure_column_definitions(name)
35
+ exec_query(<<-SQL, 'SCHEMA').rows
36
+ SELECT
37
+ argname, format_type(argtype,typtypmod), typdefault, CASE row_number() over() WHEN 1 THEN true ELSE typnotnull END, argtype, typtypmod
38
+ FROM
39
+ (
40
+ SELECT
41
+ unnest(proargnames) AS argname,
42
+ unnest(proallargtypes) AS argtype,
43
+ unnest(proargmodes) AS argmode
44
+ FROM pg_proc
45
+ WHERE proname = '#{name}'
46
+ ) t
47
+ JOIN pg_type ON t.argtype = pg_type.oid and t.argmode = 't'
48
+ SQL
49
+ end
50
+
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,92 @@
1
+ module ActiveRecord
2
+ module ConnectionAdapters
3
+ module PostgreSQL
4
+ module SchemaStatements
5
+
6
+ # Returns just a table's primary key
7
+ def primary_key(table)
8
+ if table_or_view_exists?(table)
9
+ table_primary_key(table)
10
+ else
11
+ procedure_primary_key(table)
12
+ end
13
+ end
14
+
15
+ def table_primary_key(table)
16
+ row = exec_query(<<-end_sql, 'SCHEMA').rows.first
17
+ SELECT attr.attname
18
+ FROM pg_attribute attr
19
+ INNER JOIN pg_constraint cons ON attr.attrelid = cons.conrelid AND attr.attnum = cons.conkey[1]
20
+ WHERE cons.contype = 'p'
21
+ AND cons.conrelid = (SELECT oid FROM pg_class WHERE relname = '#{table}')
22
+ end_sql
23
+ row && row.first
24
+ end
25
+
26
+ # Return the procedure's primary key
27
+ #
28
+ # The procedure doesn't have 'native' primary key, the first column is used.
29
+ def procedure_primary_key(name)
30
+ row = exec_query(<<-end_sql, 'SCHEMA').rows.first
31
+ SELECT proargnames[1] FROM pg_proc WHERE proname = '#{name}'
32
+ end_sql
33
+ row && row.first
34
+ end
35
+
36
+
37
+ # Returns the list of all tables in the schema search path or a specified schema.
38
+ # def tables(name = nil)
39
+ # query(<<-SQL, 'SCHEMA').map { |row| row[0] }
40
+ # SELECT tablename
41
+ # FROM pg_tables
42
+ # WHERE schemaname = ANY (current_schemas(false))
43
+ # SQL
44
+ # end
45
+
46
+ # Returns true if table or procedure exists.
47
+ # If the schema is not specified as part of +name+ then it will only find tables within
48
+ # the current schema search path (regardless of permissions to access tables in other schemas)
49
+ def table_exists?(name)
50
+ table_or_view_exists?(name) or procedure_exists?(name)
51
+ end
52
+
53
+ # Returns true if table exists.
54
+ # If the schema is not specified as part of +name+ then it will only find tables within
55
+ # the current schema search path (regardless of permissions to access tables in other schemas)
56
+ def table_or_view_exists?(name)
57
+ name = Utils.extract_schema_qualified_name(name.to_s)
58
+ return false unless name.identifier
59
+ exec_query(<<-SQL, 'SCHEMA').rows.first[0].to_i > 0
60
+ SELECT COUNT(*)
61
+ FROM
62
+ pg_class c
63
+ LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
64
+ WHERE
65
+ c.relkind IN ('r','v','m') -- (r)elation/table, (v)iew, (m)aterialized view
66
+ AND c.relname = '#{name.identifier}'
67
+ AND n.nspname = #{name.schema ? "'#{name.schema}'" : 'ANY (current_schemas(false))'}
68
+ SQL
69
+ end
70
+
71
+
72
+ def procedure_exists?(name)
73
+ name = Utils.extract_schema_qualified_name(name.to_s)
74
+ return false unless name.identifier
75
+ exec_query(<<-SQL, 'SCHEMA').rows.first[0].to_i > 0
76
+ SELECT COUNT(*)
77
+ FROM
78
+ pg_catalog.pg_proc p
79
+ JOIN pg_catalog.pg_namespace n ON pronamespace = n.oid
80
+ JOIN pg_catalog.pg_type t ON typelem = p.prorettype
81
+ WHERE
82
+ typname = '_record'
83
+ AND p.proname = '#{name.identifier}'
84
+ AND n.nspname = #{name.schema ? "'#{name.schema}'" : 'ANY (current_schemas(false))'}
85
+ SQL
86
+ end
87
+
88
+ end
89
+ end
90
+ end
91
+ end
92
+
@@ -0,0 +1,3 @@
1
+ module ActiverecordPostgresqlProcedures
2
+ VERSION = "0.0.2"
3
+ end
metadata ADDED
@@ -0,0 +1,137 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: activerecord_postgresql_procedures
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Tomáš Kuča
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-01-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activerecord
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '4.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '4.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: pg
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.17'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.17'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: guard
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '2.6'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '2.6'
69
+ - !ruby/object:Gem::Dependency
70
+ name: guard-bundler
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '2.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '2.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: guard-rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '4.3'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '4.3'
97
+ description: PostgreSQL allows to create a procedure which returns a result set. The
98
+ gem modifies ActiveRecord so that it's possible to create (readonly) model based
99
+ on resultset instead of a database table.
100
+ email:
101
+ - tomas.kuca@matfyz.cz
102
+ executables: []
103
+ extensions: []
104
+ extra_rdoc_files: []
105
+ files:
106
+ - MIT-LICENSE
107
+ - Rakefile
108
+ - lib/activerecord_postgresql_procedures.rb
109
+ - lib/activerecord_postgresql_procedures/postgresql_adapter.rb
110
+ - lib/activerecord_postgresql_procedures/schema_statements.rb
111
+ - lib/activerecord_postgresql_procedures/version.rb
112
+ homepage: https://github.com/tom-kuca/activerecord_postgresql_procedures
113
+ licenses:
114
+ - MIT
115
+ metadata: {}
116
+ post_install_message:
117
+ rdoc_options: []
118
+ require_paths:
119
+ - lib
120
+ required_ruby_version: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ required_rubygems_version: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - ">="
128
+ - !ruby/object:Gem::Version
129
+ version: '0'
130
+ requirements: []
131
+ rubyforge_project:
132
+ rubygems_version: 2.2.2
133
+ signing_key:
134
+ specification_version: 4
135
+ summary: Support for PostgreSQL procedures in ActiveRecord
136
+ test_files: []
137
+ has_rdoc: