sequelizer 0.1.6 → 0.3.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 +60 -0
- data/LICENSE +21 -0
- data/README.md +28 -14
- data/config/platforms/base.csv +5 -0
- data/config/platforms/rdbms/athena.csv +4 -0
- data/config/platforms/rdbms/postgres.csv +3 -0
- data/config/platforms/rdbms/snowflake.csv +1 -0
- data/config/platforms/rdbms/spark.csv +3 -0
- data/lib/sequel/extensions/cold_col.rb +41 -17
- data/lib/sequel/extensions/funky.rb +136 -0
- data/lib/sequel/extensions/make_readyable.rb +18 -10
- data/lib/sequel/extensions/platform.rb +300 -0
- data/lib/sequel/extensions/smart_select_remove.rb +101 -0
- data/lib/sequelizer/options.rb +15 -6
- data/lib/sequelizer/version.rb +1 -1
- data/lib/sequelizer/yaml_config.rb +0 -1
- metadata +90 -57
- data/.claude/settings.local.json +0 -64
- data/.devcontainer/.p10k.zsh +0 -1713
- data/.devcontainer/.zshrc +0 -29
- data/.devcontainer/Dockerfile +0 -137
- data/.devcontainer/copy-claude-credentials.sh +0 -32
- data/.devcontainer/devcontainer.json +0 -102
- data/.devcontainer/init-firewall.sh +0 -123
- data/.devcontainer/setup-credentials.sh +0 -95
- data/.github/workflows/test.yml +0 -14
- data/.gitignore +0 -40
- data/.overcommit.yml +0 -73
- data/.rubocop.yml +0 -167
- data/CLAUDE.md +0 -219
- data/Gemfile +0 -12
- data/Gemfile.lock +0 -158
- data/Guardfile +0 -28
- data/LICENSE.txt +0 -22
- data/Rakefile +0 -35
- data/examples/database.with_one_set_of_options.yml +0 -15
- data/examples/database.yml +0 -30
- data/examples/dot_env.txt +0 -10
- data/sequelizer.gemspec +0 -35
- data/test/lib/sequel/extensions/test_cold_col.rb +0 -251
- data/test/lib/sequel/extensions/test_db_opts.rb +0 -42
- data/test/lib/sequel/extensions/test_make_readyable.rb +0 -259
- data/test/lib/sequel/extensions/test_more_sql.rb +0 -132
- data/test/lib/sequel/extensions/test_settable.rb +0 -109
- data/test/lib/sequel/extensions/test_sql_recorder.rb +0 -231
- data/test/lib/sequel/extensions/test_unionize.rb +0 -76
- data/test/lib/sequel/extensions/test_usable.rb +0 -15
- data/test/lib/sequelizer/test_connection_maker.rb +0 -123
- data/test/lib/sequelizer/test_env_config.rb +0 -37
- data/test/lib/sequelizer/test_gemfile_modifier.rb +0 -88
- data/test/lib/sequelizer/test_options.rb +0 -83
- data/test/lib/sequelizer/test_yaml_config.rb +0 -83
- data/test/test_helper.rb +0 -44
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 348bea43e8571c35056619a31d45731f55b48a24cb4b93e94f23ecf7eba3a4af
|
|
4
|
+
data.tar.gz: 170ae6de8d06dc7f8030fd97151b1ff7b5666a6d94849a4fe3e056a863938a65
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 497923374b34e892918aa86dea037c0b25323dc8d829398bb0e97d77386c13e248b68d47f4c7c31650d099fdf85d9cf62203703c2576f31310054f9937df9119
|
|
7
|
+
data.tar.gz: f6a8dd133701a962fab9b16a0c0df30a4897d9c08526db07ec7ddef9029eb7140adcfbbab44974be7da2d970f2203308aa419b7112baad046947a50ad4ad93f5
|
data/CHANGELOG.md
CHANGED
|
@@ -2,9 +2,56 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [0.3.0] - 2026-10-01
|
|
6
|
+
|
|
7
|
+
### Breaking changes
|
|
8
|
+
|
|
9
|
+
- Drop support for Ruby 3.2 ([feef6de](https://github.com/outcomesinsights/sequelizer/commit/feef6de5c155dc0dd39642ad1686ff9bab0211de)): sequelizer now requires Ruby >= 3.3.0.
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- Add smart_select_remove Sequel extension ([a1366ec](https://github.com/outcomesinsights/sequelizer/commit/a1366ec8f68e64728b3c794de15c2fd78cfa9e2e))
|
|
14
|
+
- DuckDB support in make_readyable and cold_col extensions ([9433d98](https://github.com/outcomesinsights/sequelizer/commit/9433d982bc0855df11ac6f48a915e861fd78a572))
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- Extract available_tables to fix AbcSize in ReadyMaker#run ([60c6a68](https://github.com/outcomesinsights/sequelizer/commit/60c6a6803afbfde2b0747fd19e3bcd346bf2d1ef))
|
|
19
|
+
- Simplify cold_col find_columns and remove rescue nil guards ([752eab1](https://github.com/outcomesinsights/sequelizer/commit/752eab14595af23974ea56a976dd99e29d9d5552))
|
|
20
|
+
- Remove OptionalAdapterSupport, add sequel-duckdb to bundle ([74d6d16](https://github.com/outcomesinsights/sequelizer/commit/74d6d16f564742138a32e111d7b6107289abec75))
|
|
21
|
+
- Let Sequel handle adapter loading, remove pre-require ([c2b592d](https://github.com/outcomesinsights/sequelizer/commit/c2b592d1965e24370dae2f5cfb515097358cd3da))
|
|
22
|
+
- Ship only runtime files in the gem: lib/, the sequelizer executable, the platform CSVs, and the docs and licence ([1cc49b6](https://github.com/outcomesinsights/sequelizer/commit/1cc49b69dec0c6c879a469f0774c1196c467ed17))
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
|
|
26
|
+
- Fall back to database query in cold_col for unregistered tables ([d07f7c5](https://github.com/outcomesinsights/sequelizer/commit/d07f7c5e482074e631828afbf558a767d6695b66))
|
|
27
|
+
- Replace rescue modifier with explicit begin/rescue in cold_col ([6fced2b](https://github.com/outcomesinsights/sequelizer/commit/6fced2b4957277b5c6d45fabf11e89d0b476a8e5))
|
|
28
|
+
- Handle string SQL in cold_col create_table_as and create_view_sql ([8f30602](https://github.com/outcomesinsights/sequelizer/commit/8f306028857e3838370fc623cd619a9a79c8c06f))
|
|
29
|
+
- Handle Array search_path in after_connect ([c376825](https://github.com/outcomesinsights/sequelizer/commit/c3768251695286668ca49dcbb84aa12c3bbb7f69))
|
|
30
|
+
|
|
31
|
+
## 0.2.0
|
|
32
|
+
|
|
33
|
+
### Added
|
|
34
|
+
|
|
35
|
+
- funky Sequel extension for database-specific function abstraction
|
|
36
|
+
- kvcsv as a runtime dependency
|
|
37
|
+
- Platform configuration fixtures in config/platforms/
|
|
38
|
+
|
|
39
|
+
### Changed
|
|
40
|
+
|
|
41
|
+
- Broadened activesupport dependency from ~> 7.0 to >= 7, < 9
|
|
42
|
+
- Broadened hashie dependency from ~> 3.2 to >= 3.2, < 6.0
|
|
43
|
+
- Broadened dotenv dependency from ~> 2.1 to >= 2.1, < 4.0
|
|
44
|
+
- Bumped sequel from 5.93.0 to 5.101.0
|
|
45
|
+
- Added multi-Ruby CI matrix (3.2, 3.3, 3.4, 4.0) with separate lint job
|
|
46
|
+
|
|
47
|
+
### Fixed
|
|
48
|
+
|
|
49
|
+
- Adapter extraction from URL scheme for search_path processing
|
|
50
|
+
|
|
5
51
|
## 0.1.6
|
|
6
52
|
|
|
7
53
|
### Removed
|
|
54
|
+
|
|
8
55
|
- JDBC adapter support (jdbc_hive2, jdbc_impala, jdbc_postgres) - not needed for foreseeable future
|
|
9
56
|
- Native Impala adapter support - not needed for foreseeable future
|
|
10
57
|
- Kerberos authentication functionality for enterprise databases
|
|
@@ -12,9 +59,11 @@ All notable changes to this project will be documented in this file.
|
|
|
12
59
|
- 16 test methods related to JDBC and Impala adapters
|
|
13
60
|
|
|
14
61
|
### Added
|
|
62
|
+
|
|
15
63
|
- pg gem as development dependency to support PostgreSQL testing
|
|
16
64
|
|
|
17
65
|
### Changed
|
|
66
|
+
|
|
18
67
|
- Simplified ConnectionMaker class by removing adapter-specific configuration methods
|
|
19
68
|
- Improved test coverage from 84.95% to 93.54% by removing unused code paths
|
|
20
69
|
- Updated documentation to reflect focus on standard Sequel adapters
|
|
@@ -28,11 +77,13 @@ All notable changes to this project will be documented in this file.
|
|
|
28
77
|
## [0.1.0] - 2016-11-08
|
|
29
78
|
|
|
30
79
|
### Added
|
|
80
|
+
|
|
31
81
|
- Connections are cached by options to avoid over-allocation
|
|
32
82
|
- URL or URI option represent connection string
|
|
33
83
|
- sequelizer.yml is passed through ERB
|
|
34
84
|
|
|
35
85
|
### Changed
|
|
86
|
+
|
|
36
87
|
- Format of this [CHANGELOG](http://keepachangelog.com/en/0.3.0/)
|
|
37
88
|
- Prefer environment variables over other options
|
|
38
89
|
- Use config/sequelizer.yml instead of config/database.yml
|
|
@@ -40,34 +91,41 @@ All notable changes to this project will be documented in this file.
|
|
|
40
91
|
## [0.0.6] - 2015-08-21
|
|
41
92
|
|
|
42
93
|
### Added
|
|
94
|
+
|
|
43
95
|
- Support for ruby-oci8 (Oracle) in update_gemfile command
|
|
44
96
|
- Read user-level configuration from ~/.config/sequelizer/database.yml
|
|
45
97
|
|
|
46
98
|
### Fixed
|
|
99
|
+
|
|
47
100
|
- Bug where options passed as symbols where sometimes ignored.
|
|
48
101
|
|
|
49
102
|
## [0.0.5] - 2014-08-29
|
|
50
103
|
|
|
51
104
|
### Added
|
|
105
|
+
|
|
52
106
|
- Support for TinyTDS (SQL Server) in update_gemfile command
|
|
53
107
|
|
|
54
108
|
### Fixed
|
|
109
|
+
|
|
55
110
|
- timeout is always converted to integer before passing to Sequel.connect
|
|
56
111
|
|
|
57
112
|
## [0.0.4] - 2014-08-18
|
|
58
113
|
|
|
59
114
|
### Added
|
|
115
|
+
|
|
60
116
|
- `init_env` command to bin/sequelizer
|
|
61
117
|
- Prefer `search_path` over `schema_search_path` option
|
|
62
118
|
|
|
63
119
|
## [0.0.3] - 2014-07-10
|
|
64
120
|
|
|
65
121
|
### Added
|
|
122
|
+
|
|
66
123
|
- Ability to view configuration by running `sequelizer config`
|
|
67
124
|
|
|
68
125
|
## [0.0.2] - 2014-07-10
|
|
69
126
|
|
|
70
127
|
### Added
|
|
128
|
+
|
|
71
129
|
- This [CHANGELOG](http://keepachangelog.com/)
|
|
72
130
|
- Behavior to merge options from all sources (#3)
|
|
73
131
|
- Dependency on hashie gem
|
|
@@ -76,9 +134,11 @@ All notable changes to this project will be documented in this file.
|
|
|
76
134
|
- Reference to issues #1, #3 in README
|
|
77
135
|
|
|
78
136
|
### Fixed
|
|
137
|
+
|
|
79
138
|
- Prevented TestEnvConfig from polluting environment variables
|
|
80
139
|
|
|
81
140
|
## [0.0.1] - 2014-07-10
|
|
82
141
|
|
|
83
142
|
### Added
|
|
143
|
+
|
|
84
144
|
- The project itself
|
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2014-2026 Outcomes Insights, Inc.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
CHANGED
|
@@ -12,35 +12,46 @@ I normally use this gem when I'm writing a quick script or a Thor-based command
|
|
|
12
12
|
|
|
13
13
|
Add this line to your application's Gemfile:
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
```
|
|
16
|
+
gem 'sequelizer'
|
|
17
|
+
```
|
|
16
18
|
|
|
17
19
|
And then execute:
|
|
18
20
|
|
|
19
|
-
|
|
21
|
+
```
|
|
22
|
+
$ bundle
|
|
23
|
+
```
|
|
20
24
|
|
|
21
25
|
Or install it yourself as:
|
|
22
26
|
|
|
23
|
-
|
|
27
|
+
```
|
|
28
|
+
$ gem install sequelizer
|
|
29
|
+
```
|
|
24
30
|
|
|
25
31
|
## Usage
|
|
26
32
|
|
|
27
33
|
To get the most out of Sequelizer, you'll need to create a config/database.yml file or a .env file and specify your database configuration options in that file.
|
|
28
34
|
|
|
29
|
-
Sequelizer comes with a handy command that will print out your connection parameters.
|
|
35
|
+
Sequelizer comes with a handy command that will print out your connection parameters. Just run:
|
|
30
36
|
|
|
31
|
-
|
|
37
|
+
```
|
|
38
|
+
bundle exec sequelizer config
|
|
39
|
+
```
|
|
32
40
|
|
|
33
|
-
You'll also need to make sure the gem for your database is installed.
|
|
41
|
+
You'll also need to make sure the gem for your database is installed. You can do this by adding the gem to your application's Gemfile.
|
|
34
42
|
|
|
35
|
-
Sequelizer comes with a handy command that will update your Gemfile for you.
|
|
43
|
+
Sequelizer comes with a handy command that will update your Gemfile for you. Once you've specified your database configuration, run
|
|
36
44
|
|
|
37
|
-
|
|
45
|
+
```
|
|
46
|
+
bundle exec sequelizer update_gemfile
|
|
47
|
+
```
|
|
38
48
|
|
|
39
49
|
The command will look up the right gem to use with the adapter you've specified, add a line to your Gemfile specifying that gem, and run `bundle install` to install the gem for you.
|
|
40
50
|
|
|
41
51
|
Once you've specified your options and made sure your database's gem is installed, simply include the Sequelizer module in any class that needs a database connection and you'll get two handy-dandy methods: `db` and `new_db`
|
|
42
52
|
|
|
43
53
|
Observe:
|
|
54
|
+
|
|
44
55
|
```ruby
|
|
45
56
|
require 'sequelizer'
|
|
46
57
|
|
|
@@ -59,17 +70,19 @@ end
|
|
|
59
70
|
|
|
60
71
|
`new_db` will create a new connection to the database on each call.
|
|
61
72
|
|
|
62
|
-
Both take a hash of database options if you don't want to create a config/database.yml or .env file, or simply wish to override those options.
|
|
73
|
+
Both take a hash of database options if you don't want to create a config/database.yml or .env file, or simply wish to override those options. Options are merged together from all sources with the following precedence:
|
|
63
74
|
|
|
64
|
-
|
|
75
|
+
```
|
|
76
|
+
passed_options > .env > manually defined environment variables > config/database.yml > ~/.config/sequelizer/database.yml
|
|
77
|
+
```
|
|
65
78
|
|
|
66
|
-
So if config/database.yml specifies a connection, you can set an environment variable (either manually, or through .env) to override one of those options.
|
|
79
|
+
So if config/database.yml specifies a connection, you can set an environment variable (either manually, or through .env) to override one of those options. Similarly, if you pass an option to the method directly, that option will override the YAML and ENV-based options. See #3 for further discussion.
|
|
67
80
|
|
|
68
81
|
Take a look at the examples directory for a few ways you can specify your database configuration options.
|
|
69
82
|
|
|
70
83
|
## Frustrations
|
|
71
84
|
|
|
72
|
-
I can't seem to figure out a way to avoid having to specify the database gem in the a user's bundler file.
|
|
85
|
+
I can't seem to figure out a way to avoid having to specify the database gem in the a user's bundler file. If anyone has ideas on how to automagically load the correct database gem based on the database options fed to Sequelizer, please let me know (#1)!
|
|
73
86
|
|
|
74
87
|
## Contributing
|
|
75
88
|
|
|
@@ -82,9 +95,10 @@ I can't seem to figure out a way to avoid having to specify the database gem in
|
|
|
82
95
|
## Thanks
|
|
83
96
|
|
|
84
97
|
- [Outcomes Insights, Inc.](http://outins.com)
|
|
85
|
-
|
|
98
|
+
- Many thanks for allowing me to release a portion of my work as Open Source Software!
|
|
86
99
|
- Jeremy Evans
|
|
87
|
-
|
|
100
|
+
- For writing Sequel!
|
|
88
101
|
|
|
89
102
|
## License
|
|
103
|
+
|
|
90
104
|
Released under the MIT license, Copyright (c) 2014 Outcomes Insights, Inc.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
key,value
|
|
@@ -88,37 +88,27 @@ module Sequel
|
|
|
88
88
|
end
|
|
89
89
|
|
|
90
90
|
# Find column information for a given table/view name.
|
|
91
|
-
#
|
|
91
|
+
# Searches all registries in priority order:
|
|
92
92
|
# 1. Created views (highest priority - most recent)
|
|
93
93
|
# 2. Created tables (medium priority - session specific)
|
|
94
94
|
# 3. Loaded schemas (lowest priority - external definitions)
|
|
95
95
|
#
|
|
96
|
-
# @param name [String, Symbol
|
|
96
|
+
# @param name [String, Symbol, Sequel::SQL::Identifier, Sequel::SQL::QualifiedIdentifier]
|
|
97
97
|
# @return [Array<Symbol>, nil] array of column names as symbols, or nil if not found
|
|
98
98
|
def find_columns(name)
|
|
99
|
-
table_name = name.to_s
|
|
100
99
|
literal_name = @db.literal(name)
|
|
100
|
+
table_name = name_to_string(name)
|
|
101
101
|
|
|
102
|
-
# Search through registries in priority order
|
|
103
102
|
[@created_views, @created_tables, @schemas].each do |registry|
|
|
104
103
|
next unless registry
|
|
105
104
|
|
|
106
|
-
# Try literal representation first (most common for created tables/views)
|
|
107
105
|
if (columns = Sequel.synchronize { registry[literal_name] })
|
|
108
106
|
return columns.map { |c, _| c }
|
|
109
107
|
end
|
|
110
108
|
|
|
111
|
-
# Try string representation (for manually added schemas)
|
|
112
109
|
if (columns = Sequel.synchronize { registry[table_name] })
|
|
113
110
|
return columns.map { |c, _| c }
|
|
114
111
|
end
|
|
115
|
-
|
|
116
|
-
# Try finding by Sequel::LiteralString key (for test setup compatibility)
|
|
117
|
-
registry.each_key do |key|
|
|
118
|
-
if key.respond_to?(:to_s) && key.to_s == literal_name && (columns = Sequel.synchronize { registry[key] })
|
|
119
|
-
return columns.map { |c, _| c }
|
|
120
|
-
end
|
|
121
|
-
end
|
|
122
112
|
end
|
|
123
113
|
|
|
124
114
|
nil
|
|
@@ -140,6 +130,22 @@ module Sequel
|
|
|
140
130
|
Sequel.synchronize { @schemas = schemas_hash }
|
|
141
131
|
end
|
|
142
132
|
|
|
133
|
+
private
|
|
134
|
+
|
|
135
|
+
# Extract a plain string name from any Sequel name type.
|
|
136
|
+
# Sequel::SQL::Identifier#to_s returns an inspect-like string, not the value,
|
|
137
|
+
# so we must unwrap expression types to get a usable lookup key.
|
|
138
|
+
def name_to_string(name)
|
|
139
|
+
case name
|
|
140
|
+
when Sequel::SQL::QualifiedIdentifier
|
|
141
|
+
"#{name_to_string(name.table)}.#{name_to_string(name.column)}"
|
|
142
|
+
when Sequel::SQL::Identifier
|
|
143
|
+
name.value.to_s
|
|
144
|
+
else
|
|
145
|
+
name.to_s
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
143
149
|
end
|
|
144
150
|
|
|
145
151
|
# Sets up the cold column tracking when the extension is loaded
|
|
@@ -172,7 +178,12 @@ module Sequel
|
|
|
172
178
|
|
|
173
179
|
def create_table_as(name, sql, options = {})
|
|
174
180
|
super.tap do |_|
|
|
175
|
-
|
|
181
|
+
columns = begin
|
|
182
|
+
columns_from_sql(sql)
|
|
183
|
+
rescue StandardError
|
|
184
|
+
nil
|
|
185
|
+
end
|
|
186
|
+
record_table(name, columns) if columns
|
|
176
187
|
end
|
|
177
188
|
end
|
|
178
189
|
|
|
@@ -190,7 +201,12 @@ module Sequel
|
|
|
190
201
|
|
|
191
202
|
def create_view_sql(name, source, options)
|
|
192
203
|
super.tap do |_|
|
|
193
|
-
|
|
204
|
+
columns = begin
|
|
205
|
+
columns_from_sql(source)
|
|
206
|
+
rescue StandardError
|
|
207
|
+
nil
|
|
208
|
+
end
|
|
209
|
+
record_view(name, columns) if columns && !options[:dont_record]
|
|
194
210
|
end
|
|
195
211
|
end
|
|
196
212
|
|
|
@@ -292,7 +308,7 @@ module Sequel
|
|
|
292
308
|
# @param opts_chain [Hash] the dataset's query options
|
|
293
309
|
# @return [Array<Symbol>] array of column names from table.* expressions
|
|
294
310
|
def extract_table_star_columns(cols, opts_chain)
|
|
295
|
-
cols.
|
|
311
|
+
cols.grep(Sequel::SQL::ColumnAll)
|
|
296
312
|
.flat_map { |c| from_named_sources(c.table, opts_chain) }
|
|
297
313
|
end
|
|
298
314
|
|
|
@@ -348,6 +364,14 @@ module Sequel
|
|
|
348
364
|
return columns
|
|
349
365
|
end
|
|
350
366
|
|
|
367
|
+
# Fall back to database query for real tables cold_col doesn't know about
|
|
368
|
+
begin
|
|
369
|
+
columns = db[name].columns!
|
|
370
|
+
return columns if columns && !columns.empty?
|
|
371
|
+
rescue StandardError
|
|
372
|
+
nil
|
|
373
|
+
end
|
|
374
|
+
|
|
351
375
|
raise("Failed to find columns for #{literal(name)}")
|
|
352
376
|
end
|
|
353
377
|
|
|
@@ -359,7 +383,7 @@ module Sequel
|
|
|
359
383
|
# @return [Array<Symbol>, nil] column names if found, nil otherwise
|
|
360
384
|
def find_from_alias(name, opts_chain)
|
|
361
385
|
from = (opts_chain[:from] || [])
|
|
362
|
-
.
|
|
386
|
+
.grep(Sequel::SQL::AliasedExpression)
|
|
363
387
|
.detect { |f| literal(f.alias) == literal(name) }
|
|
364
388
|
|
|
365
389
|
from&.expression&.columns_search(opts_chain)
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
module Sequel
|
|
2
|
+
|
|
3
|
+
module Funky
|
|
4
|
+
|
|
5
|
+
class FunkyBase
|
|
6
|
+
|
|
7
|
+
def initialize(db)
|
|
8
|
+
@db = db
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def to_strptime(format)
|
|
12
|
+
return format if format =~ /%/
|
|
13
|
+
|
|
14
|
+
format.gsub('yyyy', '%Y').gsub('MM', '%m').gsub('dd', '%d')
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def from_strptime(format)
|
|
18
|
+
return format unless format =~ /%/
|
|
19
|
+
|
|
20
|
+
format.gsub('%Y', 'yyyy').gsub('%m', 'MM').gsub('%d', 'dd')
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
class FunkySpark < FunkyBase
|
|
26
|
+
|
|
27
|
+
def str_to_date(value, format, try: false) # rubocop:disable Lint/UnusedMethodArgument
|
|
28
|
+
Sequel.function(:to_date, Sequel.cast_string(value), format)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def hash(*)
|
|
32
|
+
Sequel.function(:xxhash64, *)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def make_json_column(ds, key_column, value_column)
|
|
36
|
+
json_object_col = Sequel.function(
|
|
37
|
+
:named_struct,
|
|
38
|
+
'key',
|
|
39
|
+
key_column,
|
|
40
|
+
'value',
|
|
41
|
+
value_column,
|
|
42
|
+
).then do |json_object_col|
|
|
43
|
+
Sequel.function(
|
|
44
|
+
:collect_list,
|
|
45
|
+
json_object_col,
|
|
46
|
+
)
|
|
47
|
+
end.then do |list_col|
|
|
48
|
+
Sequel.function(
|
|
49
|
+
:map_from_entries,
|
|
50
|
+
list_col,
|
|
51
|
+
)
|
|
52
|
+
end.then do |map_from_entries_col|
|
|
53
|
+
Sequel.function(
|
|
54
|
+
:to_json,
|
|
55
|
+
map_from_entries_col,
|
|
56
|
+
)
|
|
57
|
+
end
|
|
58
|
+
ds.from_self
|
|
59
|
+
.select(json_object_col)
|
|
60
|
+
.limit(1)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def collect_list(column)
|
|
64
|
+
Sequel.function(:collect_list, column)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
class FunkyDuckDB < FunkyBase
|
|
70
|
+
|
|
71
|
+
def str_to_date(value, format, try: false)
|
|
72
|
+
strptime_func = try ? :try_strptime : :strptime
|
|
73
|
+
Sequel.function(strptime_func, Sequel.cast_string(value), to_strptime(format))
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def hash(*)
|
|
77
|
+
Sequel.function(:hash, concat(*)).then do |hash_val|
|
|
78
|
+
Sequel.case(
|
|
79
|
+
{ hash_val <= 9_223_372_036_854_775_807 => hash_val },
|
|
80
|
+
hash_val - 18_446_744_073_709_551_616,
|
|
81
|
+
).cast(:bigint)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def concat(*)
|
|
86
|
+
Sequel.function(:concat, *)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def make_json_column(ds, key_column, value_column)
|
|
90
|
+
json_object_col = Sequel.function(
|
|
91
|
+
:json_object,
|
|
92
|
+
Sequel.cast_string(key_column),
|
|
93
|
+
value_column,
|
|
94
|
+
).then do |json_object_col|
|
|
95
|
+
Sequel.function(
|
|
96
|
+
:list,
|
|
97
|
+
json_object_col,
|
|
98
|
+
)
|
|
99
|
+
end
|
|
100
|
+
ds.from_self
|
|
101
|
+
.select(json_object_col)
|
|
102
|
+
.limit(1)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def collect_list(column)
|
|
106
|
+
Sequel.function(:list, column)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def self.extended(db)
|
|
112
|
+
db.instance_exec do
|
|
113
|
+
@funky = get_funky(db.database_type)
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def funky
|
|
118
|
+
@funky
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def get_funky(database_type)
|
|
122
|
+
case database_type
|
|
123
|
+
when :spark
|
|
124
|
+
FunkySpark.new(self)
|
|
125
|
+
when :duckdb
|
|
126
|
+
FunkyDuckDB.new(self)
|
|
127
|
+
else
|
|
128
|
+
raise "No known functions for #{database_type}"
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
Database.register_extension(:funky, Funky)
|
|
135
|
+
|
|
136
|
+
end
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
require 'pathname'
|
|
2
|
-
|
|
3
1
|
module Sequel
|
|
4
2
|
|
|
5
3
|
# = MakeReadyable
|
|
@@ -89,13 +87,9 @@ module Sequel
|
|
|
89
87
|
only_tables = Array(opts[:only])
|
|
90
88
|
created_views = Array(opts[:except]) || []
|
|
91
89
|
(opts[:search_path] || []).flatten.each do |schema|
|
|
92
|
-
schema = schema.to_sym unless schema.is_a?(Pathname)
|
|
90
|
+
schema = schema.to_sym unless schema.is_a?(Pathname) || schema.is_a?(Sequel::SQL::QualifiedIdentifier)
|
|
93
91
|
source = get_source(db, schema)
|
|
94
|
-
tables =
|
|
95
|
-
source.tables - created_views
|
|
96
|
-
else
|
|
97
|
-
source.tables(schema: schema) - created_views
|
|
98
|
-
end
|
|
92
|
+
tables = available_tables(source, schema, created_views)
|
|
99
93
|
tables &= only_tables unless only_tables.empty?
|
|
100
94
|
tables.each do |table|
|
|
101
95
|
create_view(source, table, schema)
|
|
@@ -104,6 +98,20 @@ module Sequel
|
|
|
104
98
|
end
|
|
105
99
|
end
|
|
106
100
|
|
|
101
|
+
# Returns tables (and views) from the source that haven't already been created.
|
|
102
|
+
#
|
|
103
|
+
# @param source [Sequel::Database, FileSourcerer] the source handler
|
|
104
|
+
# @param schema [Symbol, Pathname] the schema or file path
|
|
105
|
+
# @param created_views [Array<Symbol>] tables/views already created
|
|
106
|
+
# @return [Array<Symbol>] available table names
|
|
107
|
+
def available_tables(source, schema, created_views)
|
|
108
|
+
if schema.is_a?(Pathname)
|
|
109
|
+
source.tables - created_views
|
|
110
|
+
else
|
|
111
|
+
(source.tables(schema: schema) + source.views(schema: schema)) - created_views
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
107
115
|
# Creates a temporary view for the given table.
|
|
108
116
|
#
|
|
109
117
|
# @param source [Object] the source (database or FileSourcerer)
|
|
@@ -112,9 +120,9 @@ module Sequel
|
|
|
112
120
|
def create_view(source, table, schema)
|
|
113
121
|
if schema.to_s =~ %r{/}
|
|
114
122
|
source.create_view(table, temp: true)
|
|
123
|
+
elsif db.database_type == :duckdb
|
|
124
|
+
source.create_or_replace_view(table, db[Sequel.qualify(schema, table)], temp: true)
|
|
115
125
|
else
|
|
116
|
-
# For schema-based tables, just create temporary views
|
|
117
|
-
# This extension is primarily for Spark SQL-based databases
|
|
118
126
|
source.create_view(table, db[Sequel.qualify(schema, table)], temp: true)
|
|
119
127
|
end
|
|
120
128
|
end
|