schema_plus_pg_types 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
+ SHA1:
3
+ metadata.gz: ab8c1d45e50a98115b2794690905697521819a2a
4
+ data.tar.gz: d20941350da12ca252504e923683b1809e9a7783
5
+ SHA512:
6
+ metadata.gz: c04aef0c17a5ef56363a4a5585ad893caeb6e585e0707e2175aa698df7621f99b444fba1c7143ccff5d8c4d1e81649c0bd9f4831f5a3bb48614fb70f3eb9cdae
7
+ data.tar.gz: ae033ed292e5c7d0ef043b7c7b667316b1ba3e89e362f9568686a373725f141dd448ef65789ffa683da62f062b6d05f1960ab84f861c22882736632ff4adc157
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /coverage
2
+ /tmp
3
+ /pkg
4
+ /Gemfile.local
5
+
6
+ *.lock
7
+ *.log
8
+ *.sqlite3
9
+ !gemfiles/**/*.sqlite3
data/.idea/vcs.xml ADDED
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="VcsDirectoryMappings">
4
+ <mapping directory="$PROJECT_DIR$" vcs="Git" />
5
+ </component>
6
+ </project>
data/.travis.yml ADDED
@@ -0,0 +1,16 @@
1
+ # This file was auto-generated by the schema_dev tool, based on the data in
2
+ # ./schema_dev.yml
3
+ # Please do not edit this file; any changes will be overwritten next time
4
+ # schema_dev gets run.
5
+ ---
6
+ sudo: false
7
+ rvm:
8
+ - 2.3.1
9
+ gemfile:
10
+ - gemfiles/activerecord-5.0/Gemfile.postgresql
11
+ env: POSTGRESQL_DB_USER=postgres
12
+ addons:
13
+ postgresql: '9.4'
14
+ before_script: bundle exec rake create_databases
15
+ after_script: bundle exec rake drop_databases
16
+ script: bundle exec rake travis
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ File.exist?(gemfile_local = File.expand_path('../Gemfile.local', __FILE__)) and eval File.read(gemfile_local), binding, gemfile_local
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2016 Boaz Yaniv
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,116 @@
1
+ [![Gem Version](https://badge.fury.io/rb/schema_plus_pg_types.svg)](http://badge.fury.io/rb/schema_plus_pg_types)
2
+ [![Build Status](https://secure.travis-ci.org/SchemaPlus/schema_plus_pg_types.svg)](http://travis-ci.org/SchemaPlus/schema_plus_pg_types)
3
+ [![Coverage Status](https://img.shields.io/coveralls/SchemaPlus/schema_plus_pg_types.svg)](https://coveralls.io/r/SchemaPlus/schema_plus_pg_types)
4
+ [![Dependency Status](https://gemnasium.com/lomba/schema_plus_pg_types.svg)](https://gemnasium.com/SchemaPlus/schema_plus_pg_types)
5
+
6
+ # SchemaPlus::PgTypes
7
+
8
+ SchemaPlus::PgTypes adds better support for PostgreSQL-specific types to
9
+ ActiveRecord, mapping them to higher-level types instead of raw strings.
10
+ Currently this only includes the PostgreSQL `interval` type, which is mapped
11
+ to `ActiveSupport::Duration`.
12
+
13
+ ## Installation
14
+
15
+ <!-- SCHEMA_DEV: TEMPLATE INSTALLATION - begin -->
16
+ <!-- These lines are auto-inserted from a schema_dev template -->
17
+ As usual:
18
+
19
+ ```ruby
20
+ gem "schema_plus_pg_types" # in a Gemfile
21
+ gem.add_dependency "schema_plus_pg_types" # in a .gemspec
22
+ ```
23
+
24
+ <!-- SCHEMA_DEV: TEMPLATE INSTALLATION - end -->
25
+
26
+
27
+ ## Compatibility
28
+
29
+ SchemaPlus::PgTypes is tested on:
30
+
31
+ <!-- SCHEMA_DEV: MATRIX - begin -->
32
+ <!-- These lines are auto-generated by schema_dev based on schema_dev.yml -->
33
+ * ruby **2.3.1** with activerecord **5.0**, using **postgresql**
34
+
35
+ <!-- SCHEMA_DEV: MATRIX - end -->
36
+
37
+ ## Usage
38
+
39
+ This gem adds a little more syntactic sugar for defining PostgreSQL types
40
+ in your migrations. You can now simply write:
41
+
42
+ ```ruby
43
+ create_table :events do |t|
44
+ t.interval :event_duration
45
+ end
46
+ ````
47
+
48
+ Instead of:
49
+
50
+ ```ruby
51
+ create_table :events do |t|
52
+ t.column :event_duration, :interval
53
+ end
54
+ ```
55
+
56
+ The `event_duration` column will be represented as `ActiveSupport::Duration`
57
+ in your model, so you should be able to use it without the usual fuss:
58
+
59
+ ```ruby
60
+ long_events = Event.where(1.hours..10.hours)
61
+ ````
62
+
63
+ SchemaPlus::PgTypes is part of the [SchemaPlus](https://github.com/SchemaPlus/) family of Ruby on Rails ActiveRecord extension gems.
64
+
65
+
66
+ ## History
67
+
68
+ * 0.1.0 - Initial release
69
+
70
+ ## Development & Testing
71
+
72
+ Are you interested in contributing to SchemaPlus::PgTypes? Thanks! Please follow
73
+ the standard protocol: fork, feature branch, develop, push, and issue pull
74
+ request.
75
+
76
+ Some things to know about to help you develop and test:
77
+
78
+ <!-- SCHEMA_DEV: TEMPLATE USES SCHEMA_DEV - begin -->
79
+ <!-- These lines are auto-inserted from a schema_dev template -->
80
+ * **schema_dev**: SchemaPlus::PgTypes uses [schema_dev](https://github.com/SchemaPlus/schema_dev) to
81
+ facilitate running rspec tests on the matrix of ruby, activerecord, and database
82
+ versions that the gem supports, both locally and on
83
+ [travis-ci](http://travis-ci.org/SchemaPlus/schema_plus_pg_types)
84
+
85
+ To to run rspec locally on the full matrix, do:
86
+
87
+ $ schema_dev bundle install
88
+ $ schema_dev rspec
89
+
90
+ You can also run on just one configuration at a time; For info, see `schema_dev --help` or the [schema_dev](https://github.com/SchemaPlus/schema_dev) README.
91
+
92
+ The matrix of configurations is specified in `schema_dev.yml` in
93
+ the project root.
94
+
95
+
96
+ <!-- SCHEMA_DEV: TEMPLATE USES SCHEMA_DEV - end -->
97
+
98
+ <!-- SCHEMA_DEV: TEMPLATE USES SCHEMA_PLUS_CORE - begin -->
99
+ <!-- These lines are auto-inserted from a schema_dev template -->
100
+ * **schema_plus_core**: SchemaPlus::PgTypes uses the SchemaPlus::Core API that
101
+ provides middleware callback stacks to make it easy to extend
102
+ ActiveRecord's behavior. If that API is missing something you need for
103
+ your contribution, please head over to
104
+ [schema_plus_core](https://github.com/SchemaPlus/schema_plus_core) and open
105
+ an issue or pull request.
106
+
107
+ <!-- SCHEMA_DEV: TEMPLATE USES SCHEMA_PLUS_CORE - end -->
108
+
109
+ <!-- SCHEMA_DEV: TEMPLATE USES SCHEMA_MONKEY - begin -->
110
+ <!-- These lines are auto-inserted from a schema_dev template -->
111
+ * **schema_monkey**: SchemaPlus::PgTypes is implemented as a
112
+ [schema_monkey](https://github.com/SchemaPlus/schema_monkey) client,
113
+ using [schema_monkey](https://github.com/SchemaPlus/schema_monkey)'s
114
+ convention-based protocols for extending ActiveRecord and using middleware stacks.
115
+
116
+ <!-- SCHEMA_DEV: TEMPLATE USES SCHEMA_MONKEY - end -->
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'schema_dev/tasks'
5
+
6
+ task :default => :spec
7
+
8
+ require 'rspec/core/rake_task'
9
+ RSpec::Core::RakeTask.new(:spec)
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+ gemspec :path => File.expand_path('..', __FILE__)
3
+
4
+ File.exist?(gemfile_local = File.expand_path('../Gemfile.local', __FILE__)) and eval File.read(gemfile_local), binding, gemfile_local
@@ -0,0 +1,3 @@
1
+ eval File.read File.expand_path('../../Gemfile.base', __FILE__)
2
+
3
+ gem "activerecord", "~> 5.0.1"
@@ -0,0 +1,10 @@
1
+ require "pathname"
2
+ eval(Pathname.new(__FILE__).dirname.join("Gemfile.base").read, binding)
3
+
4
+ platform :ruby do
5
+ gem "pg"
6
+ end
7
+
8
+ platform :jruby do
9
+ gem 'activerecord-jdbcpostgresql-adapter'
10
+ end
@@ -0,0 +1,29 @@
1
+ require 'active_record/connection_adapters/postgresql_adapter'
2
+ require_relative 'oid/interval'
3
+
4
+ module SchemaPlus::PgTypes
5
+ module ActiveRecord
6
+ module ConnectionAdapters
7
+ module PostgreSQLAdapter
8
+ def configure_connection
9
+ super
10
+
11
+
12
+ # Set interval output format to ISO 8601 for ease of parsing by ActiveSupport::Duration.parse
13
+ execute('SET intervalstyle = iso_8601', 'SCHEMA')
14
+ end
15
+
16
+ def initialize_type_map(m)
17
+ super(m)
18
+ m.register_type 'interval' do |*_, sql_type|
19
+ precision = extract_precision(sql_type)
20
+ ::ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Interval.new(precision: precision)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ ::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::NATIVE_DATABASE_TYPES[:interval] = { name: 'interval' }
29
+
@@ -0,0 +1,24 @@
1
+ module SchemaPlus::PgTypes
2
+ module ActiveRecord
3
+ module ConnectionAdapters
4
+ module PostgreSQL
5
+ module ColumnMethods
6
+ def interval(*args, **options)
7
+ args.each { |name| column(name, :interval, options) }
8
+ end
9
+ end
10
+ module Table
11
+ def interval(*args, **options)
12
+ args.each { |name| column(name, :interval, options) }
13
+ end
14
+ end
15
+
16
+ module TableDefinition
17
+ def interval(*args, **options)
18
+ args.each { |name| column(name, :interval, options) }
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,47 @@
1
+ require 'active_support/duration'
2
+
3
+ module ActiveRecord
4
+ module ConnectionAdapters
5
+ module PostgreSQL
6
+ module OID # :nodoc:
7
+ class Interval < Type::Value # :nodoc:
8
+ def type
9
+ :interval
10
+ end
11
+
12
+ def cast_value(value)
13
+ case value
14
+ when ::ActiveSupport::Duration
15
+ value
16
+ when ::String
17
+ # Will raise +ActiveSupport::Duration::ISO8601Parser::ParsingError+ on string of unknown format
18
+ ::ActiveSupport::Duration.parse(value)
19
+ else
20
+ super
21
+ end
22
+ end
23
+
24
+ # Dump the ISO8601 date inside the schema
25
+ def type_cast_for_schema(value)
26
+ "\"#{value.iso8601}\""
27
+ end
28
+
29
+ def serialize(value)
30
+ case value
31
+ when ::ActiveSupport::Duration
32
+ value.iso8601(precision: self.precision)
33
+ when ::Numeric
34
+ # Sometimes operations on Times returns just float number of seconds so we need to handle that.
35
+ # Example: Time.current - (Time.current + 1.hour) # => -3600.000001776 (Float)
36
+ duration = ::ActiveSupport::Duration.new(value.to_i, seconds: value.to_i)
37
+ duration.iso8601(precision: self.precision)
38
+ else
39
+ super
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+
@@ -0,0 +1,27 @@
1
+ require_relative 'oid/interval'
2
+
3
+ module SchemaPlus::PgTypes
4
+ module ActiveRecord
5
+ module ConnectionAdapters
6
+ module PostgreSQL
7
+ module SchemaStatements
8
+ def type_to_sql(type, limit = nil, precision = nil, scale = nil)
9
+ case type.to_s
10
+ when 'interval'
11
+ return super(type, limit, precision, scale) unless precision
12
+
13
+ case precision
14
+ when 0..6; "interval(#{precision})"
15
+ else raise(ActiveRecordError, "No interval type has precision of #{precision}. The allowed range of precision is from 0 to 6")
16
+ end
17
+ else
18
+ super(type, limit, precision, scale)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+
27
+
@@ -0,0 +1,46 @@
1
+ require 'active_support/duration'
2
+ require 'active_support/duration/iso8601_serializer'
3
+
4
+ class ActiveSupport::Duration
5
+ # Patch rails inconsistent handling of ISO8601 dates.
6
+ # ActiveSupport::Duration uses fixes values for date and time elements:
7
+ # 1 Year = 365.25 days, 1 Month = 30 days, 1 Day = 24 hours, etc.
8
+ # The original parse() implementation advanced the current time by the
9
+ # specified date and time elements and then subtracted the current time
10
+ # again to get the duration. This produces inconsistent results since
11
+ # actual months and years can vary in length.
12
+ # In short, without this fix, the following expression wouldn't necessarily be true:
13
+ # 2.months == ActiveSupport::Duration.parse(2.months)
14
+ def self.parse(iso8601duration)
15
+ parts = ISO8601Parser.new(iso8601duration).parse!
16
+ total_seconds = 0
17
+ parts.each do |part, value|
18
+ total_seconds += value.send part.to_sym
19
+ end
20
+ new(total_seconds, parts)
21
+ end
22
+
23
+ # Patch rails to treat zero durations
24
+ # This bug was fixed in the following commit, but is still not part of Rails 5.0
25
+ # https://github.com/rails/rails/commit/629dde297ce5e4b7614fbb0218f2593effaf7e28
26
+ class ISO8601Serializer
27
+ def serialize
28
+ parts, sign = normalize
29
+ return 'PT0S'.freeze if parts.empty?
30
+
31
+ output = 'P'
32
+ output << "#{parts[:years]}Y" if parts.key?(:years)
33
+ output << "#{parts[:months]}M" if parts.key?(:months)
34
+ output << "#{parts[:weeks]}W" if parts.key?(:weeks)
35
+ output << "#{parts[:days]}D" if parts.key?(:days)
36
+ time = ''
37
+ time << "#{parts[:hours]}H" if parts.key?(:hours)
38
+ time << "#{parts[:minutes]}M" if parts.key?(:minutes)
39
+ if parts.key?(:seconds)
40
+ time << "#{sprintf(@precision ? "%0.0#{@precision}f" : '%g', parts[:seconds])}S"
41
+ end
42
+ output << "T#{time}" if time.present?
43
+ "#{sign}#{output}"
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,5 @@
1
+ module SchemaPlus
2
+ module PgTypes
3
+ VERSION = '0.1.0'
4
+ end
5
+ end
@@ -0,0 +1,17 @@
1
+ require 'schema_plus/core'
2
+
3
+ require_relative 'pg_types/active_record/connection_adapters/postgresql/adapter'
4
+ require_relative 'pg_types/active_record/connection_adapters/postgresql/schema_statements'
5
+ require_relative 'pg_types/active_record/connection_adapters/postgresql/column_methods'
6
+ require_relative 'pg_types/active_support/duration_fixes'
7
+ require_relative 'pg_types/version'
8
+
9
+ # Load any mixins to ActiveRecord modules, such as:
10
+ #
11
+ #require_relative 'pg_types/active_record/base'
12
+
13
+ # Load any middleware, such as:
14
+ #
15
+ # require_relative 'pg_types/middleware/model'
16
+
17
+ SchemaMonkey.register SchemaPlus::PgTypes
@@ -0,0 +1 @@
1
+ require_relative 'schema_plus/pg_types'
data/migration_spec.rb ADDED
@@ -0,0 +1,116 @@
1
+ require 'spec_helper'
2
+
3
+ class Item < ActiveRecord::Base
4
+ end
5
+
6
+ class AOnes < ActiveRecord::Base
7
+ end
8
+
9
+ class ABOnes < ActiveRecord::Base
10
+ end
11
+
12
+ describe "Migration" do
13
+
14
+ let(:migration) { ActiveRecord::Migration }
15
+ let(:connection) { ActiveRecord::Base.connection }
16
+ let(:schema) { ActiveRecord::Schema }
17
+
18
+ before(:each) do
19
+ define_schema_and_data
20
+ end
21
+
22
+ context "creation" do
23
+ it "should create correct views" do
24
+ expect(AOnes.all.collect(&:s)).to eq(%W[one_one one_two])
25
+ expect(ABOnes.all.collect(&:s)).to eq(%W[one_one])
26
+ end
27
+ end
28
+
29
+ context "duplicate creation" do
30
+ before(:each) do
31
+ migration.create_view('dupe_me', 'SELECT * FROM items WHERE (a=1)')
32
+ end
33
+
34
+ it "should raise an error by default" do
35
+ expect {migration.create_view('dupe_me', 'SELECT * FROM items WHERE (a=2)')}.to raise_error ActiveRecord::StatementInvalid
36
+ end
37
+
38
+ it "should override existing definition if :force true" do
39
+ migration.create_view('dupe_me', 'SELECT * FROM items WHERE (a=2)', :force => true)
40
+ expect(connection.view_definition('dupe_me')).to match(%r{WHERE .*a.*=.*2}i)
41
+ end
42
+
43
+ context "Postgres and MySQL only", :sqlite3 => :skip do
44
+ it "should override existing definition if :allow_replace is true" do
45
+ migration.create_view('dupe_me', 'SELECT * FROM items WHERE (a=2)', :allow_replace => true)
46
+ expect(connection.view_definition('dupe_me')).to match(%r{WHERE .*a.*=.*2}i)
47
+ end
48
+ end
49
+ end
50
+
51
+ context "dropping" do
52
+ it "should raise an error if the view doesn't exist" do
53
+ expect { migration.drop_view('doesnt_exist') }.to raise_error ActiveRecord::StatementInvalid
54
+ end
55
+
56
+ it "should fail silently when using if_exists option" do
57
+ expect { migration.drop_view('doesnt_exist', :if_exists => true) }.not_to raise_error
58
+ end
59
+
60
+ context "with a view that exists" do
61
+ before { migration.create_view('view_that_exists', 'SELECT * FROM items WHERE (a=1)') }
62
+
63
+ it "should succeed" do
64
+ migration.drop_view('view_that_exists')
65
+ expect(connection.views).not_to include('view_that_exists')
66
+ end
67
+ end
68
+ end
69
+
70
+ describe "rollback" do
71
+ it "properly rolls back a create_view" do
72
+ m = Class.new ::ActiveRecord::Migration.latest_version do
73
+ define_method(:change) {
74
+ create_view :copy, "SELECT * FROM items"
75
+ }
76
+ end
77
+ m.migrate(:up)
78
+ expect(connection.views).to include("copy")
79
+ m.migrate(:down)
80
+ expect(connection.views).not_to include("copy")
81
+ end
82
+
83
+ it "raises error for drop_view" do
84
+ m = Class.new ::ActiveRecord::Migration.latest_version do
85
+ define_method(:change) {
86
+ drop_view :a_ones
87
+ }
88
+ end
89
+ expect { m.migrate(:down) }.to raise_error(::ActiveRecord::IrreversibleMigration)
90
+ end
91
+ end
92
+
93
+
94
+ protected
95
+
96
+ def define_schema_and_data
97
+ connection.views.each do |view| connection.drop_view view end
98
+ connection.tables_only.each do |table| connection.drop_table table, cascade: true end
99
+
100
+ schema.define do
101
+
102
+ create_table :items, :force => true do |t|
103
+ t.integer :a
104
+ t.integer :b
105
+ t.string :s
106
+ end
107
+
108
+ create_view :a_ones, Item.select('b, s').where(:a => 1)
109
+ create_view :ab_ones, "select s from a_ones where b = 1"
110
+ end
111
+ connection.execute "insert into items (a, b, s) values (1, 1, 'one_one')"
112
+ connection.execute "insert into items (a, b, s) values (1, 2, 'one_two')"
113
+ connection.execute "insert into items (a, b, s) values (2, 1, 'two_one')"
114
+ connection.execute "insert into items (a, b, s) values (2, 2, 'two_two')"
115
+ end
116
+ end
data/schema_dev.yml ADDED
@@ -0,0 +1,6 @@
1
+ ruby:
2
+ - 2.3.1
3
+ activerecord:
4
+ - 5.0
5
+ db:
6
+ - postgresql
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'schema_plus/pg_types/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "schema_plus_pg_types"
8
+ gem.version = SchemaPlus::PgTypes::VERSION
9
+ gem.authors = ["Boaz Yaniv"]
10
+ gem.email = ["boazyan@gmail.com"]
11
+ gem.summary = %q{Adds supports for PostgreSQL types that were left out by Rails}
12
+ gem.homepage = "https://github.com/SchemaPlus/schema_plus_pg_types"
13
+ gem.license = "MIT"
14
+
15
+ gem.files = `git ls-files -z`.split("\x0")
16
+ gem.executables = gem.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_dependency "activerecord", "~> 5.0"
21
+ gem.add_dependency "schema_plus_core", "~> 2.0", ">= 2.0.1"
22
+
23
+ gem.add_development_dependency "bundler", "~> 1.7"
24
+ gem.add_development_dependency "rake", "~> 10.0"
25
+ gem.add_development_dependency "rspec", "~> 3.0"
26
+ gem.add_development_dependency "schema_dev", "~> 3.8"
27
+ gem.add_development_dependency "simplecov"
28
+ gem.add_development_dependency "simplecov-gem-profile"
29
+ end
@@ -0,0 +1,97 @@
1
+ require 'spec_helper'
2
+ require 'active_record/schema_dumper'
3
+
4
+ class Item < ActiveRecord::Base
5
+ end
6
+
7
+ class DefaultItem < ActiveRecord::Base
8
+
9
+ end
10
+
11
+ describe 'Migration' do
12
+
13
+ let(:migration) { ActiveRecord::Migration }
14
+ let(:connection) { ActiveRecord::Base.connection }
15
+ let(:schema) { ActiveRecord::Schema }
16
+
17
+ before(:each) do
18
+ define_schema
19
+ end
20
+
21
+ context 'INTERVAL data type' do
22
+ TEST_DURATIONS = [
23
+ 0.seconds,
24
+ 0.days,
25
+ 0.years,
26
+ 27.seconds,
27
+ 28.minutes,
28
+ 3.hours,
29
+ 15.days,
30
+ 3.weeks,
31
+ 2.months,
32
+ 1.year,
33
+ 5.years,
34
+ 5.years + 7.months + 10.days + 6.hours + 7.minutes + 8.seconds
35
+ ]
36
+
37
+ it 'should convert data from ActiveSupport::Duration (round trip)' do
38
+ TEST_DURATIONS.each{|duration| Item.create(duration: duration)}
39
+ durations = Item.pluck(:duration)
40
+ expect(durations).to all(be_an(ActiveSupport::Duration))
41
+ expect(durations).to eq(TEST_DURATIONS)
42
+ end
43
+
44
+ it 'should convert data to ActiveSupport::Duration' do
45
+ connection.execute(<<~EOF
46
+ INSERT INTO items (duration)
47
+ VALUES
48
+ ('0 seconds'),
49
+ ('0'),
50
+ ('0 years'),
51
+ ('27 seconds'),
52
+ ('28 minutes'),
53
+ ('3 hours'),
54
+ ('15 days'),
55
+ ('3 weeks'),
56
+ ('2 months'),
57
+ ('1 year'),
58
+ ('5 years'),
59
+ ('5 years 7 months 10 days 6 hours 7 minutes 8 seconds');
60
+ EOF
61
+ )
62
+ durations = Item.pluck(:duration)
63
+ expect(durations).to all(be_an(ActiveSupport::Duration))
64
+ expect(durations).to eq(TEST_DURATIONS)
65
+ end
66
+
67
+ it 'should support default values' do
68
+ DefaultItem.create
69
+ item_with_default_value = DefaultItem.first
70
+ expect(item_with_default_value.duration).to be_an(ActiveSupport::Duration)
71
+ expect(item_with_default_value.duration).to eq(2.years + 5.minutes)
72
+ end
73
+
74
+ it 'should properly dump the schema' do
75
+ stream = StringIO.new
76
+ ActiveRecord::SchemaDumper.dump(connection, stream)
77
+ end
78
+
79
+ end
80
+
81
+ protected
82
+
83
+ def define_schema
84
+ connection.data_sources.each do |table| connection.drop_table table, cascade: true end
85
+
86
+ schema.define do
87
+
88
+ create_table :items, force: true do |t|
89
+ t.interval :duration
90
+ end
91
+
92
+ create_table :default_items, force: true do |t|
93
+ t.interval :duration, default: 2.years + 5.minutes
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+
4
+ # A basic sanity check to have as a spec when first starting. Feel free to delete this
5
+ # once you've got real content.
6
+
7
+ describe "Sanity Check" do
8
+
9
+ it "database is connected" do
10
+ expect(ActiveRecord::Base).to be_connected
11
+ end
12
+
13
+ end
@@ -0,0 +1,21 @@
1
+ require 'simplecov'
2
+ require 'simplecov-gem-profile'
3
+ SimpleCov.start "gem"
4
+
5
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
6
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
7
+
8
+ require 'rspec'
9
+ require 'active_record'
10
+ require 'schema_plus_pg_types'
11
+ require 'schema_dev/rspec'
12
+
13
+ SchemaDev::Rspec.setup
14
+
15
+ Dir[File.dirname(__FILE__) + "/support/**/*.rb"].each {|f| require f}
16
+
17
+ RSpec.configure do |config|
18
+ config.warnings = true
19
+ end
20
+
21
+ SimpleCov.command_name "[ruby#{RUBY_VERSION}-activerecord#{::ActiveRecord.version}-#{ActiveRecord::Base.connection.adapter_name}]"
metadata ADDED
@@ -0,0 +1,189 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: schema_plus_pg_types
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Boaz Yaniv
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-01-03 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: '5.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '5.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: schema_plus_core
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.0'
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: 2.0.1
37
+ type: :runtime
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - "~>"
42
+ - !ruby/object:Gem::Version
43
+ version: '2.0'
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: 2.0.1
47
+ - !ruby/object:Gem::Dependency
48
+ name: bundler
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '1.7'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '1.7'
61
+ - !ruby/object:Gem::Dependency
62
+ name: rake
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '10.0'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '10.0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: rspec
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '3.0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '3.0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: schema_dev
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '3.8'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '3.8'
103
+ - !ruby/object:Gem::Dependency
104
+ name: simplecov
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ - !ruby/object:Gem::Dependency
118
+ name: simplecov-gem-profile
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ type: :development
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
131
+ description:
132
+ email:
133
+ - boazyan@gmail.com
134
+ executables: []
135
+ extensions: []
136
+ extra_rdoc_files: []
137
+ files:
138
+ - ".gitignore"
139
+ - ".idea/vcs.xml"
140
+ - ".travis.yml"
141
+ - Gemfile
142
+ - LICENSE.txt
143
+ - README.md
144
+ - Rakefile
145
+ - gemfiles/Gemfile.base
146
+ - gemfiles/activerecord-5.0/Gemfile.base
147
+ - gemfiles/activerecord-5.0/Gemfile.postgresql
148
+ - lib/schema_plus/pg_types.rb
149
+ - lib/schema_plus/pg_types/active_record/connection_adapters/postgresql/adapter.rb
150
+ - lib/schema_plus/pg_types/active_record/connection_adapters/postgresql/column_methods.rb
151
+ - lib/schema_plus/pg_types/active_record/connection_adapters/postgresql/oid/interval.rb
152
+ - lib/schema_plus/pg_types/active_record/connection_adapters/postgresql/schema_statements.rb
153
+ - lib/schema_plus/pg_types/active_support/duration_fixes.rb
154
+ - lib/schema_plus/pg_types/version.rb
155
+ - lib/schema_plus_pg_types.rb
156
+ - migration_spec.rb
157
+ - schema_dev.yml
158
+ - schema_plus_pg_types.gemspec
159
+ - spec/migration_spec.rb
160
+ - spec/sanity_spec.rb
161
+ - spec/spec_helper.rb
162
+ homepage: https://github.com/SchemaPlus/schema_plus_pg_types
163
+ licenses:
164
+ - MIT
165
+ metadata: {}
166
+ post_install_message:
167
+ rdoc_options: []
168
+ require_paths:
169
+ - lib
170
+ required_ruby_version: !ruby/object:Gem::Requirement
171
+ requirements:
172
+ - - ">="
173
+ - !ruby/object:Gem::Version
174
+ version: '0'
175
+ required_rubygems_version: !ruby/object:Gem::Requirement
176
+ requirements:
177
+ - - ">="
178
+ - !ruby/object:Gem::Version
179
+ version: '0'
180
+ requirements: []
181
+ rubyforge_project:
182
+ rubygems_version: 2.5.1
183
+ signing_key:
184
+ specification_version: 4
185
+ summary: Adds supports for PostgreSQL types that were left out by Rails
186
+ test_files:
187
+ - spec/migration_spec.rb
188
+ - spec/sanity_spec.rb
189
+ - spec/spec_helper.rb