pg_sql_caller 0.2.3 → 1.0.0
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/CHANGELOG.md +92 -0
- data/README.md +356 -28
- data/lib/pg_sql_caller/base.rb +45 -139
- data/lib/pg_sql_caller/bulk_update.rb +193 -0
- data/lib/pg_sql_caller/model.rb +304 -0
- data/lib/pg_sql_caller/version.rb +1 -1
- data/lib/pg_sql_caller.rb +2 -0
- metadata +27 -24
- data/.gitignore +0 -14
- data/.rspec +0 -3
- data/.rubocop.yml +0 -71
- data/.travis.yml +0 -12
- data/CODE_OF_CONDUCT.md +0 -74
- data/Gemfile +0 -12
- data/Rakefile +0 -10
- data/bin/console +0 -15
- data/bin/setup +0 -8
- data/sql_caller.gemspec +0 -32
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support/core_ext/class/attribute'
|
|
4
|
+
require 'active_support/core_ext/module/delegation'
|
|
5
|
+
|
|
6
|
+
module PgSqlCaller
|
|
7
|
+
# Wraps a single ActiveRecord class and runs raw SQL through its connection.
|
|
8
|
+
# Positional `?` placeholders are bound and sanitized by ActiveRecord, so values
|
|
9
|
+
# are never interpolated into the SQL string.
|
|
10
|
+
#
|
|
11
|
+
# sql = PgSqlCaller::Model.new(ApplicationRecord)
|
|
12
|
+
# sql.select_value('SELECT count(*) FROM users WHERE active = ?', true) # => 42
|
|
13
|
+
# sql.select_values('SELECT email FROM users WHERE dept_id = ?', 5) # => ['a@x', 'b@x']
|
|
14
|
+
# sql.select_all('SELECT id, name FROM users') # => [{ 'id' => 1, 'name' => 'Jo' }, ...]
|
|
15
|
+
# sql.transaction { sql.execute('UPDATE users SET active = false') }
|
|
16
|
+
#
|
|
17
|
+
# The `*_serialized` variants additionally cast each value back to its Ruby type
|
|
18
|
+
# using the result's column types (e.g. timestamp -> Time, int[] -> Array), and
|
|
19
|
+
# key rows by Symbol:
|
|
20
|
+
#
|
|
21
|
+
# sql.select_all_serialized('SELECT id, created_at FROM users')
|
|
22
|
+
# # => [{ id: 1, created_at: 2026-06-08 12:00:00 +0000 }, ...]
|
|
23
|
+
class Model
|
|
24
|
+
class << self
|
|
25
|
+
# Define a single connection-backed SQL instance method named +name+.
|
|
26
|
+
#
|
|
27
|
+
# @param name [Symbol] the connection method to wrap (e.g. +:select_value+)
|
|
28
|
+
# @return [Symbol] the name of the defined method
|
|
29
|
+
def define_sql_method(name)
|
|
30
|
+
define_method(name) do |sql, *bindings|
|
|
31
|
+
sql = sanitize_sql_array(sql, *bindings) if bindings.any?
|
|
32
|
+
connection.public_send(name, sql)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Define several connection-backed SQL instance methods at once — a thin wrapper
|
|
37
|
+
# over {.define_sql_method}, kept for backward compatibility.
|
|
38
|
+
#
|
|
39
|
+
# @param names [Array<Symbol>] the connection methods to wrap
|
|
40
|
+
# @return [Array<Symbol>] +names+, unchanged
|
|
41
|
+
def define_sql_methods(*names)
|
|
42
|
+
names.each { |name| define_sql_method(name) }
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# @!method select_value(sql, *bindings)
|
|
47
|
+
# Run +sql+ and return the value of the first column of the first row.
|
|
48
|
+
# @param sql [String] SQL statement, optionally containing `?` placeholders
|
|
49
|
+
# @param bindings [Array<Object>] values bound, in order, to the `?` placeholders
|
|
50
|
+
# @return [Object, nil] the single value, or nil when no row matches
|
|
51
|
+
define_sql_method :select_value
|
|
52
|
+
|
|
53
|
+
# @!method select_values(sql, *bindings)
|
|
54
|
+
# Run +sql+ and return the first column of every row.
|
|
55
|
+
# @param sql [String] SQL statement, optionally containing `?` placeholders
|
|
56
|
+
# @param bindings [Array<Object>] values bound, in order, to the `?` placeholders
|
|
57
|
+
# @return [Array<Object>]
|
|
58
|
+
define_sql_method :select_values
|
|
59
|
+
|
|
60
|
+
# @!method execute(sql, *bindings)
|
|
61
|
+
# Execute +sql+ (e.g. INSERT/UPDATE/DELETE/DDL) and return the raw adapter result.
|
|
62
|
+
# @param sql [String] SQL statement, optionally containing `?` placeholders
|
|
63
|
+
# @param bindings [Array<Object>] values bound, in order, to the `?` placeholders
|
|
64
|
+
# @return [PG::Result] the raw PostgreSQL result (e.g. +#cmd_tuples+ for affected rows)
|
|
65
|
+
define_sql_method :execute
|
|
66
|
+
|
|
67
|
+
# @!method select_all(sql, *bindings)
|
|
68
|
+
# Run +sql+ and return every row.
|
|
69
|
+
# @param sql [String] SQL statement, optionally containing `?` placeholders
|
|
70
|
+
# @param bindings [Array<Object>] values bound, in order, to the `?` placeholders
|
|
71
|
+
# @return [ActiveRecord::Result] rows as String-keyed hashes
|
|
72
|
+
define_sql_method :select_all
|
|
73
|
+
|
|
74
|
+
# @!method select_rows(sql, *bindings)
|
|
75
|
+
# Run +sql+ and return rows as arrays of column values (no column names).
|
|
76
|
+
# @param sql [String] SQL statement, optionally containing `?` placeholders
|
|
77
|
+
# @param bindings [Array<Object>] values bound, in order, to the `?` placeholders
|
|
78
|
+
# @return [Array<Array>]
|
|
79
|
+
define_sql_method :select_rows
|
|
80
|
+
|
|
81
|
+
# @return [Class<ActiveRecord::Base>] the ActiveRecord class this instance wraps
|
|
82
|
+
attr_reader :model_class
|
|
83
|
+
|
|
84
|
+
# @!method connection
|
|
85
|
+
# The ActiveRecord connection adapter of {#model_class}; every SQL method runs through it.
|
|
86
|
+
# @return [ActiveRecord::ConnectionAdapters::AbstractAdapter]
|
|
87
|
+
delegate :connection, to: :model_class
|
|
88
|
+
|
|
89
|
+
# @!method quote_column_name(name)
|
|
90
|
+
# Quote a column-name identifier for safe inclusion in SQL (delegated to the
|
|
91
|
+
# {#connection}, since the model class itself does not expose it).
|
|
92
|
+
# @param name [String, Symbol] the column name to quote
|
|
93
|
+
# @return [String] the quoted identifier
|
|
94
|
+
delegate :quote_column_name, to: :connection
|
|
95
|
+
|
|
96
|
+
# @!method quote_table_name(name)
|
|
97
|
+
# Quote a table-name identifier for safe inclusion in SQL (delegated to the
|
|
98
|
+
# {#connection}, since the model class itself does not expose it).
|
|
99
|
+
# @param name [String, Symbol] the table name to quote
|
|
100
|
+
# @return [String] the quoted identifier
|
|
101
|
+
delegate :quote_table_name, to: :connection
|
|
102
|
+
|
|
103
|
+
# @param model_class [Class<ActiveRecord::Base>] the class whose connection is used
|
|
104
|
+
# to run statements and to sanitize/typecast values
|
|
105
|
+
def initialize(model_class)
|
|
106
|
+
@model_class = model_class
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Whether a database transaction is currently open on the connection.
|
|
110
|
+
#
|
|
111
|
+
# @return [Boolean]
|
|
112
|
+
def transaction_open?
|
|
113
|
+
connection.send(:transaction_open?)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# Like {#select_all}, but cast each value back to its Ruby type (using the result's
|
|
117
|
+
# column types) and key every row by Symbol.
|
|
118
|
+
#
|
|
119
|
+
# @param sql [String] SQL statement, optionally containing `?` placeholders
|
|
120
|
+
# @param bindings [Array<Object>] values bound, in order, to the `?` placeholders
|
|
121
|
+
# @return [Array<Hash{Symbol => Object}>]
|
|
122
|
+
def select_all_serialized(sql, *bindings)
|
|
123
|
+
result = select_all(sql, *bindings)
|
|
124
|
+
result.map do |row|
|
|
125
|
+
row.to_h { |key, value| [key.to_sym, deserialize_result(result, key, value)] }
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# Like {#select_value}, but cast the value back to its Ruby type.
|
|
130
|
+
#
|
|
131
|
+
# @param sql [String] SQL statement, optionally containing `?` placeholders
|
|
132
|
+
# @param bindings [Array<Object>] values bound, in order, to the `?` placeholders
|
|
133
|
+
# @return [Object, nil] the type-cast value, or nil when no row matches
|
|
134
|
+
def select_value_serialized(sql, *bindings)
|
|
135
|
+
result = select_all(sql, *bindings)
|
|
136
|
+
key = result.first&.keys&.first
|
|
137
|
+
return if key.nil?
|
|
138
|
+
|
|
139
|
+
value = result.first.values.first
|
|
140
|
+
deserialize_result(result, key, value)
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# Run +sql+ and return each row as an array of its type-cast column values.
|
|
144
|
+
#
|
|
145
|
+
# @param sql [String] SQL statement, optionally containing `?` placeholders
|
|
146
|
+
# @param bindings [Array<Object>] values bound, in order, to the `?` placeholders
|
|
147
|
+
# @return [Array<Array>] one inner array per row
|
|
148
|
+
def select_values_serialized(sql, *bindings)
|
|
149
|
+
result = select_all(sql, *bindings)
|
|
150
|
+
result.map do |row|
|
|
151
|
+
row.map { |key, value| deserialize_result(result, key, value) }
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
# The next value of the table's `<table_name>_id_seq` sequence (its current
|
|
156
|
+
# last_value + 1), read without consuming the sequence.
|
|
157
|
+
#
|
|
158
|
+
# @param table_name [String, Symbol]
|
|
159
|
+
# @return [Integer]
|
|
160
|
+
def next_sequence_value(table_name)
|
|
161
|
+
sequence_name = quote_table_name("#{table_name}_id_seq")
|
|
162
|
+
# `sequence_name` is an identifier escaped via quote_table_name (identifiers cannot use `?`
|
|
163
|
+
# bindings), so the interpolation below is injection-safe.
|
|
164
|
+
# nosemgrep: pg-sql-caller-interpolated-raw-sql
|
|
165
|
+
select_value("SELECT last_value FROM #{sequence_name}") + 1
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
# Total on-disk size of the table including indexes and TOAST, in bytes
|
|
169
|
+
# (PostgreSQL `pg_total_relation_size`).
|
|
170
|
+
#
|
|
171
|
+
# @param table_name [String, Symbol]
|
|
172
|
+
# @return [Integer] size in bytes
|
|
173
|
+
def table_full_size(table_name)
|
|
174
|
+
select_value('SELECT pg_total_relation_size(?)', table_name)
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
# On-disk size of the table's main data fork only, in bytes
|
|
178
|
+
# (PostgreSQL `pg_relation_size`).
|
|
179
|
+
#
|
|
180
|
+
# @param table_name [String, Symbol]
|
|
181
|
+
# @return [Integer] size in bytes
|
|
182
|
+
def table_data_size(table_name)
|
|
183
|
+
select_value('SELECT pg_relation_size(?)', table_name)
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
# Run +sql+ and return the first row as an array of column values.
|
|
187
|
+
#
|
|
188
|
+
# @param sql [String] SQL statement, optionally containing `?` placeholders
|
|
189
|
+
# @param bindings [Array<Object>] values bound, in order, to the `?` placeholders
|
|
190
|
+
# @return [Array, nil] the first row, or nil when no row matches
|
|
191
|
+
def select_row(sql, *bindings)
|
|
192
|
+
select_rows(sql, *bindings)[0]
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
# Run the given block inside a database transaction, committing on success and
|
|
196
|
+
# rolling back if it raises.
|
|
197
|
+
#
|
|
198
|
+
# @yield executes within the open transaction
|
|
199
|
+
# @return [Object] the block's return value
|
|
200
|
+
# @raise [ArgumentError] if no block is given
|
|
201
|
+
def transaction(&)
|
|
202
|
+
raise ArgumentError, 'block must be given' unless block_given?
|
|
203
|
+
|
|
204
|
+
connection.transaction(&)
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
# Run `EXPLAIN ANALYZE` for +sql+ and return the query plan as text.
|
|
208
|
+
#
|
|
209
|
+
# @param sql [String] the statement to analyze
|
|
210
|
+
# @return [String] the plan, one line per row, prefixed with a +QUERY_PLAN+ header
|
|
211
|
+
def explain_analyze(sql)
|
|
212
|
+
# `sql` is the statement to analyze; the caller owns the full SQL by contract (like #execute),
|
|
213
|
+
# so there is no boundary to bind across.
|
|
214
|
+
# nosemgrep: pg-sql-caller-interpolated-raw-sql
|
|
215
|
+
result = select_values("EXPLAIN ANALYZE #{sql}")
|
|
216
|
+
['QUERY_PLAN', *result].join("\n")
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
# Encode a Ruby array into a PostgreSQL array literal for the given attribute type,
|
|
220
|
+
# ready to bind as a single `?` value.
|
|
221
|
+
#
|
|
222
|
+
# @param values [Array] the Ruby values to encode
|
|
223
|
+
# @param type [Symbol] an ActiveRecord attribute type (e.g. +:integer+, +:string+, +:datetime+)
|
|
224
|
+
# @return [String] a PostgreSQL array literal, e.g. +"{1,2,3}"+
|
|
225
|
+
def typecast_array(values, type:)
|
|
226
|
+
type = ActiveRecord::Type.lookup(type, array: true)
|
|
227
|
+
data = type.serialize(values)
|
|
228
|
+
data.encoder.encode(data.values)
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
# Interpolate `?` placeholders in +sql+ with +bindings+ through ActiveRecord's
|
|
232
|
+
# sanitizer (values are quoted/escaped, never raw-interpolated).
|
|
233
|
+
#
|
|
234
|
+
# @param sql [String] SQL containing `?` placeholders
|
|
235
|
+
# @param bindings [Array<Object>] values bound, in order, to the placeholders
|
|
236
|
+
# @return [String] the safe, ready-to-run SQL
|
|
237
|
+
def sanitize_sql_array(sql, *bindings)
|
|
238
|
+
model_class.send :sanitize_sql_array, bindings.unshift(sql)
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
# @return [String] the name of the currently connected database (`current_database()`)
|
|
242
|
+
def current_database
|
|
243
|
+
select_value('SELECT current_database();')
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
# Capture PostgreSQL NOTICE output (e.g. from +RAISE NOTICE+) emitted while the block
|
|
247
|
+
# runs, passing each message to +callback+. Lowers +client_min_messages+ to +notice+
|
|
248
|
+
# for the duration (see {#with_min_messages}) and restores the previous notice
|
|
249
|
+
# processor afterward.
|
|
250
|
+
#
|
|
251
|
+
# sql.with_notice_processor(->(msg) { logger.info(msg) }) do
|
|
252
|
+
# sql.execute("DO $$ BEGIN RAISE NOTICE 'hi'; END $$")
|
|
253
|
+
# end
|
|
254
|
+
#
|
|
255
|
+
# @param callback [#call] invoked with each notice message (a chomped String)
|
|
256
|
+
# @yield runs with the notice processor installed
|
|
257
|
+
# @return [Object] the block's return value
|
|
258
|
+
def with_notice_processor(callback)
|
|
259
|
+
with_min_messages('notice') do
|
|
260
|
+
old_processor = connection.raw_connection.set_notice_processor { |result| callback.call(result.to_s.chomp) }
|
|
261
|
+
yield
|
|
262
|
+
ensure
|
|
263
|
+
connection.raw_connection.set_notice_processor(&old_processor)
|
|
264
|
+
end
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
# Temporarily set the connection's +client_min_messages+ to +level+ for the duration
|
|
268
|
+
# of the block, restoring the previous value afterward.
|
|
269
|
+
#
|
|
270
|
+
# @param level [String] one of: debug5, debug4, debug3, debug2, debug1, log, notice, warning, error
|
|
271
|
+
# @yield runs with the level applied
|
|
272
|
+
# @return [Object] the block's return value
|
|
273
|
+
def with_min_messages(level)
|
|
274
|
+
old_level = select_value('SHOW client_min_messages')
|
|
275
|
+
execute('SET client_min_messages TO ?', level)
|
|
276
|
+
yield
|
|
277
|
+
ensure
|
|
278
|
+
execute('SET client_min_messages TO ?', old_level) unless old_level.nil?
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
# Quote and escape a value as a SQL literal, safe to inline into a statement.
|
|
282
|
+
#
|
|
283
|
+
# @param value [Object] the value to quote (e.g. String, Numeric, nil, Time)
|
|
284
|
+
# @return [String] the quoted SQL literal (e.g. +"'O''Brien'"+)
|
|
285
|
+
def quote_value(value)
|
|
286
|
+
connection.quote(value)
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
private
|
|
290
|
+
|
|
291
|
+
# Cast a raw result value back to its Ruby type using the result set's column types.
|
|
292
|
+
#
|
|
293
|
+
# @param result [ActiveRecord::Result] the result the value came from (carries column types)
|
|
294
|
+
# @param column_name [String] the column the value belongs to
|
|
295
|
+
# @param raw_value [Object] the raw value as returned by the adapter
|
|
296
|
+
# @return [Object] the type-cast value, or +raw_value+ unchanged when the column type is unknown
|
|
297
|
+
def deserialize_result(result, column_name, raw_value)
|
|
298
|
+
column_type = result.column_types[column_name]
|
|
299
|
+
return raw_value if column_type.nil?
|
|
300
|
+
|
|
301
|
+
column_type.deserialize(raw_value)
|
|
302
|
+
end
|
|
303
|
+
end
|
|
304
|
+
end
|
data/lib/pg_sql_caller.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pg_sql_caller
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 1.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Denis Talakevich
|
|
8
|
-
|
|
9
|
-
bindir: exe
|
|
8
|
+
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: activerecord
|
|
@@ -16,50 +15,56 @@ dependencies:
|
|
|
16
15
|
requirements:
|
|
17
16
|
- - ">="
|
|
18
17
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '
|
|
18
|
+
version: '7.1'
|
|
20
19
|
type: :runtime
|
|
21
20
|
prerelease: false
|
|
22
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
22
|
requirements:
|
|
24
23
|
- - ">="
|
|
25
24
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: '
|
|
25
|
+
version: '7.1'
|
|
27
26
|
- !ruby/object:Gem::Dependency
|
|
28
27
|
name: activesupport
|
|
29
28
|
requirement: !ruby/object:Gem::Requirement
|
|
30
29
|
requirements:
|
|
31
30
|
- - ">="
|
|
32
31
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: '
|
|
32
|
+
version: '7.1'
|
|
34
33
|
type: :runtime
|
|
35
34
|
prerelease: false
|
|
36
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
36
|
requirements:
|
|
38
37
|
- - ">="
|
|
39
38
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: '
|
|
41
|
-
description:
|
|
39
|
+
version: '7.1'
|
|
40
|
+
description: 'PgSqlCaller is a small, focused wrapper for running raw SQL against
|
|
41
|
+
PostgreSQL through ActiveRecord. It exposes a stable, documented API on an ActiveRecord-backed
|
|
42
|
+
class you name, covering the queries the query builder makes awkward: single-scalar
|
|
43
|
+
and single-column SELECTs, raw rows, ActiveRecord::Result reads, and type-cast (serialized)
|
|
44
|
+
variants that decode PostgreSQL arrays and custom column types into Ruby objects.
|
|
45
|
+
Every ? placeholder is bound and escaped through the ActiveRecord sanitizer, so
|
|
46
|
+
statements stay injection-safe with no manual quoting. On top of that it adds PostgreSQL-specific
|
|
47
|
+
helpers — non-consuming sequence peeking, table and relation sizes, EXPLAIN ANALYZE,
|
|
48
|
+
NOTICE capture, and quoting/sanitizing utilities — plus a fast, injection-safe bulk
|
|
49
|
+
update that partially updates many existing rows in a single UPDATE ... FROM unnest(...)
|
|
50
|
+
statement and round-trip. The reader API is extensible via define_sql_method, and
|
|
51
|
+
the gem runs on Ruby 3.2+ with Rails 7.1 through 8.1.'
|
|
42
52
|
email:
|
|
43
53
|
- senid231@gmail.com
|
|
44
54
|
executables: []
|
|
45
55
|
extensions: []
|
|
46
|
-
extra_rdoc_files:
|
|
56
|
+
extra_rdoc_files:
|
|
57
|
+
- CHANGELOG.md
|
|
58
|
+
- README.md
|
|
47
59
|
files:
|
|
48
|
-
-
|
|
49
|
-
- ".rspec"
|
|
50
|
-
- ".rubocop.yml"
|
|
51
|
-
- ".travis.yml"
|
|
52
|
-
- CODE_OF_CONDUCT.md
|
|
53
|
-
- Gemfile
|
|
60
|
+
- CHANGELOG.md
|
|
54
61
|
- LICENSE.txt
|
|
55
62
|
- README.md
|
|
56
|
-
- Rakefile
|
|
57
|
-
- bin/console
|
|
58
|
-
- bin/setup
|
|
59
63
|
- lib/pg_sql_caller.rb
|
|
60
64
|
- lib/pg_sql_caller/base.rb
|
|
65
|
+
- lib/pg_sql_caller/bulk_update.rb
|
|
66
|
+
- lib/pg_sql_caller/model.rb
|
|
61
67
|
- lib/pg_sql_caller/version.rb
|
|
62
|
-
- sql_caller.gemspec
|
|
63
68
|
homepage: https://github.com/didww/pg_sql_caller
|
|
64
69
|
licenses:
|
|
65
70
|
- MIT
|
|
@@ -67,7 +72,6 @@ metadata:
|
|
|
67
72
|
homepage_uri: https://github.com/didww/pg_sql_caller
|
|
68
73
|
source_code_uri: https://github.com/didww/pg_sql_caller
|
|
69
74
|
changelog_uri: https://github.com/didww/pg_sql_caller
|
|
70
|
-
post_install_message:
|
|
71
75
|
rdoc_options: []
|
|
72
76
|
require_paths:
|
|
73
77
|
- lib
|
|
@@ -75,15 +79,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
75
79
|
requirements:
|
|
76
80
|
- - ">="
|
|
77
81
|
- !ruby/object:Gem::Version
|
|
78
|
-
version: 2.
|
|
82
|
+
version: 3.2.0
|
|
79
83
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
80
84
|
requirements:
|
|
81
85
|
- - ">="
|
|
82
86
|
- !ruby/object:Gem::Version
|
|
83
87
|
version: '0'
|
|
84
88
|
requirements: []
|
|
85
|
-
rubygems_version: 3.
|
|
86
|
-
signing_key:
|
|
89
|
+
rubygems_version: 3.6.9
|
|
87
90
|
specification_version: 4
|
|
88
91
|
summary: Postgresql Sql Caller for ActiveRecord
|
|
89
92
|
test_files: []
|
data/.gitignore
DELETED
data/.rspec
DELETED
data/.rubocop.yml
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
AllCops:
|
|
2
|
-
DisplayCopNames: true
|
|
3
|
-
TargetRubyVersion: 2.5
|
|
4
|
-
Exclude:
|
|
5
|
-
- vendor/**/*
|
|
6
|
-
- tmp/**/*
|
|
7
|
-
|
|
8
|
-
Layout/LineLength:
|
|
9
|
-
Max: 180
|
|
10
|
-
|
|
11
|
-
Style/SymbolArray:
|
|
12
|
-
EnforcedStyle: brackets
|
|
13
|
-
|
|
14
|
-
Style/Lambda:
|
|
15
|
-
EnforcedStyle: literal
|
|
16
|
-
|
|
17
|
-
Naming/MethodParameterName:
|
|
18
|
-
AllowedNames:
|
|
19
|
-
- id
|
|
20
|
-
|
|
21
|
-
Style/HashEachMethods:
|
|
22
|
-
Enabled: true
|
|
23
|
-
|
|
24
|
-
Style/HashTransformKeys:
|
|
25
|
-
Enabled: true
|
|
26
|
-
|
|
27
|
-
Style/HashTransformValues:
|
|
28
|
-
Enabled: true
|
|
29
|
-
|
|
30
|
-
Style/Documentation:
|
|
31
|
-
Enabled: false
|
|
32
|
-
|
|
33
|
-
Metrics/PerceivedComplexity:
|
|
34
|
-
Enabled: false
|
|
35
|
-
|
|
36
|
-
Metrics/MethodLength:
|
|
37
|
-
Enabled: false
|
|
38
|
-
|
|
39
|
-
Metrics/AbcSize:
|
|
40
|
-
Enabled: false
|
|
41
|
-
|
|
42
|
-
Metrics/ModuleLength:
|
|
43
|
-
Enabled: false
|
|
44
|
-
|
|
45
|
-
Metrics/BlockLength:
|
|
46
|
-
Enabled: false
|
|
47
|
-
|
|
48
|
-
Metrics/ClassLength:
|
|
49
|
-
Enabled: false
|
|
50
|
-
|
|
51
|
-
Metrics/CyclomaticComplexity:
|
|
52
|
-
Enabled: false
|
|
53
|
-
|
|
54
|
-
Layout/MultilineOperationIndentation:
|
|
55
|
-
Enabled: false
|
|
56
|
-
|
|
57
|
-
Layout/FirstHashElementIndentation:
|
|
58
|
-
Enabled: false
|
|
59
|
-
|
|
60
|
-
Layout/FirstArrayElementIndentation:
|
|
61
|
-
Enabled: false
|
|
62
|
-
|
|
63
|
-
Layout/FirstArgumentIndentation:
|
|
64
|
-
Enabled: false
|
|
65
|
-
|
|
66
|
-
Layout/ClosingParenthesisIndentation:
|
|
67
|
-
Enabled: false
|
|
68
|
-
|
|
69
|
-
Layout/ArgumentAlignment:
|
|
70
|
-
Enabled: false
|
|
71
|
-
|
data/.travis.yml
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
sudo: false
|
|
3
|
-
language: ruby
|
|
4
|
-
cache: bundler
|
|
5
|
-
services:
|
|
6
|
-
- postgresql
|
|
7
|
-
rvm:
|
|
8
|
-
- 2.5.7
|
|
9
|
-
before_install: gem install bundler -v 2.1.4
|
|
10
|
-
before_script:
|
|
11
|
-
- psql -c 'CREATE DATABASE pg_sql_caller_test;' -U postgres
|
|
12
|
-
- cp -v spec/config/database.travis.yml spec/config/database.yml
|
data/CODE_OF_CONDUCT.md
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
# Contributor Covenant Code of Conduct
|
|
2
|
-
|
|
3
|
-
## Our Pledge
|
|
4
|
-
|
|
5
|
-
In the interest of fostering an open and welcoming environment, we as
|
|
6
|
-
contributors and maintainers pledge to making participation in our project and
|
|
7
|
-
our community a harassment-free experience for everyone, regardless of age, body
|
|
8
|
-
size, disability, ethnicity, gender identity and expression, level of experience,
|
|
9
|
-
nationality, personal appearance, race, religion, or sexual identity and
|
|
10
|
-
orientation.
|
|
11
|
-
|
|
12
|
-
## Our Standards
|
|
13
|
-
|
|
14
|
-
Examples of behavior that contributes to creating a positive environment
|
|
15
|
-
include:
|
|
16
|
-
|
|
17
|
-
* Using welcoming and inclusive language
|
|
18
|
-
* Being respectful of differing viewpoints and experiences
|
|
19
|
-
* Gracefully accepting constructive criticism
|
|
20
|
-
* Focusing on what is best for the community
|
|
21
|
-
* Showing empathy towards other community members
|
|
22
|
-
|
|
23
|
-
Examples of unacceptable behavior by participants include:
|
|
24
|
-
|
|
25
|
-
* The use of sexualized language or imagery and unwelcome sexual attention or
|
|
26
|
-
advances
|
|
27
|
-
* Trolling, insulting/derogatory comments, and personal or political attacks
|
|
28
|
-
* Public or private harassment
|
|
29
|
-
* Publishing others' private information, such as a physical or electronic
|
|
30
|
-
address, without explicit permission
|
|
31
|
-
* Other conduct which could reasonably be considered inappropriate in a
|
|
32
|
-
professional setting
|
|
33
|
-
|
|
34
|
-
## Our Responsibilities
|
|
35
|
-
|
|
36
|
-
Project maintainers are responsible for clarifying the standards of acceptable
|
|
37
|
-
behavior and are expected to take appropriate and fair corrective action in
|
|
38
|
-
response to any instances of unacceptable behavior.
|
|
39
|
-
|
|
40
|
-
Project maintainers have the right and responsibility to remove, edit, or
|
|
41
|
-
reject comments, commits, code, wiki edits, issues, and other contributions
|
|
42
|
-
that are not aligned to this Code of Conduct, or to ban temporarily or
|
|
43
|
-
permanently any contributor for other behaviors that they deem inappropriate,
|
|
44
|
-
threatening, offensive, or harmful.
|
|
45
|
-
|
|
46
|
-
## Scope
|
|
47
|
-
|
|
48
|
-
This Code of Conduct applies both within project spaces and in public spaces
|
|
49
|
-
when an individual is representing the project or its community. Examples of
|
|
50
|
-
representing a project or community include using an official project e-mail
|
|
51
|
-
address, posting via an official social media account, or acting as an appointed
|
|
52
|
-
representative at an online or offline event. Representation of a project may be
|
|
53
|
-
further defined and clarified by project maintainers.
|
|
54
|
-
|
|
55
|
-
## Enforcement
|
|
56
|
-
|
|
57
|
-
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
|
58
|
-
reported by contacting the project team at senid231@gmail.com. All
|
|
59
|
-
complaints will be reviewed and investigated and will result in a response that
|
|
60
|
-
is deemed necessary and appropriate to the circumstances. The project team is
|
|
61
|
-
obligated to maintain confidentiality with regard to the reporter of an incident.
|
|
62
|
-
Further details of specific enforcement policies may be posted separately.
|
|
63
|
-
|
|
64
|
-
Project maintainers who do not follow or enforce the Code of Conduct in good
|
|
65
|
-
faith may face temporary or permanent repercussions as determined by other
|
|
66
|
-
members of the project's leadership.
|
|
67
|
-
|
|
68
|
-
## Attribution
|
|
69
|
-
|
|
70
|
-
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
|
71
|
-
available at [https://contributor-covenant.org/version/1/4][version]
|
|
72
|
-
|
|
73
|
-
[homepage]: https://contributor-covenant.org
|
|
74
|
-
[version]: https://contributor-covenant.org/version/1/4/
|
data/Gemfile
DELETED
data/Rakefile
DELETED
data/bin/console
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
# frozen_string_literal: true
|
|
3
|
-
|
|
4
|
-
require 'bundler/setup'
|
|
5
|
-
require 'pg_sql_caller'
|
|
6
|
-
|
|
7
|
-
# You can add fixtures and/or initialization code here to make experimenting
|
|
8
|
-
# with your gem easier. You can also use a different console, if you like.
|
|
9
|
-
|
|
10
|
-
# (If you use this, don't forget to add pry to your Gemfile!)
|
|
11
|
-
# require "pry"
|
|
12
|
-
# Pry.start
|
|
13
|
-
|
|
14
|
-
require 'irb'
|
|
15
|
-
IRB.start(__FILE__)
|