que-schema 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 7527f5ce44a1b320c5d7614f8967b608ded6a21116ef4821855e49ca22fb1730
4
+ data.tar.gz: ac0e1cd4f0d2384cf5e7344724ad5075d261ce1383a6d63140c8d60071067308
5
+ SHA512:
6
+ metadata.gz: a7c65e8a37a8d36feadac9be7fd2df507898b2711edc379ecbe2a317175569604d18b47e49fdf4e23f82e5f362161ed49f5e12e835321cd70ed38818743ec6a4
7
+ data.tar.gz: af2ffccca2ea04ae3d5ed731085100cedac5c9c709032c7c0a34e6fad606ef0585fad059877add945aa7315da6c04c757dd1fcedf41f2f94a5b60b29aadf9a65
@@ -0,0 +1,15 @@
1
+ name: Release
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ inputs:
6
+ dry_run:
7
+ type: boolean
8
+ default: false
9
+ description: "Test without publishing to RubyGems"
10
+
11
+ jobs:
12
+ release:
13
+ uses: SOFware/reissue/.github/workflows/shared-ruby-gem-release.yml@main
14
+ with:
15
+ dry_run: ${{ inputs.dry_run }}
@@ -0,0 +1,39 @@
1
+ name: Test
2
+
3
+ on:
4
+ push:
5
+ branches: [main, master]
6
+ pull_request:
7
+ branches: [main, master]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+
13
+ services:
14
+ postgres:
15
+ image: postgres:16
16
+ env:
17
+ POSTGRES_USER: postgres
18
+ POSTGRES_PASSWORD: postgres
19
+ ports: ["5432:5432"]
20
+ options: >-
21
+ --health-cmd pg_isready
22
+ --health-interval 10s
23
+ --health-timeout 5s
24
+ --health-retries 5
25
+
26
+ env:
27
+ DATABASE_URL: postgresql://postgres:postgres@localhost:5432/que_schema_test
28
+
29
+ steps:
30
+ - uses: actions/checkout@v4
31
+
32
+ - name: Set up Ruby
33
+ uses: ruby/setup-ruby@v1
34
+ with:
35
+ ruby-version: "4.0"
36
+ bundler-cache: true
37
+
38
+ - name: Run tests
39
+ run: bundle exec rake
data/CHANGELOG.md ADDED
@@ -0,0 +1,9 @@
1
+ # CHANGELOG
2
+
3
+
4
+
5
+ ## [0.1.0] - 2026-03-09
6
+
7
+ ### Added
8
+
9
+ - Schema dump/load support for Que via ActiveRecord integration (0aa34d1)
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gemspec
6
+
7
+ gem "rake", "~> 13.0"
8
+
9
+ gem "pg"
10
+ gem "reissue"
11
+ gem "rspec", "~> 3.0"
12
+ gem "simplecov"
13
+ gem "simplecov_json_formatter"
14
+ gem "standardrb"
data/Gemfile.lock ADDED
@@ -0,0 +1,238 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ que-schema (0.1.0)
5
+ activerecord (>= 6.0)
6
+ que
7
+ railties (>= 6.0)
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ actionpack (8.1.2)
13
+ actionview (= 8.1.2)
14
+ activesupport (= 8.1.2)
15
+ nokogiri (>= 1.8.5)
16
+ rack (>= 2.2.4)
17
+ rack-session (>= 1.0.1)
18
+ rack-test (>= 0.6.3)
19
+ rails-dom-testing (~> 2.2)
20
+ rails-html-sanitizer (~> 1.6)
21
+ useragent (~> 0.16)
22
+ actionview (8.1.2)
23
+ activesupport (= 8.1.2)
24
+ builder (~> 3.1)
25
+ erubi (~> 1.11)
26
+ rails-dom-testing (~> 2.2)
27
+ rails-html-sanitizer (~> 1.6)
28
+ activemodel (8.1.2)
29
+ activesupport (= 8.1.2)
30
+ activerecord (8.1.2)
31
+ activemodel (= 8.1.2)
32
+ activesupport (= 8.1.2)
33
+ timeout (>= 0.4.0)
34
+ activesupport (8.1.2)
35
+ base64
36
+ bigdecimal
37
+ concurrent-ruby (~> 1.0, >= 1.3.1)
38
+ connection_pool (>= 2.2.5)
39
+ drb
40
+ i18n (>= 1.6, < 2)
41
+ json
42
+ logger (>= 1.4.2)
43
+ minitest (>= 5.1)
44
+ securerandom (>= 0.3)
45
+ tzinfo (~> 2.0, >= 2.0.5)
46
+ uri (>= 0.13.1)
47
+ ast (2.4.3)
48
+ base64 (0.3.0)
49
+ bigdecimal (4.0.1)
50
+ builder (3.3.0)
51
+ concurrent-ruby (1.3.6)
52
+ connection_pool (3.0.2)
53
+ crass (1.0.6)
54
+ date (3.5.1)
55
+ diff-lcs (1.6.2)
56
+ docile (1.4.1)
57
+ drb (2.2.3)
58
+ erb (6.0.2)
59
+ erubi (1.13.1)
60
+ i18n (1.14.8)
61
+ concurrent-ruby (~> 1.0)
62
+ io-console (0.8.2)
63
+ irb (1.17.0)
64
+ pp (>= 0.6.0)
65
+ prism (>= 1.3.0)
66
+ rdoc (>= 4.0.0)
67
+ reline (>= 0.4.2)
68
+ json (2.18.1)
69
+ language_server-protocol (3.17.0.5)
70
+ lint_roller (1.1.0)
71
+ logger (1.7.0)
72
+ loofah (2.25.0)
73
+ crass (~> 1.0.2)
74
+ nokogiri (>= 1.12.0)
75
+ minitest (6.0.2)
76
+ drb (~> 2.0)
77
+ prism (~> 1.5)
78
+ nokogiri (1.19.1-aarch64-linux-gnu)
79
+ racc (~> 1.4)
80
+ nokogiri (1.19.1-aarch64-linux-musl)
81
+ racc (~> 1.4)
82
+ nokogiri (1.19.1-arm-linux-gnu)
83
+ racc (~> 1.4)
84
+ nokogiri (1.19.1-arm-linux-musl)
85
+ racc (~> 1.4)
86
+ nokogiri (1.19.1-arm64-darwin)
87
+ racc (~> 1.4)
88
+ nokogiri (1.19.1-x86_64-darwin)
89
+ racc (~> 1.4)
90
+ nokogiri (1.19.1-x86_64-linux-gnu)
91
+ racc (~> 1.4)
92
+ nokogiri (1.19.1-x86_64-linux-musl)
93
+ racc (~> 1.4)
94
+ parallel (1.27.0)
95
+ parser (3.3.10.2)
96
+ ast (~> 2.4.1)
97
+ racc
98
+ pg (1.6.3)
99
+ pg (1.6.3-aarch64-linux)
100
+ pg (1.6.3-aarch64-linux-musl)
101
+ pg (1.6.3-arm64-darwin)
102
+ pg (1.6.3-x86_64-darwin)
103
+ pg (1.6.3-x86_64-linux)
104
+ pg (1.6.3-x86_64-linux-musl)
105
+ pp (0.6.3)
106
+ prettyprint
107
+ prettyprint (0.2.0)
108
+ prism (1.9.0)
109
+ psych (5.3.1)
110
+ date
111
+ stringio
112
+ que (2.4.1)
113
+ racc (1.8.1)
114
+ rack (3.2.5)
115
+ rack-session (2.1.1)
116
+ base64 (>= 0.1.0)
117
+ rack (>= 3.0.0)
118
+ rack-test (2.2.0)
119
+ rack (>= 1.3)
120
+ rackup (2.3.1)
121
+ rack (>= 3)
122
+ rails-dom-testing (2.3.0)
123
+ activesupport (>= 5.0.0)
124
+ minitest
125
+ nokogiri (>= 1.6)
126
+ rails-html-sanitizer (1.7.0)
127
+ loofah (~> 2.25)
128
+ nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
129
+ railties (8.1.2)
130
+ actionpack (= 8.1.2)
131
+ activesupport (= 8.1.2)
132
+ irb (~> 1.13)
133
+ rackup (>= 1.0.0)
134
+ rake (>= 12.2)
135
+ thor (~> 1.0, >= 1.2.2)
136
+ tsort (>= 0.2)
137
+ zeitwerk (~> 2.6)
138
+ rainbow (3.1.1)
139
+ rake (13.3.1)
140
+ rdoc (7.2.0)
141
+ erb
142
+ psych (>= 4.0.0)
143
+ tsort
144
+ regexp_parser (2.11.3)
145
+ reissue (0.4.18)
146
+ rake
147
+ reline (0.6.3)
148
+ io-console (~> 0.5)
149
+ rspec (3.13.2)
150
+ rspec-core (~> 3.13.0)
151
+ rspec-expectations (~> 3.13.0)
152
+ rspec-mocks (~> 3.13.0)
153
+ rspec-core (3.13.6)
154
+ rspec-support (~> 3.13.0)
155
+ rspec-expectations (3.13.5)
156
+ diff-lcs (>= 1.2.0, < 2.0)
157
+ rspec-support (~> 3.13.0)
158
+ rspec-mocks (3.13.8)
159
+ diff-lcs (>= 1.2.0, < 2.0)
160
+ rspec-support (~> 3.13.0)
161
+ rspec-support (3.13.7)
162
+ rubocop (1.84.2)
163
+ json (~> 2.3)
164
+ language_server-protocol (~> 3.17.0.2)
165
+ lint_roller (~> 1.1.0)
166
+ parallel (~> 1.10)
167
+ parser (>= 3.3.0.2)
168
+ rainbow (>= 2.2.2, < 4.0)
169
+ regexp_parser (>= 2.9.3, < 3.0)
170
+ rubocop-ast (>= 1.49.0, < 2.0)
171
+ ruby-progressbar (~> 1.7)
172
+ unicode-display_width (>= 2.4.0, < 4.0)
173
+ rubocop-ast (1.49.0)
174
+ parser (>= 3.3.7.2)
175
+ prism (~> 1.7)
176
+ rubocop-performance (1.26.1)
177
+ lint_roller (~> 1.1)
178
+ rubocop (>= 1.75.0, < 2.0)
179
+ rubocop-ast (>= 1.47.1, < 2.0)
180
+ ruby-progressbar (1.13.0)
181
+ securerandom (0.4.1)
182
+ simplecov (0.22.0)
183
+ docile (~> 1.1)
184
+ simplecov-html (~> 0.11)
185
+ simplecov_json_formatter (~> 0.1)
186
+ simplecov-html (0.13.2)
187
+ simplecov_json_formatter (0.1.4)
188
+ standard (1.54.0)
189
+ language_server-protocol (~> 3.17.0.2)
190
+ lint_roller (~> 1.0)
191
+ rubocop (~> 1.84.0)
192
+ standard-custom (~> 1.0.0)
193
+ standard-performance (~> 1.8)
194
+ standard-custom (1.0.2)
195
+ lint_roller (~> 1.0)
196
+ rubocop (~> 1.50)
197
+ standard-performance (1.9.0)
198
+ lint_roller (~> 1.1)
199
+ rubocop-performance (~> 1.26.0)
200
+ standardrb (1.0.1)
201
+ standard
202
+ stringio (3.2.0)
203
+ thor (1.5.0)
204
+ timeout (0.6.0)
205
+ tsort (0.2.0)
206
+ tzinfo (2.0.6)
207
+ concurrent-ruby (~> 1.0)
208
+ unicode-display_width (3.2.0)
209
+ unicode-emoji (~> 4.1)
210
+ unicode-emoji (4.2.0)
211
+ uri (1.1.1)
212
+ useragent (0.16.11)
213
+ zeitwerk (2.7.5)
214
+
215
+ PLATFORMS
216
+ aarch64-linux
217
+ aarch64-linux-gnu
218
+ aarch64-linux-musl
219
+ arm-linux-gnu
220
+ arm-linux-musl
221
+ arm64-darwin
222
+ x86_64-darwin
223
+ x86_64-linux
224
+ x86_64-linux-gnu
225
+ x86_64-linux-musl
226
+
227
+ DEPENDENCIES
228
+ pg
229
+ que-schema!
230
+ rake (~> 13.0)
231
+ reissue
232
+ rspec (~> 3.0)
233
+ simplecov
234
+ simplecov_json_formatter
235
+ standardrb
236
+
237
+ BUNDLED WITH
238
+ 2.7.2
data/README.md ADDED
@@ -0,0 +1,69 @@
1
+ # que-schema
2
+
3
+ Enables **schema.rb** compatibility for the [que](https://github.com/que-rb/que) job queue gem. With this gem, you can use Rails' default `:ruby` schema format instead of being forced to `structure.sql`.
4
+
5
+ ## Why
6
+
7
+ Que's migrations create PostgreSQL-specific objects (PL/pgSQL functions, triggers, UNLOGGED tables, storage options) that ActiveRecord's schema dumper doesn't represent in `schema.rb` by default. Apps using Que have typically had to set `config.active_record.schema_format = :sql` and maintain `structure.sql`. This gem patches the schema dump/load pipeline so all of Que's constructs round-trip through `schema.rb` with **zero changes** to your existing Que migrations.
8
+
9
+ ## Installation
10
+
11
+ Add to your Gemfile:
12
+
13
+ ```ruby
14
+ gem "que-schema"
15
+ ```
16
+
17
+ No configuration required. Keep using `schema.rb` (the default). If you were on `structure.sql` only for Que, you can switch back to `:ruby` and run `db:schema:dump`; the dump will include Que's schema via custom DSL calls.
18
+
19
+ ## How it works
20
+
21
+ - **Dump:** The gem prepends into `ActiveRecord::SchemaDumper`. When it sees the `que_jobs` table (and reads the Que schema version from the table comment), it emits `que_define_schema(version: N)` after table definitions (tables must exist first because Que's functions reference the `public.que_jobs` type). Any `que_*` table detected as UNLOGGED via `pg_class` is written as `que_create_unlogged_table` instead of `create_table`. GIN indexes on `que_*` tables are detected dynamically and suppressed from the normal table dumps (they are recreated by `que_define_schema`). Fillfactor settings on `que_*` tables are also suppressed.
22
+ - **Load:** `db:schema:load` runs your `schema.rb`. The gem adds `que_define_schema(version:)` and `que_create_unlogged_table` to the schema context. `que_define_schema` runs the stored SQL for that version (functions, triggers, indexes, fillfactor, table comment). `que_create_unlogged_table` is implemented as `create_table` + `ALTER TABLE ... SET UNLOGGED`.
23
+
24
+ No monkey-patching of Que; everything is done by extending ActiveRecord.
25
+
26
+ ## Supported Que versions
27
+
28
+ - **Que migration version 7** is supported (current).
29
+
30
+ Support for older migration versions (e.g. 5, 6) can be added later by adding SQL assets under `lib/que_schema/sql/v5`, etc.
31
+
32
+ ## Requirements
33
+
34
+ - Rails 6.0+
35
+ - PostgreSQL (Que is PostgreSQL-only)
36
+ - Ruby >= 2.7
37
+
38
+ ## Limitations
39
+
40
+ - **PostgreSQL only.** The gem does nothing on SQLite/MySQL; it only runs when the adapter is PostgreSQL.
41
+ - **UNLOGGED table:** `que_lockers` is created as UNLOGGED. If you run `db:schema:load` against a non-PostgreSQL database, that call would fail (expected).
42
+
43
+ ## Development
44
+
45
+ ### Tests
46
+
47
+ Uses RSpec. Requires a running PostgreSQL. The test database (`que_schema_test`) is created automatically if it doesn't exist.
48
+
49
+ ```bash
50
+ bundle install
51
+ bundle exec rake
52
+ ```
53
+
54
+ You can set `DATABASE_URL` to point to a different PostgreSQL instance:
55
+
56
+ ```bash
57
+ export DATABASE_URL=postgresql://user:pass@host:5432/que_schema_test
58
+ bundle exec rake
59
+ ```
60
+
61
+ ### Adding support for a new Que migration version
62
+
63
+ 1. Add a directory `lib/que_schema/sql/v<N>/` with `functions.sql`, `triggers.sql`, and optionally `down.sql`.
64
+ 2. Copy the exact `CREATE FUNCTION` / `CREATE TRIGGER` SQL from [que-rb/que](https://github.com/que-rb/que) for that version; use `CREATE OR REPLACE` and `DROP TRIGGER IF EXISTS` for idempotency.
65
+ 3. Extend the schema dumper version detection if the new version uses a different table comment or detection method.
66
+
67
+ ## License
68
+
69
+ MIT.
data/Rakefile ADDED
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+ require "reissue/gem"
6
+
7
+ RSpec::Core::RakeTask.new(:spec)
8
+
9
+ Reissue::Task.create :reissue do |task|
10
+ task.version_file = "lib/que_schema/version.rb"
11
+ task.fragment = :git
12
+ task.push_finalize = :branch
13
+ end
14
+
15
+ task default: :spec
@@ -0,0 +1 @@
1
+ aae14df55017ee2128437cd923ce6c9cc34f56b8b53cb77a362750c7271ad172492a1df977b92397d669907a105f8650d2ed55aceb4cb0a05343dd13ec73327c
data/lib/que-schema.rb ADDED
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "que_schema/version"
4
+ require "que_schema/schema_statements"
5
+ require "que_schema/schema_dumper"
6
+ require "que_schema/migration_helpers"
7
+ require "que_schema/railtie" if defined?(Rails)
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "que"
4
+
5
+ module QueSchema
6
+ # Convenience methods for migrations when setting up Que via ActiveRecord.
7
+ module MigrationHelpers
8
+ # Creates the Que schema for the given version.
9
+ # Delegates to Que.migrate! which handles everything.
10
+ def create_que_schema(version:)
11
+ que_define_schema(version: version)
12
+ end
13
+
14
+ # Drops the entire Que schema by migrating down to version 0.
15
+ # Removes all Que tables, functions, and triggers.
16
+ def drop_que_schema
17
+ return unless connection.adapter_name.match?(/postgresql/i)
18
+
19
+ Que.connection_proc = proc { |&block| block.call(connection.raw_connection) }
20
+ Que.migrate!(version: 0)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module QueSchema
4
+ class Railtie < ::Rails::Railtie
5
+ config.before_initialize do
6
+ ActiveSupport.on_load(:active_record) do
7
+ ActiveRecord::Migration.include(QueSchema::SchemaStatements)
8
+ ActiveRecord::Migration.include(QueSchema::MigrationHelpers)
9
+ ActiveRecord::Schema.include(QueSchema::SchemaStatements)
10
+ ActiveRecord::SchemaDumper.prepend(QueSchema::SchemaDumper)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module QueSchema
4
+ # Prepended into ActiveRecord::SchemaDumper to emit que_define_schema
5
+ # and suppress Que-managed tables (Que.migrate! recreates them on load).
6
+ module SchemaDumper
7
+ private
8
+
9
+ def tables(stream)
10
+ super
11
+
12
+ if postgresql? && (version = que_schema_version) && version > 0
13
+ stream.puts " # Que internal schema — emitted by que-schema gem"
14
+ stream.puts " que_define_schema(version: #{version})"
15
+ stream.puts
16
+ end
17
+ end
18
+
19
+ # Suppress all que_* tables — Que.migrate! creates them during schema load.
20
+ def table(table_name, stream)
21
+ return if postgresql? && que_table?(table_name)
22
+
23
+ super
24
+ end
25
+
26
+ def que_schema_version
27
+ return nil unless @connection.table_exists?("que_jobs")
28
+
29
+ result = @connection.execute(<<~SQL)
30
+ SELECT obj_description(c.oid, 'pg_class') AS comment
31
+ FROM pg_class c
32
+ WHERE c.relname = 'que_jobs'
33
+ AND c.relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'public')
34
+ SQL
35
+ raw = result.first&.[]("comment") || result.first&.[](:comment)
36
+ raw.to_s.strip.to_i
37
+ end
38
+
39
+ def postgresql?
40
+ @connection.respond_to?(:adapter_name) && @connection.adapter_name.match?(/postgresql/i)
41
+ end
42
+
43
+ def que_table?(table_name)
44
+ table_name.start_with?("que_")
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "que"
4
+
5
+ module QueSchema
6
+ # DSL methods for schema.rb: available in ActiveRecord::Schema and ActiveRecord::Migration
7
+ # so that db:schema:load can execute que_define_schema.
8
+ module SchemaStatements
9
+ # Recreates the full Que schema for the given version by delegating to
10
+ # Que.migrate!. This creates tables, functions, triggers, indexes, and
11
+ # all other database objects that Que needs.
12
+ def que_define_schema(version:)
13
+ return unless postgresql?
14
+
15
+ Que.connection_proc = proc { |&block| block.call(connection.raw_connection) }
16
+ Que.migrate!(version: version.to_i)
17
+ end
18
+
19
+ private
20
+
21
+ def postgresql?
22
+ return false unless respond_to?(:connection)
23
+
24
+ conn = connection
25
+ conn.respond_to?(:adapter_name) && conn.adapter_name.match?(/postgresql/i)
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module QueSchema
4
+ VERSION = "0.1.0"
5
+ end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+ require "stringio"
5
+
6
+ RSpec.describe "QueSchema integration (round-trip)" do
7
+ let(:conn) { QueSchema::Spec.connection }
8
+ let(:pool) { ActiveRecord::Base.connection_pool }
9
+
10
+ after do
11
+ QueSchema::Spec.clean!
12
+ end
13
+
14
+ it "full round-trip: create schema -> dump -> drop -> load -> verify" do
15
+ # Create schema via que_define_schema (which delegates to Que.migrate!)
16
+ c = conn
17
+ schema_context = Object.new.extend(QueSchema::SchemaStatements)
18
+ schema_context.define_singleton_method(:connection) { c }
19
+ schema_context.que_define_schema(version: 7)
20
+
21
+ # Dump schema
22
+ stream = StringIO.new
23
+ ActiveRecord::SchemaDumper.dump(pool, stream)
24
+ schema_rb = stream.string
25
+
26
+ expect(schema_rb).to include("que_define_schema(version: 7)")
27
+ expect(schema_rb).not_to match(/create_table "que_jobs"/)
28
+ expect(schema_rb).not_to match(/create_table "que_lockers"/)
29
+ expect(schema_rb).not_to match(/create_table "que_values"/)
30
+
31
+ # Drop everything
32
+ QueSchema::Spec.clean!
33
+ expect(conn.table_exists?(:que_jobs)).to be false
34
+
35
+ # Load schema (eval the dumped schema)
36
+ eval(schema_rb) # rubocop:disable Security/Eval
37
+
38
+ # Verify tables were recreated by Que.migrate!
39
+ expect(conn.table_exists?(:que_jobs)).to be true
40
+ expect(conn.table_exists?(:que_values)).to be true
41
+ expect(conn.table_exists?(:que_lockers)).to be true
42
+
43
+ # Verify functions were recreated
44
+ r = conn.execute(<<~SQL)
45
+ SELECT proname FROM pg_proc
46
+ WHERE proname IN ('que_validate_tags', 'que_job_notify', 'que_determine_job_state', 'que_state_notify')
47
+ SQL
48
+ names = r.map { |row| row["proname"] || row[:proname] }
49
+ expect(names).to contain_exactly("que_validate_tags", "que_job_notify", "que_determine_job_state", "que_state_notify")
50
+
51
+ # Verify triggers were recreated
52
+ r = conn.execute(<<~SQL)
53
+ SELECT tgname FROM pg_trigger
54
+ WHERE tgrelid = 'que_jobs'::regclass
55
+ AND tgname IN ('que_job_notify', 'que_state_notify')
56
+ SQL
57
+ trigger_names = r.map { |row| row["tgname"] || row[:tgname] }
58
+ expect(trigger_names).to contain_exactly("que_job_notify", "que_state_notify")
59
+
60
+ # Verify que_lockers is UNLOGGED
61
+ r = conn.execute("SELECT relpersistence FROM pg_class WHERE relname = 'que_lockers'")
62
+ expect(r.first["relpersistence"] || r.first[:relpersistence]).to eq("u")
63
+
64
+ # Verify table comment (schema version)
65
+ r = conn.execute(<<~SQL)
66
+ SELECT obj_description(c.oid, 'pg_class') AS comment
67
+ FROM pg_class c
68
+ WHERE c.relname = 'que_jobs'
69
+ SQL
70
+ expect(r.first["comment"] || r.first[:comment]).to eq("7")
71
+
72
+ # Verify a job can be inserted
73
+ conn.execute("INSERT INTO que_jobs (queue, priority, job_class, args, data, job_schema_version) VALUES ('default', 100, 'TestJob', '[]', '{}', 7)")
74
+ count = conn.execute("SELECT count(*) AS cnt FROM que_jobs")
75
+ expect((count.first["cnt"] || count.first[:cnt]).to_i).to eq(1)
76
+ end
77
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ RSpec.describe QueSchema::MigrationHelpers do
6
+ let(:test_class) do
7
+ Class.new do
8
+ include QueSchema::SchemaStatements
9
+ include QueSchema::MigrationHelpers
10
+
11
+ attr_accessor :connection
12
+ end
13
+ end
14
+
15
+ let(:connection) { QueSchema::Spec.connection }
16
+ let(:instance) { test_class.new.tap { |i| i.connection = connection } }
17
+
18
+ after do
19
+ QueSchema::Spec.clean!
20
+ end
21
+
22
+ describe "#create_que_schema" do
23
+ it "delegates to que_define_schema" do
24
+ expect(instance).to receive(:que_define_schema).with(version: 7)
25
+ instance.create_que_schema(version: 7)
26
+ end
27
+
28
+ it "creates the full Que schema" do
29
+ instance.create_que_schema(version: 7)
30
+ expect(connection.table_exists?(:que_jobs)).to be true
31
+ end
32
+ end
33
+
34
+ describe "#drop_que_schema" do
35
+ it "removes all Que tables, functions, and triggers" do
36
+ instance.create_que_schema(version: 7)
37
+ expect(connection.table_exists?(:que_jobs)).to be true
38
+
39
+ instance.drop_que_schema
40
+ expect(connection.table_exists?(:que_jobs)).to be false
41
+ expect(connection.table_exists?(:que_values)).to be false
42
+ expect(connection.table_exists?(:que_lockers)).to be false
43
+ end
44
+
45
+ context "when not PostgreSQL" do
46
+ let(:connection) { double("connection", adapter_name: "SQLite") }
47
+
48
+ it "does nothing" do
49
+ expect(connection).not_to receive(:execute)
50
+ instance.drop_que_schema
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ RSpec.describe QueSchema do
6
+ it "has a version number" do
7
+ expect(QueSchema::VERSION).to be_a(String)
8
+ expect(QueSchema::VERSION).not_to be_empty
9
+ end
10
+
11
+ it "defines SchemaStatements module" do
12
+ expect(QueSchema::SchemaStatements).to be_a(Module)
13
+ end
14
+
15
+ it "defines SchemaDumper module" do
16
+ expect(QueSchema::SchemaDumper).to be_a(Module)
17
+ end
18
+
19
+ it "defines MigrationHelpers module" do
20
+ expect(QueSchema::MigrationHelpers).to be_a(Module)
21
+ end
22
+
23
+ it "includes SchemaStatements in ActiveRecord::Migration" do
24
+ expect(ActiveRecord::Migration.ancestors).to include(QueSchema::SchemaStatements)
25
+ end
26
+
27
+ it "includes MigrationHelpers in ActiveRecord::Migration" do
28
+ expect(ActiveRecord::Migration.ancestors).to include(QueSchema::MigrationHelpers)
29
+ end
30
+
31
+ it "includes SchemaStatements in ActiveRecord::Schema" do
32
+ expect(ActiveRecord::Schema.ancestors).to include(QueSchema::SchemaStatements)
33
+ end
34
+
35
+ it "prepends SchemaDumper into ActiveRecord::SchemaDumper" do
36
+ expect(ActiveRecord::SchemaDumper.ancestors).to include(QueSchema::SchemaDumper)
37
+ end
38
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ if defined?(Rails)
6
+ RSpec.describe QueSchema::Railtie do
7
+ it "is defined as a Rails::Railtie subclass" do
8
+ # We can't fully test Railtie without Rails, but we can verify the class
9
+ # is loadable and structured correctly when Rails is defined.
10
+ expect(QueSchema::Railtie).to be < Rails::Railtie
11
+ end
12
+ end
13
+ end
14
+
15
+ # When Rails is not defined, just verify the file doesn't blow up
16
+ RSpec.describe "QueSchema without Rails" do
17
+ it "does not load Railtie when Rails is not defined" do
18
+ # que-schema.rb guards: require "que_schema/railtie" if defined?(Rails)
19
+ # Since we're not in a Rails app, Railtie may or may not be loaded
20
+ # depending on test ordering, but the gem should work without Rails
21
+ expect(defined?(QueSchema)).to eq("constant")
22
+ end
23
+ end
@@ -0,0 +1,212 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+ require "stringio"
5
+
6
+ RSpec.describe QueSchema::SchemaDumper do
7
+ let(:connection) { double("connection") }
8
+
9
+ let(:dumper_class) do
10
+ mod = described_class
11
+ Class.new do
12
+ prepend mod
13
+
14
+ attr_accessor :connection
15
+
16
+ def initialize(connection)
17
+ @connection = connection
18
+ end
19
+
20
+ def tables(stream)
21
+ stream.puts " # original tables output"
22
+ end
23
+
24
+ def table(table_name, stream)
25
+ stream.puts " create_table \"#{table_name}\", force: :cascade do |t|"
26
+ stream.puts " end"
27
+ end
28
+
29
+ private :tables, :table
30
+ end
31
+ end
32
+
33
+ let(:dumper) { dumper_class.new(connection) }
34
+
35
+ def stub_postgresql!
36
+ allow(connection).to receive(:adapter_name).and_return("PostgreSQL")
37
+ allow(connection).to receive(:respond_to?).with(:adapter_name).and_return(true)
38
+ end
39
+
40
+ describe "#tables" do
41
+ context "when PostgreSQL with que_jobs" do
42
+ before do
43
+ stub_postgresql!
44
+ allow(connection).to receive(:table_exists?).with("que_jobs").and_return(true)
45
+ allow(connection).to receive(:execute).and_return([{"comment" => "7"}])
46
+ end
47
+
48
+ it "emits que_define_schema after tables" do
49
+ stream = StringIO.new
50
+ dumper.send(:tables, stream)
51
+ output = stream.string
52
+
53
+ expect(output).to include("que_define_schema(version: 7)")
54
+ expect(output).to include("# original tables output")
55
+ expect(output.index("que_define_schema")).to be > output.index("original tables")
56
+ end
57
+ end
58
+
59
+ context "when PostgreSQL without que_jobs" do
60
+ before do
61
+ stub_postgresql!
62
+ allow(connection).to receive(:table_exists?).with("que_jobs").and_return(false)
63
+ end
64
+
65
+ it "does not emit que_define_schema" do
66
+ stream = StringIO.new
67
+ dumper.send(:tables, stream)
68
+ expect(stream.string).not_to include("que_define_schema")
69
+ end
70
+ end
71
+
72
+ context "when not PostgreSQL" do
73
+ before do
74
+ allow(connection).to receive(:adapter_name).and_return("SQLite")
75
+ allow(connection).to receive(:respond_to?).with(:adapter_name).and_return(true)
76
+ end
77
+
78
+ it "does not emit que_define_schema" do
79
+ stream = StringIO.new
80
+ dumper.send(:tables, stream)
81
+ expect(stream.string).not_to include("que_define_schema")
82
+ end
83
+ end
84
+
85
+ context "when comment is nil" do
86
+ before do
87
+ stub_postgresql!
88
+ allow(connection).to receive(:table_exists?).with("que_jobs").and_return(true)
89
+ allow(connection).to receive(:execute).and_return([{"comment" => nil}])
90
+ end
91
+
92
+ it "does not emit que_define_schema when version is 0" do
93
+ stream = StringIO.new
94
+ dumper.send(:tables, stream)
95
+ expect(stream.string).not_to include("que_define_schema")
96
+ end
97
+ end
98
+ end
99
+
100
+ describe "#table" do
101
+ context "when PostgreSQL" do
102
+ before { stub_postgresql! }
103
+
104
+ it "suppresses que_* tables" do
105
+ stream = StringIO.new
106
+ dumper.send(:table, "que_jobs", stream)
107
+ expect(stream.string).to be_empty
108
+ end
109
+
110
+ it "suppresses que_lockers" do
111
+ stream = StringIO.new
112
+ dumper.send(:table, "que_lockers", stream)
113
+ expect(stream.string).to be_empty
114
+ end
115
+
116
+ it "suppresses que_values" do
117
+ stream = StringIO.new
118
+ dumper.send(:table, "que_values", stream)
119
+ expect(stream.string).to be_empty
120
+ end
121
+
122
+ it "suppresses any future que_* table" do
123
+ stream = StringIO.new
124
+ dumper.send(:table, "que_something_new", stream)
125
+ expect(stream.string).to be_empty
126
+ end
127
+
128
+ it "does not suppress non-que tables" do
129
+ stream = StringIO.new
130
+ dumper.send(:table, "users", stream)
131
+ expect(stream.string).to include('create_table "users"')
132
+ end
133
+ end
134
+
135
+ context "when not PostgreSQL" do
136
+ before do
137
+ allow(connection).to receive(:adapter_name).and_return("SQLite")
138
+ allow(connection).to receive(:respond_to?).with(:adapter_name).and_return(true)
139
+ end
140
+
141
+ it "does not suppress que_* tables" do
142
+ stream = StringIO.new
143
+ dumper.send(:table, "que_jobs", stream)
144
+ expect(stream.string).to include('create_table "que_jobs"')
145
+ end
146
+ end
147
+ end
148
+
149
+ describe "#que_table? (private)" do
150
+ it "returns true for que_ prefixed tables" do
151
+ expect(dumper.send(:que_table?, "que_jobs")).to be true
152
+ expect(dumper.send(:que_table?, "que_lockers")).to be true
153
+ expect(dumper.send(:que_table?, "que_values")).to be true
154
+ expect(dumper.send(:que_table?, "que_new_future_table")).to be true
155
+ end
156
+
157
+ it "returns false for non-que tables" do
158
+ expect(dumper.send(:que_table?, "users")).to be false
159
+ expect(dumper.send(:que_table?, "queue_items")).to be false
160
+ end
161
+ end
162
+
163
+ describe "#que_schema_version (private)" do
164
+ it "returns the version from the table comment" do
165
+ allow(connection).to receive(:table_exists?).with("que_jobs").and_return(true)
166
+ allow(connection).to receive(:execute).and_return([{"comment" => "7"}])
167
+ expect(dumper.send(:que_schema_version)).to eq(7)
168
+ end
169
+
170
+ it "returns nil when que_jobs does not exist" do
171
+ allow(connection).to receive(:table_exists?).with("que_jobs").and_return(false)
172
+ expect(dumper.send(:que_schema_version)).to be_nil
173
+ end
174
+
175
+ it "returns 0 when comment is nil" do
176
+ allow(connection).to receive(:table_exists?).with("que_jobs").and_return(true)
177
+ allow(connection).to receive(:execute).and_return([{"comment" => nil}])
178
+ expect(dumper.send(:que_schema_version)).to eq(0)
179
+ end
180
+
181
+ it "returns 0 when no rows returned" do
182
+ allow(connection).to receive(:table_exists?).with("que_jobs").and_return(true)
183
+ allow(connection).to receive(:execute).and_return([])
184
+ expect(dumper.send(:que_schema_version)).to eq(0)
185
+ end
186
+
187
+ it "handles symbol key for comment" do
188
+ allow(connection).to receive(:table_exists?).with("que_jobs").and_return(true)
189
+ allow(connection).to receive(:execute).and_return([{comment: "7"}])
190
+ expect(dumper.send(:que_schema_version)).to eq(7)
191
+ end
192
+ end
193
+
194
+ describe "#postgresql? (private)" do
195
+ it "returns true for PostgreSQL" do
196
+ allow(connection).to receive(:respond_to?).with(:adapter_name).and_return(true)
197
+ allow(connection).to receive(:adapter_name).and_return("PostgreSQL")
198
+ expect(dumper.send(:postgresql?)).to be true
199
+ end
200
+
201
+ it "returns false for non-PostgreSQL" do
202
+ allow(connection).to receive(:respond_to?).with(:adapter_name).and_return(true)
203
+ allow(connection).to receive(:adapter_name).and_return("SQLite")
204
+ expect(dumper.send(:postgresql?)).to be false
205
+ end
206
+
207
+ it "returns false when adapter_name is not available" do
208
+ allow(connection).to receive(:respond_to?).with(:adapter_name).and_return(false)
209
+ expect(dumper.send(:postgresql?)).to be false
210
+ end
211
+ end
212
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ RSpec.describe "QueSchema schema load" do
6
+ let(:conn) { QueSchema::Spec.connection }
7
+
8
+ after do
9
+ QueSchema::Spec.clean!
10
+ end
11
+
12
+ it "que_define_schema(version: 7) creates the full Que schema" do
13
+ c = conn
14
+ schema_context = Object.new
15
+ schema_context.extend(QueSchema::SchemaStatements)
16
+ schema_context.define_singleton_method(:connection) { c }
17
+ schema_context.que_define_schema(version: 7)
18
+
19
+ # Tables
20
+ expect(conn.table_exists?(:que_jobs)).to be true
21
+ expect(conn.table_exists?(:que_values)).to be true
22
+ expect(conn.table_exists?(:que_lockers)).to be true
23
+
24
+ # Functions
25
+ r = conn.execute(<<~SQL)
26
+ SELECT proname FROM pg_proc WHERE proname IN ('que_validate_tags', 'que_job_notify', 'que_determine_job_state', 'que_state_notify')
27
+ SQL
28
+ names = r.map { |row| row["proname"] || row[:proname] }
29
+ expect(names).to contain_exactly("que_validate_tags", "que_job_notify", "que_determine_job_state", "que_state_notify")
30
+
31
+ # Triggers
32
+ r = conn.execute("SELECT tgname FROM pg_trigger WHERE tgrelid = 'que_jobs'::regclass AND tgname IN ('que_job_notify', 'que_state_notify')")
33
+ names = r.map { |row| row["tgname"] || row[:tgname] }
34
+ expect(names).to contain_exactly("que_job_notify", "que_state_notify")
35
+ end
36
+
37
+ it "que_define_schema creates que_lockers as UNLOGGED" do
38
+ c = conn
39
+ schema_context = Object.new.extend(QueSchema::SchemaStatements)
40
+ schema_context.define_singleton_method(:connection) { c }
41
+ schema_context.que_define_schema(version: 7)
42
+
43
+ r = conn.execute("SELECT relpersistence FROM pg_class WHERE relname = 'que_lockers'")
44
+ expect(r.first["relpersistence"] || r.first[:relpersistence]).to eq("u")
45
+ end
46
+ end
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ RSpec.describe QueSchema::SchemaStatements do
6
+ let(:test_class) do
7
+ Class.new do
8
+ include QueSchema::SchemaStatements
9
+
10
+ attr_accessor :connection
11
+ end
12
+ end
13
+
14
+ let(:connection) { QueSchema::Spec.connection }
15
+ let(:instance) { test_class.new.tap { |i| i.connection = connection } }
16
+
17
+ after do
18
+ QueSchema::Spec.clean!
19
+ end
20
+
21
+ describe "#que_define_schema" do
22
+ context "when not PostgreSQL" do
23
+ let(:connection) { double("connection", adapter_name: "SQLite") }
24
+
25
+ it "returns nil without executing SQL" do
26
+ expect(connection).not_to receive(:execute)
27
+ result = instance.que_define_schema(version: 7)
28
+ expect(result).to be_nil
29
+ end
30
+ end
31
+
32
+ context "when PostgreSQL" do
33
+ it "creates all Que tables, functions, and triggers for version 7" do
34
+ instance.que_define_schema(version: 7)
35
+
36
+ expect(connection.table_exists?(:que_jobs)).to be true
37
+ expect(connection.table_exists?(:que_values)).to be true
38
+ expect(connection.table_exists?(:que_lockers)).to be true
39
+
40
+ r = connection.execute("SELECT proname FROM pg_proc WHERE proname IN ('que_validate_tags', 'que_job_notify', 'que_determine_job_state', 'que_state_notify')")
41
+ names = r.map { |row| row["proname"] || row[:proname] }
42
+ expect(names).to contain_exactly("que_validate_tags", "que_job_notify", "que_determine_job_state", "que_state_notify")
43
+ end
44
+
45
+ it "creates que_lockers as UNLOGGED" do
46
+ instance.que_define_schema(version: 7)
47
+
48
+ r = connection.execute("SELECT relpersistence FROM pg_class WHERE relname = 'que_lockers'")
49
+ expect(r.first["relpersistence"] || r.first[:relpersistence]).to eq("u")
50
+ end
51
+
52
+ it "creates triggers on que_jobs" do
53
+ instance.que_define_schema(version: 7)
54
+
55
+ r = connection.execute("SELECT tgname FROM pg_trigger WHERE tgrelid = 'que_jobs'::regclass AND tgname IN ('que_job_notify', 'que_state_notify')")
56
+ names = r.map { |row| row["tgname"] || row[:tgname] }
57
+ expect(names).to contain_exactly("que_job_notify", "que_state_notify")
58
+ end
59
+
60
+ it "is idempotent" do
61
+ instance.que_define_schema(version: 7)
62
+ expect { instance.que_define_schema(version: 7) }.not_to raise_error
63
+ end
64
+ end
65
+ end
66
+
67
+ describe "#postgresql? (private)" do
68
+ it "returns false when no connection method exists" do
69
+ obj = Object.new
70
+ obj.extend(QueSchema::SchemaStatements)
71
+ expect(obj.send(:postgresql?)).to be false
72
+ end
73
+
74
+ it "returns false for non-PostgreSQL adapters" do
75
+ fake_conn = double("connection", adapter_name: "Mysql2")
76
+ allow(fake_conn).to receive(:respond_to?).with(:adapter_name).and_return(true)
77
+ inst = test_class.new.tap { |i| i.connection = fake_conn }
78
+ expect(inst.send(:postgresql?)).to be false
79
+ end
80
+
81
+ it "returns true for PostgreSQL adapter" do
82
+ expect(instance.send(:postgresql?)).to be true
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "simplecov"
4
+ require "simplecov_json_formatter"
5
+ SimpleCov.formatters = SimpleCov::Formatter::MultiFormatter.new([
6
+ SimpleCov::Formatter::HTMLFormatter,
7
+ SimpleCov::Formatter::JSONFormatter
8
+ ])
9
+ SimpleCov.start do
10
+ add_filter %r{spec/}
11
+ add_filter %r{vendor/}
12
+ minimum_coverage 90
13
+ end
14
+
15
+ require "active_record"
16
+ require "que-schema"
17
+ require "support/database"
18
+
19
+ # Apply patches when running without Rails (Railtie only runs when Rails boots)
20
+ ActiveRecord::Migration.include(QueSchema::SchemaStatements)
21
+ ActiveRecord::Migration.include(QueSchema::MigrationHelpers)
22
+ ActiveRecord::Schema.include(QueSchema::SchemaStatements)
23
+ ActiveRecord::SchemaDumper.prepend(QueSchema::SchemaDumper)
24
+
25
+ # Establish database connection for all specs
26
+ QueSchema::Spec.establish_connection
27
+
28
+ # Suppress migration output during tests
29
+ ActiveRecord::Migration.verbose = false
30
+
31
+ RSpec.configure do |config|
32
+ config.expect_with :rspec do |expectations|
33
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
34
+ end
35
+ config.mock_with :rspec do |mocks|
36
+ mocks.verify_partial_doubles = true
37
+ end
38
+ config.shared_context_metadata_behavior = :apply_to_host_groups
39
+ config.filter_run_when_matching :focus
40
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_record"
4
+ require "que"
5
+
6
+ module QueSchema
7
+ module Spec
8
+ DATABASE_NAME = "que_schema_test"
9
+ DATABASE_URL = ENV["DATABASE_URL"] || "postgresql://localhost/#{DATABASE_NAME}"
10
+
11
+ def self.establish_connection
12
+ return if @connected
13
+
14
+ begin
15
+ ActiveRecord::Base.establish_connection(DATABASE_URL)
16
+ ActiveRecord::Base.connection.execute("SELECT 1")
17
+ rescue ActiveRecord::NoDatabaseError
18
+ create_database
19
+ ActiveRecord::Base.establish_connection(DATABASE_URL)
20
+ end
21
+
22
+ @connected = true
23
+ end
24
+
25
+ def self.create_database
26
+ base_url = DATABASE_URL.sub(%r{/[^/]+\z}, "/postgres")
27
+ ActiveRecord::Base.establish_connection(base_url)
28
+ ActiveRecord::Base.connection.create_database(DATABASE_NAME)
29
+ end
30
+
31
+ def self.connection
32
+ establish_connection
33
+ ActiveRecord::Base.connection
34
+ end
35
+
36
+ def self.clean!
37
+ conn = connection
38
+
39
+ # Delegate to Que.migrate! which drops everything in the correct order,
40
+ # respecting dependencies between constraints, functions, and tables.
41
+ Que.connection_proc = proc { |&block| block.call(conn.raw_connection) }
42
+ Que.migrate!(version: 0)
43
+ rescue
44
+ # If Que.migrate! fails (e.g. tables don't exist), dynamically discover
45
+ # and drop all que_* objects so we don't hardcode Que's internal names.
46
+ conn.execute(<<~SQL).each { |row| conn.execute("DROP TABLE IF EXISTS #{conn.quote_table_name(row["tablename"])} CASCADE") }
47
+ SELECT tablename FROM pg_tables WHERE schemaname = 'public' AND tablename LIKE 'que_%'
48
+ SQL
49
+ conn.execute(<<~SQL).each { |row| conn.execute("DROP FUNCTION IF EXISTS #{row["oid"]}::regprocedure CASCADE") }
50
+ SELECT oid FROM pg_proc WHERE proname LIKE 'que_%' AND pronamespace = 'public'::regnamespace
51
+ SQL
52
+ end
53
+ end
54
+ end
metadata ADDED
@@ -0,0 +1,108 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: que-schema
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Jim Gay
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: activerecord
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '6.0'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '6.0'
26
+ - !ruby/object:Gem::Dependency
27
+ name: que
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ - !ruby/object:Gem::Dependency
41
+ name: railties
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '6.0'
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '6.0'
54
+ description: Patches Rails' ActiveRecord schema dumper so applications using que-rb/que
55
+ can use schema.rb instead of structure.sql. Round-trips Que's PostgreSQL functions,
56
+ triggers, and options through the Ruby schema format.
57
+ email:
58
+ - jim@saturnflyer.com
59
+ executables: []
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - ".github/workflows/release.yml"
64
+ - ".github/workflows/test.yml"
65
+ - CHANGELOG.md
66
+ - Gemfile
67
+ - Gemfile.lock
68
+ - README.md
69
+ - Rakefile
70
+ - checksums/que-schema-0.1.0.gem.sha512
71
+ - lib/que-schema.rb
72
+ - lib/que_schema/migration_helpers.rb
73
+ - lib/que_schema/railtie.rb
74
+ - lib/que_schema/schema_dumper.rb
75
+ - lib/que_schema/schema_statements.rb
76
+ - lib/que_schema/version.rb
77
+ - spec/integration_spec.rb
78
+ - spec/migration_helpers_spec.rb
79
+ - spec/que_schema_spec.rb
80
+ - spec/railtie_spec.rb
81
+ - spec/schema_dumper_spec.rb
82
+ - spec/schema_load_spec.rb
83
+ - spec/schema_statements_spec.rb
84
+ - spec/spec_helper.rb
85
+ - spec/support/database.rb
86
+ homepage: https://github.com/SOFware/que-schema
87
+ licenses: []
88
+ metadata:
89
+ homepage_uri: https://github.com/SOFware/que-schema
90
+ source_code_uri: https://github.com/SOFware/que-schema
91
+ rdoc_options: []
92
+ require_paths:
93
+ - lib
94
+ required_ruby_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: '2.7'
99
+ required_rubygems_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ requirements: []
105
+ rubygems_version: 4.0.5
106
+ specification_version: 4
107
+ summary: Enables schema.rb compatibility for the que job queue gem
108
+ test_files: []