activerecord_postgresql_procedures 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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: