pg_aggregates 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 +7 -0
- data/.rspec +3 -0
- data/CHANGELOG.md +5 -0
- data/LICENSE.txt +21 -0
- data/README.md +122 -0
- data/lib/generators/pg/aggregate/aggregate_generator.rb +48 -0
- data/lib/generators/pg/aggregate/templates/aggregate.sql.erb +13 -0
- data/lib/generators/pg/aggregate/templates/migration.rb.erb +5 -0
- data/lib/pg_aggregates/aggregate_definition.rb +22 -0
- data/lib/pg_aggregates/command_recorder.rb +19 -0
- data/lib/pg_aggregates/file_version.rb +25 -0
- data/lib/pg_aggregates/railtie.rb +11 -0
- data/lib/pg_aggregates/schema_dumper.rb +45 -0
- data/lib/pg_aggregates/schema_statements.rb +27 -0
- data/lib/pg_aggregates/version.rb +5 -0
- data/lib/pg_aggregates.rb +20 -0
- data/sig/pg_aggregates.rbs +4 -0
- metadata +176 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: d75685b8a6abb03dda216865bad3cbffc419d6d472b06695b98a5c92a5e05df0
|
4
|
+
data.tar.gz: 8445256690fb9a3bba119b749e1bb8d356f5024472527413402a05312a9c935e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 67babad257045327620a6b6d99c3bba1abc0821c9490ee00fb744aae15b843c63b27294f71be65c3b00efb52e231ecf63e4ca88db8c18d3125e5eaf1d70c243c
|
7
|
+
data.tar.gz: cf6465126ee2fbeeea0e5504463b4d0520ac9690917948b2bead65a10accffbc292a4e44fa3369535bb2f01bbd51023085c6115f4ba8e50c9b390aaa6ad9e231
|
data/.rspec
ADDED
data/CHANGELOG.md
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2024 mhenrixon
|
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
|
13
|
+
all 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
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
# PgAggregates
|
2
|
+
|
3
|
+
PgAggregates provides Rails integration for managing PostgreSQL aggregate functions. It allows you to version your aggregate functions and handle them through migrations, similar to how you manage database schema changes.
|
4
|
+
|
5
|
+
## Features
|
6
|
+
|
7
|
+
- Versioned aggregate functions
|
8
|
+
- Rails generator for creating new aggregates
|
9
|
+
- Migration support for adding/removing aggregates
|
10
|
+
- Proper schema.rb dumping
|
11
|
+
- Support for multiple PostgreSQL versions
|
12
|
+
|
13
|
+
## Installation
|
14
|
+
|
15
|
+
Add this line to your application's Gemfile:
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
gem 'pg_aggregates'
|
19
|
+
```
|
20
|
+
|
21
|
+
And then execute:
|
22
|
+
|
23
|
+
```bash
|
24
|
+
$ bundle install
|
25
|
+
```
|
26
|
+
|
27
|
+
## Usage
|
28
|
+
|
29
|
+
### Creating a New Aggregate
|
30
|
+
|
31
|
+
Generate a new aggregate function:
|
32
|
+
|
33
|
+
```bash
|
34
|
+
$ rails generate pg:aggregate sum_squares
|
35
|
+
```
|
36
|
+
|
37
|
+
This will create:
|
38
|
+
- A SQL file in `db/aggregates/sum_squares_v1.sql`
|
39
|
+
- A migration file to create the aggregate
|
40
|
+
|
41
|
+
You can specify a version:
|
42
|
+
|
43
|
+
```bash
|
44
|
+
$ rails generate pg:aggregate array_sum --version 2
|
45
|
+
```
|
46
|
+
|
47
|
+
### SQL Definition
|
48
|
+
|
49
|
+
Edit the generated SQL file (`db/aggregates/sum_squares_v1.sql`):
|
50
|
+
|
51
|
+
```sql
|
52
|
+
CREATE AGGREGATE sum_squares(numeric) (
|
53
|
+
sfunc = numeric_add,
|
54
|
+
stype = numeric,
|
55
|
+
initcond = '0'
|
56
|
+
);
|
57
|
+
```
|
58
|
+
|
59
|
+
### Migrations
|
60
|
+
|
61
|
+
The generated migration will look like:
|
62
|
+
|
63
|
+
```ruby
|
64
|
+
class CreateAggregateSumSquares < ActiveRecord::Migration[7.0]
|
65
|
+
def change
|
66
|
+
create_aggregate "sum_squares", version: 1
|
67
|
+
end
|
68
|
+
end
|
69
|
+
```
|
70
|
+
|
71
|
+
You can also create aggregates inline:
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
class CreateAggregateArraySum < ActiveRecord::Migration[7.0]
|
75
|
+
def change
|
76
|
+
create_aggregate "array_sum", sql_definition: <<-SQL
|
77
|
+
CREATE AGGREGATE array_sum(numeric[]) (
|
78
|
+
sfunc = array_append,
|
79
|
+
stype = numeric[],
|
80
|
+
initcond = '{}'
|
81
|
+
);
|
82
|
+
SQL
|
83
|
+
end
|
84
|
+
end
|
85
|
+
```
|
86
|
+
|
87
|
+
### Managing Versions
|
88
|
+
|
89
|
+
When you need to update an aggregate, create a new version:
|
90
|
+
|
91
|
+
1. Generate a new version:
|
92
|
+
```bash
|
93
|
+
$ rails generate pg:aggregate sum_squares --version 2
|
94
|
+
```
|
95
|
+
|
96
|
+
2. Update the SQL in `db/aggregates/sum_squares_v2.sql`
|
97
|
+
|
98
|
+
3. Create a migration to update to the new version:
|
99
|
+
```ruby
|
100
|
+
class UpdateAggregateSumSquares < ActiveRecord::Migration[7.0]
|
101
|
+
def change
|
102
|
+
drop_aggregate "sum_squares", "numeric"
|
103
|
+
create_aggregate "sum_squares", version: 2
|
104
|
+
end
|
105
|
+
end
|
106
|
+
```
|
107
|
+
|
108
|
+
## Development
|
109
|
+
|
110
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
111
|
+
|
112
|
+
## Contributing
|
113
|
+
|
114
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/mhenrixon/pg_aggregates. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/mhenrixon/pg_aggregates/blob/main/CODE_OF_CONDUCT.md).
|
115
|
+
|
116
|
+
## License
|
117
|
+
|
118
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
119
|
+
|
120
|
+
## Code of Conduct
|
121
|
+
|
122
|
+
Everyone interacting in the PgAggregates project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/mhenrixon/pg_aggregates/blob/main/CODE_OF_CONDUCT.md).
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require "rails/generators"
|
2
|
+
require "rails/generators/active_record"
|
3
|
+
|
4
|
+
module Pg
|
5
|
+
module Generators
|
6
|
+
class AggregateGenerator < Rails::Generators::NamedBase
|
7
|
+
include Rails::Generators::Migration
|
8
|
+
|
9
|
+
source_root File.expand_path("templates", __dir__)
|
10
|
+
|
11
|
+
class_option :version,
|
12
|
+
type: :string,
|
13
|
+
default: "1",
|
14
|
+
desc: "Specify a version for the aggregate"
|
15
|
+
|
16
|
+
def create_aggregate_file
|
17
|
+
@version = options[:version]
|
18
|
+
@aggregate_name = file_name
|
19
|
+
|
20
|
+
template(
|
21
|
+
"aggregate.sql.erb",
|
22
|
+
"db/aggregates/#{file_name}_v#{@version}.sql"
|
23
|
+
)
|
24
|
+
end
|
25
|
+
|
26
|
+
def create_migration_file
|
27
|
+
@version = options[:version]
|
28
|
+
@aggregate_name = file_name
|
29
|
+
@migration_version = migration_version
|
30
|
+
|
31
|
+
migration_template(
|
32
|
+
"migration.rb.erb",
|
33
|
+
"db/migrate/create_aggregate_#{file_name}.rb"
|
34
|
+
)
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def self.next_migration_number(dirname)
|
40
|
+
ActiveRecord::Generators::Base.next_migration_number(dirname)
|
41
|
+
end
|
42
|
+
|
43
|
+
def migration_version
|
44
|
+
"[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
CREATE AGGREGATE <%= @aggregate_name %>(
|
2
|
+
-- Specify your input type(s)
|
3
|
+
anyelement
|
4
|
+
) (
|
5
|
+
-- State function - called for each input value
|
6
|
+
sfunc = array_append,
|
7
|
+
|
8
|
+
-- State data type
|
9
|
+
stype = anyarray,
|
10
|
+
|
11
|
+
-- Initial state value
|
12
|
+
initcond = '{}'
|
13
|
+
);
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module PgAggregates
|
2
|
+
class AggregateDefinition
|
3
|
+
attr_reader :name, :version
|
4
|
+
|
5
|
+
def initialize(name, version:)
|
6
|
+
@name = name
|
7
|
+
@version = version
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_sql
|
11
|
+
File.read(path)
|
12
|
+
end
|
13
|
+
|
14
|
+
def path
|
15
|
+
Rails.root.join("db", "aggregates", "#{name}_v#{version}.sql").to_s
|
16
|
+
end
|
17
|
+
|
18
|
+
def full_name
|
19
|
+
name.to_s.include?(".") ? name.to_s : "public.#{name}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module PgAggregates
|
2
|
+
module CommandRecorder
|
3
|
+
def create_aggregate(*args, &block)
|
4
|
+
record(:create_aggregate, args, &block)
|
5
|
+
end
|
6
|
+
|
7
|
+
def drop_aggregate(*args)
|
8
|
+
record(:drop_aggregate, args)
|
9
|
+
end
|
10
|
+
|
11
|
+
def invert_create_aggregate(args)
|
12
|
+
[:drop_aggregate, args]
|
13
|
+
end
|
14
|
+
|
15
|
+
def invert_drop_aggregate(args)
|
16
|
+
[:create_aggregate, args]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module PgAggregates
|
2
|
+
class FileVersion
|
3
|
+
attr_reader :path, :name, :version
|
4
|
+
|
5
|
+
def initialize(path)
|
6
|
+
@path = Pathname.new(path)
|
7
|
+
@name = @path.basename.to_s.sub(/_v\d+\.sql$/, "")
|
8
|
+
@version = extract_version
|
9
|
+
end
|
10
|
+
|
11
|
+
def sql_definition
|
12
|
+
File.read(path).strip
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def extract_version
|
18
|
+
if (match = @path.basename.to_s.match(/_v(\d+)\.sql$/))
|
19
|
+
match[1].to_i
|
20
|
+
else
|
21
|
+
0
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module PgAggregates
|
2
|
+
class Railtie < Rails::Railtie
|
3
|
+
initializer "postgres_aggregates.load" do
|
4
|
+
ActiveSupport.on_load(:active_record) do
|
5
|
+
ActiveRecord::ConnectionAdapters::AbstractAdapter.include PgAggregates::SchemaStatements
|
6
|
+
ActiveRecord::Migration::CommandRecorder.include PgAggregates::CommandRecorder
|
7
|
+
ActiveRecord::SchemaDumper.prepend PgAggregates::SchemaDumper
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module PgAggregates
|
2
|
+
module SchemaDumper
|
3
|
+
def tables(stream)
|
4
|
+
# First dump aggregates
|
5
|
+
dump_custom_aggregates(stream)
|
6
|
+
stream.puts
|
7
|
+
|
8
|
+
super
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def dump_custom_aggregates(stream)
|
14
|
+
# Group all versions of each aggregate
|
15
|
+
aggregate_versions = {}
|
16
|
+
|
17
|
+
Dir.glob(Rails.root.join("db/aggregates/*_v*.sql").to_s).each do |file|
|
18
|
+
file_version = FileVersion.new(file)
|
19
|
+
aggregate_versions[file_version.name] ||= []
|
20
|
+
aggregate_versions[file_version.name] << file_version
|
21
|
+
end
|
22
|
+
|
23
|
+
# For each aggregate, use the latest version
|
24
|
+
latest_versions = aggregate_versions.transform_values do |versions|
|
25
|
+
versions.max_by(&:version)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Sort by name to ensure consistent ordering
|
29
|
+
latest_versions.keys.sort.each do |aggregate_name|
|
30
|
+
file_version = latest_versions[aggregate_name]
|
31
|
+
|
32
|
+
# Add a comment showing the version history
|
33
|
+
all_versions = aggregate_versions[aggregate_name].map(&:version).sort
|
34
|
+
version_comment = all_versions.size > 1 ? " -- versions: #{all_versions.join(', ')}" : ""
|
35
|
+
|
36
|
+
stream.puts <<-AGG
|
37
|
+
create_aggregate "#{aggregate_name}", sql_definition: <<-SQL#{version_comment}
|
38
|
+
#{file_version.sql_definition}
|
39
|
+
SQL
|
40
|
+
|
41
|
+
AGG
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module PgAggregates
|
2
|
+
module SchemaStatements
|
3
|
+
def create_aggregate(name, version: nil, sql_definition: nil)
|
4
|
+
raise ArgumentError, "Must provide either sql_definition or version" if sql_definition.nil? && version.nil?
|
5
|
+
|
6
|
+
if sql_definition
|
7
|
+
execute sql_definition
|
8
|
+
else
|
9
|
+
# Fallback to file-based definition if needed
|
10
|
+
aggregate_definition = PgAggregates::AggregateDefinition.new(name, version: version)
|
11
|
+
|
12
|
+
# Check if file exists before trying to read it
|
13
|
+
unless File.exist?(aggregate_definition.path)
|
14
|
+
raise ArgumentError, "Could not find aggregate definition file: #{aggregate_definition.path}"
|
15
|
+
end
|
16
|
+
|
17
|
+
execute aggregate_definition.to_sql
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def drop_aggregate(name, *arg_types, force: false)
|
22
|
+
arg_types_sql = arg_types.any? ? "(#{arg_types.join(', ')})" : ""
|
23
|
+
force_clause = force ? " CASCADE" : ""
|
24
|
+
execute "DROP AGGREGATE IF EXISTS #{name}#{arg_types_sql}#{force_clause}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_record/railtie"
|
4
|
+
|
5
|
+
require_relative "pg_aggregates/file_version"
|
6
|
+
require_relative "pg_aggregates/aggregate_definition"
|
7
|
+
require_relative "pg_aggregates/schema_statements"
|
8
|
+
require_relative "pg_aggregates/command_recorder"
|
9
|
+
require_relative "pg_aggregates/schema_dumper"
|
10
|
+
require_relative "pg_aggregates/railtie"
|
11
|
+
|
12
|
+
module PgAggregates
|
13
|
+
class Error < StandardError; end
|
14
|
+
|
15
|
+
class << self
|
16
|
+
def database
|
17
|
+
ActiveRecord::Base.connection
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
metadata
ADDED
@@ -0,0 +1,176 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: pg_aggregates
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- mhenrixon
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-11-04 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activerecord
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '6.1'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '6.1'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: railties
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '6.1'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '6.1'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: pg
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.1'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.1'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '13.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '13.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.12'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.12'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: ammeter
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '1.1'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '1.1'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: database_cleaner-active_record
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: appraisal
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
description: Manage PostgreSQL aggregate functions in your Rails application with
|
126
|
+
versioned migrations and schema handling. This cuts the need for keeping a structure.sql
|
127
|
+
email:
|
128
|
+
- mikael@mhenrixon.com
|
129
|
+
executables: []
|
130
|
+
extensions: []
|
131
|
+
extra_rdoc_files: []
|
132
|
+
files:
|
133
|
+
- ".rspec"
|
134
|
+
- CHANGELOG.md
|
135
|
+
- LICENSE.txt
|
136
|
+
- README.md
|
137
|
+
- lib/generators/pg/aggregate/aggregate_generator.rb
|
138
|
+
- lib/generators/pg/aggregate/templates/aggregate.sql.erb
|
139
|
+
- lib/generators/pg/aggregate/templates/migration.rb.erb
|
140
|
+
- lib/pg_aggregates.rb
|
141
|
+
- lib/pg_aggregates/aggregate_definition.rb
|
142
|
+
- lib/pg_aggregates/command_recorder.rb
|
143
|
+
- lib/pg_aggregates/file_version.rb
|
144
|
+
- lib/pg_aggregates/railtie.rb
|
145
|
+
- lib/pg_aggregates/schema_dumper.rb
|
146
|
+
- lib/pg_aggregates/schema_statements.rb
|
147
|
+
- lib/pg_aggregates/version.rb
|
148
|
+
- sig/pg_aggregates.rbs
|
149
|
+
homepage: https://github.com/mhenrixon/pg_aggregates
|
150
|
+
licenses:
|
151
|
+
- MIT
|
152
|
+
metadata:
|
153
|
+
homepage_uri: https://github.com/mhenrixon/pg_aggregates
|
154
|
+
source_code_uri: https://github.com/mhenrixon/pg_aggregates
|
155
|
+
changelog_uri: https://github.com/mhenrixon/pg_aggregates/blob/main/CHANGELOG.md
|
156
|
+
rubygems_mfa_required: 'true'
|
157
|
+
post_install_message:
|
158
|
+
rdoc_options: []
|
159
|
+
require_paths:
|
160
|
+
- lib
|
161
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
162
|
+
requirements:
|
163
|
+
- - ">="
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: 3.0.0
|
166
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
167
|
+
requirements:
|
168
|
+
- - ">="
|
169
|
+
- !ruby/object:Gem::Version
|
170
|
+
version: '0'
|
171
|
+
requirements: []
|
172
|
+
rubygems_version: 3.5.22
|
173
|
+
signing_key:
|
174
|
+
specification_version: 4
|
175
|
+
summary: Rails integration for PostgreSQL aggregate functions
|
176
|
+
test_files: []
|