schema_plus_default_expr 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: 233c5f272e73d93ee11a5689c290511864c4e613
4
+ data.tar.gz: b5989731ef1ccb2cd48b8d3e75c591d2bb3a57ec
5
+ SHA512:
6
+ metadata.gz: 37137a6e9c15d2873bcd7b2fc0b37c1e13e9d3efe7838c520d1f3f748e417015fd026c2cf650ea117c9aa7c9a17c48319de9eb66dd38da8328dea40b171b968a
7
+ data.tar.gz: 5dc9dc12ca8166865a7867220ac324e48eabc81d0c9ef873934a900ad0a15646f5610dfab46ac6d134c83891c235ebb574fa968e6cae83ea5f853f967ad6d642
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/.travis.yml ADDED
@@ -0,0 +1,17 @@
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.1.5
9
+ gemfile:
10
+ - gemfiles/activerecord-4.2/Gemfile.postgresql
11
+ - gemfiles/activerecord-4.2/Gemfile.sqlite3
12
+ env: POSTGRESQL_DB_USER=postgres
13
+ addons:
14
+ postgresql: '9.3'
15
+ before_script: bundle exec rake create_databases
16
+ after_script: bundle exec rake drop_databases
17
+ 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) 2015 ronen barzel
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,118 @@
1
+ [![Gem Version](https://badge.fury.io/rb/schema_plus_default_expr.svg)](http://badge.fury.io/rb/schema_plus_default_expr)
2
+ [![Build Status](https://secure.travis-ci.org/SchemaPlus/schema_plus_default_expr.svg)](http://travis-ci.org/SchemaPlus/schema_plus_default_expr)
3
+ [![Coverage Status](https://img.shields.io/coveralls/SchemaPlus/schema_plus_default_expr.svg)](https://coveralls.io/r/SchemaPlus/schema_plus_default_expr)
4
+ [![Dependency Status](https://gemnasium.com/lomba/schema_plus_default_expr.svg)](https://gemnasium.com/SchemaPlus/schema_plus_default_expr)
5
+
6
+ # SchemaPlus::DefaultExpr
7
+
8
+ SchemaPlus::DefaultExpr extends ActiveRecord's migrations to allow you to set the default value of a column to an SQL expression.
9
+
10
+ This gem works with PostgreSQL and Sqlite3, but not MySQL; see [Compatibility](#compatibility)below.
11
+
12
+ SchemaPlus::DefaultExpr is part of the [SchemaPlus](https://github.com/SchemaPlus/) family of Ruby on Rails ActiveRecord extension gems.
13
+
14
+ ## Installation
15
+
16
+ <!-- SCHEMA_DEV: TEMPLATE INSTALLATION - begin -->
17
+ <!-- These lines are auto-inserted from a schema_dev template -->
18
+ As usual:
19
+
20
+ ```ruby
21
+ gem "schema_plus_default_expr" # in a Gemfile
22
+ gem.add_dependency "schema_plus_default_expr" # in a .gemspec
23
+ ```
24
+
25
+ <!-- SCHEMA_DEV: TEMPLATE INSTALLATION - end -->
26
+
27
+ ## <a name="compatibility"></a>Compatibility
28
+
29
+ SchemaPlus::DefaultExpr 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.1.5** with activerecord **4.2**, using **sqlite3** and **postgresql**
34
+
35
+ <!-- SCHEMA_DEV: MATRIX - end -->
36
+
37
+ MySQL only supports SQL expression defaults for `TIMESTAMP` column types, which ActiveRecord does not use. So SchemaPlus::DefaultExpr does not work with MySQL.
38
+
39
+ ## Usage
40
+
41
+ SchemaPlus::DefaultExpr augments the syntax for setting column defaults, to support expressions or constant values:
42
+
43
+ t.datetime :seen_at, default: { expr: 'NOW()' }
44
+ t.datetime :seen_at, default: { value: "2011-12-11 00:00:00" }
45
+
46
+ The standard syntax will still work as usual:
47
+
48
+ t.datetime :seen_at, default: "2011-12-11 00:00:00"
49
+
50
+ Also, as a convenience
51
+
52
+ t.datetime :seen_at, default: :now
53
+
54
+ resolves to:
55
+
56
+ NOW() # PostgreSQL
57
+ (DATETIME('now')) # SQLite3
58
+ invalid # MySQL
59
+
60
+ ### Note on PostgreSQL & json:
61
+
62
+ If you are using Postgresql with a `json` column, ActiveRecord allows you to use a Hash for a default value. Be aware that if the hash contains just one key which is `:expr` or `:value`, then SchemaPlus::DefaultExpr will interpret, and use the corresponding value for the default. That is, these are equivalent:
63
+
64
+ t.json :fields, default: { value: { field1: 'a', field2: 'b' } }
65
+ t.json :fields, default: { field1: 'a', field2: 'b' }
66
+
67
+
68
+ ## History
69
+
70
+ * 0.1.0 - Initial release, extracted from schema_plus 1.x
71
+
72
+ ## Development & Testing
73
+
74
+ Are you interested in contributing to SchemaPlus::DefaultExpr? Thanks! Please follow
75
+ the standard protocol: fork, feature branch, develop, push, and issue pull
76
+ request.
77
+
78
+ Some things to know about to help you develop and test:
79
+
80
+ <!-- SCHEMA_DEV: TEMPLATE USES SCHEMA_DEV - begin -->
81
+ <!-- These lines are auto-inserted from a schema_dev template -->
82
+ * **schema_dev**: SchemaPlus::DefaultExpr uses [schema_dev](https://github.com/SchemaPlus/schema_dev) to
83
+ facilitate running rspec tests on the matrix of ruby, activerecord, and database
84
+ versions that the gem supports, both locally and on
85
+ [travis-ci](http://travis-ci.org/SchemaPlus/schema_plus_default_expr)
86
+
87
+ To to run rspec locally on the full matrix, do:
88
+
89
+ $ schema_dev bundle install
90
+ $ schema_dev rspec
91
+
92
+ 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.
93
+
94
+ The matrix of configurations is specified in `schema_dev.yml` in
95
+ the project root.
96
+
97
+
98
+ <!-- SCHEMA_DEV: TEMPLATE USES SCHEMA_DEV - end -->
99
+
100
+ <!-- SCHEMA_DEV: TEMPLATE USES SCHEMA_PLUS_CORE - begin -->
101
+ <!-- These lines are auto-inserted from a schema_dev template -->
102
+ * **schema_plus_core**: SchemaPlus::DefaultExpr uses the SchemaPlus::Core API that
103
+ provides middleware callback stacks to make it easy to extend
104
+ ActiveRecord's behavior. If that API is missing something you need for
105
+ your contribution, please head over to
106
+ [schema_plus_core](https://github.com/SchemaPlus/schema_plus_core) and open
107
+ an issue or pull request.
108
+
109
+ <!-- SCHEMA_DEV: TEMPLATE USES SCHEMA_PLUS_CORE - end -->
110
+
111
+ <!-- SCHEMA_DEV: TEMPLATE USES SCHEMA_MONKEY - begin -->
112
+ <!-- These lines are auto-inserted from a schema_dev template -->
113
+ * **schema_monkey**: SchemaPlus::DefaultExpr is implemented as a
114
+ [schema_monkey](https://github.com/SchemaPlus/schema_monkey) client,
115
+ using [schema_monkey](https://github.com/SchemaPlus/schema_monkey)'s
116
+ convention-based protocols for extending ActiveRecord and using middleware stacks.
117
+
118
+ <!-- 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", "~> 4.2.0"
@@ -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,10 @@
1
+ require "pathname"
2
+ eval(Pathname.new(__FILE__).dirname.join("Gemfile.base").read, binding)
3
+
4
+ platform :ruby do
5
+ gem "sqlite3"
6
+ end
7
+
8
+ platform :jruby do
9
+ gem 'activerecord-jdbcsqlite3-adapter', '>=1.3.0.beta2'
10
+ end
@@ -0,0 +1,13 @@
1
+ module SchemaPlus::DefaultExpr
2
+ module ActiveRecord
3
+ module ConnectionAdapters
4
+ module AbstractAdapter
5
+ def sql_for_function(function)
6
+ # Default nil implementation to be overriden by db adapters.
7
+ # (Keep this here to avoid failure if gem is loaded with mysql2 or
8
+ # other non-supported db adapters.)
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ module SchemaPlus::DefaultExpr
2
+ module ActiveRecord
3
+ module ConnectionAdapters
4
+ module Column
5
+ module Sqlite3
6
+ def default_function
7
+ @default_function ||= "(#{default})" if default =~ /DATETIME/
8
+ super
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,18 @@
1
+ module SchemaPlus::DefaultExpr
2
+ module ActiveRecord
3
+ module ConnectionAdapters
4
+ module PostgresqlAdapter
5
+ def default_expr_valid?(expr)
6
+ true # arbitrary sql is okay in PostgreSQL
7
+ end
8
+
9
+ def sql_for_function(function)
10
+ case function
11
+ when :now
12
+ "NOW()"
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,19 @@
1
+ module SchemaPlus::DefaultExpr
2
+ module ActiveRecord
3
+ module ConnectionAdapters
4
+ module Sqlite3Adapter
5
+
6
+ def default_expr_valid?(expr)
7
+ true # arbitrary sql is okay
8
+ end
9
+
10
+ def sql_for_function(function)
11
+ case function
12
+ when :now
13
+ "(DATETIME('now'))"
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,55 @@
1
+ module SchemaPlus::DefaultExpr
2
+ module Middleware
3
+
4
+ module Sql
5
+ module ColumnOptions
6
+
7
+ # Add options for default expressions
8
+ def before(env)
9
+ options = env.options
10
+
11
+ return unless (default = options[:default])
12
+
13
+ if default.is_a? Hash and [[:expr], [:value]].include?(default.keys)
14
+ value = default[:value]
15
+ expr = env.connection.sql_for_function(default[:expr]) || default[:expr] if default[:expr]
16
+ else
17
+ value = default
18
+ expr = env.connection.sql_for_function(default)
19
+ end
20
+
21
+ if expr
22
+ raise ArgumentError, "Invalid default expression" unless env.connection.default_expr_valid?(expr)
23
+ env.sql << " DEFAULT #{expr}"
24
+ # must explicitly check for :null to allow change_column to work on migrations
25
+ if options[:null] == false
26
+ env.sql << " NOT NULL"
27
+ end
28
+ options.delete(:default)
29
+ options.delete(:null)
30
+ else
31
+ options[:default] = value
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+ module Dumper
38
+ module Table
39
+
40
+ # Emit default expression options in dump
41
+ def after(env)
42
+ env.connection.columns(env.table.name).each do |column|
43
+ if !column.default_function.nil?
44
+ if col = env.table.columns.find(&its.name == column.name)
45
+ options = "default: { expr: #{column.default_function.inspect} }"
46
+ options += ", #{col.options}" unless col.options.blank?
47
+ col.options = options
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,5 @@
1
+ module SchemaPlus
2
+ module DefaultExpr
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,10 @@
1
+ require 'schema_plus/core'
2
+
3
+ require_relative 'default_expr/version'
4
+ require_relative 'default_expr/middleware'
5
+ require_relative 'default_expr/active_record/connection_adapters/abstract_adapter'
6
+ require_relative 'default_expr/active_record/connection_adapters/column'
7
+ require_relative 'default_expr/active_record/connection_adapters/postgresql_adapter'
8
+ require_relative 'default_expr/active_record/connection_adapters/sqlite3_adapter'
9
+
10
+ SchemaMonkey.register SchemaPlus::DefaultExpr
@@ -0,0 +1 @@
1
+ require_relative 'schema_plus/default_expr'
data/schema_dev.yml ADDED
@@ -0,0 +1,7 @@
1
+ ruby:
2
+ - 2.1.5
3
+ activerecord:
4
+ - 4.2
5
+ db:
6
+ - sqlite3
7
+ - 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/default_expr/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "schema_plus_default_expr"
8
+ gem.version = SchemaPlus::DefaultExpr::VERSION
9
+ gem.authors = ["ronen barzel"]
10
+ gem.email = ["ronen@barzel.org"]
11
+ gem.summary = %q{Extends ActiveRecord migrations to allow an SQL expression for the default value of a column}
12
+ gem.homepage = "https://github.com/SchemaPlus/schema_plus_default_expr"
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", "~> 4.2"
21
+ gem.add_dependency "schema_plus_core", "~> 0.2", ">= 0.2.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.4"
27
+ gem.add_development_dependency "simplecov"
28
+ gem.add_development_dependency "simplecov-gem-profile"
29
+ end
@@ -0,0 +1,127 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Column definition" do
4
+ before(:each) do
5
+ define_schema do
6
+ create_table :models, :force => true do |t|
7
+ end
8
+ end
9
+ class Model < ::ActiveRecord::Base ; end
10
+ end
11
+
12
+ subject {
13
+ Model.connection.execute("INSERT INTO models (dummy) values (1)")
14
+ Model.last.reload.test_column
15
+ }
16
+
17
+ context "text columns" do
18
+
19
+ before(:each) do
20
+ @nowish = /(#{Time.now.utc.to_s.sub(/:[^:]+$/, '')}|#{Time.now.to_s.sub(/:[^:]+$/,'')}).*/
21
+ end
22
+
23
+ context "just default passed" do
24
+ before(:each) do
25
+ define_test_column(:string, :default => "2011-12-11 00:00:00")
26
+ end
27
+
28
+ it "should use the normal default" do
29
+ is_expected.to eq "2011-12-11 00:00:00"
30
+ end
31
+ end
32
+
33
+ context "just default passed in hash" do
34
+ before(:each) do
35
+ define_test_column(:string, :default => { :value => "2011-12-11 00:00:00" })
36
+ end
37
+
38
+ it "should use the normal default" do
39
+ is_expected.to eq "2011-12-11 00:00:00"
40
+ end
41
+ end
42
+
43
+ context "default passed with no nulls" do
44
+ before(:each) do
45
+ define_test_column(:string, :default => "2011-12-11 00:00:00", null: false)
46
+ end
47
+
48
+ it "should use the normal default" do
49
+ is_expected.to eq "2011-12-11 00:00:00"
50
+ end
51
+ end
52
+
53
+ context "default passed in hash with no nulls" do
54
+ before(:each) do
55
+ define_test_column(:string, :default => { :value => "2011-12-11 00:00:00" }, null: false)
56
+ end
57
+
58
+ it "should use the normal default" do
59
+ is_expected.to eq "2011-12-11 00:00:00"
60
+ end
61
+ end
62
+
63
+ context "default function passed as :now" do
64
+ before(:each) do
65
+ define_test_column(:string, :default => :now)
66
+ end
67
+
68
+ it "should use NOW() as the default" do
69
+ is_expected.to match @nowish
70
+ end
71
+ end
72
+
73
+ context "default function passed as now with no nulls" do
74
+ before(:each) do
75
+ define_test_column(:string, :default => :now, null: false)
76
+ end
77
+
78
+ it "should use NOW() as the default" do
79
+ is_expected.to match @nowish
80
+ end
81
+ end
82
+
83
+ context "valid expr passed as default" do
84
+ it "uses the expression" do
85
+ define_test_column(:string, :default => { :expr => "(replace('THIS IS A TEST', 'TEST', 'DOG'))" })
86
+ is_expected.to eq "THIS IS A DOG"
87
+ end
88
+ end
89
+
90
+ end
91
+
92
+ context "boolean column" do
93
+
94
+ context "passed as boolean false" do
95
+ before(:each) do
96
+ define_test_column :boolean, :default => false
97
+ end
98
+
99
+ it "should give the default as false" do
100
+ is_expected.to eq false
101
+ end
102
+ end
103
+
104
+ context "passed as boolean true" do
105
+ before(:each) do
106
+ define_test_column :boolean, :default => true
107
+ end
108
+
109
+ it "should give the default as true" do
110
+ is_expected.to eq true
111
+ end
112
+ end
113
+ end
114
+
115
+ private
116
+
117
+ def define_test_column(type, *args)
118
+ ActiveRecord::Migration.suppress_messages do
119
+ ActiveRecord::Migration.create_table Model.table_name, :force => true do |t|
120
+ t.send type, :test_column, *args
121
+ t.integer :dummy
122
+ end
123
+ end
124
+ Model.reset_column_information
125
+ @column = Model.columns.first()
126
+ end
127
+ end
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+
3
+ describe ActiveRecord::Migration do
4
+
5
+ before(:each) do
6
+ define_schema do
7
+ create_table :posts, :force => true do |t|
8
+ t.string :content
9
+ end
10
+ end
11
+ class Post < ::ActiveRecord::Base ; end
12
+ end
13
+
14
+ context "when table is created" do
15
+
16
+ before(:each) do
17
+ @model = Post
18
+ end
19
+
20
+ it "should properly handle default values for booleans" do
21
+ expect {
22
+ recreate_table(@model) do |t|
23
+ t.boolean :bool, :default => true
24
+ end
25
+ }.to_not raise_error
26
+ expect(@model.create.reload.bool).to be true
27
+ end
28
+
29
+ it "should properly handle default values for json (#195)", :postgresql => :only do
30
+ recreate_table(@model) do |t|
31
+ t.json :json, :default => {}
32
+ end
33
+ expect(@model.create.reload.json).to eq({})
34
+ end
35
+
36
+ end
37
+
38
+ def recreate_table(model, opts={}, &block)
39
+ ActiveRecord::Migration.suppress_messages do
40
+ ActiveRecord::Migration.create_table model.table_name, opts.merge(:force => true), &block
41
+ end
42
+ model.reset_column_information
43
+ end
44
+ end
@@ -0,0 +1,113 @@
1
+ require 'spec_helper'
2
+ require 'stringio'
3
+
4
+ describe "Schema dump" do
5
+
6
+ before(:all) do
7
+ ActiveRecord::Migration.suppress_messages do
8
+ ActiveRecord::Schema.define do
9
+ connection.tables.each do |table| drop_table table, force: :cascade end
10
+
11
+ create_table :posts, :force => true do |t|
12
+ t.text :body
13
+ t.integer :user_id
14
+ t.integer :first_comment_id
15
+ t.string :string_no_default
16
+ t.integer :short_id
17
+ t.string :str_short
18
+ t.integer :integer_col
19
+ t.float :float_col
20
+ t.decimal :decimal_col
21
+ t.datetime :datetime_col
22
+ t.timestamp :timestamp_col
23
+ t.time :time_col
24
+ t.date :date_col
25
+ t.binary :binary_col
26
+ t.boolean :boolean_col
27
+ end
28
+
29
+ end
30
+ end
31
+ class ::Post < ActiveRecord::Base ; end
32
+ end
33
+
34
+ context "with date default", :postgresql => :only do
35
+ it "should dump the default hash expr as now()" do
36
+ with_additional_column Post, :posted_at, :datetime, :default => :now do
37
+ expect(dump_posts).to match(%r{t\.datetime\s+"posted_at",\s*(?:default:|:default =>)\s*\{\s*(?:expr:|:expr\s*=>)\s*"now\(\)"\s*\}})
38
+ end
39
+ end
40
+
41
+ it "should dump the default hash expr as CURRENT_TIMESTAMP" do
42
+ with_additional_column Post, :posted_at, :datetime, :default => {:expr => 'date \'2001-09-28\''} do
43
+ expect(dump_posts).to match(%r{t\.datetime\s+"posted_at",\s*(?:default:|:default =>).*2001-09-28.*})
44
+ end
45
+ end
46
+
47
+ it "can dump a complex default expression" do
48
+ with_additional_column Post, :name, :string, :default => {:expr => 'substring(random()::text from 3 for 6)'} do
49
+ expect(dump_posts).to match(%r{t\.string\s+"name",\s*(?:default:|:default\s*=>)\s*{\s*(?:expr:|:expr\s*=>)\s*"\\"substring\\"\(\(random\(\)\)::text, 3, 6\)"\s*}})
50
+ end
51
+ end
52
+ end
53
+
54
+ context "with date default", :sqlite3 => :only do
55
+ it "should dump the default hash expr as now" do
56
+ with_additional_column Post, :posted_at, :datetime, :default => :now do
57
+ expect(dump_posts).to match(%r{t\.datetime\s+"posted_at",\s*(?:default:|:default =>)\s*\{\s*(?:expr:|:expr =>)\s*"\(DATETIME\('now'\)\)"\s*\}})
58
+ end
59
+ end
60
+
61
+ it "should dump the default hash expr string as now" do
62
+ with_additional_column Post, :posted_at, :datetime, :default => { :expr => "(DATETIME('now'))" } do
63
+ expect(dump_posts).to match(%r{t\.datetime\s+"posted_at",\s*(?:default:|:default =>)\s*\{\s*(?:expr:|:expr =>)\s*"\(DATETIME\('now'\)\)"\s*\}})
64
+ end
65
+ end
66
+
67
+ it "should dump the default value normally" do
68
+ with_additional_column Post, :posted_at, :string, :default => "now" do
69
+ expect(dump_posts).to match(%r{t\.string\s*"posted_at",\s*(?:default:|:default =>)\s*"now"})
70
+ end
71
+ end
72
+ end
73
+
74
+ it "should leave out :default when default was changed to null" do
75
+ ActiveRecord::Migration.suppress_messages do
76
+ ActiveRecord::Migration.change_column_default :posts, :string_no_default, nil
77
+ end
78
+ # mysql2 includes 'limit: 255' in the output. that's OK, just want to
79
+ # make sure the full line doesn't have 'default' in it.
80
+ expect(dump_posts).to match(%r{t\.string\s+"string_no_default"\s*(,\s*limit:\s*\d+)?$})
81
+ end
82
+
83
+ protected
84
+ def to_regexp(string)
85
+ Regexp.new(Regexp.escape(string))
86
+ end
87
+
88
+ def with_additional_column(model, column_name, column_type, options)
89
+ table_columns = model.columns.reject{|column| column.name == 'id'}
90
+ ActiveRecord::Migration.suppress_messages do
91
+ ActiveRecord::Migration.create_table model.table_name, :force => true do |t|
92
+ table_columns.each do |column|
93
+ t.column column.name, column.type, :default => column.default
94
+ end
95
+ t.column column_name, column_type, options
96
+ end
97
+ end
98
+ yield
99
+ end
100
+
101
+ def dump_schema(opts={})
102
+ stream = StringIO.new
103
+ ActiveRecord::SchemaDumper.ignore_tables = Array.wrap(opts[:ignore]) || []
104
+ ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
105
+ stream.string
106
+ end
107
+
108
+ def dump_posts
109
+ dump_schema(:ignore => %w[users comments])
110
+ end
111
+
112
+ end
113
+
@@ -0,0 +1,33 @@
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_default_expr'
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
+ def define_schema(&block)
22
+ ActiveRecord::Migration.suppress_messages do
23
+ ActiveRecord::Schema.define do
24
+ connection.tables.each do |table|
25
+ drop_table table, force: :cascade
26
+ end
27
+ instance_eval &block
28
+ end
29
+ end
30
+ end
31
+
32
+
33
+ SimpleCov.command_name "[ruby#{RUBY_VERSION}-activerecord#{::ActiveRecord.version}-#{ActiveRecord::Base.connection.adapter_name}]"
metadata ADDED
@@ -0,0 +1,191 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: schema_plus_default_expr
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - ronen barzel
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-04-01 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: '4.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '4.2'
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: '0.2'
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: 0.2.1
37
+ type: :runtime
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - "~>"
42
+ - !ruby/object:Gem::Version
43
+ version: '0.2'
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: 0.2.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.4'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '3.4'
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
+ - ronen@barzel.org
134
+ executables: []
135
+ extensions: []
136
+ extra_rdoc_files: []
137
+ files:
138
+ - ".gitignore"
139
+ - ".travis.yml"
140
+ - Gemfile
141
+ - LICENSE.txt
142
+ - README.md
143
+ - Rakefile
144
+ - gemfiles/Gemfile.base
145
+ - gemfiles/activerecord-4.2/Gemfile.base
146
+ - gemfiles/activerecord-4.2/Gemfile.postgresql
147
+ - gemfiles/activerecord-4.2/Gemfile.sqlite3
148
+ - lib/schema_plus/default_expr.rb
149
+ - lib/schema_plus/default_expr/active_record/connection_adapters/abstract_adapter.rb
150
+ - lib/schema_plus/default_expr/active_record/connection_adapters/column.rb
151
+ - lib/schema_plus/default_expr/active_record/connection_adapters/postgresql_adapter.rb
152
+ - lib/schema_plus/default_expr/active_record/connection_adapters/sqlite3_adapter.rb
153
+ - lib/schema_plus/default_expr/middleware.rb
154
+ - lib/schema_plus/default_expr/version.rb
155
+ - lib/schema_plus_default_expr.rb
156
+ - schema_dev.yml
157
+ - schema_plus_default_expr.gemspec
158
+ - spec/column_default_spec.rb
159
+ - spec/migration_spec.rb
160
+ - spec/schema_dumper_spec.rb
161
+ - spec/spec_helper.rb
162
+ homepage: https://github.com/SchemaPlus/schema_plus_default_expr
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.2.2
183
+ signing_key:
184
+ specification_version: 4
185
+ summary: Extends ActiveRecord migrations to allow an SQL expression for the default
186
+ value of a column
187
+ test_files:
188
+ - spec/column_default_spec.rb
189
+ - spec/migration_spec.rb
190
+ - spec/schema_dumper_spec.rb
191
+ - spec/spec_helper.rb