evt-view_data-pg 0.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 +7 -0
- data/lib/view_data/pg.rb +10 -0
- data/lib/view_data/pg/controls.rb +18 -0
- data/lib/view_data/pg/controls/commands.rb +47 -0
- data/lib/view_data/pg/controls/consumer.rb +17 -0
- data/lib/view_data/pg/controls/data.rb +19 -0
- data/lib/view_data/pg/controls/date.rb +19 -0
- data/lib/view_data/pg/controls/enum.rb +19 -0
- data/lib/view_data/pg/controls/id.rb +10 -0
- data/lib/view_data/pg/controls/json.rb +22 -0
- data/lib/view_data/pg/controls/primary_key.rb +27 -0
- data/lib/view_data/pg/controls/row/get.rb +41 -0
- data/lib/view_data/pg/controls/row/put.rb +43 -0
- data/lib/view_data/pg/controls/table.rb +28 -0
- data/lib/view_data/pg/controls/table/all_data_types.rb +85 -0
- data/lib/view_data/pg/controls/table/composite_primary_key.rb +34 -0
- data/lib/view_data/pg/controls/time.rb +47 -0
- data/lib/view_data/pg/controls/timestamp.rb +7 -0
- data/lib/view_data/pg/handler.rb +129 -0
- data/lib/view_data/pg/log.rb +11 -0
- data/lib/view_data/pg/primary_key/get_columns.rb +71 -0
- data/lib/view_data/pg/session.rb +46 -0
- data/lib/view_data/pg/settings.rb +9 -0
- metadata +107 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 3a446a1a6d3124fa58e589403e99c2c2ea670283
|
4
|
+
data.tar.gz: 26ef15ffe45116c6002f983091c0c2538f4aba9f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 33d0921b2fcf365b97f321bc94acdb2cb9c5a7e4dd87c5fdddef6922628a74b9891b1833009a1f64b81c658c6c10f3899b3e40405047c1dd5c76ae01406b2c8e
|
7
|
+
data.tar.gz: aee4c805bb139e93d6ef9a758f1f3eeda1905863a4dc58d401e9c9e1e03f31f9fed07b72f782733bb06632243b65575338ab35dbe46f88d05c9cb0348c788419
|
data/lib/view_data/pg.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'view_data/commands/controls'
|
2
|
+
require 'clock/controls'
|
3
|
+
|
4
|
+
require 'view_data/pg/controls/id'
|
5
|
+
require 'view_data/pg/controls/commands'
|
6
|
+
require 'view_data/pg/controls/consumer'
|
7
|
+
require 'view_data/pg/controls/data'
|
8
|
+
require 'view_data/pg/controls/date'
|
9
|
+
require 'view_data/pg/controls/enum'
|
10
|
+
require 'view_data/pg/controls/json'
|
11
|
+
require 'view_data/pg/controls/primary_key'
|
12
|
+
require 'view_data/pg/controls/row/get'
|
13
|
+
require 'view_data/pg/controls/row/put'
|
14
|
+
require 'view_data/pg/controls/table'
|
15
|
+
require 'view_data/pg/controls/table/composite_primary_key'
|
16
|
+
require 'view_data/pg/controls/table/all_data_types'
|
17
|
+
require 'view_data/pg/controls/time'
|
18
|
+
require 'view_data/pg/controls/timestamp'
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module ViewData
|
2
|
+
module PG
|
3
|
+
module Controls
|
4
|
+
module Commands
|
5
|
+
module Create
|
6
|
+
def self.example(primary_key: nil, column_value: nil, table: nil)
|
7
|
+
primary_key ||= PrimaryKey::UUID.example
|
8
|
+
table ||= Table.name
|
9
|
+
data = Data.example(column_value: column_value)
|
10
|
+
|
11
|
+
ViewData::Commands::Controls::Create.example(
|
12
|
+
name: table,
|
13
|
+
identifier: primary_key,
|
14
|
+
data: data
|
15
|
+
)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
module Update
|
20
|
+
def self.example(primary_key: nil, column_value: nil, table: nil)
|
21
|
+
primary_key ||= PrimaryKey::UUID.example
|
22
|
+
table ||= Table.name
|
23
|
+
data = Data.example(column_value: column_value)
|
24
|
+
|
25
|
+
ViewData::Commands::Controls::Update.example(
|
26
|
+
name: table,
|
27
|
+
identifier: primary_key,
|
28
|
+
data: data
|
29
|
+
)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
module Delete
|
34
|
+
def self.example(primary_key: nil, table: nil)
|
35
|
+
primary_key ||= PrimaryKey::UUID.example
|
36
|
+
table ||= Table.name
|
37
|
+
|
38
|
+
ViewData::Commands::Controls::Delete.example(
|
39
|
+
name: table,
|
40
|
+
identifier: primary_key
|
41
|
+
)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module ViewData
|
2
|
+
module PG
|
3
|
+
module Controls
|
4
|
+
module Data
|
5
|
+
def self.example(column_value: nil)
|
6
|
+
column_value ||= self.column_value
|
7
|
+
|
8
|
+
{
|
9
|
+
:some_column => column_value
|
10
|
+
}
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.column_value
|
14
|
+
'some-column-value'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module ViewData
|
2
|
+
module PG
|
3
|
+
module Controls
|
4
|
+
module JSON
|
5
|
+
def self.data
|
6
|
+
{
|
7
|
+
'someString' => 'some-string',
|
8
|
+
'someNumber' => 1,
|
9
|
+
'someList' => ['a', 'b', 'c'],
|
10
|
+
'someNestedObject' => {
|
11
|
+
'someNestedAttribute' => 'some-nested-value'
|
12
|
+
}
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.text
|
17
|
+
::JSON.generate(data)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module ViewData
|
2
|
+
module PG
|
3
|
+
module Controls
|
4
|
+
module PrimaryKey
|
5
|
+
module UUID
|
6
|
+
def self.example
|
7
|
+
ID::Random.example
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.column_name
|
11
|
+
'id'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
module Composite
|
16
|
+
def self.example
|
17
|
+
[UUID.example, UUID.example]
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.column_names
|
21
|
+
['id_1', 'id_2']
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module ViewData
|
2
|
+
module PG
|
3
|
+
module Controls
|
4
|
+
module Row
|
5
|
+
module Get
|
6
|
+
def self.call(primary_key, table: nil)
|
7
|
+
table ||= Table.name
|
8
|
+
|
9
|
+
session = Session.build
|
10
|
+
|
11
|
+
result = session.execute(<<~SQL, [primary_key])
|
12
|
+
SELECT * FROM #{table} WHERE id = $1 LIMIT 1
|
13
|
+
SQL
|
14
|
+
|
15
|
+
session.close
|
16
|
+
|
17
|
+
result.to_a[0]
|
18
|
+
end
|
19
|
+
|
20
|
+
module CompositePrimaryKey
|
21
|
+
def self.call(ids)
|
22
|
+
id_1, id_2 = ids
|
23
|
+
|
24
|
+
table = Table::CompositePrimaryKey.name
|
25
|
+
|
26
|
+
session = Session.build
|
27
|
+
|
28
|
+
result = session.execute(<<~SQL, [id_1, id_2])
|
29
|
+
SELECT * FROM #{table} WHERE id_1 = $1 AND id_2 = $2 LIMIT 1
|
30
|
+
SQL
|
31
|
+
|
32
|
+
session.close
|
33
|
+
|
34
|
+
result.to_a[0]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module ViewData
|
2
|
+
module PG
|
3
|
+
module Controls
|
4
|
+
module Row
|
5
|
+
module Put
|
6
|
+
def self.call
|
7
|
+
primary_key = PrimaryKey::UUID.example
|
8
|
+
column_value = Controls::Data.column_value
|
9
|
+
table_name = Table.name
|
10
|
+
|
11
|
+
session = Session.build
|
12
|
+
|
13
|
+
session.execute(<<~SQL, [primary_key, column_value])
|
14
|
+
INSERT INTO #{table_name} (id, some_column) VALUES ($1, $2)
|
15
|
+
SQL
|
16
|
+
|
17
|
+
session.close
|
18
|
+
|
19
|
+
primary_key
|
20
|
+
end
|
21
|
+
|
22
|
+
module CompositePrimaryKey
|
23
|
+
def self.call
|
24
|
+
id_1, id_2 = PrimaryKey::Composite.example
|
25
|
+
column_value = Controls::Data.column_value
|
26
|
+
table_name = Table::CompositePrimaryKey.name
|
27
|
+
|
28
|
+
session = Session.build
|
29
|
+
|
30
|
+
session.execute(<<~SQL, [id_1, id_2, column_value])
|
31
|
+
INSERT INTO #{table_name} (id_1, id_2, some_column) VALUES ($1, $2, $3)
|
32
|
+
SQL
|
33
|
+
|
34
|
+
session.close
|
35
|
+
|
36
|
+
return id_1, id_2
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module ViewData
|
2
|
+
module PG
|
3
|
+
module Controls
|
4
|
+
module Table
|
5
|
+
def self.create(drop: nil)
|
6
|
+
session = Session.build
|
7
|
+
|
8
|
+
if drop
|
9
|
+
session.execute("DROP TABLE IF EXISTS test_table")
|
10
|
+
end
|
11
|
+
|
12
|
+
session.execute(<<~SQL)
|
13
|
+
CREATE TABLE #{name} (
|
14
|
+
id uuid PRIMARY KEY,
|
15
|
+
some_column text
|
16
|
+
)
|
17
|
+
SQL
|
18
|
+
|
19
|
+
session.close
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.name
|
23
|
+
'test_table'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module ViewData
|
2
|
+
module PG
|
3
|
+
module Controls
|
4
|
+
module Table
|
5
|
+
module AllDataTypes
|
6
|
+
def self.create(drop: nil)
|
7
|
+
session = Session.build
|
8
|
+
|
9
|
+
if drop
|
10
|
+
session.execute("DROP TABLE IF EXISTS #{name}")
|
11
|
+
session.execute("DROP TYPE some_enum_type")
|
12
|
+
end
|
13
|
+
|
14
|
+
begin
|
15
|
+
session.execute(<<~SQL)
|
16
|
+
CREATE TYPE some_enum_type AS ENUM (
|
17
|
+
'#{Enum.example}',
|
18
|
+
'#{Enum.alternate}'
|
19
|
+
)
|
20
|
+
SQL
|
21
|
+
rescue ::PG::DuplicateObject
|
22
|
+
end
|
23
|
+
|
24
|
+
session.execute(<<~SQL)
|
25
|
+
CREATE TABLE #{name} (
|
26
|
+
id uuid PRIMARY KEY,
|
27
|
+
|
28
|
+
-- Numbers
|
29
|
+
some_smallint smallint,
|
30
|
+
some_integer integer,
|
31
|
+
some_bigint bigint,
|
32
|
+
some_decimal_3_1 decimal(4, 1),
|
33
|
+
some_numeric_3_1 numeric(4, 1),
|
34
|
+
some_real real,
|
35
|
+
some_double_precision double precision,
|
36
|
+
some_smallserial smallserial,
|
37
|
+
some_serial serial,
|
38
|
+
some_bigserial bigserial,
|
39
|
+
|
40
|
+
-- Money
|
41
|
+
some_money money,
|
42
|
+
|
43
|
+
-- Character
|
44
|
+
some_varchar_3 character varying(3),
|
45
|
+
some_char_3 character(3),
|
46
|
+
some_text text,
|
47
|
+
|
48
|
+
-- Binary
|
49
|
+
some_bytea bytea,
|
50
|
+
|
51
|
+
-- Date/Time
|
52
|
+
some_timestamp_3 timestamp(3) without time zone,
|
53
|
+
some_timestamp_3_with_tz timestamp(3) with time zone,
|
54
|
+
some_date date,
|
55
|
+
some_time_3 time(3) without time zone,
|
56
|
+
some_time_3_with_tz time(3) with time zone,
|
57
|
+
some_interval_year interval YEAR,
|
58
|
+
some_interval_second_3 interval SECOND(3),
|
59
|
+
|
60
|
+
-- Boolean
|
61
|
+
some_boolean bool,
|
62
|
+
|
63
|
+
-- Enum
|
64
|
+
some_enum some_enum_type,
|
65
|
+
|
66
|
+
-- UUID
|
67
|
+
some_uuid uuid,
|
68
|
+
|
69
|
+
-- JSON
|
70
|
+
some_json_text json,
|
71
|
+
some_json_binary jsonb
|
72
|
+
)
|
73
|
+
SQL
|
74
|
+
|
75
|
+
session.close
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.name
|
79
|
+
'all_data_types'
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module ViewData
|
2
|
+
module PG
|
3
|
+
module Controls
|
4
|
+
module Table
|
5
|
+
module CompositePrimaryKey
|
6
|
+
def self.create(drop: nil)
|
7
|
+
session = Session.build
|
8
|
+
|
9
|
+
if drop
|
10
|
+
session.execute("DROP TABLE IF EXISTS #{name}")
|
11
|
+
end
|
12
|
+
|
13
|
+
session.execute(<<~SQL)
|
14
|
+
CREATE TABLE #{name} (
|
15
|
+
id_1 uuid NOT NULL,
|
16
|
+
id_2 uuid NOT NULL,
|
17
|
+
|
18
|
+
some_column text,
|
19
|
+
|
20
|
+
PRIMARY KEY(id_1, id_2)
|
21
|
+
)
|
22
|
+
SQL
|
23
|
+
|
24
|
+
session.close
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.name
|
28
|
+
'test_composite_primary_key'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module ViewData
|
2
|
+
module PG
|
3
|
+
module Controls
|
4
|
+
Time = Clock::Controls::Time
|
5
|
+
|
6
|
+
module Time
|
7
|
+
module Local
|
8
|
+
def self.example(time=nil, precision: nil)
|
9
|
+
time = Raw.example(time)
|
10
|
+
|
11
|
+
Time.example(time, precision: precision)
|
12
|
+
end
|
13
|
+
|
14
|
+
module Offset
|
15
|
+
def self.name
|
16
|
+
'CET'
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.hours
|
20
|
+
1
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.seconds
|
24
|
+
hours * 60 * 60
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
module Raw
|
29
|
+
def self.example(time=nil)
|
30
|
+
time ||= Time::Raw.example
|
31
|
+
|
32
|
+
::Time.new(
|
33
|
+
time.year,
|
34
|
+
time.month,
|
35
|
+
time.day,
|
36
|
+
time.hour,
|
37
|
+
time.min,
|
38
|
+
time.sec,
|
39
|
+
Offset.seconds
|
40
|
+
)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
module ViewData
|
2
|
+
module PG
|
3
|
+
class Handler
|
4
|
+
include Messaging::Handle
|
5
|
+
include Log::Dependency
|
6
|
+
|
7
|
+
include ViewData::Commands
|
8
|
+
|
9
|
+
dependency :session, MessageStore::Postgres::Session
|
10
|
+
dependency :get_primary_key_columns, PrimaryKey::GetColumns
|
11
|
+
|
12
|
+
def configure
|
13
|
+
Session.configure(self)
|
14
|
+
PrimaryKey::GetColumns.configure(self, session: session)
|
15
|
+
end
|
16
|
+
|
17
|
+
handle Create do |create|
|
18
|
+
table_name = create.name
|
19
|
+
|
20
|
+
logger.trace { "Inserting row (Table: #{table_name}, Identifier: #{create.identifier.inspect})" }
|
21
|
+
|
22
|
+
pkey_columns = get_primary_key_columns.(table_name)
|
23
|
+
pkey_values = Array(create.identifier)
|
24
|
+
|
25
|
+
data_columns = create.data.keys
|
26
|
+
data_values = create.data.values
|
27
|
+
|
28
|
+
columns = pkey_columns + data_columns
|
29
|
+
|
30
|
+
values = pkey_values + data_values
|
31
|
+
|
32
|
+
values_clause = values.count.times.map do |i|
|
33
|
+
"$#{i + 1}"
|
34
|
+
end
|
35
|
+
|
36
|
+
statement = <<~SQL.chomp
|
37
|
+
INSERT INTO #{table_name} (#{columns * ', '})
|
38
|
+
VALUES (#{values_clause * ', '})
|
39
|
+
SQL
|
40
|
+
|
41
|
+
begin
|
42
|
+
logger.trace { "Inserting row (Table: #{table_name}, Identifier: #{create.identifier.inspect})" }
|
43
|
+
logger.trace(tag: :data) { "SQL: #{statement}" }
|
44
|
+
logger.trace(tag: :data) { values.pretty_inspect }
|
45
|
+
|
46
|
+
session.execute(statement, values)
|
47
|
+
|
48
|
+
logger.info { "Inserted row (Table: #{table_name}, Identifier: #{create.identifier.inspect})" }
|
49
|
+
logger.info(tag: :data) { "SQL: #{statement}" }
|
50
|
+
logger.info(tag: :data) { values.pretty_inspect }
|
51
|
+
|
52
|
+
rescue ::PG::UniqueViolation
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
handle Update do |update|
|
57
|
+
table_name = update.name
|
58
|
+
|
59
|
+
logger.trace { "Updating row (Table: #{table_name}, Identifier: #{update.identifier.inspect})" }
|
60
|
+
|
61
|
+
pkey_columns = get_primary_key_columns.(table_name)
|
62
|
+
pkey_values = Array(update.identifier)
|
63
|
+
|
64
|
+
data_columns = update.data.keys
|
65
|
+
data_values = update.data.values
|
66
|
+
|
67
|
+
set_clause = data_columns.map.with_index do |column_name, index|
|
68
|
+
reference = index + 1
|
69
|
+
|
70
|
+
"#{column_name} = $#{reference}"
|
71
|
+
end
|
72
|
+
|
73
|
+
pkey_clause = pkey_columns.map.with_index do |column_name, index|
|
74
|
+
reference = index + data_columns.count + 1
|
75
|
+
|
76
|
+
"#{column_name} = $#{reference}"
|
77
|
+
end
|
78
|
+
|
79
|
+
values = data_values + pkey_values
|
80
|
+
|
81
|
+
statement = <<~SQL.chomp
|
82
|
+
UPDATE #{table_name}
|
83
|
+
SET #{set_clause * ', '}
|
84
|
+
WHERE #{pkey_clause * ' AND '}
|
85
|
+
SQL
|
86
|
+
|
87
|
+
logger.trace { "Updating row (Table: #{table_name}, Identifier: #{update.identifier.inspect})" }
|
88
|
+
logger.trace(tag: :data) { "SQL: #{statement}" }
|
89
|
+
logger.trace(tag: :data) { values.pretty_inspect }
|
90
|
+
|
91
|
+
session.execute(statement, values)
|
92
|
+
|
93
|
+
logger.info { "Updated row (Table: #{table_name}, Identifier: #{update.identifier.inspect})" }
|
94
|
+
logger.info(tag: :data) { "SQL: #{statement}" }
|
95
|
+
logger.info(tag: :data) { values.pretty_inspect }
|
96
|
+
end
|
97
|
+
|
98
|
+
handle Delete do |delete|
|
99
|
+
table_name = delete.name
|
100
|
+
|
101
|
+
logger.trace { "Deleting row (Table: #{table_name}, Identifier: #{delete.identifier.inspect})" }
|
102
|
+
|
103
|
+
pkey_columns = get_primary_key_columns.(table_name)
|
104
|
+
pkey_values = Array(delete.identifier)
|
105
|
+
|
106
|
+
pkey_clause = pkey_columns.map.with_index do |column_name, index|
|
107
|
+
reference = index + 1
|
108
|
+
|
109
|
+
"#{column_name} = $#{reference}"
|
110
|
+
end
|
111
|
+
|
112
|
+
statement = <<~SQL.chomp
|
113
|
+
DELETE FROM #{table_name}
|
114
|
+
WHERE #{pkey_clause * ' AND '}
|
115
|
+
SQL
|
116
|
+
|
117
|
+
logger.trace { "Deleting row (Table: #{table_name}, Identifier: #{delete.identifier.inspect})" }
|
118
|
+
logger.trace(tag: :data) { "SQL: #{statement}" }
|
119
|
+
logger.trace(tag: :data) { pkey_values.pretty_inspect }
|
120
|
+
|
121
|
+
session.execute(statement, pkey_values)
|
122
|
+
|
123
|
+
logger.info { "Deleted row (Table: #{table_name}, Identifier: #{delete.identifier.inspect})" }
|
124
|
+
logger.info(tag: :data) { "SQL: #{statement}" }
|
125
|
+
logger.info(tag: :data) { pkey_values.pretty_inspect }
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module ViewData
|
2
|
+
module PG
|
3
|
+
module PrimaryKey
|
4
|
+
class GetColumns
|
5
|
+
configure :get_primary_key_columns
|
6
|
+
|
7
|
+
dependency :session, Session
|
8
|
+
dependency :telemetry, ::Telemetry
|
9
|
+
|
10
|
+
def self.build(session: nil)
|
11
|
+
instance = new
|
12
|
+
Session.configure(instance, session: session)
|
13
|
+
::Telemetry.configure(instance)
|
14
|
+
instance
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.call(table)
|
18
|
+
instance = build()
|
19
|
+
instance.(table)
|
20
|
+
end
|
21
|
+
|
22
|
+
def call(table)
|
23
|
+
cache[table]
|
24
|
+
end
|
25
|
+
|
26
|
+
def query(table)
|
27
|
+
result = session.execute(<<~SQL, [table])
|
28
|
+
SELECT
|
29
|
+
TEXT(attr.attname) AS column_name
|
30
|
+
FROM pg_index AS index
|
31
|
+
JOIN pg_attribute AS attr
|
32
|
+
ON attr.attrelid = index.indrelid
|
33
|
+
AND attr.attnum = ANY(index.indkey)
|
34
|
+
WHERE index.indrelid = $1::regclass
|
35
|
+
AND index.indisprimary
|
36
|
+
SQL
|
37
|
+
|
38
|
+
columns = result.to_a.map do |hash|
|
39
|
+
hash['column_name']
|
40
|
+
end
|
41
|
+
|
42
|
+
telemetry.record(:columns_queried, Telemetry::Data.new(table, columns))
|
43
|
+
|
44
|
+
columns
|
45
|
+
end
|
46
|
+
|
47
|
+
def cache
|
48
|
+
@cache ||= Hash.new do |hash, table|
|
49
|
+
hash[table] = query(table)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.register_telemetry_sink(instance)
|
54
|
+
sink = Telemetry::Sink.new
|
55
|
+
instance.telemetry.register(sink)
|
56
|
+
sink
|
57
|
+
end
|
58
|
+
|
59
|
+
module Telemetry
|
60
|
+
class Sink
|
61
|
+
include ::Telemetry::Sink
|
62
|
+
|
63
|
+
record :columns_queried
|
64
|
+
end
|
65
|
+
|
66
|
+
Data = Struct.new(:table, :columns)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module ViewData
|
2
|
+
module PG
|
3
|
+
class Session < MessageStore::Postgres::Session
|
4
|
+
settings.each do |setting_name|
|
5
|
+
setting setting_name
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.build(settings: nil)
|
9
|
+
settings ||= Settings.instance
|
10
|
+
|
11
|
+
super(settings: settings)
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.build_connection(*)
|
15
|
+
connection = super
|
16
|
+
|
17
|
+
type_map_for_results = connection.type_map_for_results
|
18
|
+
|
19
|
+
name_decoder = ::PG::TextDecoder::String.new({
|
20
|
+
:oid => 19,
|
21
|
+
:name => 'name'
|
22
|
+
})
|
23
|
+
|
24
|
+
regproc_decoder = ::PG::TextDecoder::String.new({
|
25
|
+
:oid => 24,
|
26
|
+
:name => 'regproc'
|
27
|
+
})
|
28
|
+
|
29
|
+
numeric_decoder = ::PG::TextDecoder::Float.new({
|
30
|
+
:oid => 1700,
|
31
|
+
:name => 'numeric'
|
32
|
+
})
|
33
|
+
|
34
|
+
type_map_for_results.add_coder(name_decoder)
|
35
|
+
type_map_for_results.add_coder(regproc_decoder)
|
36
|
+
type_map_for_results.add_coder(numeric_decoder)
|
37
|
+
|
38
|
+
type_map_for_queries = ::PG::BasicTypeMapForQueries.new(connection)
|
39
|
+
|
40
|
+
connection.type_map_for_queries = type_map_for_queries
|
41
|
+
|
42
|
+
connection
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
metadata
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: evt-view_data-pg
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- The Eventide Project
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-08-04 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: evt-consumer-postgres
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: evt-view_data-commands
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: test_bench
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: " "
|
56
|
+
email: opensource@eventide-project.org
|
57
|
+
executables: []
|
58
|
+
extensions: []
|
59
|
+
extra_rdoc_files: []
|
60
|
+
files:
|
61
|
+
- lib/view_data/pg.rb
|
62
|
+
- lib/view_data/pg/controls.rb
|
63
|
+
- lib/view_data/pg/controls/commands.rb
|
64
|
+
- lib/view_data/pg/controls/consumer.rb
|
65
|
+
- lib/view_data/pg/controls/data.rb
|
66
|
+
- lib/view_data/pg/controls/date.rb
|
67
|
+
- lib/view_data/pg/controls/enum.rb
|
68
|
+
- lib/view_data/pg/controls/id.rb
|
69
|
+
- lib/view_data/pg/controls/json.rb
|
70
|
+
- lib/view_data/pg/controls/primary_key.rb
|
71
|
+
- lib/view_data/pg/controls/row/get.rb
|
72
|
+
- lib/view_data/pg/controls/row/put.rb
|
73
|
+
- lib/view_data/pg/controls/table.rb
|
74
|
+
- lib/view_data/pg/controls/table/all_data_types.rb
|
75
|
+
- lib/view_data/pg/controls/table/composite_primary_key.rb
|
76
|
+
- lib/view_data/pg/controls/time.rb
|
77
|
+
- lib/view_data/pg/controls/timestamp.rb
|
78
|
+
- lib/view_data/pg/handler.rb
|
79
|
+
- lib/view_data/pg/log.rb
|
80
|
+
- lib/view_data/pg/primary_key/get_columns.rb
|
81
|
+
- lib/view_data/pg/session.rb
|
82
|
+
- lib/view_data/pg/settings.rb
|
83
|
+
homepage: https://github.com/eventide-contrib/view-data-pg
|
84
|
+
licenses:
|
85
|
+
- MIT
|
86
|
+
metadata: {}
|
87
|
+
post_install_message:
|
88
|
+
rdoc_options: []
|
89
|
+
require_paths:
|
90
|
+
- lib
|
91
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: 2.4.0
|
96
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
97
|
+
requirements:
|
98
|
+
- - ">="
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: '0'
|
101
|
+
requirements: []
|
102
|
+
rubyforge_project:
|
103
|
+
rubygems_version: 2.6.11
|
104
|
+
signing_key:
|
105
|
+
specification_version: 4
|
106
|
+
summary: Create and populate PostgreSQL view databases from event streams
|
107
|
+
test_files: []
|