relationizer 0.3.1 → 0.4.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/.github/workflows/release.yml +35 -0
- data/.github/workflows/ruby.yml +14 -12
- data/CLAUDE.md +48 -0
- data/README.md +120 -18
- data/lib/relationizer/mysql.rb +104 -0
- data/lib/relationizer/version.rb +1 -1
- data/lib/relationizer.rb +1 -0
- data/relationizer.gemspec +3 -1
- metadata +26 -9
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a48df925940ca5fe199ef9ba19ed66836a55ec029356c80dd93e9f4a2f150558
|
|
4
|
+
data.tar.gz: 4add1225e3324e97e22e2670628820adf5c1588cd764e303c6ed4a765130d72c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f4a6b8ddaa7d11192b39f940a9ae8da1b9eb75d2b71671c616032cd16db730ce8769d1ceaa8092dac62d16e1d003333d2dfb6c2580cfaa692cd263abe1877906
|
|
7
|
+
data.tar.gz: fef4f070c8d10430a531fd67d700279511f33505f8df3c0149d0afff9463857229a872e4ab756370e831c42cdcfd8d64e697bfbbdee18f634252d671353de8e5
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*'
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
release:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
|
|
12
|
+
permissions:
|
|
13
|
+
contents: write
|
|
14
|
+
id-token: write # Required for Trusted Publisher
|
|
15
|
+
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- name: Set up Ruby
|
|
20
|
+
uses: ruby/setup-ruby@v1
|
|
21
|
+
with:
|
|
22
|
+
ruby-version: '3.3'
|
|
23
|
+
bundler-cache: true
|
|
24
|
+
|
|
25
|
+
- name: Build gem
|
|
26
|
+
run: gem build relationizer.gemspec
|
|
27
|
+
|
|
28
|
+
- name: Push to RubyGems (Trusted Publisher)
|
|
29
|
+
uses: rubygems/release-gem@v1
|
|
30
|
+
|
|
31
|
+
- name: Create GitHub Release
|
|
32
|
+
uses: softprops/action-gh-release@v1
|
|
33
|
+
with:
|
|
34
|
+
files: relationizer-*.gem
|
|
35
|
+
generate_release_notes: true
|
data/.github/workflows/ruby.yml
CHANGED
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
name: Ruby
|
|
2
2
|
|
|
3
|
-
on: [push]
|
|
3
|
+
on: [push, pull_request]
|
|
4
4
|
|
|
5
5
|
jobs:
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
test:
|
|
8
7
|
runs-on: ubuntu-latest
|
|
9
8
|
|
|
9
|
+
strategy:
|
|
10
|
+
fail-fast: false
|
|
11
|
+
matrix:
|
|
12
|
+
ruby-version: ['3.2', '3.3', '3.4', '4.0']
|
|
13
|
+
|
|
10
14
|
steps:
|
|
11
|
-
- uses: actions/checkout@
|
|
12
|
-
- name: Set up Ruby
|
|
13
|
-
uses:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
- name: Set up Ruby ${{ matrix.ruby-version }}
|
|
17
|
+
uses: ruby/setup-ruby@v1
|
|
14
18
|
with:
|
|
15
|
-
ruby-version:
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
bundle install --jobs 4 --retry 3
|
|
20
|
-
bundle exec rake
|
|
19
|
+
ruby-version: ${{ matrix.ruby-version }}
|
|
20
|
+
bundler-cache: true
|
|
21
|
+
- name: Run tests
|
|
22
|
+
run: bundle exec rake
|
data/CLAUDE.md
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## What is Relationizer
|
|
6
|
+
|
|
7
|
+
Ruby gem that converts `Array<Array>` into SQL relation literals. Two backends:
|
|
8
|
+
- **`Relationizer::BigQuery`** → `SELECT * FROM UNNEST(ARRAY<STRUCT<...>>[...])`
|
|
9
|
+
- **`Relationizer::Postgresql`** → `SELECT "col"::TYPE FROM (VALUES(...)) AS t("col")`
|
|
10
|
+
|
|
11
|
+
Both are modules intended to be `include`d. The public API is `create_relation_literal(schema, tuples)`.
|
|
12
|
+
|
|
13
|
+
## Commands
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
bundle install # Install dependencies
|
|
17
|
+
bundle exec rake # Run all tests (default task)
|
|
18
|
+
bundle exec rake test # Run all tests (explicit)
|
|
19
|
+
bin/console # IRB with gem loaded
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Architecture
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
lib/relationizer.rb # Namespace module, requires submodules
|
|
26
|
+
lib/relationizer/version.rb # VERSION constant
|
|
27
|
+
lib/relationizer/big_query.rb # BigQuery SQL generation (module)
|
|
28
|
+
lib/relationizer/postgresql.rb # PostgreSQL SQL generation (module)
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Each backend module:
|
|
32
|
+
- Infers SQL types from Ruby objects (Integer→INT64/INT8, String→STRING/TEXT, etc.)
|
|
33
|
+
- Supports manual type specification via schema hash values
|
|
34
|
+
- Has custom error classes (`ReasonlessTypeError`, `TypeNotFoundError`)
|
|
35
|
+
- Handles edge cases: NULL, single-column relations (BigQuery adds dummy column), empty tuples, Infinity
|
|
36
|
+
|
|
37
|
+
## Testing
|
|
38
|
+
|
|
39
|
+
- Framework: **test-unit** (~> 3.0.0)
|
|
40
|
+
- Test files: `test/*_test.rb`
|
|
41
|
+
- Helper: `test/to_one_line.rb` — refinement that normalizes multi-line SQL for assertion comparison
|
|
42
|
+
- Tests use `data` method for parameterized test cases
|
|
43
|
+
|
|
44
|
+
## Notes
|
|
45
|
+
|
|
46
|
+
- Zero runtime dependencies (pure Ruby)
|
|
47
|
+
- Column names are quoted (`"col"` for PG, `` `col` `` for BQ)
|
|
48
|
+
- String escaping differs per backend (doubled single quotes for PG, backslash escaping for BQ)
|
data/README.md
CHANGED
|
@@ -1,41 +1,143 @@
|
|
|
1
1
|
# Relationizer
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
TODO: Delete this and the text above, and describe your gem
|
|
3
|
+
A Ruby gem that converts `Array<Array>` into SQL relation literals. Supports BigQuery and PostgreSQL.
|
|
6
4
|
|
|
7
5
|
## Installation
|
|
8
6
|
|
|
9
|
-
Add this line to your application's Gemfile:
|
|
10
|
-
|
|
11
7
|
```ruby
|
|
12
8
|
gem 'relationizer'
|
|
13
9
|
```
|
|
14
10
|
|
|
15
|
-
|
|
11
|
+
```
|
|
12
|
+
$ bundle install
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
`include` the backend module you need and call `create_relation_literal(schema, tuples)`.
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
- `schema` — A Hash of column names to types. Set the value to `nil` to auto-infer the type from the tuples.
|
|
20
|
+
- `tuples` — Row data as `Array<Array>`.
|
|
20
21
|
|
|
21
|
-
|
|
22
|
+
### BigQuery
|
|
22
23
|
|
|
23
|
-
|
|
24
|
+
```ruby
|
|
25
|
+
require 'relationizer/big_query'
|
|
24
26
|
|
|
25
|
-
|
|
27
|
+
class MyQuery
|
|
28
|
+
include Relationizer::BigQuery
|
|
29
|
+
end
|
|
26
30
|
|
|
27
|
-
|
|
31
|
+
q = MyQuery.new
|
|
28
32
|
|
|
29
|
-
|
|
33
|
+
q.create_relation_literal(
|
|
34
|
+
{ id: nil, name: nil },
|
|
35
|
+
[[1, 'hoge'], [2, 'fuga']]
|
|
36
|
+
)
|
|
37
|
+
#=> "SELECT * FROM UNNEST(ARRAY<STRUCT<`id` INT64, `name` STRING>>[(1, 'hoge'), (2, 'fuga')])"
|
|
38
|
+
```
|
|
30
39
|
|
|
31
|
-
|
|
40
|
+
#### Auto type inference
|
|
32
41
|
|
|
33
|
-
|
|
42
|
+
| Ruby type | BigQuery type |
|
|
43
|
+
|-----------------------|---------------|
|
|
44
|
+
| `Integer` | INT64 |
|
|
45
|
+
| `Float` / `BigDecimal` | FLOAT64 |
|
|
46
|
+
| `String` | STRING |
|
|
47
|
+
| `TrueClass` / `FalseClass` | BOOL |
|
|
48
|
+
| `Time` / `DateTime` | TIMESTAMP |
|
|
49
|
+
| `Date` | DATE |
|
|
50
|
+
| `Array` | ARRAY<T> |
|
|
34
51
|
|
|
35
|
-
|
|
52
|
+
#### Manual type specification
|
|
36
53
|
|
|
54
|
+
Pass a Symbol as the schema value to override auto-inference. Useful when a column contains mixed types or when tuples are empty.
|
|
37
55
|
|
|
38
|
-
|
|
56
|
+
```ruby
|
|
57
|
+
# Force ratio column to FLOAT64 (mixed Integer and Float)
|
|
58
|
+
q.create_relation_literal(
|
|
59
|
+
{ id: nil, ratio: :FLOAT64 },
|
|
60
|
+
[[1, 1], [2, 3.14]]
|
|
61
|
+
)
|
|
62
|
+
#=> "SELECT * FROM UNNEST(ARRAY<STRUCT<`id` INT64, `ratio` FLOAT64>>[(1, 1), (2, 3.14)])"
|
|
63
|
+
|
|
64
|
+
# Empty tuples (manual type specification is required)
|
|
65
|
+
q.create_relation_literal(
|
|
66
|
+
{ id: :INT64, name: :STRING },
|
|
67
|
+
[]
|
|
68
|
+
)
|
|
69
|
+
#=> "SELECT * FROM UNNEST(ARRAY<STRUCT<`id` INT64, `name` STRING>>[])"
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
#### Array columns
|
|
73
|
+
|
|
74
|
+
```ruby
|
|
75
|
+
q.create_relation_literal(
|
|
76
|
+
{ id: nil, name: nil, combination: nil },
|
|
77
|
+
[[1, 'hoge', [1, 2, 3]], [2, 'fuga', [4, 5, 6]]]
|
|
78
|
+
)
|
|
79
|
+
#=> "SELECT * FROM UNNEST(ARRAY<STRUCT<`id` INT64, `name` STRING, `combination` ARRAY<INT64>>>[(1, 'hoge', [1, 2, 3]), (2, 'fuga', [4, 5, 6])])"
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
#### Single column
|
|
83
|
+
|
|
84
|
+
BigQuery does not support single-column STRUCTs in UNNEST, so a dummy column is added internally. Only the original column is returned in the SELECT.
|
|
85
|
+
|
|
86
|
+
```ruby
|
|
87
|
+
q.create_relation_literal(
|
|
88
|
+
{ id: nil },
|
|
89
|
+
[[1], [2], [3]]
|
|
90
|
+
)
|
|
91
|
+
#=> "SELECT id FROM UNNEST(ARRAY<STRUCT<`id` INT64, `___dummy` STRING>>[(1, NULL), (2, NULL), (3, NULL)])"
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### PostgreSQL
|
|
95
|
+
|
|
96
|
+
```ruby
|
|
97
|
+
require 'relationizer/postgresql'
|
|
98
|
+
|
|
99
|
+
class MyQuery
|
|
100
|
+
include Relationizer::Postgresql
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
q = MyQuery.new
|
|
104
|
+
|
|
105
|
+
q.create_relation_literal(
|
|
106
|
+
{ id: nil, name: nil },
|
|
107
|
+
[[1, 'hoge'], [2, 'fuga']]
|
|
108
|
+
)
|
|
109
|
+
#=> %Q{SELECT "id"::INT8, "name"::TEXT FROM (VALUES('1', 'hoge'), ('2', 'fuga')) AS t("id", "name")}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
#### Auto type inference
|
|
39
113
|
|
|
40
|
-
|
|
114
|
+
| Ruby type | PostgreSQL type |
|
|
115
|
+
|-----------------------|-----------------|
|
|
116
|
+
| `Integer` | INT8 |
|
|
117
|
+
| `Float` | FLOAT8 |
|
|
118
|
+
| `BigDecimal` | DECIMAL |
|
|
119
|
+
| `String` | TEXT |
|
|
120
|
+
| `TrueClass` / `FalseClass` | BOOLEAN |
|
|
121
|
+
| `Time` / `DateTime` | TIMESTAMPTZ |
|
|
122
|
+
| `Date` | DATE |
|
|
123
|
+
|
|
124
|
+
#### NULL
|
|
125
|
+
|
|
126
|
+
`nil` values are converted to SQL `NULL`.
|
|
127
|
+
|
|
128
|
+
```ruby
|
|
129
|
+
q.create_relation_literal(
|
|
130
|
+
{ id: nil },
|
|
131
|
+
[[1], [nil]]
|
|
132
|
+
)
|
|
133
|
+
#=> %Q{SELECT "id"::INT8 FROM (VALUES('1'), (NULL)) AS t("id")}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Errors
|
|
137
|
+
|
|
138
|
+
- `ReasonlessTypeError` — Raised when types are mixed within a single column (e.g. Integer and String in the same column)
|
|
139
|
+
- `TypeNotFoundError` (BigQuery only) — Raised when tuples are empty and types are not manually specified
|
|
140
|
+
|
|
141
|
+
## License
|
|
41
142
|
|
|
143
|
+
[MIT License](http://opensource.org/licenses/MIT)
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
require 'bigdecimal'
|
|
3
|
+
require 'date'
|
|
4
|
+
|
|
5
|
+
module Relationizer
|
|
6
|
+
module MySQL
|
|
7
|
+
class ReasonlessTypeError < StandardError; end
|
|
8
|
+
class TypeNotFoundError < StandardError; end
|
|
9
|
+
|
|
10
|
+
DEFAULT_TYPES = -> (obj) {
|
|
11
|
+
case obj
|
|
12
|
+
when Integer then :BIGINT
|
|
13
|
+
when BigDecimal then :'DECIMAL(65,30)'
|
|
14
|
+
when Float then :DOUBLE
|
|
15
|
+
when String then :TEXT
|
|
16
|
+
when TrueClass then :BOOLEAN
|
|
17
|
+
when FalseClass then :BOOLEAN
|
|
18
|
+
when Time then :DATETIME
|
|
19
|
+
when DateTime then :DATETIME
|
|
20
|
+
when Date then :DATE
|
|
21
|
+
else
|
|
22
|
+
nil
|
|
23
|
+
end
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
def create_relation_literal(schema, tuples)
|
|
27
|
+
types = fixed_types(schema.values, tuples)
|
|
28
|
+
names = schema.keys
|
|
29
|
+
|
|
30
|
+
json_string = to_json_document(names, types, tuples)
|
|
31
|
+
escaped = escape_for_sql(json_string)
|
|
32
|
+
columns_clause = to_columns_clause(names, types)
|
|
33
|
+
|
|
34
|
+
%[(SELECT * FROM JSON_TABLE('#{escaped}', "$[*]" COLUMNS(#{columns_clause})) AS t)]
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
def fixed_types(schema_values, tuples)
|
|
40
|
+
if tuples.empty?
|
|
41
|
+
raise TypeNotFoundError unless schema_values.all?
|
|
42
|
+
return schema_values
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
tuples.transpose.zip(schema_values).map { |values, type|
|
|
46
|
+
next type if type
|
|
47
|
+
|
|
48
|
+
values.
|
|
49
|
+
map(&DEFAULT_TYPES).compact.uniq.
|
|
50
|
+
tap(&method(:empty_candidate_check)).
|
|
51
|
+
tap(&method(:many_candidate_check)).
|
|
52
|
+
first
|
|
53
|
+
}
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def many_candidate_check(types)
|
|
57
|
+
raise ReasonlessTypeError.new("Many candidate: #{types.join(', ')}") unless types.one?
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def empty_candidate_check(types)
|
|
61
|
+
raise ReasonlessTypeError.new("Candidate nothing") if types.empty?
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def to_json_value(obj, type)
|
|
65
|
+
return nil if obj.nil?
|
|
66
|
+
|
|
67
|
+
case type
|
|
68
|
+
when :'DECIMAL(65,30)'
|
|
69
|
+
obj.is_a?(BigDecimal) ? obj.to_s("F") : obj.to_s
|
|
70
|
+
when :DATE
|
|
71
|
+
obj.strftime('%Y-%m-%d')
|
|
72
|
+
when :DATETIME
|
|
73
|
+
obj.strftime('%Y-%m-%d %H:%M:%S')
|
|
74
|
+
else
|
|
75
|
+
obj
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def to_json_document(names, types, tuples)
|
|
80
|
+
rows = tuples.map { |tuple|
|
|
81
|
+
hash = {}
|
|
82
|
+
names.zip(tuple, types).each do |name, value, type|
|
|
83
|
+
hash[name] = to_json_value(value, type)
|
|
84
|
+
end
|
|
85
|
+
hash
|
|
86
|
+
}
|
|
87
|
+
JSON.generate(rows)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def escape_for_sql(json_string)
|
|
91
|
+
json_string.gsub('\\', '\\\\\\\\').gsub("'", "''")
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def identifier_quote(name)
|
|
95
|
+
"`#{name}`"
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def to_columns_clause(names, types)
|
|
99
|
+
names.zip(types).map { |name, type|
|
|
100
|
+
%[#{identifier_quote(name)} #{type} PATH "$.#{name}"]
|
|
101
|
+
}.join(', ')
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
data/lib/relationizer/version.rb
CHANGED
data/lib/relationizer.rb
CHANGED
data/relationizer.gemspec
CHANGED
|
@@ -18,7 +18,9 @@ Gem::Specification.new do |spec|
|
|
|
18
18
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
19
19
|
spec.require_paths = ["lib"]
|
|
20
20
|
|
|
21
|
+
spec.add_dependency "bigdecimal"
|
|
22
|
+
|
|
21
23
|
spec.add_development_dependency "bundler"
|
|
22
24
|
spec.add_development_dependency "rake", ">= 12.3.3"
|
|
23
|
-
spec.add_development_dependency "test-unit", "~> 3.0
|
|
25
|
+
spec.add_development_dependency "test-unit", "~> 3.0"
|
|
24
26
|
end
|
metadata
CHANGED
|
@@ -1,15 +1,29 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: relationizer
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- yancya
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2026-02-14 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: bigdecimal
|
|
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'
|
|
13
27
|
- !ruby/object:Gem::Dependency
|
|
14
28
|
name: bundler
|
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -44,23 +58,25 @@ dependencies:
|
|
|
44
58
|
requirements:
|
|
45
59
|
- - "~>"
|
|
46
60
|
- !ruby/object:Gem::Version
|
|
47
|
-
version: 3.0
|
|
61
|
+
version: '3.0'
|
|
48
62
|
type: :development
|
|
49
63
|
prerelease: false
|
|
50
64
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
65
|
requirements:
|
|
52
66
|
- - "~>"
|
|
53
67
|
- !ruby/object:Gem::Version
|
|
54
|
-
version: 3.0
|
|
55
|
-
description:
|
|
68
|
+
version: '3.0'
|
|
69
|
+
description:
|
|
56
70
|
email:
|
|
57
71
|
- yancya@upec.jp
|
|
58
72
|
executables: []
|
|
59
73
|
extensions: []
|
|
60
74
|
extra_rdoc_files: []
|
|
61
75
|
files:
|
|
76
|
+
- ".github/workflows/release.yml"
|
|
62
77
|
- ".github/workflows/ruby.yml"
|
|
63
78
|
- ".gitignore"
|
|
79
|
+
- CLAUDE.md
|
|
64
80
|
- Gemfile
|
|
65
81
|
- LICENSE.txt
|
|
66
82
|
- README.md
|
|
@@ -69,6 +85,7 @@ files:
|
|
|
69
85
|
- bin/setup
|
|
70
86
|
- lib/relationizer.rb
|
|
71
87
|
- lib/relationizer/big_query.rb
|
|
88
|
+
- lib/relationizer/mysql.rb
|
|
72
89
|
- lib/relationizer/postgresql.rb
|
|
73
90
|
- lib/relationizer/version.rb
|
|
74
91
|
- relationizer.gemspec
|
|
@@ -76,7 +93,7 @@ homepage: https://github.com/yancya/relationizer
|
|
|
76
93
|
licenses:
|
|
77
94
|
- MIT
|
|
78
95
|
metadata: {}
|
|
79
|
-
post_install_message:
|
|
96
|
+
post_install_message:
|
|
80
97
|
rdoc_options: []
|
|
81
98
|
require_paths:
|
|
82
99
|
- lib
|
|
@@ -91,8 +108,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
91
108
|
- !ruby/object:Gem::Version
|
|
92
109
|
version: '0'
|
|
93
110
|
requirements: []
|
|
94
|
-
rubygems_version: 3.
|
|
95
|
-
signing_key:
|
|
111
|
+
rubygems_version: 3.5.22
|
|
112
|
+
signing_key:
|
|
96
113
|
specification_version: 4
|
|
97
114
|
summary: Array<Array> to Relation ppoi String
|
|
98
115
|
test_files: []
|