lex-postgres 0.1.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 +7 -0
- data/.github/workflows/ci.yml +16 -0
- data/.gitignore +12 -0
- data/.rspec +3 -0
- data/.rubocop.yml +50 -0
- data/CHANGELOG.md +11 -0
- data/Gemfile +11 -0
- data/README.md +76 -0
- data/lex-postgres.gemspec +30 -0
- data/lib/legion/extensions/postgres/client.rb +26 -0
- data/lib/legion/extensions/postgres/helpers/client.rb +22 -0
- data/lib/legion/extensions/postgres/runners/queries.rb +26 -0
- data/lib/legion/extensions/postgres/runners/tables.rb +39 -0
- data/lib/legion/extensions/postgres/version.rb +9 -0
- data/lib/legion/extensions/postgres.rb +15 -0
- metadata +74 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 67cba7d98266b32731852fc25ff2345aa68c857fb24d5d5ce04cb5a25169b53e
|
|
4
|
+
data.tar.gz: 567a545528468fd54336b5326357881fb3f8908cf6dab6c2a3f5a1ca2a3e5a5b
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 32d7921ab206bce10ecfe9506c7185453cb21e7ee04059c211a03a4e88c95015766fd8a46305b5ea5a8c5ae4a2c4c45f44813eedd5736bb7465a9a6701274a98
|
|
7
|
+
data.tar.gz: 2aeaa970e7849185c9a81148917b0d58d3af1f0002d94d3cd1a99ab6071a9a330f0c6b7192ebe95103f81c28412df5e6238cb9e003d09db4b1abc96566dff282
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
on:
|
|
3
|
+
push:
|
|
4
|
+
branches: [origin]
|
|
5
|
+
pull_request:
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
ci:
|
|
9
|
+
uses: LegionIO/.github/.github/workflows/ci.yml@main
|
|
10
|
+
|
|
11
|
+
release:
|
|
12
|
+
needs: ci
|
|
13
|
+
if: github.event_name == 'push' && github.ref == 'refs/heads/origin'
|
|
14
|
+
uses: LegionIO/.github/.github/workflows/release.yml@main
|
|
15
|
+
secrets:
|
|
16
|
+
rubygems-api-key: ${{ secrets.RUBYGEMS_API_KEY }}
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
AllCops:
|
|
2
|
+
TargetRubyVersion: 3.4
|
|
3
|
+
NewCops: enable
|
|
4
|
+
SuggestExtensions: false
|
|
5
|
+
|
|
6
|
+
Layout/LineLength:
|
|
7
|
+
Max: 160
|
|
8
|
+
|
|
9
|
+
Layout/SpaceAroundEqualsInParameterDefault:
|
|
10
|
+
EnforcedStyle: space
|
|
11
|
+
|
|
12
|
+
Layout/HashAlignment:
|
|
13
|
+
EnforcedHashRocketStyle: table
|
|
14
|
+
EnforcedColonStyle: table
|
|
15
|
+
|
|
16
|
+
Metrics/MethodLength:
|
|
17
|
+
Max: 50
|
|
18
|
+
|
|
19
|
+
Metrics/ClassLength:
|
|
20
|
+
Max: 1500
|
|
21
|
+
|
|
22
|
+
Metrics/ModuleLength:
|
|
23
|
+
Max: 1500
|
|
24
|
+
|
|
25
|
+
Metrics/BlockLength:
|
|
26
|
+
Max: 40
|
|
27
|
+
Exclude:
|
|
28
|
+
- 'spec/**/*'
|
|
29
|
+
|
|
30
|
+
Metrics/AbcSize:
|
|
31
|
+
Max: 60
|
|
32
|
+
|
|
33
|
+
Metrics/CyclomaticComplexity:
|
|
34
|
+
Max: 15
|
|
35
|
+
|
|
36
|
+
Metrics/PerceivedComplexity:
|
|
37
|
+
Max: 17
|
|
38
|
+
|
|
39
|
+
Style/Documentation:
|
|
40
|
+
Enabled: false
|
|
41
|
+
|
|
42
|
+
Style/SymbolArray:
|
|
43
|
+
Enabled: true
|
|
44
|
+
|
|
45
|
+
Style/FrozenStringLiteralComment:
|
|
46
|
+
Enabled: true
|
|
47
|
+
EnforcedStyle: always
|
|
48
|
+
|
|
49
|
+
Naming/FileName:
|
|
50
|
+
Enabled: false
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [0.1.0] - 2026-03-21
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- Initial release
|
|
7
|
+
- `Helpers::Client` module with `.connection` method wrapping `PG::Connection`
|
|
8
|
+
- `Runners::Queries` with `execute` (arbitrary SQL) and `execute_params` (parameterized SQL with `$1`/`$2` placeholders)
|
|
9
|
+
- `Runners::Tables` with `list_tables`, `describe_table`, and `table_size` using `information_schema` and `pg_total_relation_size`
|
|
10
|
+
- Standalone `Client` class including all runner modules
|
|
11
|
+
- Full RSpec test suite (15 specs across 3 spec files)
|
data/Gemfile
ADDED
data/README.md
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# lex-postgres
|
|
2
|
+
|
|
3
|
+
A LegionIO extension (LEX) that connects LegionIO to PostgreSQL databases via the `pg` gem.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
Add to your Gemfile:
|
|
8
|
+
|
|
9
|
+
```ruby
|
|
10
|
+
gem 'lex-postgres'
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Standalone Usage
|
|
14
|
+
|
|
15
|
+
```ruby
|
|
16
|
+
require 'lex-postgres'
|
|
17
|
+
|
|
18
|
+
client = Legion::Extensions::Postgres::Client.new(
|
|
19
|
+
host: 'db.example.com',
|
|
20
|
+
port: 5432,
|
|
21
|
+
dbname: 'myapp',
|
|
22
|
+
user: 'jane.doe',
|
|
23
|
+
password: 'secret'
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
# Execute arbitrary SQL
|
|
27
|
+
client.execute(sql: 'SELECT version()')
|
|
28
|
+
# => { result: [{ version: "PostgreSQL 16.0 ..." }] }
|
|
29
|
+
|
|
30
|
+
# Parameterized query
|
|
31
|
+
client.execute_params(sql: 'SELECT * FROM users WHERE id = $1', params: [42])
|
|
32
|
+
# => { result: [{ id: "42", name: "Jane Doe", email: "jane.doe@example.com" }] }
|
|
33
|
+
|
|
34
|
+
# List tables in a schema
|
|
35
|
+
client.list_tables(schema: 'public')
|
|
36
|
+
# => { result: ["orders", "products", "users"] }
|
|
37
|
+
|
|
38
|
+
# Describe a table's columns
|
|
39
|
+
client.describe_table(table: 'users')
|
|
40
|
+
# => { result: [{ column_name: "id", data_type: "integer", ... }, ...] }
|
|
41
|
+
|
|
42
|
+
# Total on-disk size of a table (bytes)
|
|
43
|
+
client.table_size(table: 'orders')
|
|
44
|
+
# => { result: 8192 }
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Runner Methods
|
|
48
|
+
|
|
49
|
+
### Queries
|
|
50
|
+
|
|
51
|
+
| Method | Description |
|
|
52
|
+
|--------|-------------|
|
|
53
|
+
| `execute(sql:)` | Run arbitrary SQL, returns rows as array of symbol-keyed hashes |
|
|
54
|
+
| `execute_params(sql:, params: [])` | Parameterized query with `$1`, `$2` placeholders |
|
|
55
|
+
|
|
56
|
+
### Tables
|
|
57
|
+
|
|
58
|
+
| Method | Description |
|
|
59
|
+
|--------|-------------|
|
|
60
|
+
| `list_tables(schema: 'public')` | List table names in the given schema |
|
|
61
|
+
| `describe_table(table:, schema: 'public')` | Column definitions from `information_schema.columns` |
|
|
62
|
+
| `table_size(table:)` | Total relation size in bytes via `pg_total_relation_size` |
|
|
63
|
+
|
|
64
|
+
## Connection Defaults
|
|
65
|
+
|
|
66
|
+
| Option | Default |
|
|
67
|
+
|--------|---------|
|
|
68
|
+
| `host` | `127.0.0.1` |
|
|
69
|
+
| `port` | `5432` |
|
|
70
|
+
| `dbname` | `postgres` |
|
|
71
|
+
| `user` | `postgres` |
|
|
72
|
+
| `password` | `nil` (omitted if not set) |
|
|
73
|
+
|
|
74
|
+
## License
|
|
75
|
+
|
|
76
|
+
MIT
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'lib/legion/extensions/postgres/version'
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |spec|
|
|
6
|
+
spec.name = 'lex-postgres'
|
|
7
|
+
spec.version = Legion::Extensions::Postgres::VERSION
|
|
8
|
+
spec.authors = ['Esity']
|
|
9
|
+
spec.email = ['matthewdiverson@gmail.com']
|
|
10
|
+
|
|
11
|
+
spec.summary = 'LEX::postgres'
|
|
12
|
+
spec.description = 'Connects LegionIO to PostgreSQL databases'
|
|
13
|
+
spec.homepage = 'https://github.com/LegionIO/lex-postgres'
|
|
14
|
+
spec.license = 'MIT'
|
|
15
|
+
spec.required_ruby_version = '>= 3.4'
|
|
16
|
+
|
|
17
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
|
18
|
+
spec.metadata['source_code_uri'] = 'https://github.com/LegionIO/lex-postgres'
|
|
19
|
+
spec.metadata['documentation_uri'] = 'https://github.com/LegionIO/lex-postgres'
|
|
20
|
+
spec.metadata['changelog_uri'] = 'https://github.com/LegionIO/lex-postgres'
|
|
21
|
+
spec.metadata['bug_tracker_uri'] = 'https://github.com/LegionIO/lex-postgres/issues'
|
|
22
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
|
23
|
+
|
|
24
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
|
25
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
26
|
+
end
|
|
27
|
+
spec.require_paths = ['lib']
|
|
28
|
+
|
|
29
|
+
spec.add_dependency 'pg', '~> 1.5'
|
|
30
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'helpers/client'
|
|
4
|
+
require_relative 'runners/queries'
|
|
5
|
+
require_relative 'runners/tables'
|
|
6
|
+
|
|
7
|
+
module Legion
|
|
8
|
+
module Extensions
|
|
9
|
+
module Postgres
|
|
10
|
+
class Client
|
|
11
|
+
include Runners::Queries
|
|
12
|
+
include Runners::Tables
|
|
13
|
+
|
|
14
|
+
attr_reader :opts
|
|
15
|
+
|
|
16
|
+
def initialize(**opts)
|
|
17
|
+
@opts = Helpers::Client::DEFAULTS.merge(opts)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def connection(**override)
|
|
21
|
+
Helpers::Client.connection(**@opts, **override)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'pg'
|
|
4
|
+
|
|
5
|
+
module Legion
|
|
6
|
+
module Extensions
|
|
7
|
+
module Postgres
|
|
8
|
+
module Helpers
|
|
9
|
+
module Client
|
|
10
|
+
DEFAULTS = { host: '127.0.0.1', port: 5432, dbname: 'postgres', user: 'postgres' }.freeze
|
|
11
|
+
|
|
12
|
+
def self.connection(**opts)
|
|
13
|
+
merged = DEFAULTS.merge(opts)
|
|
14
|
+
connect_hash = merged.slice(:host, :port, :dbname, :user)
|
|
15
|
+
connect_hash[:password] = merged[:password] if merged[:password]
|
|
16
|
+
::PG::Connection.new(**connect_hash)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'legion/extensions/postgres/helpers/client'
|
|
4
|
+
|
|
5
|
+
module Legion
|
|
6
|
+
module Extensions
|
|
7
|
+
module Postgres
|
|
8
|
+
module Runners
|
|
9
|
+
module Queries
|
|
10
|
+
def execute(sql:, **)
|
|
11
|
+
result = connection(**).exec(sql)
|
|
12
|
+
{ result: result.map { |row| row.transform_keys(&:to_sym) } }
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def execute_params(sql:, params: [], **)
|
|
16
|
+
result = connection(**).exec_params(sql, params)
|
|
17
|
+
{ result: result.map { |row| row.transform_keys(&:to_sym) } }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
extend Legion::Extensions::Postgres::Helpers::Client
|
|
21
|
+
include Legion::Extensions::Helpers::Lex if defined?(Legion::Extensions::Helpers::Lex)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'legion/extensions/postgres/helpers/client'
|
|
4
|
+
|
|
5
|
+
module Legion
|
|
6
|
+
module Extensions
|
|
7
|
+
module Postgres
|
|
8
|
+
module Runners
|
|
9
|
+
module Tables
|
|
10
|
+
def list_tables(schema: 'public', **)
|
|
11
|
+
sql = 'SELECT table_name FROM information_schema.tables WHERE table_schema = $1 ORDER BY table_name'
|
|
12
|
+
result = connection(**).exec_params(sql, [schema])
|
|
13
|
+
{ result: result.map { |row| row['table_name'] } }
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def describe_table(table:, schema: 'public', **)
|
|
17
|
+
sql = <<~SQL
|
|
18
|
+
SELECT column_name, data_type, character_maximum_length, is_nullable, column_default
|
|
19
|
+
FROM information_schema.columns
|
|
20
|
+
WHERE table_schema = $1 AND table_name = $2
|
|
21
|
+
ORDER BY ordinal_position
|
|
22
|
+
SQL
|
|
23
|
+
result = connection(**).exec_params(sql, [schema, table])
|
|
24
|
+
{ result: result.map { |row| row.transform_keys(&:to_sym) } }
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def table_size(table:, **)
|
|
28
|
+
sql = 'SELECT pg_total_relation_size($1) AS size'
|
|
29
|
+
result = connection(**).exec_params(sql, [table])
|
|
30
|
+
{ result: result.first['size'].to_i }
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
extend Legion::Extensions::Postgres::Helpers::Client
|
|
34
|
+
include Legion::Extensions::Helpers::Lex if defined?(Legion::Extensions::Helpers::Lex)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'legion/extensions/postgres/version'
|
|
4
|
+
require 'legion/extensions/postgres/helpers/client'
|
|
5
|
+
require 'legion/extensions/postgres/runners/queries'
|
|
6
|
+
require 'legion/extensions/postgres/runners/tables'
|
|
7
|
+
require 'legion/extensions/postgres/client'
|
|
8
|
+
|
|
9
|
+
module Legion
|
|
10
|
+
module Extensions
|
|
11
|
+
module Postgres
|
|
12
|
+
extend Legion::Extensions::Core if Legion::Extensions.const_defined? :Core
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: lex-postgres
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Esity
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: pg
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '1.5'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '1.5'
|
|
26
|
+
description: Connects LegionIO to PostgreSQL databases
|
|
27
|
+
email:
|
|
28
|
+
- matthewdiverson@gmail.com
|
|
29
|
+
executables: []
|
|
30
|
+
extensions: []
|
|
31
|
+
extra_rdoc_files: []
|
|
32
|
+
files:
|
|
33
|
+
- ".github/workflows/ci.yml"
|
|
34
|
+
- ".gitignore"
|
|
35
|
+
- ".rspec"
|
|
36
|
+
- ".rubocop.yml"
|
|
37
|
+
- CHANGELOG.md
|
|
38
|
+
- Gemfile
|
|
39
|
+
- README.md
|
|
40
|
+
- lex-postgres.gemspec
|
|
41
|
+
- lib/legion/extensions/postgres.rb
|
|
42
|
+
- lib/legion/extensions/postgres/client.rb
|
|
43
|
+
- lib/legion/extensions/postgres/helpers/client.rb
|
|
44
|
+
- lib/legion/extensions/postgres/runners/queries.rb
|
|
45
|
+
- lib/legion/extensions/postgres/runners/tables.rb
|
|
46
|
+
- lib/legion/extensions/postgres/version.rb
|
|
47
|
+
homepage: https://github.com/LegionIO/lex-postgres
|
|
48
|
+
licenses:
|
|
49
|
+
- MIT
|
|
50
|
+
metadata:
|
|
51
|
+
homepage_uri: https://github.com/LegionIO/lex-postgres
|
|
52
|
+
source_code_uri: https://github.com/LegionIO/lex-postgres
|
|
53
|
+
documentation_uri: https://github.com/LegionIO/lex-postgres
|
|
54
|
+
changelog_uri: https://github.com/LegionIO/lex-postgres
|
|
55
|
+
bug_tracker_uri: https://github.com/LegionIO/lex-postgres/issues
|
|
56
|
+
rubygems_mfa_required: 'true'
|
|
57
|
+
rdoc_options: []
|
|
58
|
+
require_paths:
|
|
59
|
+
- lib
|
|
60
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
61
|
+
requirements:
|
|
62
|
+
- - ">="
|
|
63
|
+
- !ruby/object:Gem::Version
|
|
64
|
+
version: '3.4'
|
|
65
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
66
|
+
requirements:
|
|
67
|
+
- - ">="
|
|
68
|
+
- !ruby/object:Gem::Version
|
|
69
|
+
version: '0'
|
|
70
|
+
requirements: []
|
|
71
|
+
rubygems_version: 3.6.9
|
|
72
|
+
specification_version: 4
|
|
73
|
+
summary: LEX::postgres
|
|
74
|
+
test_files: []
|