fx-sequence 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: 48e0687b9cfd59028be9a254da0c216d94e9bf56299b3ace7447c43b345598d5
4
+ data.tar.gz: 3db24cfcdc2f2ee9b9f119a2a4669d9f1cb2f5778765bf67c542e4148daf6b7e
5
+ SHA512:
6
+ metadata.gz: ced25a9fd8d9936b34ec9492dccde512776b387c3973aa565ca7964a2d68e3d6e94d83d926980bbe029fbe64c2bfb9fa8c524ad11dccc39538f968b071536ebf
7
+ data.tar.gz: ad75dd0639222d689bfcc84fade05181343d4739a4aa03e7918e215dc2d1e66f3b2b6e87e69472f4155ea2989093eeb0e73276561f511ec6b95f063b7097cba9
data/README.md ADDED
@@ -0,0 +1,21 @@
1
+ # Fx::Sequence
2
+
3
+ Extension for [fx](https://github.com/teoljungberg/fx) gem to support creation, drop and dumping to `schema.rb` PostgreSQL sequences.
4
+
5
+ ## Installation
6
+
7
+ Install the gem and add to the application's Gemfile by executing:
8
+
9
+ ```bash
10
+ bundle add fx-sequence
11
+ ```
12
+
13
+ If bundler is not being used to manage dependencies, install the gem by executing:
14
+
15
+ ```bash
16
+ gem install fx-sequence
17
+ ```
18
+
19
+ ## License
20
+
21
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rubocop/rake_task'
5
+
6
+ RuboCop::RakeTask.new
7
+
8
+ task default: %w[rubocop]
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'fx/sequence/sequence'
4
+
5
+ module Fx
6
+ module Sequence
7
+ module Adapters
8
+ class Postgres < ::Fx::Adapters::Postgres
9
+ class Sequences
10
+ SEQUENCES_WITH_DEFINITIONS_QUERY = <<~SQL
11
+ SELECT ps.relname AS name,
12
+ 'CREATE SEQUENCE IF NOT EXISTS ' || ps.relname AS definition
13
+ FROM pg_class ps
14
+ JOIN pg_namespace pn ON ps.relnamespace = pn.oid
15
+ WHERE pn.nspname = 'public'
16
+ AND ps.relkind = 'S';
17
+ SQL
18
+ private_constant :SEQUENCES_WITH_DEFINITIONS_QUERY
19
+
20
+ def self.all(...)
21
+ new(...).all
22
+ end
23
+
24
+ def initialize(connection)
25
+ @connection = connection
26
+ end
27
+
28
+ def all
29
+ sequences_from_postgres.map { |sequence| to_fx_sequence(sequence) }
30
+ end
31
+
32
+ private
33
+
34
+ attr_reader :connection
35
+
36
+ def sequences_from_postgres
37
+ connection.execute(SEQUENCES_WITH_DEFINITIONS_QUERY)
38
+ end
39
+
40
+ def to_fx_sequence(result)
41
+ Fx::Sequence::Sequence.new(result)
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'fx/sequence/adapters/postgres/sequences'
4
+
5
+ module Fx
6
+ module Sequence
7
+ module Adapters
8
+ class Postgres < ::Fx::Adapters::Postgres
9
+ def sequences
10
+ Sequences.all(connection)
11
+ end
12
+
13
+ def create_sequence(sql_definition)
14
+ execute(sql_definition)
15
+ end
16
+
17
+ def drop_sequence(name)
18
+ execute("DROP SEQUENCE #{name};")
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fx
4
+ module Sequence
5
+ module CommandRecorder
6
+ def create_sequence(*args)
7
+ record(:create_sequence, args)
8
+ end
9
+
10
+ def drop_sequence(*args)
11
+ record(:drop_sequence, args)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fx
4
+ module Sequence
5
+ class Configuration < Fx::Configuration
6
+ def initialize
7
+ super
8
+ @database = Fx::Sequence::Adapters::Postgres.new
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fx
4
+ module Sequence
5
+ class Definition < Fx::Definition
6
+ SEQUENCE = 'sequence'
7
+ private_constant :SEQUENCE
8
+
9
+ def self.sequence(name:, version:)
10
+ new(name: name, version: version, type: SEQUENCE)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/railtie'
4
+
5
+ module Fx
6
+ module Sequence
7
+ class Railtie < Rails::Railtie
8
+ initializer('fx-sequence.load') do
9
+ ActiveSupport.on_load(:active_record) do
10
+ Fx::Sequence.load
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fx
4
+ module Sequence
5
+ module SchemaDumper
6
+ def tables(stream)
7
+ sequences(stream)
8
+ empty_line(stream)
9
+
10
+ super
11
+ end
12
+
13
+ private
14
+
15
+ def empty_line(stream)
16
+ stream.puts if dumpable_sequences_in_database.any?
17
+ end
18
+
19
+ def sequences(stream)
20
+ dumpable_sequences_in_database.each do |sequence|
21
+ stream.puts(sequence.to_schema)
22
+ end
23
+ end
24
+
25
+ def dumpable_sequences_in_database
26
+ @dumpable_sequences_in_database ||= Fx::Sequence.database.sequences
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fx
4
+ module Sequence
5
+ class Sequence
6
+ include Comparable
7
+
8
+ attr_reader :name, :definition
9
+
10
+ delegate :<=>, to: :name
11
+
12
+ def initialize(row)
13
+ @name = row.fetch('name')
14
+ @definition = row.fetch('definition')
15
+ end
16
+
17
+ def ==(other)
18
+ name == other.name && definition == other.definition
19
+ end
20
+
21
+ def to_schema
22
+ <<-SCHEMA
23
+ create_sequence :#{name}, sql_definition: <<-\SQL
24
+ #{definition}
25
+ SQL
26
+ SCHEMA
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fx
4
+ module Sequence
5
+ module Statements
6
+ def create_sequence(name, **options)
7
+ version = options.fetch(:version, 1)
8
+ sql_definition = options[:sql_definition]
9
+
10
+ raise(ArgumentError, 'version or sql_definition must be specified') if version.nil? && sql_definition.nil?
11
+
12
+ sql_definition = sql_definition.strip_heredoc if sql_definition
13
+ sql_definition ||= Fx::Sequence::Definition.sequence(name: name, version: version).to_sql
14
+
15
+ Fx::Sequence.database.create_sequence(sql_definition)
16
+ end
17
+
18
+ def drop_sequence(name, _ = {})
19
+ Fx::Sequence.database.drop_sequence(name)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fx
4
+ module Sequence
5
+ VERSION = '0.1.0'
6
+ public_constant :VERSION
7
+ end
8
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails'
4
+
5
+ require 'fx'
6
+
7
+ require 'fx/sequence/version'
8
+ require 'fx/sequence/adapters/postgres'
9
+ require 'fx/sequence/command_recorder'
10
+ require 'fx/sequence/configuration'
11
+ require 'fx/sequence/definition'
12
+ require 'fx/sequence/sequence'
13
+ require 'fx/sequence/statements'
14
+ require 'fx/sequence/schema_dumper'
15
+ require 'fx/sequence/railtie'
16
+
17
+ module Fx
18
+ module Sequence
19
+ def self.load
20
+ ActiveRecord::Migration::CommandRecorder.include(Fx::Sequence::CommandRecorder)
21
+ ActiveRecord::ConnectionAdapters::AbstractAdapter.include(Fx::Sequence::Statements)
22
+ ActiveRecord::SchemaDumper.prepend(Fx::Sequence::SchemaDumper)
23
+
24
+ true
25
+ end
26
+
27
+ def self.configuration
28
+ @configuration ||= Fx::Sequence::Configuration.new
29
+ end
30
+
31
+ def self.database
32
+ configuration.database
33
+ end
34
+ end
35
+ end
metadata ADDED
@@ -0,0 +1,73 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fx-sequence
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - "@aevula"
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2025-03-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: fx
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'
27
+ description: Extension for fx gem for creating, droping and dumping to schema.rb sequences
28
+ email:
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - README.md
34
+ - Rakefile
35
+ - lib/fx/sequence.rb
36
+ - lib/fx/sequence/adapters/postgres.rb
37
+ - lib/fx/sequence/adapters/postgres/sequences.rb
38
+ - lib/fx/sequence/command_recorder.rb
39
+ - lib/fx/sequence/configuration.rb
40
+ - lib/fx/sequence/definition.rb
41
+ - lib/fx/sequence/railtie.rb
42
+ - lib/fx/sequence/schema_dumper.rb
43
+ - lib/fx/sequence/sequence.rb
44
+ - lib/fx/sequence/statements.rb
45
+ - lib/fx/sequence/version.rb
46
+ homepage: https://github.com/aevula/fx-sequence
47
+ licenses:
48
+ - MIT
49
+ metadata:
50
+ homepage_uri: https://github.com/aevula/fx-sequence
51
+ source_code_uri: https://github.com/aevula/fx-sequence/tree/master
52
+ changelog_uri: https://github.com/aevula/fx-sequence/tree/master/CHANGELOG.md
53
+ rubygems_mfa_required: 'true'
54
+ post_install_message:
55
+ rdoc_options: []
56
+ require_paths:
57
+ - lib
58
+ required_ruby_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '3.1'
63
+ required_rubygems_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ requirements: []
69
+ rubygems_version: 3.3.27
70
+ signing_key:
71
+ specification_version: 4
72
+ summary: Extension for fx gem for sequence support
73
+ test_files: []