conceptql 0.4.0 → 0.4.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 +4 -4
- data/CHANGELOG.md +20 -0
- data/lib/conceptql/query.rb +5 -2
- data/lib/conceptql/rdbms/duckdb.rb +0 -4
- data/lib/conceptql/rdbms/generic.rb +0 -4
- data/lib/conceptql/rdbms/postgres.rb +0 -4
- data/lib/conceptql/rdbms/spark.rb +0 -4
- data/lib/conceptql/utils.rb +0 -43
- data/lib/conceptql/version.rb +1 -1
- metadata +15 -3
- data/lib/conceptql/sql_formatters/formatter.rb +0 -25
- data/lib/conceptql/sql_formatters.rb +0 -22
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1958ad620e733aede026fc74e0c21f06a2376031b514d6a7736ef287eda9afc5
|
|
4
|
+
data.tar.gz: 0ed440d679a23994a83237d54120eabac40bbcd9d9b7499e8cfff18c076aabd8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f42b9ec69eefd01041c9eab5f3aa421aaf8fc63df0933df1e0ab79a9919f4e4da06f48338c96f6af51226fb567ce15f3355116a962dd757d111efd14bdf262da
|
|
7
|
+
data.tar.gz: c50c2a4934b10f457ea25fb317f7844ab98f5816f55ea09aad50f1cb9a24424b567f67abf4ec9585ac677435641db986947b2b78b33f388b4f46a1bdb6f9bcd8
|
data/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,26 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.4.1] - 2026-10-28
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- `Query#sql(:formatted)` formats SQL inside the Ruby process with the new runtime dependency
|
|
12
|
+
sequel-sqlformat (`~> 0.1`), a binding to the Rust `sqlformat` crate. It no longer starts
|
|
13
|
+
sql-formatter, pg_format or sqlformat once per statement. A large algorithm (78 statements)
|
|
14
|
+
now formats in about 0.13 s instead of about 8.3 s. Formatting changes only whitespace and
|
|
15
|
+
keyword case, for Postgres, DuckDB and Spark SQL. sequel-sqlformat ships precompiled gems
|
|
16
|
+
for Linux and macOS, so no Rust toolchain is needed.
|
|
17
|
+
- The development dependency sequel-duckdb is now `~> 0.4.2` (was `~> 0.4.1`). 0.4.2 fixes
|
|
18
|
+
`create_or_replace_view` and drops support for the duckdb gem 1.5.x, which conceptql
|
|
19
|
+
already did not use.
|
|
20
|
+
|
|
21
|
+
### Removed
|
|
22
|
+
|
|
23
|
+
- `ConceptQL::SqlFormatters`, every adapter's `preferred_formatter`, and
|
|
24
|
+
`ConceptQL::Utils.timed_capture`. The external formatter programs are no longer used.
|
|
25
|
+
- The test Docker image no longer installs the `sqlformat` package.
|
|
26
|
+
|
|
7
27
|
## [0.4.0] - 2026-10-26
|
|
8
28
|
|
|
9
29
|
### Added
|
data/lib/conceptql/query.rb
CHANGED
|
@@ -4,7 +4,7 @@ require "json"
|
|
|
4
4
|
require "forwardable"
|
|
5
5
|
require_relative "scope"
|
|
6
6
|
require_relative "nodifier"
|
|
7
|
-
|
|
7
|
+
require "sequel/sqlformat"
|
|
8
8
|
|
|
9
9
|
module ConceptQL
|
|
10
10
|
class Query
|
|
@@ -208,8 +208,11 @@ module ConceptQL
|
|
|
208
208
|
end
|
|
209
209
|
end
|
|
210
210
|
|
|
211
|
+
# Formats inside the Ruby process with the sequel-sqlformat gem (the Rust
|
|
212
|
+
# sqlformat crate). It changes only whitespace and keyword case, and it never
|
|
213
|
+
# fails on unknown syntax, so DuckDB and Spark SQL format too.
|
|
211
214
|
def format(sql)
|
|
212
|
-
|
|
215
|
+
Sequel::SQLFormat.format(sql, dialect: Sequel::SQLFormat.dialect_for(cdb.database_type), indent: 2, uppercase: true)
|
|
213
216
|
end
|
|
214
217
|
end
|
|
215
218
|
end
|
|
@@ -59,10 +59,6 @@ module ConceptQL
|
|
|
59
59
|
end
|
|
60
60
|
end
|
|
61
61
|
|
|
62
|
-
def preferred_formatter
|
|
63
|
-
SqlFormatters::SQL_FORMATTER
|
|
64
|
-
end
|
|
65
|
-
|
|
66
62
|
# Returns from - to in days, NOT to - from, so datediff(later, earlier)
|
|
67
63
|
# is positive. Every adapter keeps this order. This default emits
|
|
68
64
|
# Spark's datediff(endDate, startDate), which returns endDate - startDate,
|
|
@@ -14,10 +14,6 @@ module ConceptQL
|
|
|
14
14
|
db.vacuum_table(table_name, analyze: true) if analyze_temp_tables?
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
-
def preferred_formatter
|
|
18
|
-
SqlFormatters::POSTGRES
|
|
19
|
-
end
|
|
20
|
-
|
|
21
17
|
# DISTINCT ON is Postgres-only. The other adapters inherit
|
|
22
18
|
# Generic#primary_concepts, which uses ROW_NUMBER() instead.
|
|
23
19
|
def primary_concepts(db, all_primary_ids)
|
data/lib/conceptql/utils.rb
CHANGED
|
@@ -4,8 +4,6 @@ require "active_support/core_ext/array/conversions"
|
|
|
4
4
|
require "active_support/core_ext/object/blank"
|
|
5
5
|
require "active_support/core_ext/string/inflections"
|
|
6
6
|
require "json"
|
|
7
|
-
require "open3"
|
|
8
|
-
require "timeout"
|
|
9
7
|
|
|
10
8
|
module ConceptQL
|
|
11
9
|
module Utils
|
|
@@ -31,47 +29,6 @@ module ConceptQL
|
|
|
31
29
|
end
|
|
32
30
|
end
|
|
33
31
|
|
|
34
|
-
def timed_capture(*commands)
|
|
35
|
-
# Heavily adapted from:
|
|
36
|
-
# https://gist.github.com/lpar/1032297#gistcomment-1738285
|
|
37
|
-
opts = extract_opts!(commands)
|
|
38
|
-
timeout = opts.fetch(:timeout)
|
|
39
|
-
|
|
40
|
-
stdin, stdout, stderr, wait_thread = Open3.popen3(*commands)
|
|
41
|
-
wait_thread[:timed_out] = false
|
|
42
|
-
stdin.puts opts[:stdin_data] if opts[:stdin_data]
|
|
43
|
-
stdin.close
|
|
44
|
-
|
|
45
|
-
# Purposefully NOT using Timeout.rb because in general it is a dangerous API!
|
|
46
|
-
# http://blog.headius.com/2008/02/rubys-threadraise-threadkill-timeoutrb.html
|
|
47
|
-
Thread.new do
|
|
48
|
-
sleep timeout
|
|
49
|
-
if wait_thread.alive?
|
|
50
|
-
begin
|
|
51
|
-
wait_thread[:timed_out] = true
|
|
52
|
-
# please note: we are assuming the command will create ONE process (not handling subprocs / proc groups)
|
|
53
|
-
command = "kill -9 #{wait_thread.pid}"
|
|
54
|
-
system(command)
|
|
55
|
-
rescue(Errno::ESRCH)
|
|
56
|
-
# Do nothing!
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
if (es = wait_thread.value.exitstatus) && !es.zero?
|
|
62
|
-
raise stderr.read
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
out = stdout.read
|
|
66
|
-
stdout.close
|
|
67
|
-
|
|
68
|
-
if wait_thread[:timed_out]
|
|
69
|
-
raise Timeout::Error, "Command #{commands} failed to complete after #{timeout} seconds"
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
out
|
|
73
|
-
end
|
|
74
|
-
|
|
75
32
|
def extract_opts!(arr)
|
|
76
33
|
return {} unless arr.last.is_a?(Hash)
|
|
77
34
|
|
data/lib/conceptql/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: conceptql
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.4.
|
|
4
|
+
version: 0.4.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ryan Duryea
|
|
@@ -79,6 +79,20 @@ dependencies:
|
|
|
79
79
|
- - "~>"
|
|
80
80
|
- !ruby/object:Gem::Version
|
|
81
81
|
version: '5.66'
|
|
82
|
+
- !ruby/object:Gem::Dependency
|
|
83
|
+
name: sequel-sqlformat
|
|
84
|
+
requirement: !ruby/object:Gem::Requirement
|
|
85
|
+
requirements:
|
|
86
|
+
- - "~>"
|
|
87
|
+
- !ruby/object:Gem::Version
|
|
88
|
+
version: '0.1'
|
|
89
|
+
type: :runtime
|
|
90
|
+
prerelease: false
|
|
91
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
92
|
+
requirements:
|
|
93
|
+
- - "~>"
|
|
94
|
+
- !ruby/object:Gem::Version
|
|
95
|
+
version: '0.1'
|
|
82
96
|
- !ruby/object:Gem::Dependency
|
|
83
97
|
name: sequelizer
|
|
84
98
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -416,8 +430,6 @@ files:
|
|
|
416
430
|
- lib/conceptql/rdbms/postgres.rb
|
|
417
431
|
- lib/conceptql/rdbms/spark.rb
|
|
418
432
|
- lib/conceptql/scope.rb
|
|
419
|
-
- lib/conceptql/sql_formatters.rb
|
|
420
|
-
- lib/conceptql/sql_formatters/formatter.rb
|
|
421
433
|
- lib/conceptql/utils.rb
|
|
422
434
|
- lib/conceptql/utils_cli.rb
|
|
423
435
|
- lib/conceptql/version.rb
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module ConceptQL
|
|
4
|
-
module SqlFormatters
|
|
5
|
-
# An external SQL formatter, given as a command array that reads SQL on
|
|
6
|
-
# stdin, e.g. Formatter.new(%w[sql-formatter -l postgresql]).
|
|
7
|
-
class Formatter
|
|
8
|
-
attr_reader :command
|
|
9
|
-
|
|
10
|
-
def initialize(command)
|
|
11
|
-
@command = command
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def available?
|
|
15
|
-
system("which", command.first, out: File::NULL, err: File::NULL)
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def format(sql)
|
|
19
|
-
ConceptQL::Utils.timed_capture(*command, stdin_data: sql, timeout: 10)
|
|
20
|
-
rescue Timeout::Error
|
|
21
|
-
sql
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
end
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative "sql_formatters/formatter"
|
|
4
|
-
|
|
5
|
-
module ConceptQL
|
|
6
|
-
module SqlFormatters
|
|
7
|
-
SQL_FORMATTER = %w[sql-formatter].freeze
|
|
8
|
-
POSTGRES = %w[sql-formatter -l postgresql].freeze
|
|
9
|
-
SQLFORMAT = %w[sqlformat --reindent --use_space_around_operators --identifiers lower --keywords upper -].freeze
|
|
10
|
-
PG_FORMAT = %w[pg_format].freeze
|
|
11
|
-
|
|
12
|
-
# Formats with the rdbms's preferred formatter, else the first of the
|
|
13
|
-
# fallbacks that is installed, else returns the SQL untouched.
|
|
14
|
-
def self.format(sql, rdbms)
|
|
15
|
-
formatter = [ rdbms.preferred_formatter, SQL_FORMATTER, SQLFORMAT, PG_FORMAT ]
|
|
16
|
-
.compact
|
|
17
|
-
.map { |command| Formatter.new(command) }
|
|
18
|
-
.detect(&:available?)
|
|
19
|
-
formatter ? formatter.format(sql) : sql
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|