diff --git a/.gitignore b/.gitignore index 14e3ed5..b774463 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ + *.gem *.rbc /.config @@ -71,3 +72,5 @@ bower.json # Ignore pow environment settings .powenv + +/.env diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..923a439 --- /dev/null +++ b/Gemfile @@ -0,0 +1,61 @@ +source 'https://rubygems.org' +ruby '2.3.0' + +# Bundle edge Rails instead: gem 'rails', github: 'rails/rails' +gem 'rails', '4.2.6' +# Use sqlite3 as the database for Active Record +gem 'pg' +# Use SCSS for stylesheets +gem 'sass-rails', '~> 5.0' +# Use Uglifier as compressor for JavaScript assets +gem 'uglifier', '>= 1.3.0' +# Use CoffeeScript for .coffee assets and views +gem 'coffee-rails', '~> 4.1.0' +# See https://github.com/rails/execjs#readme for more supported runtimes +# gem 'therubyracer', platforms: :ruby + +# Use jquery as the JavaScript library +gem 'jquery-rails' +# Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks +gem 'turbolinks' +# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder +gem 'jbuilder', '~> 2.0' +# bundle exec rake doc:rails generates the API under doc/api. +gem 'sdoc', '~> 0.4.0', group: :doc + +gem 'active_shipping' +# Use ActiveModel has_secure_password +gem 'bcrypt', '~> 3.1.7' +gem 'dotenv-rails' + +# Use Unicorn as the app server +# gem 'unicorn' + +# Use Capistrano for deployment +# gem 'capistrano-rails', group: :development + +group :development, :test do + # Call 'byebug' anywhere in the code to stop execution and get a debugger console + gem 'byebug' + gem 'dotenv-rails' + gem 'minitest' + gem 'minitest-reporters' + gem 'simplecov' + gem 'minitest-vcr' + gem 'webmock' +end + +group :development do + # Access an IRB console on exception pages or by using <%= console %> in views + gem 'web-console', '~> 2.0' + gem 'rails-erd' + # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring + gem 'spring' + gem "pry-rails" + gem "better_errors" + gem "binding_of_caller" +end + +group :production do + gem 'rails_12factor' +end diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..14d77ca --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,244 @@ +GEM + remote: https://rubygems.org/ + specs: + actionmailer (4.2.6) + actionpack (= 4.2.6) + actionview (= 4.2.6) + activejob (= 4.2.6) + mail (~> 2.5, >= 2.5.4) + rails-dom-testing (~> 1.0, >= 1.0.5) + actionpack (4.2.6) + actionview (= 4.2.6) + activesupport (= 4.2.6) + rack (~> 1.6) + rack-test (~> 0.6.2) + rails-dom-testing (~> 1.0, >= 1.0.5) + rails-html-sanitizer (~> 1.0, >= 1.0.2) + actionview (4.2.6) + activesupport (= 4.2.6) + builder (~> 3.1) + erubis (~> 2.7.0) + rails-dom-testing (~> 1.0, >= 1.0.5) + rails-html-sanitizer (~> 1.0, >= 1.0.2) + active_shipping (1.7.2) + active_utils (~> 3.2.0) + activesupport (>= 3.2, < 5.0.0) + nokogiri (>= 1.6) + quantified (~> 1.0.1) + active_utils (3.2.0) + activesupport (>= 3.2) + i18n + activejob (4.2.6) + activesupport (= 4.2.6) + globalid (>= 0.3.0) + activemodel (4.2.6) + activesupport (= 4.2.6) + builder (~> 3.1) + activerecord (4.2.6) + activemodel (= 4.2.6) + activesupport (= 4.2.6) + arel (~> 6.0) + activesupport (4.2.6) + i18n (~> 0.7) + json (~> 1.7, >= 1.7.7) + minitest (~> 5.1) + thread_safe (~> 0.3, >= 0.3.4) + tzinfo (~> 1.1) + addressable (2.4.0) + ansi (1.5.0) + arel (6.0.3) + bcrypt (3.1.11) + better_errors (2.1.1) + coderay (>= 1.0.0) + erubis (>= 2.6.6) + rack (>= 0.9.0) + binding_of_caller (0.7.2) + debug_inspector (>= 0.0.1) + builder (3.2.2) + byebug (9.0.4) + choice (0.2.0) + coderay (1.1.1) + coffee-rails (4.1.1) + coffee-script (>= 2.2.0) + railties (>= 4.0.0, < 5.1.x) + coffee-script (2.4.1) + coffee-script-source + execjs + coffee-script-source (1.10.0) + concurrent-ruby (1.0.2) + crack (0.4.3) + safe_yaml (~> 1.0.0) + debug_inspector (0.0.2) + docile (1.1.5) + dotenv (2.1.1) + dotenv-rails (2.1.1) + dotenv (= 2.1.1) + railties (>= 4.0, < 5.1) + erubis (2.7.0) + execjs (2.7.0) + globalid (0.3.6) + activesupport (>= 4.1.0) + hashdiff (0.3.0) + i18n (0.7.0) + jbuilder (2.4.1) + activesupport (>= 3.0.0, < 5.1) + multi_json (~> 1.2) + jquery-rails (4.1.1) + rails-dom-testing (>= 1, < 3) + railties (>= 4.2.0) + thor (>= 0.14, < 2.0) + json (1.8.3) + loofah (2.0.3) + nokogiri (>= 1.5.9) + mail (2.6.4) + mime-types (>= 1.16, < 4) + method_source (0.8.2) + mime-types (3.1) + mime-types-data (~> 3.2015) + mime-types-data (3.2016.0521) + mini_portile2 (2.0.0) + minispec-metadata (2.0.0) + minitest + minitest (5.9.0) + minitest-reporters (1.1.9) + ansi + builder + minitest (>= 5.0) + ruby-progressbar + minitest-vcr (1.4.0) + minispec-metadata (~> 2.0) + minitest (>= 4.7.5) + vcr (>= 2.9) + multi_json (1.12.1) + nokogiri (1.6.7.2) + mini_portile2 (~> 2.0.0.rc2) + pg (0.18.4) + pry (0.10.3) + coderay (~> 1.1.0) + method_source (~> 0.8.1) + slop (~> 3.4) + pry-rails (0.3.4) + pry (>= 0.9.10) + quantified (1.0.1) + rack (1.6.4) + rack-test (0.6.3) + rack (>= 1.0) + rails (4.2.6) + actionmailer (= 4.2.6) + actionpack (= 4.2.6) + actionview (= 4.2.6) + activejob (= 4.2.6) + activemodel (= 4.2.6) + activerecord (= 4.2.6) + activesupport (= 4.2.6) + bundler (>= 1.3.0, < 2.0) + railties (= 4.2.6) + sprockets-rails + rails-deprecated_sanitizer (1.0.3) + activesupport (>= 4.2.0.alpha) + rails-dom-testing (1.0.7) + activesupport (>= 4.2.0.beta, < 5.0) + nokogiri (~> 1.6.0) + rails-deprecated_sanitizer (>= 1.0.1) + rails-erd (1.4.7) + activerecord (>= 3.2) + activesupport (>= 3.2) + choice (~> 0.2.0) + ruby-graphviz (~> 1.2) + rails-html-sanitizer (1.0.3) + loofah (~> 2.0) + rails_12factor (0.0.3) + rails_serve_static_assets + rails_stdout_logging + rails_serve_static_assets (0.0.5) + rails_stdout_logging (0.0.5) + railties (4.2.6) + actionpack (= 4.2.6) + activesupport (= 4.2.6) + rake (>= 0.8.7) + thor (>= 0.18.1, < 2.0) + rake (11.1.2) + rdoc (4.2.2) + json (~> 1.4) + ruby-graphviz (1.2.2) + ruby-progressbar (1.8.1) + safe_yaml (1.0.4) + sass (3.4.22) + sass-rails (5.0.4) + railties (>= 4.0.0, < 5.0) + sass (~> 3.1) + sprockets (>= 2.8, < 4.0) + sprockets-rails (>= 2.0, < 4.0) + tilt (>= 1.1, < 3) + sdoc (0.4.1) + json (~> 1.7, >= 1.7.7) + rdoc (~> 4.0) + simplecov (0.11.2) + docile (~> 1.1.0) + json (~> 1.8) + simplecov-html (~> 0.10.0) + simplecov-html (0.10.0) + slop (3.6.0) + spring (1.7.1) + sprockets (3.6.0) + concurrent-ruby (~> 1.0) + rack (> 1, < 3) + sprockets-rails (3.0.4) + actionpack (>= 4.0) + activesupport (>= 4.0) + sprockets (>= 3.0.0) + thor (0.19.1) + thread_safe (0.3.5) + tilt (2.0.4) + turbolinks (2.5.3) + coffee-rails + tzinfo (1.2.2) + thread_safe (~> 0.1) + uglifier (3.0.0) + execjs (>= 0.3.0, < 3) + vcr (3.0.3) + web-console (2.3.0) + activemodel (>= 4.0) + binding_of_caller (>= 0.7.2) + railties (>= 4.0) + sprockets-rails (>= 2.0, < 4.0) + webmock (2.0.3) + addressable (>= 2.3.6) + crack (>= 0.3.2) + hashdiff + +PLATFORMS + ruby + +DEPENDENCIES + active_shipping + bcrypt (~> 3.1.7) + better_errors + binding_of_caller + byebug + coffee-rails (~> 4.1.0) + dotenv-rails + jbuilder (~> 2.0) + jquery-rails + minitest + minitest-reporters + minitest-vcr + pg + pry-rails + rails (= 4.2.6) + rails-erd + rails_12factor + sass-rails (~> 5.0) + sdoc (~> 0.4.0) + simplecov + spring + turbolinks + uglifier (>= 1.3.0) + web-console (~> 2.0) + webmock + +RUBY VERSION + ruby 2.2.3p173 + +BUNDLED WITH + 1.12.4 diff --git a/README.rdoc b/README.rdoc new file mode 100644 index 0000000..dd4e97e --- /dev/null +++ b/README.rdoc @@ -0,0 +1,28 @@ +== README + +This README would normally document whatever steps are necessary to get the +application up and running. + +Things you may want to cover: + +* Ruby version + +* System dependencies + +* Configuration + +* Database creation + +* Database initialization + +* How to run the test suite + +* Services (job queues, cache servers, search engines, etc.) + +* Deployment instructions + +* ... + + +Please feel free to use a different markup language if you do not plan to run +rake doc:app. diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..ba6b733 --- /dev/null +++ b/Rakefile @@ -0,0 +1,6 @@ +# Add your own tasks in files placed in lib/tasks ending in .rake, +# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. + +require File.expand_path('../config/application', __FILE__) + +Rails.application.load_tasks diff --git a/app/assets/images/.keep b/app/assets/images/.keep new file mode 100644 index 0000000..e69de29 diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js new file mode 100644 index 0000000..e07c5a8 --- /dev/null +++ b/app/assets/javascripts/application.js @@ -0,0 +1,16 @@ +// This is a manifest file that'll be compiled into application.js, which will include all the files +// listed below. +// +// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts, +// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path. +// +// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the +// compiled file. +// +// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details +// about supported directives. +// +//= require jquery +//= require jquery_ujs +//= require turbolinks +//= require_tree . diff --git a/app/assets/javascripts/shippings.coffee b/app/assets/javascripts/shippings.coffee new file mode 100644 index 0000000..24f83d1 --- /dev/null +++ b/app/assets/javascripts/shippings.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css new file mode 100644 index 0000000..f9cd5b3 --- /dev/null +++ b/app/assets/stylesheets/application.css @@ -0,0 +1,15 @@ +/* + * This is a manifest file that'll be compiled into application.css, which will include all the files + * listed below. + * + * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets, + * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path. + * + * You're free to add application-wide styles to this file and they'll appear at the bottom of the + * compiled file so the styles you add here take precedence over styles defined in any styles + * defined in the other CSS/SCSS files in this directory. It is generally better to create a new + * file per style scope. + * + *= require_tree . + *= require_self + */ diff --git a/app/assets/stylesheets/shippings.scss b/app/assets/stylesheets/shippings.scss new file mode 100644 index 0000000..786f3f9 --- /dev/null +++ b/app/assets/stylesheets/shippings.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the Shippings controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb new file mode 100644 index 0000000..3c2196e --- /dev/null +++ b/app/controllers/application_controller.rb @@ -0,0 +1,8 @@ +class ApplicationController < ActionController::Base + # Prevent CSRF attacks by raising an exception. + # For APIs, you may want to use :null_session instead. + # protect_from_forgery with: :exception + + protect_from_forgery with: :null_session, if: Proc.new { |c| c.request.format == 'application/json' } + +end diff --git a/app/controllers/concerns/.keep b/app/controllers/concerns/.keep new file mode 100644 index 0000000..e69de29 diff --git a/app/controllers/shippings_controller.rb b/app/controllers/shippings_controller.rb new file mode 100644 index 0000000..1546952 --- /dev/null +++ b/app/controllers/shippings_controller.rb @@ -0,0 +1,28 @@ +class ShippingsController < ApplicationController + + def shipping_rates + # get the shipping rate from shipping.rb rate method + # using the params(orgin, destination and package weight info) + + origins = params["origins"] + destination = params["destination"] + # order = params[:shipping][:order] + + + # send the response to method that will calculate rate + # rates = shipping_rate_calculator(orgin, destination, weight) + + shipping_rates_values = Shipping.shipping_rates_calculator(origins, destination) + + response = {shipping_rates_values: shipping_rates_values} + # create a log of incoming request from user + log = Log.create(request: response.to_s, response: response.to_s) + + + if shipping_rates_values + render json: shipping_rates_values.as_json + else + render json: [], status: :no_content + end + end +end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb new file mode 100644 index 0000000..de6be79 --- /dev/null +++ b/app/helpers/application_helper.rb @@ -0,0 +1,2 @@ +module ApplicationHelper +end diff --git a/app/helpers/shippings_helper.rb b/app/helpers/shippings_helper.rb new file mode 100644 index 0000000..44e7bda --- /dev/null +++ b/app/helpers/shippings_helper.rb @@ -0,0 +1,2 @@ +module ShippingsHelper +end diff --git a/app/mailers/.keep b/app/mailers/.keep new file mode 100644 index 0000000..e69de29 diff --git a/app/models/.keep b/app/models/.keep new file mode 100644 index 0000000..e69de29 diff --git a/app/models/concerns/.keep b/app/models/concerns/.keep new file mode 100644 index 0000000..e69de29 diff --git a/app/models/log.rb b/app/models/log.rb new file mode 100644 index 0000000..8e2fbe7 --- /dev/null +++ b/app/models/log.rb @@ -0,0 +1,3 @@ +class Log < ActiveRecord::Base + +end diff --git a/app/models/shipping.rb b/app/models/shipping.rb new file mode 100644 index 0000000..83fd517 --- /dev/null +++ b/app/models/shipping.rb @@ -0,0 +1,76 @@ + require 'active_shipping' + + # returns shipping rates and determines the size of a package given weight + # uses active shipping to calculate and return rates + class Shipping + + SMALL = [5, 5, 5] + MEDIUM = [10, 10, 10] + LARGE = [20, 20, 20] + + + # UPS_KEY = "9D0CA9FE6A4849E8" + + def initializer + + # @ups = ActiveShipping::UPS.new(login: ENV["UPS_LOGIN"], password: ENV["UPS_PASSWORD"], key: ENV["UPS_KEY"]) + @ups = ActiveShipping::UPS.new(login: ENV["UPS_LOGIN"], password: ENV["UPS_PASSWORD"], key: ENV["UPS_KEY"]) + + end + + def self.shipping_rates_calculator(origins, destination) + + destination = active_shipping_location(destination) + + total_rates = origins.map do |origin_hash| + + origin = active_shipping_location(origin_hash["origin"]) + + package = active_shipping_package(origin_hash) + @ups = ActiveShipping::UPS.new(login: ENV["UPS_LOGIN"], password: ENV["UPS_PASSWORD"], key: ENV["UPS_KEY"]) + + response = @ups.find_rates(origin, destination, package) + if response.message == "Success" + response.rates.sort_by(&:price).collect {|rate| [rate.service_name, rate.price]} + # response.rates will return an array of values + # => [["UPS Standard", 3936], + # ["UPS Worldwide Expedited", 8682], + # ["UPS Saver", 9348], + # ["UPS Express", 9702], + # ["UPS Worldwide Express Plus", 14502]] + else + "Invalid" + end + end + total_rates + end + + def self.active_shipping_location(location) + + + # location = ActiveShipping::Location.new(country: location["country"], state: location["state"], city: location["city"], zip: location["zip"]) + location = ActiveShipping::Location.new(country: location["country"], + state: location["state"], + city: location["city"], + zip: location["zip"]) + + + end + + def self.active_shipping_package(package_info) + package = ActiveShipping::Package.new((package_info["weight"].to_f) * 16, + package_size(package_info["weight"].to_f)) + end + + def self.package_size(weight) + # determine the size of the package depending on the weight using set box sizes + if weight < 20 + SMALL + elsif weight < 40 + MEDIUM + else + LARGE + end + end + + end diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb new file mode 100644 index 0000000..f59267c --- /dev/null +++ b/app/views/layouts/application.html.erb @@ -0,0 +1,14 @@ + + + + BetsyShippingService + <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %> + <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %> + <%= csrf_meta_tags %> + + + +<%= yield %> + + + diff --git a/bin/bundle b/bin/bundle new file mode 100755 index 0000000..66e9889 --- /dev/null +++ b/bin/bundle @@ -0,0 +1,3 @@ +#!/usr/bin/env ruby +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) +load Gem.bin_path('bundler', 'bundle') diff --git a/bin/rails b/bin/rails new file mode 100755 index 0000000..0138d79 --- /dev/null +++ b/bin/rails @@ -0,0 +1,9 @@ +#!/usr/bin/env ruby +begin + load File.expand_path('../spring', __FILE__) +rescue LoadError => e + raise unless e.message.include?('spring') +end +APP_PATH = File.expand_path('../../config/application', __FILE__) +require_relative '../config/boot' +require 'rails/commands' diff --git a/bin/rake b/bin/rake new file mode 100755 index 0000000..d87d5f5 --- /dev/null +++ b/bin/rake @@ -0,0 +1,9 @@ +#!/usr/bin/env ruby +begin + load File.expand_path('../spring', __FILE__) +rescue LoadError => e + raise unless e.message.include?('spring') +end +require_relative '../config/boot' +require 'rake' +Rake.application.run diff --git a/bin/setup b/bin/setup new file mode 100755 index 0000000..acdb2c1 --- /dev/null +++ b/bin/setup @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby +require 'pathname' + +# path to your application root. +APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) + +Dir.chdir APP_ROOT do + # This script is a starting point to setup your application. + # Add necessary setup steps to this file: + + puts "== Installing dependencies ==" + system "gem install bundler --conservative" + system "bundle check || bundle install" + + # puts "\n== Copying sample files ==" + # unless File.exist?("config/database.yml") + # system "cp config/database.yml.sample config/database.yml" + # end + + puts "\n== Preparing database ==" + system "bin/rake db:setup" + + puts "\n== Removing old logs and tempfiles ==" + system "rm -f log/*" + system "rm -rf tmp/cache" + + puts "\n== Restarting application server ==" + system "touch tmp/restart.txt" +end diff --git a/bin/spring b/bin/spring new file mode 100755 index 0000000..7fe232c --- /dev/null +++ b/bin/spring @@ -0,0 +1,15 @@ +#!/usr/bin/env ruby + +# This file loads spring without using Bundler, in order to be fast. +# It gets overwritten when you run the `spring binstub` command. + +unless defined?(Spring) + require 'rubygems' + require 'bundler' + + if (match = Bundler.default_lockfile.read.match(/^GEM$.*?^ (?: )*spring \((.*?)\)$.*?^$/m)) + Gem.paths = { 'GEM_PATH' => [Bundler.bundle_path.to_s, *Gem.path].uniq.join(Gem.path_separator) } + gem 'spring', match[1] + require 'spring/binstub' + end +end diff --git a/config.ru b/config.ru new file mode 100644 index 0000000..bd83b25 --- /dev/null +++ b/config.ru @@ -0,0 +1,4 @@ +# This file is used by Rack-based servers to start the application. + +require ::File.expand_path('../config/environment', __FILE__) +run Rails.application diff --git a/config/application.rb b/config/application.rb new file mode 100644 index 0000000..4306643 --- /dev/null +++ b/config/application.rb @@ -0,0 +1,26 @@ +require File.expand_path('../boot', __FILE__) + +require 'rails/all' + +# Require the gems listed in Gemfile, including any gems +# you've limited to :test, :development, or :production. +Bundler.require(*Rails.groups) + +module BetsyShippingService + class Application < Rails::Application + # Settings in config/environments/* take precedence over those specified here. + # Application configuration should go into files in config/initializers + # -- all .rb files in that directory are automatically loaded. + + # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. + # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. + # config.time_zone = 'Central Time (US & Canada)' + + # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. + # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] + # config.i18n.default_locale = :de + + # Do not swallow errors in after_commit/after_rollback callbacks. + config.active_record.raise_in_transactional_callbacks = true + end +end diff --git a/config/boot.rb b/config/boot.rb new file mode 100644 index 0000000..6b750f0 --- /dev/null +++ b/config/boot.rb @@ -0,0 +1,3 @@ +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) + +require 'bundler/setup' # Set up gems listed in the Gemfile. diff --git a/config/database.yml b/config/database.yml new file mode 100644 index 0000000..d514edc --- /dev/null +++ b/config/database.yml @@ -0,0 +1,27 @@ +# SQLite version 3.x +# gem install sqlite3 +# +# Ensure the SQLite 3 gem is defined in your Gemfile +# gem 'sqlite3' +# +default: &default + adapter: postgresql + encoding: unicode + pool: 5 + +development: + <<: *default + database: shipping_development + +# Warning: The database defined as "test" will be erased and +# re-generated from your development database when you run "rake". +# Do not set this db to the same as development or production. +test: + <<: *default + database: shipping_test + +production: + <<: *default + database: shipping_development + username: shipping + password: <%= ENV['SHIPPING_DATABASE_PASSWORD'] %> diff --git a/config/environment.rb b/config/environment.rb new file mode 100644 index 0000000..ee8d90d --- /dev/null +++ b/config/environment.rb @@ -0,0 +1,5 @@ +# Load the Rails application. +require File.expand_path('../application', __FILE__) + +# Initialize the Rails application. +Rails.application.initialize! diff --git a/config/environments/development.rb b/config/environments/development.rb new file mode 100644 index 0000000..b55e214 --- /dev/null +++ b/config/environments/development.rb @@ -0,0 +1,41 @@ +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # In the development environment your application's code is reloaded on + # every request. This slows down response time but is perfect for development + # since you don't have to restart the web server when you make code changes. + config.cache_classes = false + + # Do not eager load code on boot. + config.eager_load = false + + # Show full error reports and disable caching. + config.consider_all_requests_local = true + config.action_controller.perform_caching = false + + # Don't care if the mailer can't send. + config.action_mailer.raise_delivery_errors = false + + # Print deprecation notices to the Rails logger. + config.active_support.deprecation = :log + + # Raise an error on page load if there are pending migrations. + config.active_record.migration_error = :page_load + + # Debug mode disables concatenation and preprocessing of assets. + # This option may cause significant delays in view rendering with a large + # number of complex assets. + config.assets.debug = true + + # Asset digests allow you to set far-future HTTP expiration dates on all assets, + # yet still be able to expire them through the digest params. + config.assets.digest = true + + # Adds additional error checking when serving assets at runtime. + # Checks for improperly declared sprockets dependencies. + # Raises helpful error messages. + config.assets.raise_runtime_errors = true + + # Raises error for missing translations + # config.action_view.raise_on_missing_translations = true +end diff --git a/config/environments/production.rb b/config/environments/production.rb new file mode 100644 index 0000000..5c1b32e --- /dev/null +++ b/config/environments/production.rb @@ -0,0 +1,79 @@ +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # Code is not reloaded between requests. + config.cache_classes = true + + # Eager load code on boot. This eager loads most of Rails and + # your application in memory, allowing both threaded web servers + # and those relying on copy on write to perform better. + # Rake tasks automatically ignore this option for performance. + config.eager_load = true + + # Full error reports are disabled and caching is turned on. + config.consider_all_requests_local = false + config.action_controller.perform_caching = true + + # Enable Rack::Cache to put a simple HTTP cache in front of your application + # Add `rack-cache` to your Gemfile before enabling this. + # For large-scale production use, consider using a caching reverse proxy like + # NGINX, varnish or squid. + # config.action_dispatch.rack_cache = true + + # Disable serving static files from the `/public` folder by default since + # Apache or NGINX already handles this. + config.serve_static_files = ENV['RAILS_SERVE_STATIC_FILES'].present? + + # Compress JavaScripts and CSS. + config.assets.js_compressor = :uglifier + # config.assets.css_compressor = :sass + + # Do not fallback to assets pipeline if a precompiled asset is missed. + config.assets.compile = false + + # Asset digests allow you to set far-future HTTP expiration dates on all assets, + # yet still be able to expire them through the digest params. + config.assets.digest = true + + # `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb + + # Specifies the header that your server uses for sending files. + # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache + # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX + + # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. + # config.force_ssl = true + + # Use the lowest log level to ensure availability of diagnostic information + # when problems arise. + config.log_level = :debug + + # Prepend all log lines with the following tags. + # config.log_tags = [ :subdomain, :uuid ] + + # Use a different logger for distributed setups. + # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) + + # Use a different cache store in production. + # config.cache_store = :mem_cache_store + + # Enable serving of images, stylesheets, and JavaScripts from an asset server. + # config.action_controller.asset_host = 'http://assets.example.com' + + # Ignore bad email addresses and do not raise email delivery errors. + # Set this to true and configure the email server for immediate delivery to raise delivery errors. + # config.action_mailer.raise_delivery_errors = false + + # Enable locale fallbacks for I18n (makes lookups for any locale fall back to + # the I18n.default_locale when a translation cannot be found). + config.i18n.fallbacks = true + + # Send deprecation notices to registered listeners. + config.active_support.deprecation = :notify + + # Use default logging formatter so that PID and timestamp are not suppressed. + config.log_formatter = ::Logger::Formatter.new + + # Do not dump schema after migrations. + config.active_record.dump_schema_after_migration = false +end diff --git a/config/environments/test.rb b/config/environments/test.rb new file mode 100644 index 0000000..1c19f08 --- /dev/null +++ b/config/environments/test.rb @@ -0,0 +1,42 @@ +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # The test environment is used exclusively to run your application's + # test suite. You never need to work with it otherwise. Remember that + # your test database is "scratch space" for the test suite and is wiped + # and recreated between test runs. Don't rely on the data there! + config.cache_classes = true + + # Do not eager load code on boot. This avoids loading your whole application + # just for the purpose of running a single test. If you are using a tool that + # preloads Rails for running tests, you may have to set it to true. + config.eager_load = false + + # Configure static file server for tests with Cache-Control for performance. + config.serve_static_files = true + config.static_cache_control = 'public, max-age=3600' + + # Show full error reports and disable caching. + config.consider_all_requests_local = true + config.action_controller.perform_caching = false + + # Raise exceptions instead of rendering exception templates. + config.action_dispatch.show_exceptions = false + + # Disable request forgery protection in test environment. + config.action_controller.allow_forgery_protection = false + + # Tell Action Mailer not to deliver emails to the real world. + # The :test delivery method accumulates sent emails in the + # ActionMailer::Base.deliveries array. + config.action_mailer.delivery_method = :test + + # Randomize the order test cases are executed. + config.active_support.test_order = :random + + # Print deprecation notices to the stderr. + config.active_support.deprecation = :stderr + + # Raises error for missing translations + # config.action_view.raise_on_missing_translations = true +end diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb new file mode 100644 index 0000000..01ef3e6 --- /dev/null +++ b/config/initializers/assets.rb @@ -0,0 +1,11 @@ +# Be sure to restart your server when you modify this file. + +# Version of your assets, change this if you want to expire all your assets. +Rails.application.config.assets.version = '1.0' + +# Add additional assets to the asset load path +# Rails.application.config.assets.paths << Emoji.images_path + +# Precompile additional assets. +# application.js, application.css, and all non-JS/CSS in app/assets folder are already added. +# Rails.application.config.assets.precompile += %w( search.js ) diff --git a/config/initializers/backtrace_silencers.rb b/config/initializers/backtrace_silencers.rb new file mode 100644 index 0000000..59385cd --- /dev/null +++ b/config/initializers/backtrace_silencers.rb @@ -0,0 +1,7 @@ +# Be sure to restart your server when you modify this file. + +# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. +# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } + +# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. +# Rails.backtrace_cleaner.remove_silencers! diff --git a/config/initializers/cookies_serializer.rb b/config/initializers/cookies_serializer.rb new file mode 100644 index 0000000..7f70458 --- /dev/null +++ b/config/initializers/cookies_serializer.rb @@ -0,0 +1,3 @@ +# Be sure to restart your server when you modify this file. + +Rails.application.config.action_dispatch.cookies_serializer = :json diff --git a/config/initializers/filter_parameter_logging.rb b/config/initializers/filter_parameter_logging.rb new file mode 100644 index 0000000..4a994e1 --- /dev/null +++ b/config/initializers/filter_parameter_logging.rb @@ -0,0 +1,4 @@ +# Be sure to restart your server when you modify this file. + +# Configure sensitive parameters which will be filtered from the log file. +Rails.application.config.filter_parameters += [:password] diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb new file mode 100644 index 0000000..3a5a406 --- /dev/null +++ b/config/initializers/inflections.rb @@ -0,0 +1,19 @@ +# ActiveSupport::Inflector.inflections(:en) do |inflect| +# inflect.acronym 'API' +# end +# Be sure to restart your server when you modify this file. + +# Add new inflection rules using the following format. Inflections +# are locale specific, and you may define rules for as many different +# locales as you wish. All of these examples are active by default: +# ActiveSupport::Inflector.inflections(:en) do |inflect| +# inflect.plural /^(ox)$/i, '\1en' +# inflect.singular /^(ox)en/i, '\1' +# inflect.irregular 'person', 'people' +# inflect.uncountable %w( fish sheep ) +# end + +# These inflection rules are supported but not enabled by default: +# ActiveSupport::Inflector.inflections(:en) do |inflect| +# inflect.acronym 'RESTful' +# end diff --git a/config/initializers/mime_types.rb b/config/initializers/mime_types.rb new file mode 100644 index 0000000..dc18996 --- /dev/null +++ b/config/initializers/mime_types.rb @@ -0,0 +1,4 @@ +# Be sure to restart your server when you modify this file. + +# Add new mime types for use in respond_to blocks: +# Mime::Type.register "text/richtext", :rtf diff --git a/config/initializers/session_store.rb b/config/initializers/session_store.rb new file mode 100644 index 0000000..d697a21 --- /dev/null +++ b/config/initializers/session_store.rb @@ -0,0 +1,3 @@ +# Be sure to restart your server when you modify this file. + +Rails.application.config.session_store :cookie_store, key: '_betsy-shipping-service_session' diff --git a/config/initializers/wrap_parameters.rb b/config/initializers/wrap_parameters.rb new file mode 100644 index 0000000..33725e9 --- /dev/null +++ b/config/initializers/wrap_parameters.rb @@ -0,0 +1,14 @@ +# Be sure to restart your server when you modify this file. + +# This file contains settings for ActionController::ParamsWrapper which +# is enabled by default. + +# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. +ActiveSupport.on_load(:action_controller) do + wrap_parameters format: [:json] if respond_to?(:wrap_parameters) +end + +# To enable root element in JSON for ActiveRecord objects. +# ActiveSupport.on_load(:active_record) do +# self.include_root_in_json = true +# end diff --git a/config/locales/en.yml b/config/locales/en.yml new file mode 100644 index 0000000..0653957 --- /dev/null +++ b/config/locales/en.yml @@ -0,0 +1,23 @@ +# Files in the config/locales directory are used for internationalization +# and are automatically loaded by Rails. If you want to use locales other +# than English, add the necessary files in this directory. +# +# To use the locales, use `I18n.t`: +# +# I18n.t 'hello' +# +# In views, this is aliased to just `t`: +# +# <%= t('hello') %> +# +# To use a different locale, set it with `I18n.locale`: +# +# I18n.locale = :es +# +# This would use the information in config/locales/es.yml. +# +# To learn more, please read the Rails Internationalization guide +# available at http://guides.rubyonrails.org/i18n.html. + +en: + hello: "Hello world" diff --git a/config/routes.rb b/config/routes.rb new file mode 100644 index 0000000..4d9043f --- /dev/null +++ b/config/routes.rb @@ -0,0 +1,67 @@ +Rails.application.routes.draw do + +# namespace :api do + resources :shippings do + collection do + post 'shipping_rates' + end + end + + + + + # The priority is based upon order of creation: first created -> highest priority. + # See how all your routes lay out with "rake routes". + + # You can have the root of your site routed with "root" + # root 'welcome#index' + + # Example of regular route: + # get 'products/:id' => 'catalog#view' + + # Example of named route that can be invoked with purchase_url(id: product.id) + # get 'products/:id/purchase' => 'catalog#purchase', as: :purchase + + # Example resource route (maps HTTP verbs to controller actions automatically): + # resources :products + + # Example resource route with options: + # resources :products do + # member do + # get 'short' + # post 'toggle' + # end + # + # collection do + # get 'sold' + # end + # end + + # Example resource route with sub-resources: + # resources :products do + # resources :comments, :sales + # resource :seller + # end + + # Example resource route with more complex sub-resources: + # resources :products do + # resources :comments + # resources :sales do + # get 'recent', on: :collection + # end + # end + + # Example resource route with concerns: + # concern :toggleable do + # post 'toggle' + # end + # resources :posts, concerns: :toggleable + # resources :photos, concerns: :toggleable + + # Example resource route within a namespace: + # namespace :admin do + # # Directs /admin/products/* to Admin::ProductsController + # # (app/controllers/admin/products_controller.rb) + # resources :products + # end +end diff --git a/config/secrets.yml b/config/secrets.yml new file mode 100644 index 0000000..9ecf2b1 --- /dev/null +++ b/config/secrets.yml @@ -0,0 +1,22 @@ +# Be sure to restart your server when you modify this file. + +# Your secret key is used for verifying the integrity of signed cookies. +# If you change this key, all old signed cookies will become invalid! + +# Make sure the secret is at least 30 characters and all random, +# no regular words or you'll be exposed to dictionary attacks. +# You can use `rake secret` to generate a secure secret key. + +# Make sure the secrets in this file are kept private +# if you're sharing your code publicly. + +development: + secret_key_base: 3f92f94d0be452bc7f0ff3e5392f4298cfffa1244d935042954d9af85b68cd40a96df6504302c21aff62ebf99abd0cdfb79dfdc6355f8c29934756476546cc86 + +test: + secret_key_base: 6f7fd13fb8609f2abbb3728aed7f2d4bc3882e844a4bd4678fea9fc8e43a03d383a0f67bfa94fccfa2a222d927db7c6a534b3f5bc40ff07779e66c6599b848e5 + +# Do not keep production secrets in the repository, +# instead read values from the environment. +production: + secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> diff --git a/db/migrate/20160524180944_create_logs.rb b/db/migrate/20160524180944_create_logs.rb new file mode 100644 index 0000000..0eaa105 --- /dev/null +++ b/db/migrate/20160524180944_create_logs.rb @@ -0,0 +1,8 @@ +class CreateLogs < ActiveRecord::Migration + def change + create_table :logs do |t| + + t.timestamps null: false + end + end +end diff --git a/db/migrate/20160524181023_create_shippings.rb b/db/migrate/20160524181023_create_shippings.rb new file mode 100644 index 0000000..01b1737 --- /dev/null +++ b/db/migrate/20160524181023_create_shippings.rb @@ -0,0 +1,8 @@ +class CreateShippings < ActiveRecord::Migration + def change + create_table :shippings do |t| + + t.timestamps null: false + end + end +end diff --git a/db/migrate/20160527222102_add_request_to_logs.rb b/db/migrate/20160527222102_add_request_to_logs.rb new file mode 100644 index 0000000..980b54f --- /dev/null +++ b/db/migrate/20160527222102_add_request_to_logs.rb @@ -0,0 +1,6 @@ +class AddRequestToLogs < ActiveRecord::Migration + def change + add_column :logs, :request, :string + add_column :logs, :response, :string + end +end diff --git a/db/migrate/20160527222123_add_response_to_logs.rb b/db/migrate/20160527222123_add_response_to_logs.rb new file mode 100644 index 0000000..04dcbfa --- /dev/null +++ b/db/migrate/20160527222123_add_response_to_logs.rb @@ -0,0 +1,4 @@ +class AddResponseToLogs < ActiveRecord::Migration + def change + end +end diff --git a/db/schema.rb b/db/schema.rb new file mode 100644 index 0000000..1ea8e68 --- /dev/null +++ b/db/schema.rb @@ -0,0 +1,31 @@ +# encoding: UTF-8 +# This file is auto-generated from the current state of the database. Instead +# of editing this file, please use the migrations feature of Active Record to +# incrementally modify your database, and then regenerate this schema definition. +# +# Note that this schema.rb definition is the authoritative source for your +# database schema. If you need to create the application database on another +# system, you should be using db:schema:load, not running all the migrations +# from scratch. The latter is a flawed and unsustainable approach (the more migrations +# you'll amass, the slower it'll run and the greater likelihood for issues). +# +# It's strongly recommended that you check this file into your version control system. + +ActiveRecord::Schema.define(version: 20160527222123) do + + # These are extensions that must be enabled in order to support this database + enable_extension "plpgsql" + + create_table "logs", force: :cascade do |t| + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "request" + t.string "response" + end + + create_table "shippings", force: :cascade do |t| + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + +end diff --git a/db/seeds.rb b/db/seeds.rb new file mode 100644 index 0000000..4edb1e8 --- /dev/null +++ b/db/seeds.rb @@ -0,0 +1,7 @@ +# This file should contain all the record creation needed to seed the database with its default values. +# The data can then be loaded with the rake db:seed (or created alongside the db with db:setup). +# +# Examples: +# +# cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }]) +# Mayor.create(name: 'Emanuel', city: cities.first) diff --git a/lib/assets/.keep b/lib/assets/.keep new file mode 100644 index 0000000..e69de29 diff --git a/lib/tasks/.keep b/lib/tasks/.keep new file mode 100644 index 0000000..e69de29 diff --git a/log/.keep b/log/.keep new file mode 100644 index 0000000..e69de29 diff --git a/public/404.html b/public/404.html new file mode 100644 index 0000000..b612547 --- /dev/null +++ b/public/404.html @@ -0,0 +1,67 @@ + + + + The page you were looking for doesn't exist (404) + + + + + + +
+
+

The page you were looking for doesn't exist.

+

You may have mistyped the address or the page may have moved.

+
+

If you are the application owner check the logs for more information.

+
+ + diff --git a/public/422.html b/public/422.html new file mode 100644 index 0000000..a21f82b --- /dev/null +++ b/public/422.html @@ -0,0 +1,67 @@ + + + + The change you wanted was rejected (422) + + + + + + +
+
+

The change you wanted was rejected.

+

Maybe you tried to change something you didn't have access to.

+
+

If you are the application owner check the logs for more information.

+
+ + diff --git a/public/500.html b/public/500.html new file mode 100644 index 0000000..061abc5 --- /dev/null +++ b/public/500.html @@ -0,0 +1,66 @@ + + + + We're sorry, but something went wrong (500) + + + + + + +
+
+

We're sorry, but something went wrong.

+
+

If you are the application owner check the logs for more information.

+
+ + diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000..e69de29 diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000..3c9c7c0 --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,5 @@ +# See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file +# +# To ban all spiders from the entire site uncomment the next two lines: +# User-agent: * +# Disallow: / diff --git a/test/cassettes/shipping_rates/should_return_an_array_of_arrays.yml b/test/cassettes/shipping_rates/should_return_an_array_of_arrays.yml new file mode 100644 index 0000000..3abc2f6 --- /dev/null +++ b/test/cassettes/shipping_rates/should_return_an_array_of_arrays.yml @@ -0,0 +1,123 @@ +--- +http_interactions: +- request: + method: post + uri: https://onlinetools.ups.com/ups.app/xml/Rate + body: + encoding: UTF-8 + string: | + + + 9D0CA9FE6A4849E8 + rishallen_5 + 29E8Y5 + + + + + Rate + Shop + + + 01 + + + 01 + + + +
+ Beverly Hills + CA + 90210 + US + true +
+
+ +
+ Ottawa + ON + K1P 1J1 + CA + true +
+
+ + + 02 + + + + IN + + 36.614 + 3.937 + 3.937 + + + + LBS + + 0.22 + + + + + + 02 + + + + IN + + 15.0 + 10.0 + 4.5 + + + + LBS + + 7.5 + + + +
+
+ headers: + Content-Type: + - application/x-www-form-urlencoded + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 24 May 2016 23:26:32 GMT + Server: + - Apache + X-Frame-Options: + - SAMEORIGIN + Pragma: + - no-cache + Content-Length: + - '6737' + X-Content-Type-Options: + - nosniff + Content-Type: + - application/xml + body: + encoding: UTF-8 + string: |- + + 1Success07Your invoice may vary from the displayed reference ratesLBS13.0USD160.50USD0.00USD160.50112:00 NoonUSD0.00USD0.00USD0.000.3LBS5.0USD0.00USD0.00USD0.007.5LBS8.008Your invoice may vary from the displayed reference ratesLBS13.0USD138.01USD0.00USD138.01USD0.00USD0.00USD0.000.3LBS5.0USD0.00USD0.00USD0.007.5LBS8.065Your invoice may vary from the displayed reference ratesLBS13.0USD158.00USD0.00USD158.001USD0.00USD0.00USD0.000.3LBS5.0USD0.00USD0.00USD0.007.5LBS8.011Your invoice may vary from the displayed reference ratesLBS30.0USD58.45USD0.00USD58.45USD0.00USD0.00USD0.000.3LBS5.0USD0.00USD0.00USD0.007.5LBS8.0 + http_version: + recorded_at: Tue, 24 May 2016 23:26:31 GMT +recorded_with: VCR 3.0.3 diff --git a/test/cassettes/shipping_rates/should_return_some_shipping_rates.yml b/test/cassettes/shipping_rates/should_return_some_shipping_rates.yml new file mode 100644 index 0000000..0cc9300 --- /dev/null +++ b/test/cassettes/shipping_rates/should_return_some_shipping_rates.yml @@ -0,0 +1,123 @@ +--- +http_interactions: +- request: + method: post + uri: https://onlinetools.ups.com/ups.app/xml/Rate + body: + encoding: UTF-8 + string: | + + + 9D0CA9FE6A4849E8 + rishallen_5 + 29E8Y5 + + + + + Rate + Shop + + + 01 + + + 01 + + + +
+ Beverly Hills + CA + 90210 + US + true +
+
+ +
+ Ottawa + ON + K1P 1J1 + CA + true +
+
+ + + 02 + + + + IN + + 36.614 + 3.937 + 3.937 + + + + LBS + + 0.22 + + + + + + 02 + + + + IN + + 15.0 + 10.0 + 4.5 + + + + LBS + + 7.5 + + + +
+
+ headers: + Content-Type: + - application/x-www-form-urlencoded + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 24 May 2016 23:17:06 GMT + Server: + - Apache + X-Frame-Options: + - SAMEORIGIN + Pragma: + - no-cache + Content-Length: + - '6737' + X-Content-Type-Options: + - nosniff + Content-Type: + - application/xml + body: + encoding: UTF-8 + string: |- + + 1Success07Your invoice may vary from the displayed reference ratesLBS13.0USD160.50USD0.00USD160.50112:00 NoonUSD0.00USD0.00USD0.000.3LBS5.0USD0.00USD0.00USD0.007.5LBS8.008Your invoice may vary from the displayed reference ratesLBS13.0USD138.01USD0.00USD138.01USD0.00USD0.00USD0.000.3LBS5.0USD0.00USD0.00USD0.007.5LBS8.065Your invoice may vary from the displayed reference ratesLBS13.0USD158.00USD0.00USD158.001USD0.00USD0.00USD0.000.3LBS5.0USD0.00USD0.00USD0.007.5LBS8.011Your invoice may vary from the displayed reference ratesLBS30.0USD58.45USD0.00USD58.45USD0.00USD0.00USD0.000.3LBS5.0USD0.00USD0.00USD0.007.5LBS8.0 + http_version: + recorded_at: Tue, 24 May 2016 23:17:06 GMT +recorded_with: VCR 3.0.3 diff --git a/test/controllers/.keep b/test/controllers/.keep new file mode 100644 index 0000000..e69de29 diff --git a/test/controllers/shippings_controller_test.rb b/test/controllers/shippings_controller_test.rb new file mode 100644 index 0000000..18efd96 --- /dev/null +++ b/test/controllers/shippings_controller_test.rb @@ -0,0 +1,39 @@ +require 'test_helper' + +class ShippingsControllerTest < ActionController::TestCase + setup do + # expecting json and that will be what I get back + @request.headers['Accept'] = Mime::JSON + @request.headers['Content-Type'] = Mime::JSON.to_s + # orgin = [] order_item: (country: 'US', state: 'CA', city: 'Beverly Hills', zip: '90210', weight: "20"} + origins = [{order_item: 1, country: 'US', city: "oakland", state: "CA", weight: '20', zip: '94619'}] + destination = {country: 'US', state: 'NY', city: 'New York City', zip: '10022'} + post :shipping_rates, shipping: { origins: origins, destination: destination} + @body = JSON.parse(response.body) + + end + + test "can post #shipping_rates" do + assert_response :success #also known as HTTP code 200 + end + + + + + + # test "can get #shipping_rates" do + # assert_equal Array, @body #also known as HTTP code 200 + # end +# test "return an hash with specific key values from ups shipping" do +# hash = [["UPS Standard", 3936], +# ["UPS Worldwide Expedited", 8682], +# ["UPS Saver", 9348], +# ["UPS Express", 9702], +# ["UPS Worldwide Express Plus", 14502]] +# hash = {} +# assert_match +# end + + + +end diff --git a/test/fixtures/.keep b/test/fixtures/.keep new file mode 100644 index 0000000..e69de29 diff --git a/test/fixtures/logs.yml b/test/fixtures/logs.yml new file mode 100644 index 0000000..937a0c0 --- /dev/null +++ b/test/fixtures/logs.yml @@ -0,0 +1,11 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +# This model initially had no columns defined. If you add columns to the +# model remove the '{}' from the fixture names and add the columns immediately +# below each fixture, per the syntax in the comments below +# +one: {} +# column: value +# +two: {} +# column: value diff --git a/test/helpers/.keep b/test/helpers/.keep new file mode 100644 index 0000000..e69de29 diff --git a/test/integration/.keep b/test/integration/.keep new file mode 100644 index 0000000..e69de29 diff --git a/test/mailers/.keep b/test/mailers/.keep new file mode 100644 index 0000000..e69de29 diff --git a/test/models/.keep b/test/models/.keep new file mode 100644 index 0000000..e69de29 diff --git a/test/models/log_test.rb b/test/models/log_test.rb new file mode 100644 index 0000000..f2afee2 --- /dev/null +++ b/test/models/log_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class LogTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/models/shipping_test.rb b/test/models/shipping_test.rb new file mode 100644 index 0000000..5c5cede --- /dev/null +++ b/test/models/shipping_test.rb @@ -0,0 +1,28 @@ +require 'test_helper' +require 'pry' + +class ShippingTest < ActiveSupport::TestCase + + # @origin = {country: 'US', city: "oakland", state: "CA", zip: '94619'} + # @destination = {country: 'US', state: 'NY', city: 'New York City', zip: '10022'} + # + # + # describe "shipping rates" do + # it "should return an rates if given a destination and origin and package size" do + # ups = ActiveShipping::UPS.new(login: ENV["UPS_LOGIN"], password: ENV["UPS_PASSWORD"], key: ENV["UPS_KEY"]) + # origin = ActiveShipping::Location.new(@origin) + # destination = ActiveShipping::Location.new(@destination) + # package = ActiveShipping::Package.new(20* 16, [2, 2, 2]) + # + # response = @ups.find_rates(origin, destination, package) + # result = response.rates.sort_by(&:price).collect {|rate| [rate.service_name, rate.price]} + # + # shipping_rates = Shipping.find(origin, destination, packages) + # assert_match Hash, origin.class + # end + # end + +end + + + # find rates, should return a collection of objects diff --git a/test/test_helper.rb b/test/test_helper.rb new file mode 100644 index 0000000..087f0d3 --- /dev/null +++ b/test/test_helper.rb @@ -0,0 +1,31 @@ +require 'simplecov' +SimpleCov.start 'rails' + +ENV['RAILS_ENV'] ||= 'test' +require File.expand_path('../../config/environment', __FILE__) +require 'rails/test_help' +require "minitest/reporters" +require 'minitest/spec' +require 'minispec-metadata' +require 'vcr' +require 'minitest-vcr' +require 'webmock/minitest' +require 'minitest/reporters' + +require 'active_shipping' + +VCR.configure do |c| + c.cassette_library_dir = 'test/cassettes' + c.hook_into :webmock +end + +Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new +MinitestVcr::Spec.configure! + + +class ActiveSupport::TestCase + # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order. + fixtures :all + + # Add more helper methods to be used by all tests here... +end diff --git a/vendor/assets/javascripts/.keep b/vendor/assets/javascripts/.keep new file mode 100644 index 0000000..e69de29 diff --git a/vendor/assets/stylesheets/.keep b/vendor/assets/stylesheets/.keep new file mode 100644 index 0000000..e69de29 diff --git a/vendor/bundle/bin/bundler b/vendor/bundle/bin/bundler new file mode 100755 index 0000000..c8de858 --- /dev/null +++ b/vendor/bundle/bin/bundler @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'bundler' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("bundler", "bundler") diff --git a/vendor/bundle/bin/byebug b/vendor/bundle/bin/byebug new file mode 100755 index 0000000..73a6342 --- /dev/null +++ b/vendor/bundle/bin/byebug @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'byebug' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("byebug", "byebug") diff --git a/vendor/bundle/bin/coderay b/vendor/bundle/bin/coderay new file mode 100755 index 0000000..4f6a7ca --- /dev/null +++ b/vendor/bundle/bin/coderay @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'coderay' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("coderay", "coderay") diff --git a/vendor/bundle/bin/dot2ruby b/vendor/bundle/bin/dot2ruby new file mode 100755 index 0000000..ed0cd83 --- /dev/null +++ b/vendor/bundle/bin/dot2ruby @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'dot2ruby' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("ruby-graphviz", "dot2ruby") diff --git a/vendor/bundle/bin/dotenv b/vendor/bundle/bin/dotenv new file mode 100755 index 0000000..b6c52e1 --- /dev/null +++ b/vendor/bundle/bin/dotenv @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'dotenv' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("dotenv", "dotenv") diff --git a/vendor/bundle/bin/erd b/vendor/bundle/bin/erd new file mode 100755 index 0000000..4e410aa --- /dev/null +++ b/vendor/bundle/bin/erd @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'erd' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("rails-erd", "erd") diff --git a/vendor/bundle/bin/erubis b/vendor/bundle/bin/erubis new file mode 100755 index 0000000..02d3190 --- /dev/null +++ b/vendor/bundle/bin/erubis @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'erubis' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("erubis", "erubis") diff --git a/vendor/bundle/bin/gem2gv b/vendor/bundle/bin/gem2gv new file mode 100755 index 0000000..8d7632e --- /dev/null +++ b/vendor/bundle/bin/gem2gv @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'gem2gv' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("ruby-graphviz", "gem2gv") diff --git a/vendor/bundle/bin/git2gv b/vendor/bundle/bin/git2gv new file mode 100755 index 0000000..b2a00df --- /dev/null +++ b/vendor/bundle/bin/git2gv @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'git2gv' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("ruby-graphviz", "git2gv") diff --git a/vendor/bundle/bin/nokogiri b/vendor/bundle/bin/nokogiri new file mode 100755 index 0000000..1be6309 --- /dev/null +++ b/vendor/bundle/bin/nokogiri @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'nokogiri' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("nokogiri", "nokogiri") diff --git a/vendor/bundle/bin/pry b/vendor/bundle/bin/pry new file mode 100755 index 0000000..9740d23 --- /dev/null +++ b/vendor/bundle/bin/pry @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'pry' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("pry", "pry") diff --git a/vendor/bundle/bin/rackup b/vendor/bundle/bin/rackup new file mode 100755 index 0000000..fa8481a --- /dev/null +++ b/vendor/bundle/bin/rackup @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'rackup' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("rack", "rackup") diff --git a/vendor/bundle/bin/rails b/vendor/bundle/bin/rails new file mode 100755 index 0000000..6e722f6 --- /dev/null +++ b/vendor/bundle/bin/rails @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'rails' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("railties", "rails") diff --git a/vendor/bundle/bin/rake b/vendor/bundle/bin/rake new file mode 100755 index 0000000..c0042a5 --- /dev/null +++ b/vendor/bundle/bin/rake @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'rake' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("rake", "rake") diff --git a/vendor/bundle/bin/rdoc b/vendor/bundle/bin/rdoc new file mode 100755 index 0000000..221cdf2 --- /dev/null +++ b/vendor/bundle/bin/rdoc @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'rdoc' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("rdoc", "rdoc") diff --git a/vendor/bundle/bin/ri b/vendor/bundle/bin/ri new file mode 100755 index 0000000..8614289 --- /dev/null +++ b/vendor/bundle/bin/ri @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'ri' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("rdoc", "ri") diff --git a/vendor/bundle/bin/ruby2gv b/vendor/bundle/bin/ruby2gv new file mode 100755 index 0000000..974cd76 --- /dev/null +++ b/vendor/bundle/bin/ruby2gv @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'ruby2gv' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("ruby-graphviz", "ruby2gv") diff --git a/vendor/bundle/bin/safe_yaml b/vendor/bundle/bin/safe_yaml new file mode 100755 index 0000000..25e7b80 --- /dev/null +++ b/vendor/bundle/bin/safe_yaml @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'safe_yaml' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("safe_yaml", "safe_yaml") diff --git a/vendor/bundle/bin/sass b/vendor/bundle/bin/sass new file mode 100755 index 0000000..263b174 --- /dev/null +++ b/vendor/bundle/bin/sass @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'sass' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("sass", "sass") diff --git a/vendor/bundle/bin/sass-convert b/vendor/bundle/bin/sass-convert new file mode 100755 index 0000000..d32d897 --- /dev/null +++ b/vendor/bundle/bin/sass-convert @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'sass-convert' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("sass", "sass-convert") diff --git a/vendor/bundle/bin/scss b/vendor/bundle/bin/scss new file mode 100755 index 0000000..12adb80 --- /dev/null +++ b/vendor/bundle/bin/scss @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'scss' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("sass", "scss") diff --git a/vendor/bundle/bin/sdoc b/vendor/bundle/bin/sdoc new file mode 100755 index 0000000..3dad332 --- /dev/null +++ b/vendor/bundle/bin/sdoc @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'sdoc' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("sdoc", "sdoc") diff --git a/vendor/bundle/bin/sdoc-merge b/vendor/bundle/bin/sdoc-merge new file mode 100755 index 0000000..857dd43 --- /dev/null +++ b/vendor/bundle/bin/sdoc-merge @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'sdoc-merge' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("sdoc", "sdoc-merge") diff --git a/vendor/bundle/bin/spring b/vendor/bundle/bin/spring new file mode 100755 index 0000000..f378a53 --- /dev/null +++ b/vendor/bundle/bin/spring @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'spring' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("spring", "spring") diff --git a/vendor/bundle/bin/sprockets b/vendor/bundle/bin/sprockets new file mode 100755 index 0000000..6f595cc --- /dev/null +++ b/vendor/bundle/bin/sprockets @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'sprockets' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("sprockets", "sprockets") diff --git a/vendor/bundle/bin/thor b/vendor/bundle/bin/thor new file mode 100755 index 0000000..c6eb555 --- /dev/null +++ b/vendor/bundle/bin/thor @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'thor' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("thor", "thor") diff --git a/vendor/bundle/bin/tilt b/vendor/bundle/bin/tilt new file mode 100755 index 0000000..0009515 --- /dev/null +++ b/vendor/bundle/bin/tilt @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'tilt' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("tilt", "tilt") diff --git a/vendor/bundle/bin/xml2gv b/vendor/bundle/bin/xml2gv new file mode 100755 index 0000000..be3af17 --- /dev/null +++ b/vendor/bundle/bin/xml2gv @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'xml2gv' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("ruby-graphviz", "xml2gv") diff --git a/vendor/bundle/ruby/2.2.0/bin/byebug b/vendor/bundle/ruby/2.2.0/bin/byebug new file mode 100755 index 0000000..95091f6 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/bin/byebug @@ -0,0 +1,23 @@ +#!/usr/bin/env ruby +# +# This file was generated by RubyGems. +# +# The application 'byebug' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +version = ">= 0" + +if ARGV.first + str = ARGV.first + str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding + if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then + version = $1 + ARGV.shift + end +end + +gem 'byebug', version +load Gem.bin_path('byebug', 'byebug', version) diff --git a/vendor/bundle/ruby/2.2.0/bin/dotenv b/vendor/bundle/ruby/2.2.0/bin/dotenv new file mode 100755 index 0000000..df8972c --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/bin/dotenv @@ -0,0 +1,23 @@ +#!/usr/bin/env ruby +# +# This file was generated by RubyGems. +# +# The application 'dotenv' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +version = ">= 0" + +if ARGV.first + str = ARGV.first + str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding + if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then + version = $1 + ARGV.shift + end +end + +gem 'dotenv', version +load Gem.bin_path('dotenv', 'dotenv', version) diff --git a/vendor/bundle/ruby/2.2.0/bin/erubis b/vendor/bundle/ruby/2.2.0/bin/erubis new file mode 100755 index 0000000..301dd30 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/bin/erubis @@ -0,0 +1,23 @@ +#!/usr/bin/env ruby +# +# This file was generated by RubyGems. +# +# The application 'erubis' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +version = ">= 0" + +if ARGV.first + str = ARGV.first + str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding + if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then + version = $1 + ARGV.shift + end +end + +gem 'erubis', version +load Gem.bin_path('erubis', 'erubis', version) diff --git a/vendor/bundle/ruby/2.2.0/bin/nokogiri b/vendor/bundle/ruby/2.2.0/bin/nokogiri new file mode 100755 index 0000000..43d6203 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/bin/nokogiri @@ -0,0 +1,23 @@ +#!/usr/bin/env ruby +# +# This file was generated by RubyGems. +# +# The application 'nokogiri' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +version = ">= 0" + +if ARGV.first + str = ARGV.first + str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding + if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then + version = $1 + ARGV.shift + end +end + +gem 'nokogiri', version +load Gem.bin_path('nokogiri', 'nokogiri', version) diff --git a/vendor/bundle/ruby/2.2.0/bin/rackup b/vendor/bundle/ruby/2.2.0/bin/rackup new file mode 100755 index 0000000..416d30a --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/bin/rackup @@ -0,0 +1,23 @@ +#!/usr/bin/env ruby +# +# This file was generated by RubyGems. +# +# The application 'rack' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +version = ">= 0" + +if ARGV.first + str = ARGV.first + str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding + if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then + version = $1 + ARGV.shift + end +end + +gem 'rack', version +load Gem.bin_path('rack', 'rackup', version) diff --git a/vendor/bundle/ruby/2.2.0/bin/rails b/vendor/bundle/ruby/2.2.0/bin/rails new file mode 100755 index 0000000..b2a661f --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/bin/rails @@ -0,0 +1,23 @@ +#!/usr/bin/env ruby +# +# This file was generated by RubyGems. +# +# The application 'railties' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +version = ">= 0" + +if ARGV.first + str = ARGV.first + str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding + if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then + version = $1 + ARGV.shift + end +end + +gem 'railties', version +load Gem.bin_path('railties', 'rails', version) diff --git a/vendor/bundle/ruby/2.2.0/bin/rake b/vendor/bundle/ruby/2.2.0/bin/rake new file mode 100755 index 0000000..97d1fcc --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/bin/rake @@ -0,0 +1,23 @@ +#!/usr/bin/env ruby +# +# This file was generated by RubyGems. +# +# The application 'rake' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +version = ">= 0" + +if ARGV.first + str = ARGV.first + str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding + if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then + version = $1 + ARGV.shift + end +end + +gem 'rake', version +load Gem.bin_path('rake', 'rake', version) diff --git a/vendor/bundle/ruby/2.2.0/bin/rdoc b/vendor/bundle/ruby/2.2.0/bin/rdoc new file mode 100755 index 0000000..0d3d314 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/bin/rdoc @@ -0,0 +1,23 @@ +#!/usr/bin/env ruby +# +# This file was generated by RubyGems. +# +# The application 'rdoc' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +version = ">= 0" + +if ARGV.first + str = ARGV.first + str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding + if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then + version = $1 + ARGV.shift + end +end + +gem 'rdoc', version +load Gem.bin_path('rdoc', 'rdoc', version) diff --git a/vendor/bundle/ruby/2.2.0/bin/ri b/vendor/bundle/ruby/2.2.0/bin/ri new file mode 100755 index 0000000..cf45350 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/bin/ri @@ -0,0 +1,23 @@ +#!/usr/bin/env ruby +# +# This file was generated by RubyGems. +# +# The application 'rdoc' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +version = ">= 0" + +if ARGV.first + str = ARGV.first + str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding + if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then + version = $1 + ARGV.shift + end +end + +gem 'rdoc', version +load Gem.bin_path('rdoc', 'ri', version) diff --git a/vendor/bundle/ruby/2.2.0/bin/sass b/vendor/bundle/ruby/2.2.0/bin/sass new file mode 100755 index 0000000..2ade46c --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/bin/sass @@ -0,0 +1,23 @@ +#!/usr/bin/env ruby +# +# This file was generated by RubyGems. +# +# The application 'sass' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +version = ">= 0" + +if ARGV.first + str = ARGV.first + str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding + if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then + version = $1 + ARGV.shift + end +end + +gem 'sass', version +load Gem.bin_path('sass', 'sass', version) diff --git a/vendor/bundle/ruby/2.2.0/bin/sass-convert b/vendor/bundle/ruby/2.2.0/bin/sass-convert new file mode 100755 index 0000000..2c1393c --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/bin/sass-convert @@ -0,0 +1,23 @@ +#!/usr/bin/env ruby +# +# This file was generated by RubyGems. +# +# The application 'sass' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +version = ">= 0" + +if ARGV.first + str = ARGV.first + str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding + if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then + version = $1 + ARGV.shift + end +end + +gem 'sass', version +load Gem.bin_path('sass', 'sass-convert', version) diff --git a/vendor/bundle/ruby/2.2.0/bin/scss b/vendor/bundle/ruby/2.2.0/bin/scss new file mode 100755 index 0000000..6be603a --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/bin/scss @@ -0,0 +1,23 @@ +#!/usr/bin/env ruby +# +# This file was generated by RubyGems. +# +# The application 'sass' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +version = ">= 0" + +if ARGV.first + str = ARGV.first + str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding + if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then + version = $1 + ARGV.shift + end +end + +gem 'sass', version +load Gem.bin_path('sass', 'scss', version) diff --git a/vendor/bundle/ruby/2.2.0/bin/sdoc b/vendor/bundle/ruby/2.2.0/bin/sdoc new file mode 100755 index 0000000..d625313 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/bin/sdoc @@ -0,0 +1,25 @@ +#!/bin/sh +'exec' "ruby" '-x' "$0" "$@" +#!/Users/RA/.rvm/rubies/ruby-2.2.3/bin/ruby +# +# This file was generated by RubyGems. +# +# The application 'sdoc' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +version = ">= 0" + +if ARGV.first + str = ARGV.first + str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding + if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then + version = $1 + ARGV.shift + end +end + +gem 'sdoc', version +load Gem.bin_path('sdoc', 'sdoc', version) diff --git a/vendor/bundle/ruby/2.2.0/bin/sdoc-merge b/vendor/bundle/ruby/2.2.0/bin/sdoc-merge new file mode 100755 index 0000000..55bdde2 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/bin/sdoc-merge @@ -0,0 +1,25 @@ +#!/bin/sh +'exec' "ruby" '-x' "$0" "$@" +#!/Users/RA/.rvm/rubies/ruby-2.2.3/bin/ruby +# +# This file was generated by RubyGems. +# +# The application 'sdoc' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +version = ">= 0" + +if ARGV.first + str = ARGV.first + str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding + if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then + version = $1 + ARGV.shift + end +end + +gem 'sdoc', version +load Gem.bin_path('sdoc', 'sdoc-merge', version) diff --git a/vendor/bundle/ruby/2.2.0/bin/sprockets b/vendor/bundle/ruby/2.2.0/bin/sprockets new file mode 100755 index 0000000..bb01742 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/bin/sprockets @@ -0,0 +1,23 @@ +#!/usr/bin/env ruby +# +# This file was generated by RubyGems. +# +# The application 'sprockets' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +version = ">= 0" + +if ARGV.first + str = ARGV.first + str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding + if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then + version = $1 + ARGV.shift + end +end + +gem 'sprockets', version +load Gem.bin_path('sprockets', 'sprockets', version) diff --git a/vendor/bundle/ruby/2.2.0/bin/thor b/vendor/bundle/ruby/2.2.0/bin/thor new file mode 100755 index 0000000..2533f7b --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/bin/thor @@ -0,0 +1,23 @@ +#!/usr/bin/env ruby +# +# This file was generated by RubyGems. +# +# The application 'thor' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +version = ">= 0" + +if ARGV.first + str = ARGV.first + str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding + if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then + version = $1 + ARGV.shift + end +end + +gem 'thor', version +load Gem.bin_path('thor', 'thor', version) diff --git a/vendor/bundle/ruby/2.2.0/bin/tilt b/vendor/bundle/ruby/2.2.0/bin/tilt new file mode 100755 index 0000000..cba5196 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/bin/tilt @@ -0,0 +1,23 @@ +#!/usr/bin/env ruby +# +# This file was generated by RubyGems. +# +# The application 'tilt' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +version = ">= 0" + +if ARGV.first + str = ARGV.first + str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding + if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then + version = $1 + ARGV.shift + end +end + +gem 'tilt', version +load Gem.bin_path('tilt', 'tilt', version) diff --git a/vendor/bundle/ruby/2.2.0/cache/actionmailer-4.2.6.gem b/vendor/bundle/ruby/2.2.0/cache/actionmailer-4.2.6.gem new file mode 100644 index 0000000..db35b1e Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/actionmailer-4.2.6.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/actionpack-4.2.6.gem b/vendor/bundle/ruby/2.2.0/cache/actionpack-4.2.6.gem new file mode 100644 index 0000000..105e4ba Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/actionpack-4.2.6.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/actionview-4.2.6.gem b/vendor/bundle/ruby/2.2.0/cache/actionview-4.2.6.gem new file mode 100644 index 0000000..7e4b00f Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/actionview-4.2.6.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/activejob-4.2.6.gem b/vendor/bundle/ruby/2.2.0/cache/activejob-4.2.6.gem new file mode 100644 index 0000000..39fbb31 Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/activejob-4.2.6.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/activemodel-4.2.6.gem b/vendor/bundle/ruby/2.2.0/cache/activemodel-4.2.6.gem new file mode 100644 index 0000000..9b31664 Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/activemodel-4.2.6.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/activerecord-4.2.6.gem b/vendor/bundle/ruby/2.2.0/cache/activerecord-4.2.6.gem new file mode 100644 index 0000000..4f4ae1d Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/activerecord-4.2.6.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/activesupport-4.2.6.gem b/vendor/bundle/ruby/2.2.0/cache/activesupport-4.2.6.gem new file mode 100644 index 0000000..7254e95 Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/activesupport-4.2.6.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/ansi-1.5.0.gem b/vendor/bundle/ruby/2.2.0/cache/ansi-1.5.0.gem new file mode 100644 index 0000000..8c0e145 Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/ansi-1.5.0.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/arel-6.0.3.gem b/vendor/bundle/ruby/2.2.0/cache/arel-6.0.3.gem new file mode 100644 index 0000000..ce9fdaa Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/arel-6.0.3.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/bcrypt-3.1.11.gem b/vendor/bundle/ruby/2.2.0/cache/bcrypt-3.1.11.gem new file mode 100644 index 0000000..53fa448 Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/bcrypt-3.1.11.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/builder-3.2.2.gem b/vendor/bundle/ruby/2.2.0/cache/builder-3.2.2.gem new file mode 100644 index 0000000..b59ef92 Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/builder-3.2.2.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/byebug-9.0.4.gem b/vendor/bundle/ruby/2.2.0/cache/byebug-9.0.4.gem new file mode 100644 index 0000000..735f704 Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/byebug-9.0.4.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/coffee-rails-4.1.1.gem b/vendor/bundle/ruby/2.2.0/cache/coffee-rails-4.1.1.gem new file mode 100644 index 0000000..726e8ba Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/coffee-rails-4.1.1.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/coffee-script-2.4.1.gem b/vendor/bundle/ruby/2.2.0/cache/coffee-script-2.4.1.gem new file mode 100644 index 0000000..7e4066d Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/coffee-script-2.4.1.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/coffee-script-source-1.10.0.gem b/vendor/bundle/ruby/2.2.0/cache/coffee-script-source-1.10.0.gem new file mode 100644 index 0000000..0bc7d02 Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/coffee-script-source-1.10.0.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/concurrent-ruby-1.0.2.gem b/vendor/bundle/ruby/2.2.0/cache/concurrent-ruby-1.0.2.gem new file mode 100644 index 0000000..12607b1 Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/concurrent-ruby-1.0.2.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/docile-1.1.5.gem b/vendor/bundle/ruby/2.2.0/cache/docile-1.1.5.gem new file mode 100644 index 0000000..4eb5de6 Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/docile-1.1.5.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/dotenv-2.1.1.gem b/vendor/bundle/ruby/2.2.0/cache/dotenv-2.1.1.gem new file mode 100644 index 0000000..759cfca Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/dotenv-2.1.1.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/dotenv-rails-2.1.1.gem b/vendor/bundle/ruby/2.2.0/cache/dotenv-rails-2.1.1.gem new file mode 100644 index 0000000..ba75c31 Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/dotenv-rails-2.1.1.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/erubis-2.7.0.gem b/vendor/bundle/ruby/2.2.0/cache/erubis-2.7.0.gem new file mode 100644 index 0000000..4acd2e7 Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/erubis-2.7.0.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/execjs-2.7.0.gem b/vendor/bundle/ruby/2.2.0/cache/execjs-2.7.0.gem new file mode 100644 index 0000000..1247cce Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/execjs-2.7.0.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/globalid-0.3.6.gem b/vendor/bundle/ruby/2.2.0/cache/globalid-0.3.6.gem new file mode 100644 index 0000000..eaf5d6a Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/globalid-0.3.6.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/i18n-0.7.0.gem b/vendor/bundle/ruby/2.2.0/cache/i18n-0.7.0.gem new file mode 100644 index 0000000..6f8cf73 Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/i18n-0.7.0.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/jbuilder-2.4.1.gem b/vendor/bundle/ruby/2.2.0/cache/jbuilder-2.4.1.gem new file mode 100644 index 0000000..57458bf Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/jbuilder-2.4.1.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/jquery-rails-4.1.1.gem b/vendor/bundle/ruby/2.2.0/cache/jquery-rails-4.1.1.gem new file mode 100644 index 0000000..5fc8120 Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/jquery-rails-4.1.1.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/json-1.8.3.gem b/vendor/bundle/ruby/2.2.0/cache/json-1.8.3.gem new file mode 100644 index 0000000..6474a4f Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/json-1.8.3.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/loofah-2.0.3.gem b/vendor/bundle/ruby/2.2.0/cache/loofah-2.0.3.gem new file mode 100644 index 0000000..1aa5e84 Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/loofah-2.0.3.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/mail-2.6.4.gem b/vendor/bundle/ruby/2.2.0/cache/mail-2.6.4.gem new file mode 100644 index 0000000..4fa553a Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/mail-2.6.4.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/mime-types-3.1.gem b/vendor/bundle/ruby/2.2.0/cache/mime-types-3.1.gem new file mode 100644 index 0000000..142b7d6 Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/mime-types-3.1.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/mime-types-data-3.2016.0521.gem b/vendor/bundle/ruby/2.2.0/cache/mime-types-data-3.2016.0521.gem new file mode 100644 index 0000000..7b90077 Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/mime-types-data-3.2016.0521.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/mini_portile2-2.0.0.gem b/vendor/bundle/ruby/2.2.0/cache/mini_portile2-2.0.0.gem new file mode 100644 index 0000000..03f6246 Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/mini_portile2-2.0.0.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/minitest-5.9.0.gem b/vendor/bundle/ruby/2.2.0/cache/minitest-5.9.0.gem new file mode 100644 index 0000000..24693f1 Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/minitest-5.9.0.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/minitest-reporters-1.1.9.gem b/vendor/bundle/ruby/2.2.0/cache/minitest-reporters-1.1.9.gem new file mode 100644 index 0000000..a64573e Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/minitest-reporters-1.1.9.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/multi_json-1.12.1.gem b/vendor/bundle/ruby/2.2.0/cache/multi_json-1.12.1.gem new file mode 100644 index 0000000..bf1ffad Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/multi_json-1.12.1.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/nokogiri-1.6.7.2.gem b/vendor/bundle/ruby/2.2.0/cache/nokogiri-1.6.7.2.gem new file mode 100644 index 0000000..aa77f2a Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/nokogiri-1.6.7.2.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/pg-0.18.4.gem b/vendor/bundle/ruby/2.2.0/cache/pg-0.18.4.gem new file mode 100644 index 0000000..3cd0fac Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/pg-0.18.4.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/rack-1.6.4.gem b/vendor/bundle/ruby/2.2.0/cache/rack-1.6.4.gem new file mode 100644 index 0000000..6d06fed Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/rack-1.6.4.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/rack-test-0.6.3.gem b/vendor/bundle/ruby/2.2.0/cache/rack-test-0.6.3.gem new file mode 100644 index 0000000..914afe9 Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/rack-test-0.6.3.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/rails-4.2.6.gem b/vendor/bundle/ruby/2.2.0/cache/rails-4.2.6.gem new file mode 100644 index 0000000..07646ba Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/rails-4.2.6.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/rails-deprecated_sanitizer-1.0.3.gem b/vendor/bundle/ruby/2.2.0/cache/rails-deprecated_sanitizer-1.0.3.gem new file mode 100644 index 0000000..56bbe9e Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/rails-deprecated_sanitizer-1.0.3.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/rails-dom-testing-1.0.7.gem b/vendor/bundle/ruby/2.2.0/cache/rails-dom-testing-1.0.7.gem new file mode 100644 index 0000000..6249f00 Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/rails-dom-testing-1.0.7.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/rails-html-sanitizer-1.0.3.gem b/vendor/bundle/ruby/2.2.0/cache/rails-html-sanitizer-1.0.3.gem new file mode 100644 index 0000000..a419361 Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/rails-html-sanitizer-1.0.3.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/rails_12factor-0.0.3.gem b/vendor/bundle/ruby/2.2.0/cache/rails_12factor-0.0.3.gem new file mode 100644 index 0000000..26b17bf Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/rails_12factor-0.0.3.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/rails_serve_static_assets-0.0.5.gem b/vendor/bundle/ruby/2.2.0/cache/rails_serve_static_assets-0.0.5.gem new file mode 100644 index 0000000..dfe349c Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/rails_serve_static_assets-0.0.5.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/rails_stdout_logging-0.0.5.gem b/vendor/bundle/ruby/2.2.0/cache/rails_stdout_logging-0.0.5.gem new file mode 100644 index 0000000..f09bc21 Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/rails_stdout_logging-0.0.5.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/railties-4.2.6.gem b/vendor/bundle/ruby/2.2.0/cache/railties-4.2.6.gem new file mode 100644 index 0000000..db46131 Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/railties-4.2.6.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/rake-11.1.2.gem b/vendor/bundle/ruby/2.2.0/cache/rake-11.1.2.gem new file mode 100644 index 0000000..a04ab6d Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/rake-11.1.2.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/rdoc-4.2.2.gem b/vendor/bundle/ruby/2.2.0/cache/rdoc-4.2.2.gem new file mode 100644 index 0000000..d73cfad Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/rdoc-4.2.2.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/ruby-progressbar-1.8.1.gem b/vendor/bundle/ruby/2.2.0/cache/ruby-progressbar-1.8.1.gem new file mode 100644 index 0000000..6f8065a Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/ruby-progressbar-1.8.1.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/sass-3.4.22.gem b/vendor/bundle/ruby/2.2.0/cache/sass-3.4.22.gem new file mode 100644 index 0000000..ce4282b Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/sass-3.4.22.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/sass-rails-5.0.4.gem b/vendor/bundle/ruby/2.2.0/cache/sass-rails-5.0.4.gem new file mode 100644 index 0000000..1a81627 Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/sass-rails-5.0.4.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/sdoc-0.4.1.gem b/vendor/bundle/ruby/2.2.0/cache/sdoc-0.4.1.gem new file mode 100644 index 0000000..223dc70 Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/sdoc-0.4.1.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/simplecov-0.11.2.gem b/vendor/bundle/ruby/2.2.0/cache/simplecov-0.11.2.gem new file mode 100644 index 0000000..016ee49 Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/simplecov-0.11.2.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/simplecov-html-0.10.0.gem b/vendor/bundle/ruby/2.2.0/cache/simplecov-html-0.10.0.gem new file mode 100644 index 0000000..43921dc Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/simplecov-html-0.10.0.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/sprockets-3.6.0.gem b/vendor/bundle/ruby/2.2.0/cache/sprockets-3.6.0.gem new file mode 100644 index 0000000..f3c69a1 Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/sprockets-3.6.0.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/sprockets-rails-3.0.4.gem b/vendor/bundle/ruby/2.2.0/cache/sprockets-rails-3.0.4.gem new file mode 100644 index 0000000..e91d0ac Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/sprockets-rails-3.0.4.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/sqlite3-1.3.11.gem b/vendor/bundle/ruby/2.2.0/cache/sqlite3-1.3.11.gem new file mode 100644 index 0000000..69760cd Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/sqlite3-1.3.11.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/thor-0.19.1.gem b/vendor/bundle/ruby/2.2.0/cache/thor-0.19.1.gem new file mode 100644 index 0000000..1ca502f Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/thor-0.19.1.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/thread_safe-0.3.5.gem b/vendor/bundle/ruby/2.2.0/cache/thread_safe-0.3.5.gem new file mode 100644 index 0000000..ab806b6 Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/thread_safe-0.3.5.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/tilt-2.0.4.gem b/vendor/bundle/ruby/2.2.0/cache/tilt-2.0.4.gem new file mode 100644 index 0000000..ad2ca4c Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/tilt-2.0.4.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/turbolinks-2.5.3.gem b/vendor/bundle/ruby/2.2.0/cache/turbolinks-2.5.3.gem new file mode 100644 index 0000000..fe4e0ec Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/turbolinks-2.5.3.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/tzinfo-1.2.2.gem b/vendor/bundle/ruby/2.2.0/cache/tzinfo-1.2.2.gem new file mode 100644 index 0000000..57dd326 Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/tzinfo-1.2.2.gem differ diff --git a/vendor/bundle/ruby/2.2.0/cache/uglifier-3.0.0.gem b/vendor/bundle/ruby/2.2.0/cache/uglifier-3.0.0.gem new file mode 100644 index 0000000..ab05793 Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/cache/uglifier-3.0.0.gem differ diff --git a/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/bcrypt-3.1.11/bcrypt_ext.bundle b/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/bcrypt-3.1.11/bcrypt_ext.bundle new file mode 100755 index 0000000..3f16f2d Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/bcrypt-3.1.11/bcrypt_ext.bundle differ diff --git a/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/bcrypt-3.1.11/gem.build_complete b/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/bcrypt-3.1.11/gem.build_complete new file mode 100644 index 0000000..e69de29 diff --git a/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/bcrypt-3.1.11/gem_make.out b/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/bcrypt-3.1.11/gem_make.out new file mode 100644 index 0000000..2ce08f6 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/bcrypt-3.1.11/gem_make.out @@ -0,0 +1,16 @@ +/Users/RA/.rvm/rubies/ruby-2.2.3/bin/ruby -r ./siteconf20160523-33198-18cgnjr.rb extconf.rb +creating Makefile + +make "DESTDIR=" clean + +make "DESTDIR=" +compiling bcrypt_ext.c +compiling crypt.c +compiling crypt_blowfish.c +compiling crypt_gensalt.c +compiling wrapper.c +linking shared-object bcrypt_ext.bundle +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' + +make "DESTDIR=" install +/usr/bin/install -m 0755 bcrypt_ext.bundle ./.gem.20160523-33198-15ej3t0 diff --git a/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/byebug-9.0.4/byebug/byebug.bundle b/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/byebug-9.0.4/byebug/byebug.bundle new file mode 100755 index 0000000..f102a57 Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/byebug-9.0.4/byebug/byebug.bundle differ diff --git a/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/byebug-9.0.4/gem.build_complete b/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/byebug-9.0.4/gem.build_complete new file mode 100644 index 0000000..e69de29 diff --git a/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/byebug-9.0.4/gem_make.out b/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/byebug-9.0.4/gem_make.out new file mode 100644 index 0000000..bcb4cb3 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/byebug-9.0.4/gem_make.out @@ -0,0 +1,16 @@ +/Users/RA/.rvm/rubies/ruby-2.2.3/bin/ruby -r ./siteconf20160523-33198-5dadjx.rb extconf.rb +creating Makefile + +make "DESTDIR=" clean + +make "DESTDIR=" +compiling breakpoint.c +compiling byebug.c +compiling context.c +compiling locker.c +compiling threads.c +linking shared-object byebug/byebug.bundle +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' + +make "DESTDIR=" install +/usr/bin/install -m 0755 byebug.bundle ./.gem.20160523-33198-xt6kiv/byebug diff --git a/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/json-1.8.3/gem.build_complete b/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/json-1.8.3/gem.build_complete new file mode 100644 index 0000000..e69de29 diff --git a/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/json-1.8.3/gem_make.out b/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/json-1.8.3/gem_make.out new file mode 100644 index 0000000..e3c9ddd --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/json-1.8.3/gem_make.out @@ -0,0 +1,9 @@ +/Users/RA/.rvm/rubies/ruby-2.2.3/bin/ruby -r ./siteconf20160523-33198-zsdi01.rb extconf.rb +creating Makefile + +make "DESTDIR=" clean + +make "DESTDIR=" +make: Nothing to be done for `all'. + +make "DESTDIR=" install diff --git a/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/json-1.8.3/json/ext/generator.bundle b/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/json-1.8.3/json/ext/generator.bundle new file mode 100755 index 0000000..7411f54 Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/json-1.8.3/json/ext/generator.bundle differ diff --git a/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/json-1.8.3/json/ext/parser.bundle b/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/json-1.8.3/json/ext/parser.bundle new file mode 100755 index 0000000..47508f6 Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/json-1.8.3/json/ext/parser.bundle differ diff --git a/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/nokogiri-1.6.7.2/gem.build_complete b/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/nokogiri-1.6.7.2/gem.build_complete new file mode 100644 index 0000000..e69de29 diff --git a/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/nokogiri-1.6.7.2/gem_make.out b/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/nokogiri-1.6.7.2/gem_make.out new file mode 100644 index 0000000..c63cbb7 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/nokogiri-1.6.7.2/gem_make.out @@ -0,0 +1,243 @@ +/Users/RA/.rvm/rubies/ruby-2.2.3/bin/ruby -r ./siteconf20160523-33198-nby6ly.rb extconf.rb +checking if the C compiler accepts ... yes +checking if the C compiler accepts -Wno-error=unused-command-line-argument-hard-error-in-future... no +Building nokogiri using packaged libraries. +Using mini_portile version 2.0.0 +checking for iconv.h... yes +checking for gzdopen() in -lz... yes +checking for iconv... yes +************************************************************************ +IMPORTANT NOTICE: + +Building Nokogiri with a packaged version of libxml2-2.9.2 +with the following patches applied: + - 0001-Revert-Missing-initialization-for-the-catalog-module.patch + - 0002-Fix-missing-entities-after-CVE-2014-3660-fix.patch + - 0003-Stop-parsing-on-entities-boundaries-errors.patch + - 0004-Cleanup-conditional-section-error-handling.patch + - 0005-CVE-2015-1819-Enforce-the-reader-to-run-in-constant-.patch + - 0006-Another-variation-of-overflow-in-Conditional-section.patch + - 0007-Fix-an-error-in-previous-Conditional-section-patch.patch + - 0008-CVE-2015-8035-Fix-XZ-compression-support-loop.patch + - 0009-Updated-config.guess.patch + - 0010-Fix-parsering-short-unclosed-comment-uninitialized-access.patch + - 0011-Avoid-extra-processing-of-MarkupDecl-when-EOF.patch + - 0012-Avoid-processing-entities-after-encoding-conversion-.patch + - 0013-CVE-2015-7497-Avoid-an-heap-buffer-overflow-in-xmlDi.patch + - 0014-CVE-2015-5312-Another-entity-expansion-issue.patch + - 0015-Add-xmlHaltParser-to-stop-the-parser.patch + - 0016-Detect-incoherency-on-GROW.patch + - 0017-CVE-2015-7500-Fix-memory-access-error-due-to-incorre.patch + - 0018-CVE-2015-8242-Buffer-overead-with-HTML-parser-in-pus.patch + - 0019-Do-not-print-error-context-when-there-is-none.patch + - 0020-xmlStopParser-reset-errNo.patch + - 0021-Reuse-xmlHaltParser-where-it-makes-sense.patch + +Team Nokogiri will keep on doing their best to provide security +updates in a timely manner, but if this is a concern for you and want +to use the system library instead; abort this installation process and +reinstall nokogiri as follows: + + gem install nokogiri -- --use-system-libraries + [--with-xml2-config=/path/to/xml2-config] + [--with-xslt-config=/path/to/xslt-config] + +If you are using Bundler, tell it to use the option: + + bundle config build.nokogiri --use-system-libraries + bundle install + +Note, however, that nokogiri is not fully compatible with arbitrary +versions of libxml2 provided by OS/package vendors. +************************************************************************ +Extracting libxml2-2.9.2.tar.gz into tmp/x86_64-apple-darwin14.5.0/ports/libxml2/2.9.2... OK +Running git apply with /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/patches/libxml2/0001-Revert-Missing-initialization-for-the-catalog-module.patch... OK +Running git apply with /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/patches/libxml2/0002-Fix-missing-entities-after-CVE-2014-3660-fix.patch... OK +Running git apply with /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/patches/libxml2/0003-Stop-parsing-on-entities-boundaries-errors.patch... OK +Running git apply with /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/patches/libxml2/0004-Cleanup-conditional-section-error-handling.patch... OK +Running git apply with /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/patches/libxml2/0005-CVE-2015-1819-Enforce-the-reader-to-run-in-constant-.patch... OK +Running git apply with /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/patches/libxml2/0006-Another-variation-of-overflow-in-Conditional-section.patch... OK +Running git apply with /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/patches/libxml2/0007-Fix-an-error-in-previous-Conditional-section-patch.patch... OK +Running git apply with /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/patches/libxml2/0008-CVE-2015-8035-Fix-XZ-compression-support-loop.patch... OK +Running git apply with /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/patches/libxml2/0009-Updated-config.guess.patch... OK +Running git apply with /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/patches/libxml2/0010-Fix-parsering-short-unclosed-comment-uninitialized-access.patch... OK +Running git apply with /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/patches/libxml2/0011-Avoid-extra-processing-of-MarkupDecl-when-EOF.patch... OK +Running git apply with /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/patches/libxml2/0012-Avoid-processing-entities-after-encoding-conversion-.patch... OK +Running git apply with /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/patches/libxml2/0013-CVE-2015-7497-Avoid-an-heap-buffer-overflow-in-xmlDi.patch... OK +Running git apply with /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/patches/libxml2/0014-CVE-2015-5312-Another-entity-expansion-issue.patch... OK +Running git apply with /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/patches/libxml2/0015-Add-xmlHaltParser-to-stop-the-parser.patch... OK +Running git apply with /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/patches/libxml2/0016-Detect-incoherency-on-GROW.patch... OK +Running git apply with /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/patches/libxml2/0017-CVE-2015-7500-Fix-memory-access-error-due-to-incorre.patch... OK +Running git apply with /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/patches/libxml2/0018-CVE-2015-8242-Buffer-overead-with-HTML-parser-in-pus.patch... OK +Running git apply with /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/patches/libxml2/0019-Do-not-print-error-context-when-there-is-none.patch... OK +Running git apply with /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/patches/libxml2/0020-xmlStopParser-reset-errNo.patch... OK +Running git apply with /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/patches/libxml2/0021-Reuse-xmlHaltParser-where-it-makes-sense.patch... OK +Running 'configure' for libxml2 2.9.2... OK +Running 'compile' for libxml2 2.9.2... OK +Running 'install' for libxml2 2.9.2... OK +Activating libxml2 2.9.2 (from /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2)... +************************************************************************ +IMPORTANT NOTICE: + +Building Nokogiri with a packaged version of libxslt-1.1.28 +with the following patches applied: + - 0001-Adding-doc-update-related-to-1.1.28.patch + - 0002-Fix-a-couple-of-places-where-f-printf-parameters-wer.patch + - 0003-Initialize-pseudo-random-number-generator-with-curre.patch + - 0004-EXSLT-function-str-replace-is-broken-as-is.patch + - 0006-Fix-str-padding-to-work-with-UTF-8-strings.patch + - 0007-Separate-function-for-predicate-matching-in-patterns.patch + - 0008-Fix-direct-pattern-matching.patch + - 0009-Fix-certain-patterns-with-predicates.patch + - 0010-Fix-handling-of-UTF-8-strings-in-EXSLT-crypto-module.patch + - 0013-Memory-leak-in-xsltCompileIdKeyPattern-error-path.patch + - 0014-Fix-for-bug-436589.patch + - 0015-Fix-mkdir-for-mingw.patch + - 0016-Fix-for-type-confusion-in-preprocessing-attributes.patch + - 0017-Updated-config.guess.patch + +Team Nokogiri will keep on doing their best to provide security +updates in a timely manner, but if this is a concern for you and want +to use the system library instead; abort this installation process and +reinstall nokogiri as follows: + + gem install nokogiri -- --use-system-libraries + [--with-xml2-config=/path/to/xml2-config] + [--with-xslt-config=/path/to/xslt-config] + +If you are using Bundler, tell it to use the option: + + bundle config build.nokogiri --use-system-libraries + bundle install +************************************************************************ +Extracting libxslt-1.1.28.tar.gz into tmp/x86_64-apple-darwin14.5.0/ports/libxslt/1.1.28... OK +Running git apply with /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/patches/libxslt/0001-Adding-doc-update-related-to-1.1.28.patch... OK +Running git apply with /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/patches/libxslt/0002-Fix-a-couple-of-places-where-f-printf-parameters-wer.patch... OK +Running git apply with /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/patches/libxslt/0003-Initialize-pseudo-random-number-generator-with-curre.patch... OK +Running git apply with /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/patches/libxslt/0004-EXSLT-function-str-replace-is-broken-as-is.patch... OK +Running git apply with /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/patches/libxslt/0006-Fix-str-padding-to-work-with-UTF-8-strings.patch... OK +Running git apply with /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/patches/libxslt/0007-Separate-function-for-predicate-matching-in-patterns.patch... OK +Running git apply with /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/patches/libxslt/0008-Fix-direct-pattern-matching.patch... OK +Running git apply with /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/patches/libxslt/0009-Fix-certain-patterns-with-predicates.patch... OK +Running git apply with /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/patches/libxslt/0010-Fix-handling-of-UTF-8-strings-in-EXSLT-crypto-module.patch... OK +Running git apply with /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/patches/libxslt/0013-Memory-leak-in-xsltCompileIdKeyPattern-error-path.patch... OK +Running git apply with /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/patches/libxslt/0014-Fix-for-bug-436589.patch... OK +Running git apply with /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/patches/libxslt/0015-Fix-mkdir-for-mingw.patch... OK +Running git apply with /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/patches/libxslt/0016-Fix-for-type-confusion-in-preprocessing-attributes.patch... OK +Running git apply with /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/patches/libxslt/0017-Updated-config.guess.patch... OK +Running 'configure' for libxslt 1.1.28... OK +Running 'compile' for libxslt 1.1.28... OK +Running 'install' for libxslt 1.1.28... OK +Activating libxslt 1.1.28 (from /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28)... +checking for main() in -llzma... yes +checking for xmlParseDoc() in libxml/parser.h... yes +checking for xsltParseStylesheetDoc() in libxslt/xslt.h... yes +checking for exsltFuncRegister() in libexslt/exslt.h... yes +checking for xmlHasFeature()... yes +checking for xmlFirstElementChild()... yes +checking for xmlRelaxNGSetParserStructuredErrors()... yes +checking for xmlRelaxNGSetParserStructuredErrors()... yes +checking for xmlRelaxNGSetValidStructuredErrors()... yes +checking for xmlSchemaSetValidStructuredErrors()... yes +checking for xmlSchemaSetParserStructuredErrors()... yes +creating Makefile + +make "DESTDIR=" clean + +make "DESTDIR=" +compiling html_document.c +compiling html_element_description.c +html_element_description.c:252:48: warning: cast from 'const struct _htmlElemDesc *' to 'void *' drops const qualifier [-Wcast-qual] + return Data_Wrap_Struct(klass, 0, 0, (void *)description); + ^ +/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/ruby.h:1028:35: note: expanded from macro 'Data_Wrap_Struct' + rb_data_object_alloc((klass),(sval),(RUBY_DATA_FUNC)(mark),(RUBY_DATA_FUNC)(free)) + ^ +1 warning generated. +compiling html_entity_lookup.c +compiling html_sax_parser_context.c +compiling html_sax_push_parser.c +compiling nokogiri.c +compiling xml_attr.c +compiling xml_attribute_decl.c +compiling xml_cdata.c +compiling xml_comment.c +compiling xml_document.c +xml_document.c:182:21: warning: cast from 'const unsigned char *' to 'char *' drops const qualifier [-Wcast-qual] + free((char *) doc->encoding); /* this may produce a gcc cast warning */ + ^ +xml_document.c:537:26: warning: cast from 'const char *' to 'unsigned char *' drops const qualifier [-Wcast-qual] + ns[i] = (xmlChar*) ptr; + ^ +2 warnings generated. +compiling xml_document_fragment.c +compiling xml_dtd.c +compiling xml_element_content.c +compiling xml_element_decl.c +compiling xml_encoding_handler.c +compiling xml_entity_decl.c +compiling xml_entity_reference.c +compiling xml_io.c +compiling xml_libxml2_hacks.c +compiling xml_namespace.c +compiling xml_node.c +xml_node.c:168:15: warning: 14 enumeration values not handled in switch: 'XML_ATTRIBUTE_NODE', 'XML_ENTITY_NODE', 'XML_DOCUMENT_NODE'... [-Wswitch] + switch (reparentee->type) { + ^ +xml_node.c:186:15: warning: 15 enumeration values not handled in switch: 'XML_ATTRIBUTE_NODE', 'XML_ENTITY_NODE', 'XML_DOCUMENT_NODE'... [-Wswitch] + switch (reparentee->type) { + ^ +xml_node.c:197:15: warning: 19 enumeration values not handled in switch: 'XML_ELEMENT_NODE', 'XML_ATTRIBUTE_NODE', 'XML_CDATA_SECTION_NODE'... [-Wswitch] + switch (reparentee->type) { + ^ +xml_node.c:165:13: warning: 14 enumeration values not handled in switch: 'XML_CDATA_SECTION_NODE', 'XML_ENTITY_NODE', 'XML_PI_NODE'... [-Wswitch] + switch (parent->type) { + ^ +4 warnings generated. +compiling xml_node_set.c +xml_node_set.c:9:24: warning: cast from 'const unsigned char *' to 'unsigned char *' drops const qualifier [-Wcast-qual] + xmlFree((xmlChar *)ns->href); + ^ +xml_node_set.c:11:24: warning: cast from 'const unsigned char *' to 'unsigned char *' drops const qualifier [-Wcast-qual] + xmlFree((xmlChar *)ns->prefix); + ^ +2 warnings generated. +compiling xml_processing_instruction.c +compiling xml_reader.c +compiling xml_relax_ng.c +compiling xml_sax_parser.c +compiling xml_sax_parser_context.c +compiling xml_sax_push_parser.c +compiling xml_schema.c +compiling xml_syntax_error.c +compiling xml_text.c +compiling xml_xpath_context.c +compiling xslt_stylesheet.c +xslt_stylesheet.c:217:21: warning: incompatible pointer to integer conversion passing 'void *' to parameter of type 'VALUE' (aka 'unsigned long') [-Wint-conversion] + Data_Get_Struct(ctxt->style->_private, nokogiriXsltStylesheetTuple, + ^~~~~~~~~~~~~~~~~~~~~ +/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/ruby.h:1044:41: note: expanded from macro 'Data_Get_Struct' + ((sval) = (type*)rb_data_object_get(obj)) + ^ +/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/ruby.h:1189:26: note: passing argument to parameter 'obj' here +rb_data_object_get(VALUE obj) + ^ +xslt_stylesheet.c:230:21: warning: incompatible pointer to integer conversion passing 'void *' to parameter of type 'VALUE' (aka 'unsigned long') [-Wint-conversion] + Data_Get_Struct(ctxt->style->_private, nokogiriXsltStylesheetTuple, + ^~~~~~~~~~~~~~~~~~~~~ +/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/ruby.h:1044:41: note: expanded from macro 'Data_Get_Struct' + ((sval) = (type*)rb_data_object_get(obj)) + ^ +/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/ruby.h:1189:26: note: passing argument to parameter 'obj' here +rb_data_object_get(VALUE obj) + ^ +2 warnings generated. +linking shared-object nokogiri/nokogiri.bundle +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +Cleaning files only used during build. +rm -rf /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ext/nokogiri/tmp/x86_64-apple-darwin14.5.0/ports +rmdir -p /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ext/nokogiri/tmp/x86_64-apple-darwin14.5.0 +rm -rf /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports + +make "DESTDIR=" install +/usr/bin/install -m 0755 nokogiri.bundle ./.gem.20160523-33198-1tvrj0j/nokogiri diff --git a/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/nokogiri-1.6.7.2/mkmf.log b/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/nokogiri-1.6.7.2/mkmf.log new file mode 100644 index 0000000..85f5dc8 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/nokogiri-1.6.7.2/mkmf.log @@ -0,0 +1,989 @@ +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -arch x86_64 -lruby-static -framework CoreFoundation -lpthread -ldl -lobjc " +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: int main(int argc, char **argv) +4: { +5: return 0; +6: } +/* end */ + +"gcc -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe -arch x86_64 -Werror -c conftest.c" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: int main() {return 0;} +/* end */ + +"gcc -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe -Wno-error=unused-command-line-argument-hard-error-in-future -arch x86_64 -Werror -c conftest.c" +error: unknown warning option '-Werror=unused-command-line-argument-hard-error-in-future'; did you mean '-Werror=unused-command-line-argument'? [-Werror,-Wunknown-warning-option] +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: int main() {return 0;} +/* end */ + +have_header: checking for iconv.h... -------------------- yes + +"gcc -E -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe -Wall -Wcast-qual -Wwrite-strings -Wconversion -Wmissing-noreturn -Winline conftest.c -o conftest.i" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +/* end */ + +-------------------- + +have_library: checking for gzdopen() in -lz... -------------------- yes + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe -Wall -Wcast-qual -Wwrite-strings -Wconversion -Wmissing-noreturn -Winline conftest.c -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -arch x86_64 -lruby-static -framework CoreFoundation -lz -lpthread -ldl -lobjc " +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: extern int t(void); + 7: int main(int argc, char **argv) + 8: { + 9: if (argc > 1000000) { +10: printf("%p", &t); +11: } +12: +13: return 0; +14: } +15: int t(void) { void ((*volatile p)()); p = (void ((*)()))gzdopen; return 0; } +/* end */ + +-------------------- + +have_iconv?: checking for iconv... -------------------- yes + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe -Wall -Wcast-qual -Wwrite-strings -Wconversion -Wmissing-noreturn -Winline conftest.c -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -arch x86_64 -lruby-static -framework CoreFoundation -lpthread -ldl -lobjc " +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +Undefined symbols for architecture x86_64: + "_iconv", referenced from: + _main in conftest-ac5bfa.o + "_iconv_open", referenced from: + _main in conftest-ac5bfa.o +ld: symbol(s) not found for architecture x86_64 +clang: error: linker command failed with exit code 1 (use -v to see invocation) +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: #include + 5: + 6: int main(void) + 7: { + 8: iconv_t cd = iconv_open("", ""); + 9: iconv(cd, NULL, NULL, NULL, NULL); +10: return EXIT_SUCCESS; +11: } +/* end */ + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe -Wall -Wcast-qual -Wwrite-strings -Wconversion -Wmissing-noreturn -Winline conftest.c -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -arch x86_64 -lruby-static -framework CoreFoundation -liconv -lpthread -ldl -lobjc " +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: #include + 5: + 6: int main(void) + 7: { + 8: iconv_t cd = iconv_open("", ""); + 9: iconv(cd, NULL, NULL, NULL, NULL); +10: return EXIT_SUCCESS; +11: } +/* end */ + +-------------------- + +have_library: checking for main() in -llzma... -------------------- yes + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe -Wall -Wcast-qual -Wwrite-strings -Wconversion -Wmissing-noreturn -Winline -DNOKOGIRI_USE_PACKAGED_LIBRARIES conftest.c -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -arch x86_64 -lruby-static -framework CoreFoundation -llzma -lpthread -ldl -lobjc " +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { void ((*volatile p)()); p = (void ((*)()))main; return 0; } +/* end */ + +-------------------- + +have_func: checking for xmlParseDoc() in libxml/parser.h... -------------------- yes + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/include -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/include/libxml2 -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/include/libxml2 -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT "-DNOKOGIRI_LIBXML2_PATH=\"/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2\"" "-DNOKOGIRI_LIBXML2_PATCHES=\"0001-Revert-Missing-initialization-for-the-catalog-module.patch 0002-Fix-missing-entities-after-CVE-2014-3660-fix.patch 0003-Stop-parsing-on-entities-boundaries-errors.patch 0004-Cleanup-conditional-section-error-handling.patch 0005-CVE-2015-1819-Enforce-the-reader-to-run-in-constant-.patch 0006-Another-variation-of-overflow-in-Conditional-section.patch 0007-Fix-an-error-in-previous-Conditional-section-patch.patch 0008-CVE-2015-8035-Fix-XZ-compression-support-loop.patch 0009-Updated-config.guess.patch 0010-Fix-parsering-short-unclosed-comment-uninitialized-access.patch 0011-Avoid-extra-processing-of-MarkupDecl-when-EOF.patch 0012-Avoid-processing-entities-after-encoding-conversion-.patch 0013-CVE-2015-7497-Avoid-an-heap-buffer-overflow-in-xmlDi.patch 0014-CVE-2015-5312-Another-entity-expansion-issue.patch 0015-Add-xmlHaltParser-to-stop-the-parser.patch 0016-Detect-incoherency-on-GROW.patch 0017-CVE-2015-7500-Fix-memory-access-error-due-to-incorre.patch 0018-CVE-2015-8242-Buffer-overead-with-HTML-parser-in-pus.patch 0019-Do-not-print-error-context-when-there-is-none.patch 0020-xmlStopParser-reset-errNo.patch 0021-Reuse-xmlHaltParser-where-it-makes-sense.patch\"" "-DNOKOGIRI_LIBXSLT_PATH=\"/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28\"" "-DNOKOGIRI_LIBXSLT_PATCHES=\"0001-Adding-doc-update-related-to-1.1.28.patch 0002-Fix-a-couple-of-places-where-f-printf-parameters-wer.patch 0003-Initialize-pseudo-random-number-generator-with-curre.patch 0004-EXSLT-function-str-replace-is-broken-as-is.patch 0006-Fix-str-padding-to-work-with-UTF-8-strings.patch 0007-Separate-function-for-predicate-matching-in-patterns.patch 0008-Fix-direct-pattern-matching.patch 0009-Fix-certain-patterns-with-predicates.patch 0010-Fix-handling-of-UTF-8-strings-in-EXSLT-crypto-module.patch 0013-Memory-leak-in-xsltCompileIdKeyPattern-error-path.patch 0014-Fix-for-bug-436589.patch 0015-Fix-mkdir-for-mingw.patch 0016-Fix-for-type-confusion-in-preprocessing-attributes.patch 0017-Updated-config.guess.patch\"" -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe -Wall -Wcast-qual -Wwrite-strings -Wconversion -Wmissing-noreturn -Winline -DNOKOGIRI_USE_PACKAGED_LIBRARIES conftest.c -L/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib -L/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -arch x86_64 /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libexslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a -llzma -lruby-static -framework CoreFoundation /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libexslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a -llzma -lpthread -ldl -lobjc " +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(parser.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(HTMLparser.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(globals.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(parserInternals.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(threads.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(error.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(SAX2.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(tree.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlIO.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(buf.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(uri.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(catalog.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(encoding.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(chvalid.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlstring.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlmemory.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(valid.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(dict.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(entities.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(hash.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(relaxng.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlschemastypes.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xpath.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(HTMLtree.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(SAX.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlregexp.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(debugXML.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlsave.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(pattern.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(list.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(nanoftp.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(nanohttp.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlschemas.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xpointer.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlreader.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlunicode.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xinclude.o)) was built for newer OSX version (10.10) than being linked (10.7) +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: extern int t(void); + 7: int main(int argc, char **argv) + 8: { + 9: if (argc > 1000000) { +10: printf("%p", &t); +11: } +12: +13: return 0; +14: } +15: int t(void) { void ((*volatile p)()); p = (void ((*)()))xmlParseDoc; return 0; } +/* end */ + +-------------------- + +have_func: checking for xsltParseStylesheetDoc() in libxslt/xslt.h... -------------------- yes + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/include -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/include/libxml2 -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/include/libxml2 -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT "-DNOKOGIRI_LIBXML2_PATH=\"/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2\"" "-DNOKOGIRI_LIBXML2_PATCHES=\"0001-Revert-Missing-initialization-for-the-catalog-module.patch 0002-Fix-missing-entities-after-CVE-2014-3660-fix.patch 0003-Stop-parsing-on-entities-boundaries-errors.patch 0004-Cleanup-conditional-section-error-handling.patch 0005-CVE-2015-1819-Enforce-the-reader-to-run-in-constant-.patch 0006-Another-variation-of-overflow-in-Conditional-section.patch 0007-Fix-an-error-in-previous-Conditional-section-patch.patch 0008-CVE-2015-8035-Fix-XZ-compression-support-loop.patch 0009-Updated-config.guess.patch 0010-Fix-parsering-short-unclosed-comment-uninitialized-access.patch 0011-Avoid-extra-processing-of-MarkupDecl-when-EOF.patch 0012-Avoid-processing-entities-after-encoding-conversion-.patch 0013-CVE-2015-7497-Avoid-an-heap-buffer-overflow-in-xmlDi.patch 0014-CVE-2015-5312-Another-entity-expansion-issue.patch 0015-Add-xmlHaltParser-to-stop-the-parser.patch 0016-Detect-incoherency-on-GROW.patch 0017-CVE-2015-7500-Fix-memory-access-error-due-to-incorre.patch 0018-CVE-2015-8242-Buffer-overead-with-HTML-parser-in-pus.patch 0019-Do-not-print-error-context-when-there-is-none.patch 0020-xmlStopParser-reset-errNo.patch 0021-Reuse-xmlHaltParser-where-it-makes-sense.patch\"" "-DNOKOGIRI_LIBXSLT_PATH=\"/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28\"" "-DNOKOGIRI_LIBXSLT_PATCHES=\"0001-Adding-doc-update-related-to-1.1.28.patch 0002-Fix-a-couple-of-places-where-f-printf-parameters-wer.patch 0003-Initialize-pseudo-random-number-generator-with-curre.patch 0004-EXSLT-function-str-replace-is-broken-as-is.patch 0006-Fix-str-padding-to-work-with-UTF-8-strings.patch 0007-Separate-function-for-predicate-matching-in-patterns.patch 0008-Fix-direct-pattern-matching.patch 0009-Fix-certain-patterns-with-predicates.patch 0010-Fix-handling-of-UTF-8-strings-in-EXSLT-crypto-module.patch 0013-Memory-leak-in-xsltCompileIdKeyPattern-error-path.patch 0014-Fix-for-bug-436589.patch 0015-Fix-mkdir-for-mingw.patch 0016-Fix-for-type-confusion-in-preprocessing-attributes.patch 0017-Updated-config.guess.patch\"" -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe -Wall -Wcast-qual -Wwrite-strings -Wconversion -Wmissing-noreturn -Winline -DNOKOGIRI_USE_PACKAGED_LIBRARIES conftest.c -L/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib -L/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -arch x86_64 /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libexslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a -llzma -lruby-static -framework CoreFoundation /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libexslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a -llzma -lpthread -ldl -lobjc " +conftest.c:15:57: error: use of undeclared identifier 'xsltParseStylesheetDoc' +int t(void) { void ((*volatile p)()); p = (void ((*)()))xsltParseStylesheetDoc; return 0; } + ^ +1 error generated. +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: extern int t(void); + 7: int main(int argc, char **argv) + 8: { + 9: if (argc > 1000000) { +10: printf("%p", &t); +11: } +12: +13: return 0; +14: } +15: int t(void) { void ((*volatile p)()); p = (void ((*)()))xsltParseStylesheetDoc; return 0; } +/* end */ + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/include -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/include/libxml2 -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/include/libxml2 -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT "-DNOKOGIRI_LIBXML2_PATH=\"/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2\"" "-DNOKOGIRI_LIBXML2_PATCHES=\"0001-Revert-Missing-initialization-for-the-catalog-module.patch 0002-Fix-missing-entities-after-CVE-2014-3660-fix.patch 0003-Stop-parsing-on-entities-boundaries-errors.patch 0004-Cleanup-conditional-section-error-handling.patch 0005-CVE-2015-1819-Enforce-the-reader-to-run-in-constant-.patch 0006-Another-variation-of-overflow-in-Conditional-section.patch 0007-Fix-an-error-in-previous-Conditional-section-patch.patch 0008-CVE-2015-8035-Fix-XZ-compression-support-loop.patch 0009-Updated-config.guess.patch 0010-Fix-parsering-short-unclosed-comment-uninitialized-access.patch 0011-Avoid-extra-processing-of-MarkupDecl-when-EOF.patch 0012-Avoid-processing-entities-after-encoding-conversion-.patch 0013-CVE-2015-7497-Avoid-an-heap-buffer-overflow-in-xmlDi.patch 0014-CVE-2015-5312-Another-entity-expansion-issue.patch 0015-Add-xmlHaltParser-to-stop-the-parser.patch 0016-Detect-incoherency-on-GROW.patch 0017-CVE-2015-7500-Fix-memory-access-error-due-to-incorre.patch 0018-CVE-2015-8242-Buffer-overead-with-HTML-parser-in-pus.patch 0019-Do-not-print-error-context-when-there-is-none.patch 0020-xmlStopParser-reset-errNo.patch 0021-Reuse-xmlHaltParser-where-it-makes-sense.patch\"" "-DNOKOGIRI_LIBXSLT_PATH=\"/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28\"" "-DNOKOGIRI_LIBXSLT_PATCHES=\"0001-Adding-doc-update-related-to-1.1.28.patch 0002-Fix-a-couple-of-places-where-f-printf-parameters-wer.patch 0003-Initialize-pseudo-random-number-generator-with-curre.patch 0004-EXSLT-function-str-replace-is-broken-as-is.patch 0006-Fix-str-padding-to-work-with-UTF-8-strings.patch 0007-Separate-function-for-predicate-matching-in-patterns.patch 0008-Fix-direct-pattern-matching.patch 0009-Fix-certain-patterns-with-predicates.patch 0010-Fix-handling-of-UTF-8-strings-in-EXSLT-crypto-module.patch 0013-Memory-leak-in-xsltCompileIdKeyPattern-error-path.patch 0014-Fix-for-bug-436589.patch 0015-Fix-mkdir-for-mingw.patch 0016-Fix-for-type-confusion-in-preprocessing-attributes.patch 0017-Updated-config.guess.patch\"" -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe -Wall -Wcast-qual -Wwrite-strings -Wconversion -Wmissing-noreturn -Winline -DNOKOGIRI_USE_PACKAGED_LIBRARIES conftest.c -L/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib -L/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -arch x86_64 /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libexslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a -llzma -lruby-static -framework CoreFoundation /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libexslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a -llzma -lpthread -ldl -lobjc " +conftest.c:15:15: warning: implicit declaration of function 'xsltParseStylesheetDoc' is invalid in C99 [-Wimplicit-function-declaration] +int t(void) { xsltParseStylesheetDoc(); return 0; } + ^ +1 warning generated. +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a(xslt.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(tree.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(uri.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(dict.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(globals.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(valid.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(hash.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlstring.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xpath.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a(keys.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a(pattern.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a(extensions.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a(security.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a(attrvt.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a(documents.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a(attributes.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a(namespaces.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a(variables.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a(preproc.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a(xsltutils.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a(imports.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a(extra.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(threads.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlIO.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(error.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(HTMLtree.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(SAX.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(parser.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlregexp.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(buf.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(chvalid.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(parserInternals.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(entities.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(debugXML.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(encoding.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(pattern.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(list.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlsave.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(SAX2.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xinclude.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xpointer.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a(transform.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a(templates.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a(xsltlocale.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(HTMLparser.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(catalog.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlmemory.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(nanoftp.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(nanohttp.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(relaxng.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlschemastypes.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlunicode.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a(numbers.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a(functions.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlschemas.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlreader.o)) was built for newer OSX version (10.10) than being linked (10.7) +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: extern int t(void); + 7: int main(int argc, char **argv) + 8: { + 9: if (argc > 1000000) { +10: printf("%p", &t); +11: } +12: +13: return 0; +14: } +15: int t(void) { xsltParseStylesheetDoc(); return 0; } +/* end */ + +-------------------- + +have_func: checking for exsltFuncRegister() in libexslt/exslt.h... -------------------- yes + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/include -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/include/libxml2 -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/include/libxml2 -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT "-DNOKOGIRI_LIBXML2_PATH=\"/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2\"" "-DNOKOGIRI_LIBXML2_PATCHES=\"0001-Revert-Missing-initialization-for-the-catalog-module.patch 0002-Fix-missing-entities-after-CVE-2014-3660-fix.patch 0003-Stop-parsing-on-entities-boundaries-errors.patch 0004-Cleanup-conditional-section-error-handling.patch 0005-CVE-2015-1819-Enforce-the-reader-to-run-in-constant-.patch 0006-Another-variation-of-overflow-in-Conditional-section.patch 0007-Fix-an-error-in-previous-Conditional-section-patch.patch 0008-CVE-2015-8035-Fix-XZ-compression-support-loop.patch 0009-Updated-config.guess.patch 0010-Fix-parsering-short-unclosed-comment-uninitialized-access.patch 0011-Avoid-extra-processing-of-MarkupDecl-when-EOF.patch 0012-Avoid-processing-entities-after-encoding-conversion-.patch 0013-CVE-2015-7497-Avoid-an-heap-buffer-overflow-in-xmlDi.patch 0014-CVE-2015-5312-Another-entity-expansion-issue.patch 0015-Add-xmlHaltParser-to-stop-the-parser.patch 0016-Detect-incoherency-on-GROW.patch 0017-CVE-2015-7500-Fix-memory-access-error-due-to-incorre.patch 0018-CVE-2015-8242-Buffer-overead-with-HTML-parser-in-pus.patch 0019-Do-not-print-error-context-when-there-is-none.patch 0020-xmlStopParser-reset-errNo.patch 0021-Reuse-xmlHaltParser-where-it-makes-sense.patch\"" "-DNOKOGIRI_LIBXSLT_PATH=\"/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28\"" "-DNOKOGIRI_LIBXSLT_PATCHES=\"0001-Adding-doc-update-related-to-1.1.28.patch 0002-Fix-a-couple-of-places-where-f-printf-parameters-wer.patch 0003-Initialize-pseudo-random-number-generator-with-curre.patch 0004-EXSLT-function-str-replace-is-broken-as-is.patch 0006-Fix-str-padding-to-work-with-UTF-8-strings.patch 0007-Separate-function-for-predicate-matching-in-patterns.patch 0008-Fix-direct-pattern-matching.patch 0009-Fix-certain-patterns-with-predicates.patch 0010-Fix-handling-of-UTF-8-strings-in-EXSLT-crypto-module.patch 0013-Memory-leak-in-xsltCompileIdKeyPattern-error-path.patch 0014-Fix-for-bug-436589.patch 0015-Fix-mkdir-for-mingw.patch 0016-Fix-for-type-confusion-in-preprocessing-attributes.patch 0017-Updated-config.guess.patch\"" -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe -Wall -Wcast-qual -Wwrite-strings -Wconversion -Wmissing-noreturn -Winline -DNOKOGIRI_USE_PACKAGED_LIBRARIES conftest.c -L/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib -L/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -arch x86_64 /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libexslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a -llzma -lruby-static -framework CoreFoundation /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libexslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a -llzma -lpthread -ldl -lobjc " +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libexslt.a(functions.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xpath.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(debugXML.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(globals.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(tree.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(hash.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlstring.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a(transform.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a(variables.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a(xsltutils.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a(extensions.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a(imports.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a(xslt.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(threads.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlIO.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(error.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(dict.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(HTMLtree.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(HTMLparser.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(SAX.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(valid.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(buf.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(uri.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(chvalid.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(parserInternals.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(entities.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlsave.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(encoding.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(pattern.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlmemory.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(parser.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(relaxng.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(SAX2.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xpointer.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a(keys.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a(pattern.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a(attributes.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a(templates.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a(security.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a(attrvt.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a(namespaces.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a(extra.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a(documents.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a(preproc.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a(xsltlocale.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a(numbers.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a(functions.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlregexp.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(catalog.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(list.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(nanoftp.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(nanohttp.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlschemas.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlschemastypes.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xinclude.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlreader.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlunicode.o)) was built for newer OSX version (10.10) than being linked (10.7) +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: extern int t(void); + 7: int main(int argc, char **argv) + 8: { + 9: if (argc > 1000000) { +10: printf("%p", &t); +11: } +12: +13: return 0; +14: } +15: int t(void) { void ((*volatile p)()); p = (void ((*)()))exsltFuncRegister; return 0; } +/* end */ + +-------------------- + +have_func: checking for xmlHasFeature()... -------------------- yes + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/include -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/include/libxml2 -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/include/libxml2 -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT "-DNOKOGIRI_LIBXML2_PATH=\"/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2\"" "-DNOKOGIRI_LIBXML2_PATCHES=\"0001-Revert-Missing-initialization-for-the-catalog-module.patch 0002-Fix-missing-entities-after-CVE-2014-3660-fix.patch 0003-Stop-parsing-on-entities-boundaries-errors.patch 0004-Cleanup-conditional-section-error-handling.patch 0005-CVE-2015-1819-Enforce-the-reader-to-run-in-constant-.patch 0006-Another-variation-of-overflow-in-Conditional-section.patch 0007-Fix-an-error-in-previous-Conditional-section-patch.patch 0008-CVE-2015-8035-Fix-XZ-compression-support-loop.patch 0009-Updated-config.guess.patch 0010-Fix-parsering-short-unclosed-comment-uninitialized-access.patch 0011-Avoid-extra-processing-of-MarkupDecl-when-EOF.patch 0012-Avoid-processing-entities-after-encoding-conversion-.patch 0013-CVE-2015-7497-Avoid-an-heap-buffer-overflow-in-xmlDi.patch 0014-CVE-2015-5312-Another-entity-expansion-issue.patch 0015-Add-xmlHaltParser-to-stop-the-parser.patch 0016-Detect-incoherency-on-GROW.patch 0017-CVE-2015-7500-Fix-memory-access-error-due-to-incorre.patch 0018-CVE-2015-8242-Buffer-overead-with-HTML-parser-in-pus.patch 0019-Do-not-print-error-context-when-there-is-none.patch 0020-xmlStopParser-reset-errNo.patch 0021-Reuse-xmlHaltParser-where-it-makes-sense.patch\"" "-DNOKOGIRI_LIBXSLT_PATH=\"/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28\"" "-DNOKOGIRI_LIBXSLT_PATCHES=\"0001-Adding-doc-update-related-to-1.1.28.patch 0002-Fix-a-couple-of-places-where-f-printf-parameters-wer.patch 0003-Initialize-pseudo-random-number-generator-with-curre.patch 0004-EXSLT-function-str-replace-is-broken-as-is.patch 0006-Fix-str-padding-to-work-with-UTF-8-strings.patch 0007-Separate-function-for-predicate-matching-in-patterns.patch 0008-Fix-direct-pattern-matching.patch 0009-Fix-certain-patterns-with-predicates.patch 0010-Fix-handling-of-UTF-8-strings-in-EXSLT-crypto-module.patch 0013-Memory-leak-in-xsltCompileIdKeyPattern-error-path.patch 0014-Fix-for-bug-436589.patch 0015-Fix-mkdir-for-mingw.patch 0016-Fix-for-type-confusion-in-preprocessing-attributes.patch 0017-Updated-config.guess.patch\"" -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe -Wall -Wcast-qual -Wwrite-strings -Wconversion -Wmissing-noreturn -Winline -DNOKOGIRI_USE_PACKAGED_LIBRARIES conftest.c -L/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib -L/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -arch x86_64 /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libexslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a -llzma -lruby-static -framework CoreFoundation /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libexslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a -llzma -lpthread -ldl -lobjc " +conftest.c:13:57: error: use of undeclared identifier 'xmlHasFeature' +int t(void) { void ((*volatile p)()); p = (void ((*)()))xmlHasFeature; return 0; } + ^ +1 error generated. +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { void ((*volatile p)()); p = (void ((*)()))xmlHasFeature; return 0; } +/* end */ + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/include -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/include/libxml2 -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/include/libxml2 -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT "-DNOKOGIRI_LIBXML2_PATH=\"/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2\"" "-DNOKOGIRI_LIBXML2_PATCHES=\"0001-Revert-Missing-initialization-for-the-catalog-module.patch 0002-Fix-missing-entities-after-CVE-2014-3660-fix.patch 0003-Stop-parsing-on-entities-boundaries-errors.patch 0004-Cleanup-conditional-section-error-handling.patch 0005-CVE-2015-1819-Enforce-the-reader-to-run-in-constant-.patch 0006-Another-variation-of-overflow-in-Conditional-section.patch 0007-Fix-an-error-in-previous-Conditional-section-patch.patch 0008-CVE-2015-8035-Fix-XZ-compression-support-loop.patch 0009-Updated-config.guess.patch 0010-Fix-parsering-short-unclosed-comment-uninitialized-access.patch 0011-Avoid-extra-processing-of-MarkupDecl-when-EOF.patch 0012-Avoid-processing-entities-after-encoding-conversion-.patch 0013-CVE-2015-7497-Avoid-an-heap-buffer-overflow-in-xmlDi.patch 0014-CVE-2015-5312-Another-entity-expansion-issue.patch 0015-Add-xmlHaltParser-to-stop-the-parser.patch 0016-Detect-incoherency-on-GROW.patch 0017-CVE-2015-7500-Fix-memory-access-error-due-to-incorre.patch 0018-CVE-2015-8242-Buffer-overead-with-HTML-parser-in-pus.patch 0019-Do-not-print-error-context-when-there-is-none.patch 0020-xmlStopParser-reset-errNo.patch 0021-Reuse-xmlHaltParser-where-it-makes-sense.patch\"" "-DNOKOGIRI_LIBXSLT_PATH=\"/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28\"" "-DNOKOGIRI_LIBXSLT_PATCHES=\"0001-Adding-doc-update-related-to-1.1.28.patch 0002-Fix-a-couple-of-places-where-f-printf-parameters-wer.patch 0003-Initialize-pseudo-random-number-generator-with-curre.patch 0004-EXSLT-function-str-replace-is-broken-as-is.patch 0006-Fix-str-padding-to-work-with-UTF-8-strings.patch 0007-Separate-function-for-predicate-matching-in-patterns.patch 0008-Fix-direct-pattern-matching.patch 0009-Fix-certain-patterns-with-predicates.patch 0010-Fix-handling-of-UTF-8-strings-in-EXSLT-crypto-module.patch 0013-Memory-leak-in-xsltCompileIdKeyPattern-error-path.patch 0014-Fix-for-bug-436589.patch 0015-Fix-mkdir-for-mingw.patch 0016-Fix-for-type-confusion-in-preprocessing-attributes.patch 0017-Updated-config.guess.patch\"" -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe -Wall -Wcast-qual -Wwrite-strings -Wconversion -Wmissing-noreturn -Winline -DNOKOGIRI_USE_PACKAGED_LIBRARIES conftest.c -L/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib -L/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -arch x86_64 /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libexslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a -llzma -lruby-static -framework CoreFoundation /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libexslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a -llzma -lpthread -ldl -lobjc " +conftest.c:13:15: warning: implicit declaration of function 'xmlHasFeature' is invalid in C99 [-Wimplicit-function-declaration] +int t(void) { xmlHasFeature(); return 0; } + ^ +1 warning generated. +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(parser.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(HTMLparser.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(globals.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(parserInternals.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(threads.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(error.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(SAX2.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(tree.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlIO.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(buf.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(uri.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(catalog.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(encoding.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(chvalid.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlstring.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlmemory.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(valid.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(dict.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(entities.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(hash.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(relaxng.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlschemastypes.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xpath.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(HTMLtree.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(SAX.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlregexp.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(debugXML.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlsave.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(pattern.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(list.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(nanoftp.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(nanohttp.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlschemas.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xpointer.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlreader.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlunicode.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xinclude.o)) was built for newer OSX version (10.10) than being linked (10.7) +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { xmlHasFeature(); return 0; } +/* end */ + +-------------------- + +have_func: checking for xmlFirstElementChild()... -------------------- yes + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/include -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/include/libxml2 -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/include/libxml2 -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT "-DNOKOGIRI_LIBXML2_PATH=\"/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2\"" "-DNOKOGIRI_LIBXML2_PATCHES=\"0001-Revert-Missing-initialization-for-the-catalog-module.patch 0002-Fix-missing-entities-after-CVE-2014-3660-fix.patch 0003-Stop-parsing-on-entities-boundaries-errors.patch 0004-Cleanup-conditional-section-error-handling.patch 0005-CVE-2015-1819-Enforce-the-reader-to-run-in-constant-.patch 0006-Another-variation-of-overflow-in-Conditional-section.patch 0007-Fix-an-error-in-previous-Conditional-section-patch.patch 0008-CVE-2015-8035-Fix-XZ-compression-support-loop.patch 0009-Updated-config.guess.patch 0010-Fix-parsering-short-unclosed-comment-uninitialized-access.patch 0011-Avoid-extra-processing-of-MarkupDecl-when-EOF.patch 0012-Avoid-processing-entities-after-encoding-conversion-.patch 0013-CVE-2015-7497-Avoid-an-heap-buffer-overflow-in-xmlDi.patch 0014-CVE-2015-5312-Another-entity-expansion-issue.patch 0015-Add-xmlHaltParser-to-stop-the-parser.patch 0016-Detect-incoherency-on-GROW.patch 0017-CVE-2015-7500-Fix-memory-access-error-due-to-incorre.patch 0018-CVE-2015-8242-Buffer-overead-with-HTML-parser-in-pus.patch 0019-Do-not-print-error-context-when-there-is-none.patch 0020-xmlStopParser-reset-errNo.patch 0021-Reuse-xmlHaltParser-where-it-makes-sense.patch\"" "-DNOKOGIRI_LIBXSLT_PATH=\"/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28\"" "-DNOKOGIRI_LIBXSLT_PATCHES=\"0001-Adding-doc-update-related-to-1.1.28.patch 0002-Fix-a-couple-of-places-where-f-printf-parameters-wer.patch 0003-Initialize-pseudo-random-number-generator-with-curre.patch 0004-EXSLT-function-str-replace-is-broken-as-is.patch 0006-Fix-str-padding-to-work-with-UTF-8-strings.patch 0007-Separate-function-for-predicate-matching-in-patterns.patch 0008-Fix-direct-pattern-matching.patch 0009-Fix-certain-patterns-with-predicates.patch 0010-Fix-handling-of-UTF-8-strings-in-EXSLT-crypto-module.patch 0013-Memory-leak-in-xsltCompileIdKeyPattern-error-path.patch 0014-Fix-for-bug-436589.patch 0015-Fix-mkdir-for-mingw.patch 0016-Fix-for-type-confusion-in-preprocessing-attributes.patch 0017-Updated-config.guess.patch\"" -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe -Wall -Wcast-qual -Wwrite-strings -Wconversion -Wmissing-noreturn -Winline -DNOKOGIRI_USE_PACKAGED_LIBRARIES conftest.c -L/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib -L/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -arch x86_64 /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libexslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a -llzma -lruby-static -framework CoreFoundation /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libexslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a -llzma -lpthread -ldl -lobjc " +conftest.c:13:57: error: use of undeclared identifier 'xmlFirstElementChild' +int t(void) { void ((*volatile p)()); p = (void ((*)()))xmlFirstElementChild; return 0; } + ^ +1 error generated. +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { void ((*volatile p)()); p = (void ((*)()))xmlFirstElementChild; return 0; } +/* end */ + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/include -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/include/libxml2 -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/include/libxml2 -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT "-DNOKOGIRI_LIBXML2_PATH=\"/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2\"" "-DNOKOGIRI_LIBXML2_PATCHES=\"0001-Revert-Missing-initialization-for-the-catalog-module.patch 0002-Fix-missing-entities-after-CVE-2014-3660-fix.patch 0003-Stop-parsing-on-entities-boundaries-errors.patch 0004-Cleanup-conditional-section-error-handling.patch 0005-CVE-2015-1819-Enforce-the-reader-to-run-in-constant-.patch 0006-Another-variation-of-overflow-in-Conditional-section.patch 0007-Fix-an-error-in-previous-Conditional-section-patch.patch 0008-CVE-2015-8035-Fix-XZ-compression-support-loop.patch 0009-Updated-config.guess.patch 0010-Fix-parsering-short-unclosed-comment-uninitialized-access.patch 0011-Avoid-extra-processing-of-MarkupDecl-when-EOF.patch 0012-Avoid-processing-entities-after-encoding-conversion-.patch 0013-CVE-2015-7497-Avoid-an-heap-buffer-overflow-in-xmlDi.patch 0014-CVE-2015-5312-Another-entity-expansion-issue.patch 0015-Add-xmlHaltParser-to-stop-the-parser.patch 0016-Detect-incoherency-on-GROW.patch 0017-CVE-2015-7500-Fix-memory-access-error-due-to-incorre.patch 0018-CVE-2015-8242-Buffer-overead-with-HTML-parser-in-pus.patch 0019-Do-not-print-error-context-when-there-is-none.patch 0020-xmlStopParser-reset-errNo.patch 0021-Reuse-xmlHaltParser-where-it-makes-sense.patch\"" "-DNOKOGIRI_LIBXSLT_PATH=\"/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28\"" "-DNOKOGIRI_LIBXSLT_PATCHES=\"0001-Adding-doc-update-related-to-1.1.28.patch 0002-Fix-a-couple-of-places-where-f-printf-parameters-wer.patch 0003-Initialize-pseudo-random-number-generator-with-curre.patch 0004-EXSLT-function-str-replace-is-broken-as-is.patch 0006-Fix-str-padding-to-work-with-UTF-8-strings.patch 0007-Separate-function-for-predicate-matching-in-patterns.patch 0008-Fix-direct-pattern-matching.patch 0009-Fix-certain-patterns-with-predicates.patch 0010-Fix-handling-of-UTF-8-strings-in-EXSLT-crypto-module.patch 0013-Memory-leak-in-xsltCompileIdKeyPattern-error-path.patch 0014-Fix-for-bug-436589.patch 0015-Fix-mkdir-for-mingw.patch 0016-Fix-for-type-confusion-in-preprocessing-attributes.patch 0017-Updated-config.guess.patch\"" -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe -Wall -Wcast-qual -Wwrite-strings -Wconversion -Wmissing-noreturn -Winline -DNOKOGIRI_USE_PACKAGED_LIBRARIES conftest.c -L/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib -L/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -arch x86_64 /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libexslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a -llzma -lruby-static -framework CoreFoundation /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libexslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a -llzma -lpthread -ldl -lobjc " +conftest.c:13:15: warning: implicit declaration of function 'xmlFirstElementChild' is invalid in C99 [-Wimplicit-function-declaration] +int t(void) { xmlFirstElementChild(); return 0; } + ^ +1 warning generated. +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(tree.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(globals.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(error.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(valid.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(buf.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(uri.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(chvalid.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlstring.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(parserInternals.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(entities.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(dict.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(hash.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(threads.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlIO.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(SAX.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(parser.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlregexp.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(catalog.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(encoding.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(SAX2.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(list.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(HTMLparser.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(HTMLtree.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlmemory.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(nanoftp.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(nanohttp.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(relaxng.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlsave.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlschemastypes.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlunicode.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xpath.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(debugXML.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(pattern.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlschemas.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xpointer.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlreader.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xinclude.o)) was built for newer OSX version (10.10) than being linked (10.7) +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { xmlFirstElementChild(); return 0; } +/* end */ + +-------------------- + +have_func: checking for xmlRelaxNGSetParserStructuredErrors()... -------------------- yes + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/include -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/include/libxml2 -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/include/libxml2 -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT "-DNOKOGIRI_LIBXML2_PATH=\"/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2\"" "-DNOKOGIRI_LIBXML2_PATCHES=\"0001-Revert-Missing-initialization-for-the-catalog-module.patch 0002-Fix-missing-entities-after-CVE-2014-3660-fix.patch 0003-Stop-parsing-on-entities-boundaries-errors.patch 0004-Cleanup-conditional-section-error-handling.patch 0005-CVE-2015-1819-Enforce-the-reader-to-run-in-constant-.patch 0006-Another-variation-of-overflow-in-Conditional-section.patch 0007-Fix-an-error-in-previous-Conditional-section-patch.patch 0008-CVE-2015-8035-Fix-XZ-compression-support-loop.patch 0009-Updated-config.guess.patch 0010-Fix-parsering-short-unclosed-comment-uninitialized-access.patch 0011-Avoid-extra-processing-of-MarkupDecl-when-EOF.patch 0012-Avoid-processing-entities-after-encoding-conversion-.patch 0013-CVE-2015-7497-Avoid-an-heap-buffer-overflow-in-xmlDi.patch 0014-CVE-2015-5312-Another-entity-expansion-issue.patch 0015-Add-xmlHaltParser-to-stop-the-parser.patch 0016-Detect-incoherency-on-GROW.patch 0017-CVE-2015-7500-Fix-memory-access-error-due-to-incorre.patch 0018-CVE-2015-8242-Buffer-overead-with-HTML-parser-in-pus.patch 0019-Do-not-print-error-context-when-there-is-none.patch 0020-xmlStopParser-reset-errNo.patch 0021-Reuse-xmlHaltParser-where-it-makes-sense.patch\"" "-DNOKOGIRI_LIBXSLT_PATH=\"/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28\"" "-DNOKOGIRI_LIBXSLT_PATCHES=\"0001-Adding-doc-update-related-to-1.1.28.patch 0002-Fix-a-couple-of-places-where-f-printf-parameters-wer.patch 0003-Initialize-pseudo-random-number-generator-with-curre.patch 0004-EXSLT-function-str-replace-is-broken-as-is.patch 0006-Fix-str-padding-to-work-with-UTF-8-strings.patch 0007-Separate-function-for-predicate-matching-in-patterns.patch 0008-Fix-direct-pattern-matching.patch 0009-Fix-certain-patterns-with-predicates.patch 0010-Fix-handling-of-UTF-8-strings-in-EXSLT-crypto-module.patch 0013-Memory-leak-in-xsltCompileIdKeyPattern-error-path.patch 0014-Fix-for-bug-436589.patch 0015-Fix-mkdir-for-mingw.patch 0016-Fix-for-type-confusion-in-preprocessing-attributes.patch 0017-Updated-config.guess.patch\"" -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe -Wall -Wcast-qual -Wwrite-strings -Wconversion -Wmissing-noreturn -Winline -DNOKOGIRI_USE_PACKAGED_LIBRARIES conftest.c -L/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib -L/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -arch x86_64 /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libexslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a -llzma -lruby-static -framework CoreFoundation /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libexslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a -llzma -lpthread -ldl -lobjc " +conftest.c:13:57: error: use of undeclared identifier 'xmlRelaxNGSetParserStructuredErrors' +int t(void) { void ((*volatile p)()); p = (void ((*)()))xmlRelaxNGSetParserStructuredErrors; return 0; } + ^ +1 error generated. +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { void ((*volatile p)()); p = (void ((*)()))xmlRelaxNGSetParserStructuredErrors; return 0; } +/* end */ + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/include -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/include/libxml2 -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/include/libxml2 -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT "-DNOKOGIRI_LIBXML2_PATH=\"/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2\"" "-DNOKOGIRI_LIBXML2_PATCHES=\"0001-Revert-Missing-initialization-for-the-catalog-module.patch 0002-Fix-missing-entities-after-CVE-2014-3660-fix.patch 0003-Stop-parsing-on-entities-boundaries-errors.patch 0004-Cleanup-conditional-section-error-handling.patch 0005-CVE-2015-1819-Enforce-the-reader-to-run-in-constant-.patch 0006-Another-variation-of-overflow-in-Conditional-section.patch 0007-Fix-an-error-in-previous-Conditional-section-patch.patch 0008-CVE-2015-8035-Fix-XZ-compression-support-loop.patch 0009-Updated-config.guess.patch 0010-Fix-parsering-short-unclosed-comment-uninitialized-access.patch 0011-Avoid-extra-processing-of-MarkupDecl-when-EOF.patch 0012-Avoid-processing-entities-after-encoding-conversion-.patch 0013-CVE-2015-7497-Avoid-an-heap-buffer-overflow-in-xmlDi.patch 0014-CVE-2015-5312-Another-entity-expansion-issue.patch 0015-Add-xmlHaltParser-to-stop-the-parser.patch 0016-Detect-incoherency-on-GROW.patch 0017-CVE-2015-7500-Fix-memory-access-error-due-to-incorre.patch 0018-CVE-2015-8242-Buffer-overead-with-HTML-parser-in-pus.patch 0019-Do-not-print-error-context-when-there-is-none.patch 0020-xmlStopParser-reset-errNo.patch 0021-Reuse-xmlHaltParser-where-it-makes-sense.patch\"" "-DNOKOGIRI_LIBXSLT_PATH=\"/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28\"" "-DNOKOGIRI_LIBXSLT_PATCHES=\"0001-Adding-doc-update-related-to-1.1.28.patch 0002-Fix-a-couple-of-places-where-f-printf-parameters-wer.patch 0003-Initialize-pseudo-random-number-generator-with-curre.patch 0004-EXSLT-function-str-replace-is-broken-as-is.patch 0006-Fix-str-padding-to-work-with-UTF-8-strings.patch 0007-Separate-function-for-predicate-matching-in-patterns.patch 0008-Fix-direct-pattern-matching.patch 0009-Fix-certain-patterns-with-predicates.patch 0010-Fix-handling-of-UTF-8-strings-in-EXSLT-crypto-module.patch 0013-Memory-leak-in-xsltCompileIdKeyPattern-error-path.patch 0014-Fix-for-bug-436589.patch 0015-Fix-mkdir-for-mingw.patch 0016-Fix-for-type-confusion-in-preprocessing-attributes.patch 0017-Updated-config.guess.patch\"" -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe -Wall -Wcast-qual -Wwrite-strings -Wconversion -Wmissing-noreturn -Winline -DNOKOGIRI_USE_PACKAGED_LIBRARIES conftest.c -L/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib -L/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -arch x86_64 /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libexslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a -llzma -lruby-static -framework CoreFoundation /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libexslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a -llzma -lpthread -ldl -lobjc " +conftest.c:13:15: warning: implicit declaration of function 'xmlRelaxNGSetParserStructuredErrors' is invalid in C99 [-Wimplicit-function-declaration] +int t(void) { xmlRelaxNGSetParserStructuredErrors(); return 0; } + ^ +1 warning generated. +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(relaxng.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(globals.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(error.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(tree.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlregexp.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(uri.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlstring.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlsave.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(hash.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(parser.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlschemas.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlschemastypes.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(valid.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(HTMLparser.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(parserInternals.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(threads.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlIO.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(dict.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(SAX2.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(HTMLtree.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(SAX.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(buf.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(catalog.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(encoding.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(chvalid.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlmemory.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(entities.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(pattern.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(list.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlreader.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlunicode.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xpath.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(debugXML.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(nanoftp.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(nanohttp.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xinclude.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xpointer.o)) was built for newer OSX version (10.10) than being linked (10.7) +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { xmlRelaxNGSetParserStructuredErrors(); return 0; } +/* end */ + +-------------------- + +have_func: checking for xmlRelaxNGSetParserStructuredErrors()... -------------------- yes + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/include -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/include/libxml2 -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/include/libxml2 -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT "-DNOKOGIRI_LIBXML2_PATH=\"/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2\"" "-DNOKOGIRI_LIBXML2_PATCHES=\"0001-Revert-Missing-initialization-for-the-catalog-module.patch 0002-Fix-missing-entities-after-CVE-2014-3660-fix.patch 0003-Stop-parsing-on-entities-boundaries-errors.patch 0004-Cleanup-conditional-section-error-handling.patch 0005-CVE-2015-1819-Enforce-the-reader-to-run-in-constant-.patch 0006-Another-variation-of-overflow-in-Conditional-section.patch 0007-Fix-an-error-in-previous-Conditional-section-patch.patch 0008-CVE-2015-8035-Fix-XZ-compression-support-loop.patch 0009-Updated-config.guess.patch 0010-Fix-parsering-short-unclosed-comment-uninitialized-access.patch 0011-Avoid-extra-processing-of-MarkupDecl-when-EOF.patch 0012-Avoid-processing-entities-after-encoding-conversion-.patch 0013-CVE-2015-7497-Avoid-an-heap-buffer-overflow-in-xmlDi.patch 0014-CVE-2015-5312-Another-entity-expansion-issue.patch 0015-Add-xmlHaltParser-to-stop-the-parser.patch 0016-Detect-incoherency-on-GROW.patch 0017-CVE-2015-7500-Fix-memory-access-error-due-to-incorre.patch 0018-CVE-2015-8242-Buffer-overead-with-HTML-parser-in-pus.patch 0019-Do-not-print-error-context-when-there-is-none.patch 0020-xmlStopParser-reset-errNo.patch 0021-Reuse-xmlHaltParser-where-it-makes-sense.patch\"" "-DNOKOGIRI_LIBXSLT_PATH=\"/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28\"" "-DNOKOGIRI_LIBXSLT_PATCHES=\"0001-Adding-doc-update-related-to-1.1.28.patch 0002-Fix-a-couple-of-places-where-f-printf-parameters-wer.patch 0003-Initialize-pseudo-random-number-generator-with-curre.patch 0004-EXSLT-function-str-replace-is-broken-as-is.patch 0006-Fix-str-padding-to-work-with-UTF-8-strings.patch 0007-Separate-function-for-predicate-matching-in-patterns.patch 0008-Fix-direct-pattern-matching.patch 0009-Fix-certain-patterns-with-predicates.patch 0010-Fix-handling-of-UTF-8-strings-in-EXSLT-crypto-module.patch 0013-Memory-leak-in-xsltCompileIdKeyPattern-error-path.patch 0014-Fix-for-bug-436589.patch 0015-Fix-mkdir-for-mingw.patch 0016-Fix-for-type-confusion-in-preprocessing-attributes.patch 0017-Updated-config.guess.patch\"" -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe -Wall -Wcast-qual -Wwrite-strings -Wconversion -Wmissing-noreturn -Winline -DNOKOGIRI_USE_PACKAGED_LIBRARIES conftest.c -L/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib -L/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -arch x86_64 /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libexslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a -llzma -lruby-static -framework CoreFoundation /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libexslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a -llzma -lpthread -ldl -lobjc " +conftest.c:13:57: error: use of undeclared identifier 'xmlRelaxNGSetParserStructuredErrors' +int t(void) { void ((*volatile p)()); p = (void ((*)()))xmlRelaxNGSetParserStructuredErrors; return 0; } + ^ +1 error generated. +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { void ((*volatile p)()); p = (void ((*)()))xmlRelaxNGSetParserStructuredErrors; return 0; } +/* end */ + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/include -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/include/libxml2 -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/include/libxml2 -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT "-DNOKOGIRI_LIBXML2_PATH=\"/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2\"" "-DNOKOGIRI_LIBXML2_PATCHES=\"0001-Revert-Missing-initialization-for-the-catalog-module.patch 0002-Fix-missing-entities-after-CVE-2014-3660-fix.patch 0003-Stop-parsing-on-entities-boundaries-errors.patch 0004-Cleanup-conditional-section-error-handling.patch 0005-CVE-2015-1819-Enforce-the-reader-to-run-in-constant-.patch 0006-Another-variation-of-overflow-in-Conditional-section.patch 0007-Fix-an-error-in-previous-Conditional-section-patch.patch 0008-CVE-2015-8035-Fix-XZ-compression-support-loop.patch 0009-Updated-config.guess.patch 0010-Fix-parsering-short-unclosed-comment-uninitialized-access.patch 0011-Avoid-extra-processing-of-MarkupDecl-when-EOF.patch 0012-Avoid-processing-entities-after-encoding-conversion-.patch 0013-CVE-2015-7497-Avoid-an-heap-buffer-overflow-in-xmlDi.patch 0014-CVE-2015-5312-Another-entity-expansion-issue.patch 0015-Add-xmlHaltParser-to-stop-the-parser.patch 0016-Detect-incoherency-on-GROW.patch 0017-CVE-2015-7500-Fix-memory-access-error-due-to-incorre.patch 0018-CVE-2015-8242-Buffer-overead-with-HTML-parser-in-pus.patch 0019-Do-not-print-error-context-when-there-is-none.patch 0020-xmlStopParser-reset-errNo.patch 0021-Reuse-xmlHaltParser-where-it-makes-sense.patch\"" "-DNOKOGIRI_LIBXSLT_PATH=\"/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28\"" "-DNOKOGIRI_LIBXSLT_PATCHES=\"0001-Adding-doc-update-related-to-1.1.28.patch 0002-Fix-a-couple-of-places-where-f-printf-parameters-wer.patch 0003-Initialize-pseudo-random-number-generator-with-curre.patch 0004-EXSLT-function-str-replace-is-broken-as-is.patch 0006-Fix-str-padding-to-work-with-UTF-8-strings.patch 0007-Separate-function-for-predicate-matching-in-patterns.patch 0008-Fix-direct-pattern-matching.patch 0009-Fix-certain-patterns-with-predicates.patch 0010-Fix-handling-of-UTF-8-strings-in-EXSLT-crypto-module.patch 0013-Memory-leak-in-xsltCompileIdKeyPattern-error-path.patch 0014-Fix-for-bug-436589.patch 0015-Fix-mkdir-for-mingw.patch 0016-Fix-for-type-confusion-in-preprocessing-attributes.patch 0017-Updated-config.guess.patch\"" -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe -Wall -Wcast-qual -Wwrite-strings -Wconversion -Wmissing-noreturn -Winline -DNOKOGIRI_USE_PACKAGED_LIBRARIES conftest.c -L/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib -L/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -arch x86_64 /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libexslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a -llzma -lruby-static -framework CoreFoundation /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libexslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a -llzma -lpthread -ldl -lobjc " +conftest.c:13:15: warning: implicit declaration of function 'xmlRelaxNGSetParserStructuredErrors' is invalid in C99 [-Wimplicit-function-declaration] +int t(void) { xmlRelaxNGSetParserStructuredErrors(); return 0; } + ^ +1 warning generated. +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(relaxng.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(globals.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(error.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(tree.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlregexp.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(uri.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlstring.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlsave.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(hash.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(parser.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlschemas.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlschemastypes.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(valid.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(HTMLparser.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(parserInternals.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(threads.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlIO.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(dict.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(SAX2.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(HTMLtree.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(SAX.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(buf.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(catalog.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(encoding.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(chvalid.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlmemory.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(entities.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(pattern.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(list.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlreader.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlunicode.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xpath.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(debugXML.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(nanoftp.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(nanohttp.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xinclude.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xpointer.o)) was built for newer OSX version (10.10) than being linked (10.7) +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { xmlRelaxNGSetParserStructuredErrors(); return 0; } +/* end */ + +-------------------- + +have_func: checking for xmlRelaxNGSetValidStructuredErrors()... -------------------- yes + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/include -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/include/libxml2 -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/include/libxml2 -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT "-DNOKOGIRI_LIBXML2_PATH=\"/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2\"" "-DNOKOGIRI_LIBXML2_PATCHES=\"0001-Revert-Missing-initialization-for-the-catalog-module.patch 0002-Fix-missing-entities-after-CVE-2014-3660-fix.patch 0003-Stop-parsing-on-entities-boundaries-errors.patch 0004-Cleanup-conditional-section-error-handling.patch 0005-CVE-2015-1819-Enforce-the-reader-to-run-in-constant-.patch 0006-Another-variation-of-overflow-in-Conditional-section.patch 0007-Fix-an-error-in-previous-Conditional-section-patch.patch 0008-CVE-2015-8035-Fix-XZ-compression-support-loop.patch 0009-Updated-config.guess.patch 0010-Fix-parsering-short-unclosed-comment-uninitialized-access.patch 0011-Avoid-extra-processing-of-MarkupDecl-when-EOF.patch 0012-Avoid-processing-entities-after-encoding-conversion-.patch 0013-CVE-2015-7497-Avoid-an-heap-buffer-overflow-in-xmlDi.patch 0014-CVE-2015-5312-Another-entity-expansion-issue.patch 0015-Add-xmlHaltParser-to-stop-the-parser.patch 0016-Detect-incoherency-on-GROW.patch 0017-CVE-2015-7500-Fix-memory-access-error-due-to-incorre.patch 0018-CVE-2015-8242-Buffer-overead-with-HTML-parser-in-pus.patch 0019-Do-not-print-error-context-when-there-is-none.patch 0020-xmlStopParser-reset-errNo.patch 0021-Reuse-xmlHaltParser-where-it-makes-sense.patch\"" "-DNOKOGIRI_LIBXSLT_PATH=\"/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28\"" "-DNOKOGIRI_LIBXSLT_PATCHES=\"0001-Adding-doc-update-related-to-1.1.28.patch 0002-Fix-a-couple-of-places-where-f-printf-parameters-wer.patch 0003-Initialize-pseudo-random-number-generator-with-curre.patch 0004-EXSLT-function-str-replace-is-broken-as-is.patch 0006-Fix-str-padding-to-work-with-UTF-8-strings.patch 0007-Separate-function-for-predicate-matching-in-patterns.patch 0008-Fix-direct-pattern-matching.patch 0009-Fix-certain-patterns-with-predicates.patch 0010-Fix-handling-of-UTF-8-strings-in-EXSLT-crypto-module.patch 0013-Memory-leak-in-xsltCompileIdKeyPattern-error-path.patch 0014-Fix-for-bug-436589.patch 0015-Fix-mkdir-for-mingw.patch 0016-Fix-for-type-confusion-in-preprocessing-attributes.patch 0017-Updated-config.guess.patch\"" -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe -Wall -Wcast-qual -Wwrite-strings -Wconversion -Wmissing-noreturn -Winline -DNOKOGIRI_USE_PACKAGED_LIBRARIES conftest.c -L/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib -L/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -arch x86_64 /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libexslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a -llzma -lruby-static -framework CoreFoundation /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libexslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a -llzma -lpthread -ldl -lobjc " +conftest.c:13:57: error: use of undeclared identifier 'xmlRelaxNGSetValidStructuredErrors' +int t(void) { void ((*volatile p)()); p = (void ((*)()))xmlRelaxNGSetValidStructuredErrors; return 0; } + ^ +1 error generated. +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { void ((*volatile p)()); p = (void ((*)()))xmlRelaxNGSetValidStructuredErrors; return 0; } +/* end */ + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/include -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/include/libxml2 -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/include/libxml2 -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT "-DNOKOGIRI_LIBXML2_PATH=\"/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2\"" "-DNOKOGIRI_LIBXML2_PATCHES=\"0001-Revert-Missing-initialization-for-the-catalog-module.patch 0002-Fix-missing-entities-after-CVE-2014-3660-fix.patch 0003-Stop-parsing-on-entities-boundaries-errors.patch 0004-Cleanup-conditional-section-error-handling.patch 0005-CVE-2015-1819-Enforce-the-reader-to-run-in-constant-.patch 0006-Another-variation-of-overflow-in-Conditional-section.patch 0007-Fix-an-error-in-previous-Conditional-section-patch.patch 0008-CVE-2015-8035-Fix-XZ-compression-support-loop.patch 0009-Updated-config.guess.patch 0010-Fix-parsering-short-unclosed-comment-uninitialized-access.patch 0011-Avoid-extra-processing-of-MarkupDecl-when-EOF.patch 0012-Avoid-processing-entities-after-encoding-conversion-.patch 0013-CVE-2015-7497-Avoid-an-heap-buffer-overflow-in-xmlDi.patch 0014-CVE-2015-5312-Another-entity-expansion-issue.patch 0015-Add-xmlHaltParser-to-stop-the-parser.patch 0016-Detect-incoherency-on-GROW.patch 0017-CVE-2015-7500-Fix-memory-access-error-due-to-incorre.patch 0018-CVE-2015-8242-Buffer-overead-with-HTML-parser-in-pus.patch 0019-Do-not-print-error-context-when-there-is-none.patch 0020-xmlStopParser-reset-errNo.patch 0021-Reuse-xmlHaltParser-where-it-makes-sense.patch\"" "-DNOKOGIRI_LIBXSLT_PATH=\"/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28\"" "-DNOKOGIRI_LIBXSLT_PATCHES=\"0001-Adding-doc-update-related-to-1.1.28.patch 0002-Fix-a-couple-of-places-where-f-printf-parameters-wer.patch 0003-Initialize-pseudo-random-number-generator-with-curre.patch 0004-EXSLT-function-str-replace-is-broken-as-is.patch 0006-Fix-str-padding-to-work-with-UTF-8-strings.patch 0007-Separate-function-for-predicate-matching-in-patterns.patch 0008-Fix-direct-pattern-matching.patch 0009-Fix-certain-patterns-with-predicates.patch 0010-Fix-handling-of-UTF-8-strings-in-EXSLT-crypto-module.patch 0013-Memory-leak-in-xsltCompileIdKeyPattern-error-path.patch 0014-Fix-for-bug-436589.patch 0015-Fix-mkdir-for-mingw.patch 0016-Fix-for-type-confusion-in-preprocessing-attributes.patch 0017-Updated-config.guess.patch\"" -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe -Wall -Wcast-qual -Wwrite-strings -Wconversion -Wmissing-noreturn -Winline -DNOKOGIRI_USE_PACKAGED_LIBRARIES conftest.c -L/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib -L/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -arch x86_64 /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libexslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a -llzma -lruby-static -framework CoreFoundation /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libexslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a -llzma -lpthread -ldl -lobjc " +conftest.c:13:15: warning: implicit declaration of function 'xmlRelaxNGSetValidStructuredErrors' is invalid in C99 [-Wimplicit-function-declaration] +int t(void) { xmlRelaxNGSetValidStructuredErrors(); return 0; } + ^ +1 warning generated. +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(relaxng.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(globals.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(error.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(tree.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlregexp.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(uri.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlstring.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlsave.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(hash.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(parser.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlschemas.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlschemastypes.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(valid.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(HTMLparser.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(parserInternals.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(threads.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlIO.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(dict.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(SAX2.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(HTMLtree.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(SAX.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(buf.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(catalog.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(encoding.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(chvalid.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlmemory.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(entities.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(pattern.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(list.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlreader.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlunicode.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xpath.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(debugXML.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(nanoftp.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(nanohttp.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xinclude.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xpointer.o)) was built for newer OSX version (10.10) than being linked (10.7) +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { xmlRelaxNGSetValidStructuredErrors(); return 0; } +/* end */ + +-------------------- + +have_func: checking for xmlSchemaSetValidStructuredErrors()... -------------------- yes + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/include -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/include/libxml2 -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/include/libxml2 -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT "-DNOKOGIRI_LIBXML2_PATH=\"/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2\"" "-DNOKOGIRI_LIBXML2_PATCHES=\"0001-Revert-Missing-initialization-for-the-catalog-module.patch 0002-Fix-missing-entities-after-CVE-2014-3660-fix.patch 0003-Stop-parsing-on-entities-boundaries-errors.patch 0004-Cleanup-conditional-section-error-handling.patch 0005-CVE-2015-1819-Enforce-the-reader-to-run-in-constant-.patch 0006-Another-variation-of-overflow-in-Conditional-section.patch 0007-Fix-an-error-in-previous-Conditional-section-patch.patch 0008-CVE-2015-8035-Fix-XZ-compression-support-loop.patch 0009-Updated-config.guess.patch 0010-Fix-parsering-short-unclosed-comment-uninitialized-access.patch 0011-Avoid-extra-processing-of-MarkupDecl-when-EOF.patch 0012-Avoid-processing-entities-after-encoding-conversion-.patch 0013-CVE-2015-7497-Avoid-an-heap-buffer-overflow-in-xmlDi.patch 0014-CVE-2015-5312-Another-entity-expansion-issue.patch 0015-Add-xmlHaltParser-to-stop-the-parser.patch 0016-Detect-incoherency-on-GROW.patch 0017-CVE-2015-7500-Fix-memory-access-error-due-to-incorre.patch 0018-CVE-2015-8242-Buffer-overead-with-HTML-parser-in-pus.patch 0019-Do-not-print-error-context-when-there-is-none.patch 0020-xmlStopParser-reset-errNo.patch 0021-Reuse-xmlHaltParser-where-it-makes-sense.patch\"" "-DNOKOGIRI_LIBXSLT_PATH=\"/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28\"" "-DNOKOGIRI_LIBXSLT_PATCHES=\"0001-Adding-doc-update-related-to-1.1.28.patch 0002-Fix-a-couple-of-places-where-f-printf-parameters-wer.patch 0003-Initialize-pseudo-random-number-generator-with-curre.patch 0004-EXSLT-function-str-replace-is-broken-as-is.patch 0006-Fix-str-padding-to-work-with-UTF-8-strings.patch 0007-Separate-function-for-predicate-matching-in-patterns.patch 0008-Fix-direct-pattern-matching.patch 0009-Fix-certain-patterns-with-predicates.patch 0010-Fix-handling-of-UTF-8-strings-in-EXSLT-crypto-module.patch 0013-Memory-leak-in-xsltCompileIdKeyPattern-error-path.patch 0014-Fix-for-bug-436589.patch 0015-Fix-mkdir-for-mingw.patch 0016-Fix-for-type-confusion-in-preprocessing-attributes.patch 0017-Updated-config.guess.patch\"" -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe -Wall -Wcast-qual -Wwrite-strings -Wconversion -Wmissing-noreturn -Winline -DNOKOGIRI_USE_PACKAGED_LIBRARIES conftest.c -L/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib -L/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -arch x86_64 /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libexslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a -llzma -lruby-static -framework CoreFoundation /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libexslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a -llzma -lpthread -ldl -lobjc " +conftest.c:13:57: error: use of undeclared identifier 'xmlSchemaSetValidStructuredErrors' +int t(void) { void ((*volatile p)()); p = (void ((*)()))xmlSchemaSetValidStructuredErrors; return 0; } + ^ +1 error generated. +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { void ((*volatile p)()); p = (void ((*)()))xmlSchemaSetValidStructuredErrors; return 0; } +/* end */ + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/include -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/include/libxml2 -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/include/libxml2 -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT "-DNOKOGIRI_LIBXML2_PATH=\"/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2\"" "-DNOKOGIRI_LIBXML2_PATCHES=\"0001-Revert-Missing-initialization-for-the-catalog-module.patch 0002-Fix-missing-entities-after-CVE-2014-3660-fix.patch 0003-Stop-parsing-on-entities-boundaries-errors.patch 0004-Cleanup-conditional-section-error-handling.patch 0005-CVE-2015-1819-Enforce-the-reader-to-run-in-constant-.patch 0006-Another-variation-of-overflow-in-Conditional-section.patch 0007-Fix-an-error-in-previous-Conditional-section-patch.patch 0008-CVE-2015-8035-Fix-XZ-compression-support-loop.patch 0009-Updated-config.guess.patch 0010-Fix-parsering-short-unclosed-comment-uninitialized-access.patch 0011-Avoid-extra-processing-of-MarkupDecl-when-EOF.patch 0012-Avoid-processing-entities-after-encoding-conversion-.patch 0013-CVE-2015-7497-Avoid-an-heap-buffer-overflow-in-xmlDi.patch 0014-CVE-2015-5312-Another-entity-expansion-issue.patch 0015-Add-xmlHaltParser-to-stop-the-parser.patch 0016-Detect-incoherency-on-GROW.patch 0017-CVE-2015-7500-Fix-memory-access-error-due-to-incorre.patch 0018-CVE-2015-8242-Buffer-overead-with-HTML-parser-in-pus.patch 0019-Do-not-print-error-context-when-there-is-none.patch 0020-xmlStopParser-reset-errNo.patch 0021-Reuse-xmlHaltParser-where-it-makes-sense.patch\"" "-DNOKOGIRI_LIBXSLT_PATH=\"/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28\"" "-DNOKOGIRI_LIBXSLT_PATCHES=\"0001-Adding-doc-update-related-to-1.1.28.patch 0002-Fix-a-couple-of-places-where-f-printf-parameters-wer.patch 0003-Initialize-pseudo-random-number-generator-with-curre.patch 0004-EXSLT-function-str-replace-is-broken-as-is.patch 0006-Fix-str-padding-to-work-with-UTF-8-strings.patch 0007-Separate-function-for-predicate-matching-in-patterns.patch 0008-Fix-direct-pattern-matching.patch 0009-Fix-certain-patterns-with-predicates.patch 0010-Fix-handling-of-UTF-8-strings-in-EXSLT-crypto-module.patch 0013-Memory-leak-in-xsltCompileIdKeyPattern-error-path.patch 0014-Fix-for-bug-436589.patch 0015-Fix-mkdir-for-mingw.patch 0016-Fix-for-type-confusion-in-preprocessing-attributes.patch 0017-Updated-config.guess.patch\"" -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe -Wall -Wcast-qual -Wwrite-strings -Wconversion -Wmissing-noreturn -Winline -DNOKOGIRI_USE_PACKAGED_LIBRARIES conftest.c -L/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib -L/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -arch x86_64 /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libexslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a -llzma -lruby-static -framework CoreFoundation /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libexslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a -llzma -lpthread -ldl -lobjc " +conftest.c:13:15: warning: implicit declaration of function 'xmlSchemaSetValidStructuredErrors' is invalid in C99 [-Wimplicit-function-declaration] +int t(void) { xmlSchemaSetValidStructuredErrors(); return 0; } + ^ +1 warning generated. +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlschemas.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(globals.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(error.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(parser.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(tree.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(valid.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlregexp.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(uri.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(dict.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(parserInternals.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(pattern.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(hash.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlIO.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(SAX2.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlschemastypes.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlstring.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlreader.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(HTMLparser.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(threads.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(HTMLtree.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(SAX.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(entities.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(buf.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(encoding.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(catalog.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(chvalid.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlmemory.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(list.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(nanoftp.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(nanohttp.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlsave.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(relaxng.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlunicode.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xinclude.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xpath.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(debugXML.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xpointer.o)) was built for newer OSX version (10.10) than being linked (10.7) +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { xmlSchemaSetValidStructuredErrors(); return 0; } +/* end */ + +-------------------- + +have_func: checking for xmlSchemaSetParserStructuredErrors()... -------------------- yes + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/include -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/include/libxml2 -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/include/libxml2 -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT "-DNOKOGIRI_LIBXML2_PATH=\"/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2\"" "-DNOKOGIRI_LIBXML2_PATCHES=\"0001-Revert-Missing-initialization-for-the-catalog-module.patch 0002-Fix-missing-entities-after-CVE-2014-3660-fix.patch 0003-Stop-parsing-on-entities-boundaries-errors.patch 0004-Cleanup-conditional-section-error-handling.patch 0005-CVE-2015-1819-Enforce-the-reader-to-run-in-constant-.patch 0006-Another-variation-of-overflow-in-Conditional-section.patch 0007-Fix-an-error-in-previous-Conditional-section-patch.patch 0008-CVE-2015-8035-Fix-XZ-compression-support-loop.patch 0009-Updated-config.guess.patch 0010-Fix-parsering-short-unclosed-comment-uninitialized-access.patch 0011-Avoid-extra-processing-of-MarkupDecl-when-EOF.patch 0012-Avoid-processing-entities-after-encoding-conversion-.patch 0013-CVE-2015-7497-Avoid-an-heap-buffer-overflow-in-xmlDi.patch 0014-CVE-2015-5312-Another-entity-expansion-issue.patch 0015-Add-xmlHaltParser-to-stop-the-parser.patch 0016-Detect-incoherency-on-GROW.patch 0017-CVE-2015-7500-Fix-memory-access-error-due-to-incorre.patch 0018-CVE-2015-8242-Buffer-overead-with-HTML-parser-in-pus.patch 0019-Do-not-print-error-context-when-there-is-none.patch 0020-xmlStopParser-reset-errNo.patch 0021-Reuse-xmlHaltParser-where-it-makes-sense.patch\"" "-DNOKOGIRI_LIBXSLT_PATH=\"/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28\"" "-DNOKOGIRI_LIBXSLT_PATCHES=\"0001-Adding-doc-update-related-to-1.1.28.patch 0002-Fix-a-couple-of-places-where-f-printf-parameters-wer.patch 0003-Initialize-pseudo-random-number-generator-with-curre.patch 0004-EXSLT-function-str-replace-is-broken-as-is.patch 0006-Fix-str-padding-to-work-with-UTF-8-strings.patch 0007-Separate-function-for-predicate-matching-in-patterns.patch 0008-Fix-direct-pattern-matching.patch 0009-Fix-certain-patterns-with-predicates.patch 0010-Fix-handling-of-UTF-8-strings-in-EXSLT-crypto-module.patch 0013-Memory-leak-in-xsltCompileIdKeyPattern-error-path.patch 0014-Fix-for-bug-436589.patch 0015-Fix-mkdir-for-mingw.patch 0016-Fix-for-type-confusion-in-preprocessing-attributes.patch 0017-Updated-config.guess.patch\"" -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe -Wall -Wcast-qual -Wwrite-strings -Wconversion -Wmissing-noreturn -Winline -DNOKOGIRI_USE_PACKAGED_LIBRARIES conftest.c -L/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib -L/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -arch x86_64 /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libexslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a -llzma -lruby-static -framework CoreFoundation /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libexslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a -llzma -lpthread -ldl -lobjc " +conftest.c:13:57: error: use of undeclared identifier 'xmlSchemaSetParserStructuredErrors' +int t(void) { void ((*volatile p)()); p = (void ((*)()))xmlSchemaSetParserStructuredErrors; return 0; } + ^ +1 error generated. +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { void ((*volatile p)()); p = (void ((*)()))xmlSchemaSetParserStructuredErrors; return 0; } +/* end */ + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/include -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/include/libxml2 -I/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/include/libxml2 -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT "-DNOKOGIRI_LIBXML2_PATH=\"/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2\"" "-DNOKOGIRI_LIBXML2_PATCHES=\"0001-Revert-Missing-initialization-for-the-catalog-module.patch 0002-Fix-missing-entities-after-CVE-2014-3660-fix.patch 0003-Stop-parsing-on-entities-boundaries-errors.patch 0004-Cleanup-conditional-section-error-handling.patch 0005-CVE-2015-1819-Enforce-the-reader-to-run-in-constant-.patch 0006-Another-variation-of-overflow-in-Conditional-section.patch 0007-Fix-an-error-in-previous-Conditional-section-patch.patch 0008-CVE-2015-8035-Fix-XZ-compression-support-loop.patch 0009-Updated-config.guess.patch 0010-Fix-parsering-short-unclosed-comment-uninitialized-access.patch 0011-Avoid-extra-processing-of-MarkupDecl-when-EOF.patch 0012-Avoid-processing-entities-after-encoding-conversion-.patch 0013-CVE-2015-7497-Avoid-an-heap-buffer-overflow-in-xmlDi.patch 0014-CVE-2015-5312-Another-entity-expansion-issue.patch 0015-Add-xmlHaltParser-to-stop-the-parser.patch 0016-Detect-incoherency-on-GROW.patch 0017-CVE-2015-7500-Fix-memory-access-error-due-to-incorre.patch 0018-CVE-2015-8242-Buffer-overead-with-HTML-parser-in-pus.patch 0019-Do-not-print-error-context-when-there-is-none.patch 0020-xmlStopParser-reset-errNo.patch 0021-Reuse-xmlHaltParser-where-it-makes-sense.patch\"" "-DNOKOGIRI_LIBXSLT_PATH=\"/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28\"" "-DNOKOGIRI_LIBXSLT_PATCHES=\"0001-Adding-doc-update-related-to-1.1.28.patch 0002-Fix-a-couple-of-places-where-f-printf-parameters-wer.patch 0003-Initialize-pseudo-random-number-generator-with-curre.patch 0004-EXSLT-function-str-replace-is-broken-as-is.patch 0006-Fix-str-padding-to-work-with-UTF-8-strings.patch 0007-Separate-function-for-predicate-matching-in-patterns.patch 0008-Fix-direct-pattern-matching.patch 0009-Fix-certain-patterns-with-predicates.patch 0010-Fix-handling-of-UTF-8-strings-in-EXSLT-crypto-module.patch 0013-Memory-leak-in-xsltCompileIdKeyPattern-error-path.patch 0014-Fix-for-bug-436589.patch 0015-Fix-mkdir-for-mingw.patch 0016-Fix-for-type-confusion-in-preprocessing-attributes.patch 0017-Updated-config.guess.patch\"" -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe -Wall -Wcast-qual -Wwrite-strings -Wconversion -Wmissing-noreturn -Winline -DNOKOGIRI_USE_PACKAGED_LIBRARIES conftest.c -L/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib -L/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -arch x86_64 /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libexslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a -llzma -lruby-static -framework CoreFoundation /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libexslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxslt/1.1.28/lib/libxslt.a -lm -liconv -lpthread -lz /Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a -llzma -lpthread -ldl -lobjc " +conftest.c:13:15: warning: implicit declaration of function 'xmlSchemaSetParserStructuredErrors' is invalid in C99 [-Wimplicit-function-declaration] +int t(void) { xmlSchemaSetParserStructuredErrors(); return 0; } + ^ +1 warning generated. +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlschemas.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(globals.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(error.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(parser.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(tree.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(valid.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlregexp.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(uri.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(dict.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(parserInternals.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(pattern.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(hash.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlIO.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(SAX2.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlschemastypes.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlstring.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlreader.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(HTMLparser.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(threads.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(HTMLtree.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(SAX.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(entities.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(buf.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(encoding.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(catalog.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(chvalid.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlmemory.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(list.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(nanoftp.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(nanohttp.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlsave.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(relaxng.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xmlunicode.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xinclude.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xpath.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(debugXML.o)) was built for newer OSX version (10.10) than being linked (10.7) +ld: warning: object file (/Users/RA/C5/projects/shipping-service/shipping-service-betsy/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.7.2/ports/x86_64-apple-darwin14.5.0/libxml2/2.9.2/lib/libxml2.a(xpointer.o)) was built for newer OSX version (10.10) than being linked (10.7) +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { xmlSchemaSetParserStructuredErrors(); return 0; } +/* end */ + +-------------------- + diff --git a/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/nokogiri-1.6.7.2/nokogiri/nokogiri.bundle b/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/nokogiri-1.6.7.2/nokogiri/nokogiri.bundle new file mode 100755 index 0000000..9b6d3cc Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/nokogiri-1.6.7.2/nokogiri/nokogiri.bundle differ diff --git a/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/pg-0.18.4/gem.build_complete b/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/pg-0.18.4/gem.build_complete new file mode 100644 index 0000000..e69de29 diff --git a/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/pg-0.18.4/gem_make.out b/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/pg-0.18.4/gem_make.out new file mode 100644 index 0000000..19143be --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/pg-0.18.4/gem_make.out @@ -0,0 +1,74 @@ +/Users/RA/.rvm/rubies/ruby-2.2.3/bin/ruby -r ./siteconf20160523-33198-1wq78wm.rb extconf.rb +checking for pg_config... yes +Using config values from /usr/local/bin/pg_config +checking for libpq-fe.h... yes +checking for libpq/libpq-fs.h... yes +checking for pg_config_manual.h... yes +checking for PQconnectdb() in -lpq... yes +checking for PQconnectionUsedPassword()... yes +checking for PQisthreadsafe()... yes +checking for PQprepare()... yes +checking for PQexecParams()... yes +checking for PQescapeString()... yes +checking for PQescapeStringConn()... yes +checking for PQescapeLiteral()... yes +checking for PQescapeIdentifier()... yes +checking for PQgetCancel()... yes +checking for lo_create()... yes +checking for pg_encoding_to_char()... yes +checking for pg_char_to_encoding()... yes +checking for PQsetClientEncoding()... yes +checking for PQlibVersion()... yes +checking for PQping()... yes +checking for PQsetSingleRowMode()... yes +checking for PQconninfo()... yes +checking for rb_encdb_alias()... yes +checking for rb_enc_alias()... yes +checking for rb_thread_call_without_gvl()... yes +checking for rb_thread_call_with_gvl()... yes +checking for rb_thread_fd_select()... yes +checking for rb_w32_wrap_io_handle()... no +checking for rb_str_modify_expand()... yes +checking for rb_hash_dup()... yes +checking for PGRES_COPY_BOTH in libpq-fe.h... yes +checking for PGRES_SINGLE_TUPLE in libpq-fe.h... yes +checking for PG_DIAG_TABLE_NAME in libpq-fe.h... yes +checking for struct pgNotify.extra in libpq-fe.h... yes +checking for unistd.h... yes +checking for inttypes.h... yes +checking for ruby/st.h... yes +checking for C99 variable length arrays... yes +creating extconf.h +creating Makefile + +make "DESTDIR=" clean + +make "DESTDIR=" +compiling gvl_wrappers.c +compiling pg.c +compiling pg_binary_decoder.c +compiling pg_binary_encoder.c +compiling pg_coder.c +compiling pg_connection.c +pg_connection.c:2394:3: warning: implicit declaration of function 'gettimeofday' is invalid in C99 [-Wimplicit-function-declaration] + gettimeofday(&currtime, NULL); + ^ +1 warning generated. +compiling pg_copy_coder.c +compiling pg_errors.c +compiling pg_result.c +compiling pg_text_decoder.c +compiling pg_text_encoder.c +compiling pg_type_map.c +compiling pg_type_map_all_strings.c +compiling pg_type_map_by_class.c +compiling pg_type_map_by_column.c +compiling pg_type_map_by_mri_type.c +compiling pg_type_map_by_oid.c +compiling pg_type_map_in_ruby.c +compiling util.c +linking shared-object pg_ext.bundle +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' + +make "DESTDIR=" install +/usr/bin/install -m 0755 pg_ext.bundle ./.gem.20160523-33198-9ud2wa diff --git a/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/pg-0.18.4/mkmf.log b/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/pg-0.18.4/mkmf.log new file mode 100644 index 0000000..1fee930 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/pg-0.18.4/mkmf.log @@ -0,0 +1,1394 @@ +find_executable: checking for pg_config... -------------------- yes + +-------------------- + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -arch x86_64 -lruby-static -framework CoreFoundation -lpthread -ldl -lobjc " +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: int main(int argc, char **argv) +4: { +5: return 0; +6: } +/* end */ + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -arch x86_64 -lruby-static -framework CoreFoundation -Wl,-rpath,/usr/local/lib -lpthread -ldl -lobjc " +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: int main() {return 0;} +/* end */ + +find_header: checking for libpq-fe.h... -------------------- yes + +"gcc -E -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -o conftest.i" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +/* end */ + +-------------------- + +find_header: checking for libpq/libpq-fs.h... -------------------- yes + +"gcc -E -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -o conftest.i" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +/* end */ + +-------------------- + +find_header: checking for pg_config_manual.h... -------------------- yes + +"gcc -E -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -o conftest.i" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +/* end */ + +-------------------- + +have_library: checking for PQconnectdb() in -lpq... -------------------- yes + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -Wl,-rpath,/usr/local/lib -arch x86_64 -lruby-static -framework CoreFoundation -lpq -lpthread -ldl -lobjc " +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: extern int t(void); + 7: int main(int argc, char **argv) + 8: { + 9: if (argc > 1000000) { +10: printf("%p", &t); +11: } +12: +13: return 0; +14: } +15: int t(void) { void ((*volatile p)()); p = (void ((*)()))PQconnectdb; return 0; } +/* end */ + +-------------------- + +have_func: checking for PQconnectionUsedPassword()... -------------------- yes + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -Wl,-rpath,/usr/local/lib -arch x86_64 -lpq -lruby-static -framework CoreFoundation -lpq -lpthread -ldl -lobjc " +conftest.c:13:57: error: use of undeclared identifier 'PQconnectionUsedPassword' +int t(void) { void ((*volatile p)()); p = (void ((*)()))PQconnectionUsedPassword; return 0; } + ^ +1 error generated. +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { void ((*volatile p)()); p = (void ((*)()))PQconnectionUsedPassword; return 0; } +/* end */ + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -Wl,-rpath,/usr/local/lib -arch x86_64 -lpq -lruby-static -framework CoreFoundation -lpq -lpthread -ldl -lobjc " +conftest.c:13:15: warning: implicit declaration of function 'PQconnectionUsedPassword' is invalid in C99 [-Wimplicit-function-declaration] +int t(void) { PQconnectionUsedPassword(); return 0; } + ^ +1 warning generated. +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { PQconnectionUsedPassword(); return 0; } +/* end */ + +-------------------- + +have_func: checking for PQisthreadsafe()... -------------------- yes + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -Wl,-rpath,/usr/local/lib -arch x86_64 -lpq -lruby-static -framework CoreFoundation -lpq -lpthread -ldl -lobjc " +conftest.c:13:57: error: use of undeclared identifier 'PQisthreadsafe' +int t(void) { void ((*volatile p)()); p = (void ((*)()))PQisthreadsafe; return 0; } + ^ +1 error generated. +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { void ((*volatile p)()); p = (void ((*)()))PQisthreadsafe; return 0; } +/* end */ + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -Wl,-rpath,/usr/local/lib -arch x86_64 -lpq -lruby-static -framework CoreFoundation -lpq -lpthread -ldl -lobjc " +conftest.c:13:15: warning: implicit declaration of function 'PQisthreadsafe' is invalid in C99 [-Wimplicit-function-declaration] +int t(void) { PQisthreadsafe(); return 0; } + ^ +1 warning generated. +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { PQisthreadsafe(); return 0; } +/* end */ + +-------------------- + +have_func: checking for PQprepare()... -------------------- yes + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -Wl,-rpath,/usr/local/lib -arch x86_64 -lpq -lruby-static -framework CoreFoundation -lpq -lpthread -ldl -lobjc " +conftest.c:13:57: error: use of undeclared identifier 'PQprepare' +int t(void) { void ((*volatile p)()); p = (void ((*)()))PQprepare; return 0; } + ^ +1 error generated. +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { void ((*volatile p)()); p = (void ((*)()))PQprepare; return 0; } +/* end */ + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -Wl,-rpath,/usr/local/lib -arch x86_64 -lpq -lruby-static -framework CoreFoundation -lpq -lpthread -ldl -lobjc " +conftest.c:13:15: warning: implicit declaration of function 'PQprepare' is invalid in C99 [-Wimplicit-function-declaration] +int t(void) { PQprepare(); return 0; } + ^ +1 warning generated. +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { PQprepare(); return 0; } +/* end */ + +-------------------- + +have_func: checking for PQexecParams()... -------------------- yes + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -Wl,-rpath,/usr/local/lib -arch x86_64 -lpq -lruby-static -framework CoreFoundation -lpq -lpthread -ldl -lobjc " +conftest.c:13:57: error: use of undeclared identifier 'PQexecParams' +int t(void) { void ((*volatile p)()); p = (void ((*)()))PQexecParams; return 0; } + ^ +1 error generated. +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { void ((*volatile p)()); p = (void ((*)()))PQexecParams; return 0; } +/* end */ + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -Wl,-rpath,/usr/local/lib -arch x86_64 -lpq -lruby-static -framework CoreFoundation -lpq -lpthread -ldl -lobjc " +conftest.c:13:15: warning: implicit declaration of function 'PQexecParams' is invalid in C99 [-Wimplicit-function-declaration] +int t(void) { PQexecParams(); return 0; } + ^ +1 warning generated. +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { PQexecParams(); return 0; } +/* end */ + +-------------------- + +have_func: checking for PQescapeString()... -------------------- yes + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -Wl,-rpath,/usr/local/lib -arch x86_64 -lpq -lruby-static -framework CoreFoundation -lpq -lpthread -ldl -lobjc " +conftest.c:13:57: error: use of undeclared identifier 'PQescapeString' +int t(void) { void ((*volatile p)()); p = (void ((*)()))PQescapeString; return 0; } + ^ +1 error generated. +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { void ((*volatile p)()); p = (void ((*)()))PQescapeString; return 0; } +/* end */ + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -Wl,-rpath,/usr/local/lib -arch x86_64 -lpq -lruby-static -framework CoreFoundation -lpq -lpthread -ldl -lobjc " +conftest.c:13:15: warning: implicit declaration of function 'PQescapeString' is invalid in C99 [-Wimplicit-function-declaration] +int t(void) { PQescapeString(); return 0; } + ^ +1 warning generated. +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { PQescapeString(); return 0; } +/* end */ + +-------------------- + +have_func: checking for PQescapeStringConn()... -------------------- yes + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -Wl,-rpath,/usr/local/lib -arch x86_64 -lpq -lruby-static -framework CoreFoundation -lpq -lpthread -ldl -lobjc " +conftest.c:13:57: error: use of undeclared identifier 'PQescapeStringConn' +int t(void) { void ((*volatile p)()); p = (void ((*)()))PQescapeStringConn; return 0; } + ^ +1 error generated. +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { void ((*volatile p)()); p = (void ((*)()))PQescapeStringConn; return 0; } +/* end */ + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -Wl,-rpath,/usr/local/lib -arch x86_64 -lpq -lruby-static -framework CoreFoundation -lpq -lpthread -ldl -lobjc " +conftest.c:13:15: warning: implicit declaration of function 'PQescapeStringConn' is invalid in C99 [-Wimplicit-function-declaration] +int t(void) { PQescapeStringConn(); return 0; } + ^ +1 warning generated. +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { PQescapeStringConn(); return 0; } +/* end */ + +-------------------- + +have_func: checking for PQescapeLiteral()... -------------------- yes + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -Wl,-rpath,/usr/local/lib -arch x86_64 -lpq -lruby-static -framework CoreFoundation -lpq -lpthread -ldl -lobjc " +conftest.c:13:57: error: use of undeclared identifier 'PQescapeLiteral' +int t(void) { void ((*volatile p)()); p = (void ((*)()))PQescapeLiteral; return 0; } + ^ +1 error generated. +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { void ((*volatile p)()); p = (void ((*)()))PQescapeLiteral; return 0; } +/* end */ + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -Wl,-rpath,/usr/local/lib -arch x86_64 -lpq -lruby-static -framework CoreFoundation -lpq -lpthread -ldl -lobjc " +conftest.c:13:15: warning: implicit declaration of function 'PQescapeLiteral' is invalid in C99 [-Wimplicit-function-declaration] +int t(void) { PQescapeLiteral(); return 0; } + ^ +1 warning generated. +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { PQescapeLiteral(); return 0; } +/* end */ + +-------------------- + +have_func: checking for PQescapeIdentifier()... -------------------- yes + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -Wl,-rpath,/usr/local/lib -arch x86_64 -lpq -lruby-static -framework CoreFoundation -lpq -lpthread -ldl -lobjc " +conftest.c:13:57: error: use of undeclared identifier 'PQescapeIdentifier' +int t(void) { void ((*volatile p)()); p = (void ((*)()))PQescapeIdentifier; return 0; } + ^ +1 error generated. +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { void ((*volatile p)()); p = (void ((*)()))PQescapeIdentifier; return 0; } +/* end */ + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -Wl,-rpath,/usr/local/lib -arch x86_64 -lpq -lruby-static -framework CoreFoundation -lpq -lpthread -ldl -lobjc " +conftest.c:13:15: warning: implicit declaration of function 'PQescapeIdentifier' is invalid in C99 [-Wimplicit-function-declaration] +int t(void) { PQescapeIdentifier(); return 0; } + ^ +1 warning generated. +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { PQescapeIdentifier(); return 0; } +/* end */ + +-------------------- + +have_func: checking for PQgetCancel()... -------------------- yes + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -Wl,-rpath,/usr/local/lib -arch x86_64 -lpq -lruby-static -framework CoreFoundation -lpq -lpthread -ldl -lobjc " +conftest.c:13:57: error: use of undeclared identifier 'PQgetCancel' +int t(void) { void ((*volatile p)()); p = (void ((*)()))PQgetCancel; return 0; } + ^ +1 error generated. +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { void ((*volatile p)()); p = (void ((*)()))PQgetCancel; return 0; } +/* end */ + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -Wl,-rpath,/usr/local/lib -arch x86_64 -lpq -lruby-static -framework CoreFoundation -lpq -lpthread -ldl -lobjc " +conftest.c:13:15: warning: implicit declaration of function 'PQgetCancel' is invalid in C99 [-Wimplicit-function-declaration] +int t(void) { PQgetCancel(); return 0; } + ^ +1 warning generated. +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { PQgetCancel(); return 0; } +/* end */ + +-------------------- + +have_func: checking for lo_create()... -------------------- yes + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -Wl,-rpath,/usr/local/lib -arch x86_64 -lpq -lruby-static -framework CoreFoundation -lpq -lpthread -ldl -lobjc " +conftest.c:13:57: error: use of undeclared identifier 'lo_create' +int t(void) { void ((*volatile p)()); p = (void ((*)()))lo_create; return 0; } + ^ +1 error generated. +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { void ((*volatile p)()); p = (void ((*)()))lo_create; return 0; } +/* end */ + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -Wl,-rpath,/usr/local/lib -arch x86_64 -lpq -lruby-static -framework CoreFoundation -lpq -lpthread -ldl -lobjc " +conftest.c:13:15: warning: implicit declaration of function 'lo_create' is invalid in C99 [-Wimplicit-function-declaration] +int t(void) { lo_create(); return 0; } + ^ +1 warning generated. +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { lo_create(); return 0; } +/* end */ + +-------------------- + +have_func: checking for pg_encoding_to_char()... -------------------- yes + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -Wl,-rpath,/usr/local/lib -arch x86_64 -lpq -lruby-static -framework CoreFoundation -lpq -lpthread -ldl -lobjc " +conftest.c:13:57: error: use of undeclared identifier 'pg_encoding_to_char' +int t(void) { void ((*volatile p)()); p = (void ((*)()))pg_encoding_to_char; return 0; } + ^ +1 error generated. +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { void ((*volatile p)()); p = (void ((*)()))pg_encoding_to_char; return 0; } +/* end */ + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -Wl,-rpath,/usr/local/lib -arch x86_64 -lpq -lruby-static -framework CoreFoundation -lpq -lpthread -ldl -lobjc " +conftest.c:13:15: warning: implicit declaration of function 'pg_encoding_to_char' is invalid in C99 [-Wimplicit-function-declaration] +int t(void) { pg_encoding_to_char(); return 0; } + ^ +1 warning generated. +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { pg_encoding_to_char(); return 0; } +/* end */ + +-------------------- + +have_func: checking for pg_char_to_encoding()... -------------------- yes + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -Wl,-rpath,/usr/local/lib -arch x86_64 -lpq -lruby-static -framework CoreFoundation -lpq -lpthread -ldl -lobjc " +conftest.c:13:57: error: use of undeclared identifier 'pg_char_to_encoding' +int t(void) { void ((*volatile p)()); p = (void ((*)()))pg_char_to_encoding; return 0; } + ^ +1 error generated. +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { void ((*volatile p)()); p = (void ((*)()))pg_char_to_encoding; return 0; } +/* end */ + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -Wl,-rpath,/usr/local/lib -arch x86_64 -lpq -lruby-static -framework CoreFoundation -lpq -lpthread -ldl -lobjc " +conftest.c:13:15: warning: implicit declaration of function 'pg_char_to_encoding' is invalid in C99 [-Wimplicit-function-declaration] +int t(void) { pg_char_to_encoding(); return 0; } + ^ +1 warning generated. +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { pg_char_to_encoding(); return 0; } +/* end */ + +-------------------- + +have_func: checking for PQsetClientEncoding()... -------------------- yes + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -Wl,-rpath,/usr/local/lib -arch x86_64 -lpq -lruby-static -framework CoreFoundation -lpq -lpthread -ldl -lobjc " +conftest.c:13:57: error: use of undeclared identifier 'PQsetClientEncoding' +int t(void) { void ((*volatile p)()); p = (void ((*)()))PQsetClientEncoding; return 0; } + ^ +1 error generated. +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { void ((*volatile p)()); p = (void ((*)()))PQsetClientEncoding; return 0; } +/* end */ + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -Wl,-rpath,/usr/local/lib -arch x86_64 -lpq -lruby-static -framework CoreFoundation -lpq -lpthread -ldl -lobjc " +conftest.c:13:15: warning: implicit declaration of function 'PQsetClientEncoding' is invalid in C99 [-Wimplicit-function-declaration] +int t(void) { PQsetClientEncoding(); return 0; } + ^ +1 warning generated. +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { PQsetClientEncoding(); return 0; } +/* end */ + +-------------------- + +have_func: checking for PQlibVersion()... -------------------- yes + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -Wl,-rpath,/usr/local/lib -arch x86_64 -lpq -lruby-static -framework CoreFoundation -lpq -lpthread -ldl -lobjc " +conftest.c:13:57: error: use of undeclared identifier 'PQlibVersion' +int t(void) { void ((*volatile p)()); p = (void ((*)()))PQlibVersion; return 0; } + ^ +1 error generated. +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { void ((*volatile p)()); p = (void ((*)()))PQlibVersion; return 0; } +/* end */ + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -Wl,-rpath,/usr/local/lib -arch x86_64 -lpq -lruby-static -framework CoreFoundation -lpq -lpthread -ldl -lobjc " +conftest.c:13:15: warning: implicit declaration of function 'PQlibVersion' is invalid in C99 [-Wimplicit-function-declaration] +int t(void) { PQlibVersion(); return 0; } + ^ +1 warning generated. +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { PQlibVersion(); return 0; } +/* end */ + +-------------------- + +have_func: checking for PQping()... -------------------- yes + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -Wl,-rpath,/usr/local/lib -arch x86_64 -lpq -lruby-static -framework CoreFoundation -lpq -lpthread -ldl -lobjc " +conftest.c:13:57: error: use of undeclared identifier 'PQping' +int t(void) { void ((*volatile p)()); p = (void ((*)()))PQping; return 0; } + ^ +1 error generated. +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { void ((*volatile p)()); p = (void ((*)()))PQping; return 0; } +/* end */ + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -Wl,-rpath,/usr/local/lib -arch x86_64 -lpq -lruby-static -framework CoreFoundation -lpq -lpthread -ldl -lobjc " +conftest.c:13:15: warning: implicit declaration of function 'PQping' is invalid in C99 [-Wimplicit-function-declaration] +int t(void) { PQping(); return 0; } + ^ +1 warning generated. +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { PQping(); return 0; } +/* end */ + +-------------------- + +have_func: checking for PQsetSingleRowMode()... -------------------- yes + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -Wl,-rpath,/usr/local/lib -arch x86_64 -lpq -lruby-static -framework CoreFoundation -lpq -lpthread -ldl -lobjc " +conftest.c:13:57: error: use of undeclared identifier 'PQsetSingleRowMode' +int t(void) { void ((*volatile p)()); p = (void ((*)()))PQsetSingleRowMode; return 0; } + ^ +1 error generated. +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { void ((*volatile p)()); p = (void ((*)()))PQsetSingleRowMode; return 0; } +/* end */ + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -Wl,-rpath,/usr/local/lib -arch x86_64 -lpq -lruby-static -framework CoreFoundation -lpq -lpthread -ldl -lobjc " +conftest.c:13:15: warning: implicit declaration of function 'PQsetSingleRowMode' is invalid in C99 [-Wimplicit-function-declaration] +int t(void) { PQsetSingleRowMode(); return 0; } + ^ +1 warning generated. +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { PQsetSingleRowMode(); return 0; } +/* end */ + +-------------------- + +have_func: checking for PQconninfo()... -------------------- yes + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -Wl,-rpath,/usr/local/lib -arch x86_64 -lpq -lruby-static -framework CoreFoundation -lpq -lpthread -ldl -lobjc " +conftest.c:13:57: error: use of undeclared identifier 'PQconninfo' +int t(void) { void ((*volatile p)()); p = (void ((*)()))PQconninfo; return 0; } + ^ +1 error generated. +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { void ((*volatile p)()); p = (void ((*)()))PQconninfo; return 0; } +/* end */ + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -Wl,-rpath,/usr/local/lib -arch x86_64 -lpq -lruby-static -framework CoreFoundation -lpq -lpthread -ldl -lobjc " +conftest.c:13:15: warning: implicit declaration of function 'PQconninfo' is invalid in C99 [-Wimplicit-function-declaration] +int t(void) { PQconninfo(); return 0; } + ^ +1 warning generated. +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { PQconninfo(); return 0; } +/* end */ + +-------------------- + +have_func: checking for rb_encdb_alias()... -------------------- yes + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -Wl,-rpath,/usr/local/lib -arch x86_64 -lpq -lruby-static -framework CoreFoundation -lpq -lpthread -ldl -lobjc " +conftest.c:13:57: error: use of undeclared identifier 'rb_encdb_alias' +int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_encdb_alias; return 0; } + ^ +1 error generated. +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_encdb_alias; return 0; } +/* end */ + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -Wl,-rpath,/usr/local/lib -arch x86_64 -lpq -lruby-static -framework CoreFoundation -lpq -lpthread -ldl -lobjc " +conftest.c:13:15: warning: implicit declaration of function 'rb_encdb_alias' is invalid in C99 [-Wimplicit-function-declaration] +int t(void) { rb_encdb_alias(); return 0; } + ^ +1 warning generated. +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { rb_encdb_alias(); return 0; } +/* end */ + +-------------------- + +have_func: checking for rb_enc_alias()... -------------------- yes + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -Wl,-rpath,/usr/local/lib -arch x86_64 -lpq -lruby-static -framework CoreFoundation -lpq -lpthread -ldl -lobjc " +conftest.c:13:57: error: use of undeclared identifier 'rb_enc_alias' +int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_enc_alias; return 0; } + ^ +1 error generated. +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_enc_alias; return 0; } +/* end */ + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -Wl,-rpath,/usr/local/lib -arch x86_64 -lpq -lruby-static -framework CoreFoundation -lpq -lpthread -ldl -lobjc " +conftest.c:13:15: warning: implicit declaration of function 'rb_enc_alias' is invalid in C99 [-Wimplicit-function-declaration] +int t(void) { rb_enc_alias(); return 0; } + ^ +1 warning generated. +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { rb_enc_alias(); return 0; } +/* end */ + +-------------------- + +have_func: checking for rb_thread_call_without_gvl()... -------------------- yes + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -Wl,-rpath,/usr/local/lib -arch x86_64 -lpq -lruby-static -framework CoreFoundation -lpq -lpthread -ldl -lobjc " +conftest.c:13:57: error: use of undeclared identifier 'rb_thread_call_without_gvl' +int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_thread_call_without_gvl; return 0; } + ^ +1 error generated. +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_thread_call_without_gvl; return 0; } +/* end */ + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -Wl,-rpath,/usr/local/lib -arch x86_64 -lpq -lruby-static -framework CoreFoundation -lpq -lpthread -ldl -lobjc " +conftest.c:13:15: warning: implicit declaration of function 'rb_thread_call_without_gvl' is invalid in C99 [-Wimplicit-function-declaration] +int t(void) { rb_thread_call_without_gvl(); return 0; } + ^ +1 warning generated. +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { rb_thread_call_without_gvl(); return 0; } +/* end */ + +-------------------- + +have_func: checking for rb_thread_call_with_gvl()... -------------------- yes + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -Wl,-rpath,/usr/local/lib -arch x86_64 -lpq -lruby-static -framework CoreFoundation -lpq -lpthread -ldl -lobjc " +conftest.c:13:57: error: use of undeclared identifier 'rb_thread_call_with_gvl' +int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_thread_call_with_gvl; return 0; } + ^ +1 error generated. +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_thread_call_with_gvl; return 0; } +/* end */ + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -Wl,-rpath,/usr/local/lib -arch x86_64 -lpq -lruby-static -framework CoreFoundation -lpq -lpthread -ldl -lobjc " +conftest.c:13:15: warning: implicit declaration of function 'rb_thread_call_with_gvl' is invalid in C99 [-Wimplicit-function-declaration] +int t(void) { rb_thread_call_with_gvl(); return 0; } + ^ +1 warning generated. +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { rb_thread_call_with_gvl(); return 0; } +/* end */ + +-------------------- + +have_func: checking for rb_thread_fd_select()... -------------------- yes + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -Wl,-rpath,/usr/local/lib -arch x86_64 -lpq -lruby-static -framework CoreFoundation -lpq -lpthread -ldl -lobjc " +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_thread_fd_select; return 0; } +/* end */ + +-------------------- + +have_func: checking for rb_w32_wrap_io_handle()... -------------------- no + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -Wl,-rpath,/usr/local/lib -arch x86_64 -lpq -lruby-static -framework CoreFoundation -lpq -lpthread -ldl -lobjc " +conftest.c:13:57: error: use of undeclared identifier 'rb_w32_wrap_io_handle' +int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_w32_wrap_io_handle; return 0; } + ^ +1 error generated. +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_w32_wrap_io_handle; return 0; } +/* end */ + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -Wl,-rpath,/usr/local/lib -arch x86_64 -lpq -lruby-static -framework CoreFoundation -lpq -lpthread -ldl -lobjc " +conftest.c:13:15: warning: implicit declaration of function 'rb_w32_wrap_io_handle' is invalid in C99 [-Wimplicit-function-declaration] +int t(void) { rb_w32_wrap_io_handle(); return 0; } + ^ +1 warning generated. +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +Undefined symbols for architecture x86_64: + "_rb_w32_wrap_io_handle", referenced from: + _t in conftest-f27b5b.o +ld: symbol(s) not found for architecture x86_64 +clang: error: linker command failed with exit code 1 (use -v to see invocation) +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { rb_w32_wrap_io_handle(); return 0; } +/* end */ + +-------------------- + +have_func: checking for rb_str_modify_expand()... -------------------- yes + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -Wl,-rpath,/usr/local/lib -arch x86_64 -lpq -lruby-static -framework CoreFoundation -lpq -lpthread -ldl -lobjc " +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_str_modify_expand; return 0; } +/* end */ + +-------------------- + +have_func: checking for rb_hash_dup()... -------------------- yes + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L/usr/local/lib -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -Wl,-rpath,/usr/local/lib -arch x86_64 -lpq -lruby-static -framework CoreFoundation -lpq -lpthread -ldl -lobjc " +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_hash_dup; return 0; } +/* end */ + +-------------------- + +have_const: checking for PGRES_COPY_BOTH in libpq-fe.h... -------------------- yes + +"gcc -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe -arch x86_64 -c conftest.c" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +4: +5: /*top*/ +6: typedef int conftest_type; +7: conftest_type conftestval = (int)PGRES_COPY_BOTH; +/* end */ + +-------------------- + +have_const: checking for PGRES_SINGLE_TUPLE in libpq-fe.h... -------------------- yes + +"gcc -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe -arch x86_64 -c conftest.c" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +4: +5: /*top*/ +6: typedef int conftest_type; +7: conftest_type conftestval = (int)PGRES_SINGLE_TUPLE; +/* end */ + +-------------------- + +have_const: checking for PG_DIAG_TABLE_NAME in libpq-fe.h... -------------------- yes + +"gcc -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe -arch x86_64 -c conftest.c" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +4: +5: /*top*/ +6: typedef int conftest_type; +7: conftest_type conftestval = (int)PG_DIAG_TABLE_NAME; +/* end */ + +-------------------- + +have_struct_member: checking for struct pgNotify.extra in libpq-fe.h... -------------------- yes + +"gcc -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe -arch x86_64 -c conftest.c" +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: int s = (char *)&((struct pgNotify*)0)->extra - (char *)0; + 7: int main(int argc, char **argv) + 8: { + 9: return 0; +10: } +/* end */ + +-------------------- + +have_header: checking for unistd.h... -------------------- yes + +"gcc -E -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -o conftest.i" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +/* end */ + +-------------------- + +have_header: checking for inttypes.h... -------------------- yes + +"gcc -E -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -o conftest.i" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +/* end */ + +-------------------- + +have_header: checking for ruby/st.h... -------------------- yes + +"gcc -E -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -o conftest.i" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +/* end */ + +-------------------- + +checking for C99 variable length arrays... -------------------- yes + +"gcc -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -I/usr/local/Cellar/postgresql/9.4.5_2/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe -arch x86_64 -c conftest.c" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: void test_vla(int l){ int vla[l]; } +/* end */ + +-------------------- + +extconf.h is: +/* begin */ + 1: #ifndef EXTCONF_H + 2: #define EXTCONF_H + 3: #define HAVE_PQCONNECTIONUSEDPASSWORD 1 + 4: #define HAVE_PQISTHREADSAFE 1 + 5: #define HAVE_PQPREPARE 1 + 6: #define HAVE_PQEXECPARAMS 1 + 7: #define HAVE_PQESCAPESTRING 1 + 8: #define HAVE_PQESCAPESTRINGCONN 1 + 9: #define HAVE_PQESCAPELITERAL 1 +10: #define HAVE_PQESCAPEIDENTIFIER 1 +11: #define HAVE_PQGETCANCEL 1 +12: #define HAVE_LO_CREATE 1 +13: #define HAVE_PG_ENCODING_TO_CHAR 1 +14: #define HAVE_PG_CHAR_TO_ENCODING 1 +15: #define HAVE_PQSETCLIENTENCODING 1 +16: #define HAVE_PQLIBVERSION 1 +17: #define HAVE_PQPING 1 +18: #define HAVE_PQSETSINGLEROWMODE 1 +19: #define HAVE_PQCONNINFO 1 +20: #define HAVE_RB_ENCDB_ALIAS 1 +21: #define HAVE_RB_ENC_ALIAS 1 +22: #define HAVE_RB_THREAD_CALL_WITHOUT_GVL 1 +23: #define HAVE_RB_THREAD_CALL_WITH_GVL 1 +24: #define HAVE_RB_THREAD_FD_SELECT 1 +25: #define HAVE_RB_STR_MODIFY_EXPAND 1 +26: #define HAVE_RB_HASH_DUP 1 +27: #define HAVE_CONST_PGRES_COPY_BOTH 1 +28: #define HAVE_CONST_PGRES_SINGLE_TUPLE 1 +29: #define HAVE_CONST_PG_DIAG_TABLE_NAME 1 +30: #define HAVE_STRUCT_PGNOTIFY_EXTRA 1 +31: #define HAVE_ST_EXTRA 1 +32: #define HAVE_ST_NOTIFY_EXTRA 1 +33: #define HAVE_UNISTD_H 1 +34: #define HAVE_INTTYPES_H 1 +35: #define HAVE_RUBY_ST_H 1 +36: #define HAVE_VARIABLE_LENGTH_ARRAYS 1 +37: #endif +/* end */ + diff --git a/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/pg-0.18.4/pg_ext.bundle b/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/pg-0.18.4/pg_ext.bundle new file mode 100755 index 0000000..a4f8962 Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/pg-0.18.4/pg_ext.bundle differ diff --git a/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/sqlite3-1.3.11/gem.build_complete b/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/sqlite3-1.3.11/gem.build_complete new file mode 100644 index 0000000..e69de29 diff --git a/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/sqlite3-1.3.11/gem_make.out b/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/sqlite3-1.3.11/gem_make.out new file mode 100644 index 0000000..a800af3 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/sqlite3-1.3.11/gem_make.out @@ -0,0 +1,29 @@ +/Users/RA/.rvm/rubies/ruby-2.2.3/bin/ruby -r ./siteconf20160523-33198-net3d0.rb extconf.rb +checking for sqlite3.h... yes +checking for sqlite3_libversion_number() in -lsqlite3... yes +checking for rb_proc_arity()... yes +checking for rb_integer_pack()... yes +checking for sqlite3_initialize()... yes +checking for sqlite3_backup_init()... yes +checking for sqlite3_column_database_name()... no +checking for sqlite3_enable_load_extension()... no +checking for sqlite3_load_extension()... no +checking for sqlite3_open_v2()... yes +checking for sqlite3_prepare_v2()... yes +checking for sqlite3_int64 in sqlite3.h... yes +checking for sqlite3_uint64 in sqlite3.h... yes +creating Makefile + +make "DESTDIR=" clean + +make "DESTDIR=" +compiling backup.c +compiling database.c +compiling exception.c +compiling sqlite3.c +compiling statement.c +linking shared-object sqlite3/sqlite3_native.bundle +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' + +make "DESTDIR=" install +/usr/bin/install -m 0755 sqlite3_native.bundle ./.gem.20160523-33198-2z0jvn/sqlite3 diff --git a/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/sqlite3-1.3.11/mkmf.log b/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/sqlite3-1.3.11/mkmf.log new file mode 100644 index 0000000..86cb8d6 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/sqlite3-1.3.11/mkmf.log @@ -0,0 +1,509 @@ +find_header: checking for sqlite3.h... -------------------- yes + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -arch x86_64 -lruby-static -framework CoreFoundation -lpthread -ldl -lobjc " +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: int main(int argc, char **argv) +4: { +5: return 0; +6: } +/* end */ + +"gcc -E -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -o conftest.i" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +/* end */ + +-------------------- + +find_library: checking for sqlite3_libversion_number() in -lsqlite3... -------------------- yes + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -arch x86_64 -lruby-static -framework CoreFoundation -lsqlite3 -lpthread -ldl -lobjc " +conftest.c:13:57: error: use of undeclared identifier 'sqlite3_libversion_number' +int t(void) { void ((*volatile p)()); p = (void ((*)()))sqlite3_libversion_number; return 0; } + ^ +1 error generated. +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { void ((*volatile p)()); p = (void ((*)()))sqlite3_libversion_number; return 0; } +/* end */ + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -arch x86_64 -lruby-static -framework CoreFoundation -lsqlite3 -lpthread -ldl -lobjc " +conftest.c:13:15: warning: implicit declaration of function 'sqlite3_libversion_number' is invalid in C99 [-Wimplicit-function-declaration] +int t(void) { sqlite3_libversion_number(); return 0; } + ^ +1 warning generated. +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { sqlite3_libversion_number(); return 0; } +/* end */ + +-------------------- + +have_func: checking for rb_proc_arity()... -------------------- yes + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -arch x86_64 -lsqlite3 -lruby-static -framework CoreFoundation -lsqlite3 -lpthread -ldl -lobjc " +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_proc_arity; return 0; } +/* end */ + +-------------------- + +have_func: checking for rb_integer_pack()... -------------------- yes + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -arch x86_64 -lsqlite3 -lruby-static -framework CoreFoundation -lsqlite3 -lpthread -ldl -lobjc " +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_integer_pack; return 0; } +/* end */ + +-------------------- + +have_func: checking for sqlite3_initialize()... -------------------- yes + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -arch x86_64 -lsqlite3 -lruby-static -framework CoreFoundation -lsqlite3 -lpthread -ldl -lobjc " +conftest.c:13:57: error: use of undeclared identifier 'sqlite3_initialize' +int t(void) { void ((*volatile p)()); p = (void ((*)()))sqlite3_initialize; return 0; } + ^ +1 error generated. +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { void ((*volatile p)()); p = (void ((*)()))sqlite3_initialize; return 0; } +/* end */ + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -arch x86_64 -lsqlite3 -lruby-static -framework CoreFoundation -lsqlite3 -lpthread -ldl -lobjc " +conftest.c:13:15: warning: implicit declaration of function 'sqlite3_initialize' is invalid in C99 [-Wimplicit-function-declaration] +int t(void) { sqlite3_initialize(); return 0; } + ^ +1 warning generated. +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { sqlite3_initialize(); return 0; } +/* end */ + +-------------------- + +have_func: checking for sqlite3_backup_init()... -------------------- yes + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -arch x86_64 -lsqlite3 -lruby-static -framework CoreFoundation -lsqlite3 -lpthread -ldl -lobjc " +conftest.c:13:57: error: use of undeclared identifier 'sqlite3_backup_init' +int t(void) { void ((*volatile p)()); p = (void ((*)()))sqlite3_backup_init; return 0; } + ^ +1 error generated. +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { void ((*volatile p)()); p = (void ((*)()))sqlite3_backup_init; return 0; } +/* end */ + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -arch x86_64 -lsqlite3 -lruby-static -framework CoreFoundation -lsqlite3 -lpthread -ldl -lobjc " +conftest.c:13:15: warning: implicit declaration of function 'sqlite3_backup_init' is invalid in C99 [-Wimplicit-function-declaration] +int t(void) { sqlite3_backup_init(); return 0; } + ^ +1 warning generated. +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { sqlite3_backup_init(); return 0; } +/* end */ + +-------------------- + +have_func: checking for sqlite3_column_database_name()... -------------------- no + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -arch x86_64 -lsqlite3 -lruby-static -framework CoreFoundation -lsqlite3 -lpthread -ldl -lobjc " +conftest.c:13:57: error: use of undeclared identifier 'sqlite3_column_database_name' +int t(void) { void ((*volatile p)()); p = (void ((*)()))sqlite3_column_database_name; return 0; } + ^ +1 error generated. +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { void ((*volatile p)()); p = (void ((*)()))sqlite3_column_database_name; return 0; } +/* end */ + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -arch x86_64 -lsqlite3 -lruby-static -framework CoreFoundation -lsqlite3 -lpthread -ldl -lobjc " +conftest.c:13:15: warning: implicit declaration of function 'sqlite3_column_database_name' is invalid in C99 [-Wimplicit-function-declaration] +int t(void) { sqlite3_column_database_name(); return 0; } + ^ +1 warning generated. +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +Undefined symbols for architecture x86_64: + "_sqlite3_column_database_name", referenced from: + _t in conftest-517572.o +ld: symbol(s) not found for architecture x86_64 +clang: error: linker command failed with exit code 1 (use -v to see invocation) +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { sqlite3_column_database_name(); return 0; } +/* end */ + +-------------------- + +have_func: checking for sqlite3_enable_load_extension()... -------------------- no + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -arch x86_64 -lsqlite3 -lruby-static -framework CoreFoundation -lsqlite3 -lpthread -ldl -lobjc " +conftest.c:13:57: error: use of undeclared identifier 'sqlite3_enable_load_extension' +int t(void) { void ((*volatile p)()); p = (void ((*)()))sqlite3_enable_load_extension; return 0; } + ^ +1 error generated. +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { void ((*volatile p)()); p = (void ((*)()))sqlite3_enable_load_extension; return 0; } +/* end */ + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -arch x86_64 -lsqlite3 -lruby-static -framework CoreFoundation -lsqlite3 -lpthread -ldl -lobjc " +conftest.c:13:15: warning: implicit declaration of function 'sqlite3_enable_load_extension' is invalid in C99 [-Wimplicit-function-declaration] +int t(void) { sqlite3_enable_load_extension(); return 0; } + ^ +1 warning generated. +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +Undefined symbols for architecture x86_64: + "_sqlite3_enable_load_extension", referenced from: + _t in conftest-c7ba11.o +ld: symbol(s) not found for architecture x86_64 +clang: error: linker command failed with exit code 1 (use -v to see invocation) +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { sqlite3_enable_load_extension(); return 0; } +/* end */ + +-------------------- + +have_func: checking for sqlite3_load_extension()... -------------------- no + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -arch x86_64 -lsqlite3 -lruby-static -framework CoreFoundation -lsqlite3 -lpthread -ldl -lobjc " +conftest.c:13:57: error: use of undeclared identifier 'sqlite3_load_extension' +int t(void) { void ((*volatile p)()); p = (void ((*)()))sqlite3_load_extension; return 0; } + ^ +1 error generated. +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { void ((*volatile p)()); p = (void ((*)()))sqlite3_load_extension; return 0; } +/* end */ + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -arch x86_64 -lsqlite3 -lruby-static -framework CoreFoundation -lsqlite3 -lpthread -ldl -lobjc " +conftest.c:13:15: warning: implicit declaration of function 'sqlite3_load_extension' is invalid in C99 [-Wimplicit-function-declaration] +int t(void) { sqlite3_load_extension(); return 0; } + ^ +1 warning generated. +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +Undefined symbols for architecture x86_64: + "_sqlite3_load_extension", referenced from: + _t in conftest-452bef.o +ld: symbol(s) not found for architecture x86_64 +clang: error: linker command failed with exit code 1 (use -v to see invocation) +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { sqlite3_load_extension(); return 0; } +/* end */ + +-------------------- + +have_func: checking for sqlite3_open_v2()... -------------------- yes + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -arch x86_64 -lsqlite3 -lruby-static -framework CoreFoundation -lsqlite3 -lpthread -ldl -lobjc " +conftest.c:13:57: error: use of undeclared identifier 'sqlite3_open_v2' +int t(void) { void ((*volatile p)()); p = (void ((*)()))sqlite3_open_v2; return 0; } + ^ +1 error generated. +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { void ((*volatile p)()); p = (void ((*)()))sqlite3_open_v2; return 0; } +/* end */ + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -arch x86_64 -lsqlite3 -lruby-static -framework CoreFoundation -lsqlite3 -lpthread -ldl -lobjc " +conftest.c:13:15: warning: implicit declaration of function 'sqlite3_open_v2' is invalid in C99 [-Wimplicit-function-declaration] +int t(void) { sqlite3_open_v2(); return 0; } + ^ +1 warning generated. +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { sqlite3_open_v2(); return 0; } +/* end */ + +-------------------- + +have_func: checking for sqlite3_prepare_v2()... -------------------- yes + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -arch x86_64 -lsqlite3 -lruby-static -framework CoreFoundation -lsqlite3 -lpthread -ldl -lobjc " +conftest.c:13:57: error: use of undeclared identifier 'sqlite3_prepare_v2' +int t(void) { void ((*volatile p)()); p = (void ((*)()))sqlite3_prepare_v2; return 0; } + ^ +1 error generated. +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { void ((*volatile p)()); p = (void ((*)()))sqlite3_prepare_v2; return 0; } +/* end */ + +"gcc -o conftest -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe conftest.c -L. -L/Users/RA/.rvm/rubies/ruby-2.2.3/lib -L. -L/Users/haven/.sm/pkg/active/lib -fPIC -Bstatic -lz -fstack-protector -L/usr/local/lib -arch x86_64 -lsqlite3 -lruby-static -framework CoreFoundation -lsqlite3 -lpthread -ldl -lobjc " +conftest.c:13:15: warning: implicit declaration of function 'sqlite3_prepare_v2' is invalid in C99 [-Wimplicit-function-declaration] +int t(void) { sqlite3_prepare_v2(); return 0; } + ^ +1 warning generated. +ld: warning: directory not found for option '-L/Users/haven/.sm/pkg/active/lib' +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: printf("%p", &t); + 9: } +10: +11: return 0; +12: } +13: int t(void) { sqlite3_prepare_v2(); return 0; } +/* end */ + +-------------------- + +have_type: checking for sqlite3_int64 in sqlite3.h... -------------------- yes + +"gcc -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe -arch x86_64 -c conftest.c" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +4: +5: /*top*/ +6: typedef sqlite3_int64 conftest_type; +7: int conftestval[sizeof(conftest_type)?1:-1]; +/* end */ + +-------------------- + +have_type: checking for sqlite3_uint64 in sqlite3.h... -------------------- yes + +"gcc -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14 -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/Users/RA/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe -arch x86_64 -c conftest.c" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +4: +5: /*top*/ +6: typedef sqlite3_uint64 conftest_type; +7: int conftestval[sizeof(conftest_type)?1:-1]; +/* end */ + +-------------------- + diff --git a/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/sqlite3-1.3.11/sqlite3/sqlite3_native.bundle b/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/sqlite3-1.3.11/sqlite3/sqlite3_native.bundle new file mode 100755 index 0000000..11e2eda Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/extensions/x86_64-darwin-14/2.2.0-static/sqlite3-1.3.11/sqlite3/sqlite3_native.bundle differ diff --git a/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/CHANGELOG.md b/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/CHANGELOG.md new file mode 100644 index 0000000..d0e1079 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/CHANGELOG.md @@ -0,0 +1,124 @@ +## Rails 4.2.6 (March 07, 2016) ## + +* No changes. + + +## Rails 4.2.5.2 (February 26, 2016) ## + +* No changes. + + +## Rails 4.2.5.1 (January 25, 2015) ## + +* No changes. + + +## Rails 4.2.5 (November 12, 2015) ## + +* No changes. + + +## Rails 4.2.4 (August 24, 2015) ## + +* No Changes * + + +## Rails 4.2.3 (June 25, 2015) ## + +* `assert_emails` in block form use the given number as expected value. + This makes the error message much easier to understand. + + *Yuji Yaginuma* + +* Mailer preview now uses `url_for` to fix links to emails for apps running on + a subdirectory. + + *Remo Mueller* + +* Mailer previews no longer crash when the `mail` method wasn't called + (`NullMail`). + + Fixes #19849. + + *Yves Senn* + +* Make sure labels and values line up in mailer previews. + + *Yves Senn* + + +## Rails 4.2.2 (June 16, 2015) ## + +* No Changes * + + +## Rails 4.2.1 (March 19, 2015) ## + +* No Changes * + + +## Rails 4.2.0 (December 20, 2014) ## + +* `MailerGenerator` now generates layouts by default. The HTML mailer layout + now includes `` and `` tags which improve the spam rating in + some spam detection engines. Mailers now inherit from `ApplicationMailer` + which sets the default layout. + + *Andy Jeffries* + +* `link_to` and `url_for` now generate URLs by default in templates. + Passing `only_path: false` is no longer needed. + + Fixes #16497 and #16589. + + *Xavier Noria*, *Richard Schneeman* + +* Attachments can now be added while rendering the mail template. + + Fixes #16974. + + *Christian Felder* + +* Add `#deliver_later` and `#deliver_now` methods and deprecate `#deliver` in + favor of `#deliver_now`. `#deliver_later` will enqueue a job to render and + deliver the mail instead of delivering it immediately. The job is enqueued + using the new Active Job framework in Rails and will use the queue that you + have configured in Rails. + + *DHH*, *Abdelkader Boudih*, *Cristian Bica* + +* `ActionMailer::Previews` are now class methods instead of instance methods. + + *Cristian Bica* + +* Deprecate `*_path` helpers in email views. They generated broken links in + email views and were not the intention of most developers. The `*_url` + helper is recommended instead. + + *Richard Schneeman* + +* Raise an exception when attachments are added after `mail` is called. + This is a safeguard to prevent invalid emails. + + Fixes #16163. + + *Yves Senn* + +* Add `config.action_mailer.show_previews` configuration option. + + This configuration option can be used to enable the mail preview in + environments other than development (such as staging). + + Defaults to `true` in development and `false` elsewhere. + + *Leonard Garvey* + +* Allow preview interceptors to be registered through + `config.action_mailer.preview_interceptors`. + + See #15739. + + *Yves Senn* + +Please check [4-1-stable](https://github.com/rails/rails/blob/4-1-stable/actionmailer/CHANGELOG.md) +for previous changes. diff --git a/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/MIT-LICENSE b/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/MIT-LICENSE new file mode 100644 index 0000000..d58dd9e --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/MIT-LICENSE @@ -0,0 +1,21 @@ +Copyright (c) 2004-2014 David Heinemeier Hansson + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/README.rdoc b/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/README.rdoc new file mode 100644 index 0000000..fa44bec --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/README.rdoc @@ -0,0 +1,176 @@ += Action Mailer -- Easy email delivery and testing + +Action Mailer is a framework for designing email service layers. These layers +are used to consolidate code for sending out forgotten passwords, welcome +wishes on signup, invoices for billing, and any other use case that requires +a written notification to either a person or another system. + +Action Mailer is in essence a wrapper around Action Controller and the +Mail gem. It provides a way to make emails using templates in the same +way that Action Controller renders views using templates. + +Additionally, an Action Mailer class can be used to process incoming email, +such as allowing a blog to accept new posts from an email (which could even +have been sent from a phone). + +== Sending emails + +The framework works by initializing any instance variables you want to be +available in the email template, followed by a call to +mail+ to deliver +the email. + +This can be as simple as: + + class Notifier < ActionMailer::Base + default from: 'system@loudthinking.com' + + def welcome(recipient) + @recipient = recipient + mail(to: recipient, + subject: "[Signed up] Welcome #{recipient}") + end + end + +The body of the email is created by using an Action View template (regular +ERB) that has the instance variables that are declared in the mailer action. + +So the corresponding body template for the method above could look like this: + + Hello there, + + Mr. <%= @recipient %> + + Thank you for signing up! + +If the recipient was given as "david@loudthinking.com", the email +generated would look like this: + + Date: Mon, 25 Jan 2010 22:48:09 +1100 + From: system@loudthinking.com + To: david@loudthinking.com + Message-ID: <4b5d84f9dd6a5_7380800b81ac29578@void.loudthinking.com.mail> + Subject: [Signed up] Welcome david@loudthinking.com + Mime-Version: 1.0 + Content-Type: text/plain; + charset="US-ASCII"; + Content-Transfer-Encoding: 7bit + + Hello there, + + Mr. david@loudthinking.com + + Thank you for signing up! + +In order to send mails, you simply call the method and then call +deliver_now+ on the return value. + +Calling the method returns a Mail Message object: + + message = Notifier.welcome("david@loudthinking.com") # => Returns a Mail::Message object + message.deliver_now # => delivers the email + +Or you can just chain the methods together like: + + Notifier.welcome("david@loudthinking.com").deliver_now # Creates the email and sends it immediately + +== Setting defaults + +It is possible to set default values that will be used in every method in your +Action Mailer class. To implement this functionality, you just call the public +class method +default+ which you get for free from ActionMailer::Base. +This method accepts a Hash as the parameter. You can use any of the headers, +email messages have, like +:from+ as the key. You can also pass in a string as +the key, like "Content-Type", but Action Mailer does this out of the box for you, +so you won't need to worry about that. Finally, it is also possible to pass in a +Proc that will get evaluated when it is needed. + +Note that every value you set with this method will get overwritten if you use the +same key in your mailer method. + +Example: + + class AuthenticationMailer < ActionMailer::Base + default from: "awesome@application.com", subject: Proc.new { "E-mail was generated at #{Time.now}" } + ..... + end + +== Receiving emails + +To receive emails, you need to implement a public instance method called ++receive+ that takes an email object as its single parameter. The Action Mailer +framework has a corresponding class method, which is also called +receive+, that +accepts a raw, unprocessed email as a string, which it then turns into the email +object and calls the receive instance method. + +Example: + + class Mailman < ActionMailer::Base + def receive(email) + page = Page.find_by(address: email.to.first) + page.emails.create( + subject: email.subject, body: email.body + ) + + if email.has_attachments? + email.attachments.each do |attachment| + page.attachments.create({ + file: attachment, description: email.subject + }) + end + end + end + end + +This Mailman can be the target for Postfix or other MTAs. In Rails, you would use +the runner in the trivial case like this: + + rails runner 'Mailman.receive(STDIN.read)' + +However, invoking Rails in the runner for each mail to be received is very +resource intensive. A single instance of Rails should be run within a daemon, if +it is going to process more than just a limited amount of email. + +== Configuration + +The Base class has the full list of configuration options. Here's an example: + + ActionMailer::Base.smtp_settings = { + address: 'smtp.yourserver.com', # default: localhost + port: '25', # default: 25 + user_name: 'user', + password: 'pass', + authentication: :plain # :plain, :login or :cram_md5 + } + + +== Download and installation + +The latest version of Action Mailer can be installed with RubyGems: + + % [sudo] gem install actionmailer + +Source code can be downloaded as part of the Rails project on GitHub + +* https://github.com/rails/rails/tree/4-2-stable/actionmailer + + +== License + +Action Mailer is released under the MIT license: + +* http://www.opensource.org/licenses/MIT + + +== Support + +API documentation is at + +* http://api.rubyonrails.org + +Bug reports can be filed for the Ruby on Rails project here: + +* https://github.com/rails/rails/issues + +Feature requests should be discussed on the rails-core mailing list here: + +* https://groups.google.com/forum/?fromgroups#!forum/rubyonrails-core + diff --git a/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/action_mailer.rb b/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/action_mailer.rb new file mode 100644 index 0000000..1e4d617 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/action_mailer.rb @@ -0,0 +1,58 @@ +#-- +# Copyright (c) 2004-2014 David Heinemeier Hansson +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +#++ + +require 'abstract_controller' +require 'action_mailer/version' + +# Common Active Support usage in Action Mailer +require 'active_support/rails' +require 'active_support/core_ext/class' +require 'active_support/core_ext/module/attr_internal' +require 'active_support/core_ext/string/inflections' +require 'active_support/lazy_load_hooks' + +module ActionMailer + extend ::ActiveSupport::Autoload + + eager_autoload do + autoload :Collector + end + + autoload :Base + autoload :DeliveryMethods + autoload :InlinePreviewInterceptor + autoload :MailHelper + autoload :Preview + autoload :Previews, 'action_mailer/preview' + autoload :TestCase + autoload :TestHelper + autoload :MessageDelivery + autoload :DeliveryJob +end + +autoload :Mime, 'action_dispatch/http/mime_type' + +ActiveSupport.on_load(:action_view) do + ActionView::Base.default_formats ||= Mime::SET.symbols + ActionView::Template::Types.delegate_to Mime +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/action_mailer/base.rb b/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/action_mailer/base.rb new file mode 100644 index 0000000..518c29f --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/action_mailer/base.rb @@ -0,0 +1,948 @@ +require 'mail' +require 'action_mailer/collector' +require 'active_support/core_ext/string/inflections' +require 'active_support/core_ext/hash/except' +require 'active_support/core_ext/module/anonymous' + +require 'action_mailer/log_subscriber' + +module ActionMailer + # Action Mailer allows you to send email from your application using a mailer model and views. + # + # = Mailer Models + # + # To use Action Mailer, you need to create a mailer model. + # + # $ rails generate mailer Notifier + # + # The generated model inherits from ApplicationMailer which in turn + # inherits from ActionMailer::Base. A mailer model defines methods + # used to generate an email message. In these methods, you can setup variables to be used in + # the mailer views, options on the mail itself such as the :from address, and attachments. + # + # class ApplicationMailer < ActionMailer::Base + # default from: 'from@exmaple.com' + # layout 'mailer' + # end + # + # class Notifier < ApplicationMailer + # default from: 'no-reply@example.com', + # return_path: 'system@example.com' + # + # def welcome(recipient) + # @account = recipient + # mail(to: recipient.email_address_with_name, + # bcc: ["bcc@example.com", "Order Watcher "]) + # end + # end + # + # Within the mailer method, you have access to the following methods: + # + # * attachments[]= - Allows you to add attachments to your email in an intuitive + # manner; attachments['filename.png'] = File.read('path/to/filename.png') + # + # * attachments.inline[]= - Allows you to add an inline attachment to your email + # in the same manner as attachments[]= + # + # * headers[]= - Allows you to specify any header field in your email such + # as headers['X-No-Spam'] = 'True'. Note that declaring a header multiple times + # will add many fields of the same name. Read #headers doc for more information. + # + # * headers(hash) - Allows you to specify multiple headers in your email such + # as headers({'X-No-Spam' => 'True', 'In-Reply-To' => '1234@message.id'}) + # + # * mail - Allows you to specify email to be sent. + # + # The hash passed to the mail method allows you to specify any header that a Mail::Message + # will accept (any valid email header including optional fields). + # + # The mail method, if not passed a block, will inspect your views and send all the views with + # the same name as the method, so the above action would send the +welcome.text.erb+ view + # file as well as the +welcome.html.erb+ view file in a +multipart/alternative+ email. + # + # If you want to explicitly render only certain templates, pass a block: + # + # mail(to: user.email) do |format| + # format.text + # format.html + # end + # + # The block syntax is also useful in providing information specific to a part: + # + # mail(to: user.email) do |format| + # format.text(content_transfer_encoding: "base64") + # format.html + # end + # + # Or even to render a special view: + # + # mail(to: user.email) do |format| + # format.text + # format.html { render "some_other_template" } + # end + # + # = Mailer views + # + # Like Action Controller, each mailer class has a corresponding view directory in which each + # method of the class looks for a template with its name. + # + # To define a template to be used with a mailing, create an .erb file with the same + # name as the method in your mailer model. For example, in the mailer defined above, the template at + # app/views/notifier/welcome.text.erb would be used to generate the email. + # + # Variables defined in the methods of your mailer model are accessible as instance variables in their + # corresponding view. + # + # Emails by default are sent in plain text, so a sample view for our model example might look like this: + # + # Hi <%= @account.name %>, + # Thanks for joining our service! Please check back often. + # + # You can even use Action View helpers in these views. For example: + # + # You got a new note! + # <%= truncate(@note.body, length: 25) %> + # + # If you need to access the subject, from or the recipients in the view, you can do that through message object: + # + # You got a new note from <%= message.from %>! + # <%= truncate(@note.body, length: 25) %> + # + # + # = Generating URLs + # + # URLs can be generated in mailer views using url_for or named routes. Unlike controllers from + # Action Pack, the mailer instance doesn't have any context about the incoming request, so you'll need + # to provide all of the details needed to generate a URL. + # + # When using url_for you'll need to provide the :host, :controller, and :action: + # + # <%= url_for(host: "example.com", controller: "welcome", action: "greeting") %> + # + # When using named routes you only need to supply the :host: + # + # <%= users_url(host: "example.com") %> + # + # You should use the named_route_url style (which generates absolute URLs) and avoid using the + # named_route_path style (which generates relative URLs), since clients reading the mail will + # have no concept of a current URL from which to determine a relative path. + # + # It is also possible to set a default host that will be used in all mailers by setting the :host + # option as a configuration option in config/application.rb: + # + # config.action_mailer.default_url_options = { host: "example.com" } + # + # When you decide to set a default :host for your mailers, then you need to make sure to use the + # only_path: false option when using url_for. Since the url_for view helper + # will generate relative URLs by default when a :host option isn't explicitly provided, passing + # only_path: false will ensure that absolute URLs are generated. + # + # = Sending mail + # + # Once a mailer action and template are defined, you can deliver your message or create it and save it + # for delivery later: + # + # Notifier.welcome(User.first).deliver_now # sends the email + # mail = Notifier.welcome(User.first) # => an ActionMailer::MessageDelivery object + # mail.deliver_now # sends the email + # + # The ActionMailer::MessageDelivery class is a wrapper around a Mail::Message object. If + # you want direct access to the Mail::Message object you can call the message method on + # the ActionMailer::MessageDelivery object. + # + # Notifier.welcome(User.first).message # => a Mail::Message object + # + # Action Mailer is nicely integrated with Active Job so you can send emails in the background (example: outside + # of the request-response cycle, so the user doesn't have to wait on it): + # + # Notifier.welcome(User.first).deliver_later # enqueue the email sending to Active Job + # + # You never instantiate your mailer class. Rather, you just call the method you defined on the class itself. + # + # = Multipart Emails + # + # Multipart messages can also be used implicitly because Action Mailer will automatically detect and use + # multipart templates, where each template is named after the name of the action, followed by the content + # type. Each such detected template will be added as a separate part to the message. + # + # For example, if the following templates exist: + # * signup_notification.text.erb + # * signup_notification.html.erb + # * signup_notification.xml.builder + # * signup_notification.yml.erb + # + # Each would be rendered and added as a separate part to the message, with the corresponding content + # type. The content type for the entire message is automatically set to multipart/alternative, + # which indicates that the email contains multiple different representations of the same email + # body. The same instance variables defined in the action are passed to all email templates. + # + # Implicit template rendering is not performed if any attachments or parts have been added to the email. + # This means that you'll have to manually add each part to the email and set the content type of the email + # to multipart/alternative. + # + # = Attachments + # + # Sending attachment in emails is easy: + # + # class Notifier < ApplicationMailer + # def welcome(recipient) + # attachments['free_book.pdf'] = File.read('path/to/file.pdf') + # mail(to: recipient, subject: "New account information") + # end + # end + # + # Which will (if it had both a welcome.text.erb and welcome.html.erb + # template in the view directory), send a complete multipart/mixed email with two parts, + # the first part being a multipart/alternative with the text and HTML email parts inside, + # and the second being a application/pdf with a Base64 encoded copy of the file.pdf book + # with the filename +free_book.pdf+. + # + # If you need to send attachments with no content, you need to create an empty view for it, + # or add an empty body parameter like this: + # + # class Notifier < ApplicationMailer + # def welcome(recipient) + # attachments['free_book.pdf'] = File.read('path/to/file.pdf') + # mail(to: recipient, subject: "New account information", body: "") + # end + # end + # + # = Inline Attachments + # + # You can also specify that a file should be displayed inline with other HTML. This is useful + # if you want to display a corporate logo or a photo. + # + # class Notifier < ApplicationMailer + # def welcome(recipient) + # attachments.inline['photo.png'] = File.read('path/to/photo.png') + # mail(to: recipient, subject: "Here is what we look like") + # end + # end + # + # And then to reference the image in the view, you create a welcome.html.erb file and + # make a call to +image_tag+ passing in the attachment you want to display and then call + # +url+ on the attachment to get the relative content id path for the image source: + # + #

Please Don't Cringe

+ # + # <%= image_tag attachments['photo.png'].url -%> + # + # As we are using Action View's +image_tag+ method, you can pass in any other options you want: + # + #

Please Don't Cringe

+ # + # <%= image_tag attachments['photo.png'].url, alt: 'Our Photo', class: 'photo' -%> + # + # = Observing and Intercepting Mails + # + # Action Mailer provides hooks into the Mail observer and interceptor methods. These allow you to + # register classes that are called during the mail delivery life cycle. + # + # An observer class must implement the :delivered_email(message) method which will be + # called once for every email sent after the email has been sent. + # + # An interceptor class must implement the :delivering_email(message) method which will be + # called before the email is sent, allowing you to make modifications to the email before it hits + # the delivery agents. Your class should make any needed modifications directly to the passed + # in Mail::Message instance. + # + # = Default Hash + # + # Action Mailer provides some intelligent defaults for your emails, these are usually specified in a + # default method inside the class definition: + # + # class Notifier < ApplicationMailer + # default sender: 'system@example.com' + # end + # + # You can pass in any header value that a Mail::Message accepts. Out of the box, + # ActionMailer::Base sets the following: + # + # * mime_version: "1.0" + # * charset: "UTF-8", + # * content_type: "text/plain", + # * parts_order: [ "text/plain", "text/enriched", "text/html" ] + # + # parts_order and charset are not actually valid Mail::Message header fields, + # but Action Mailer translates them appropriately and sets the correct values. + # + # As you can pass in any header, you need to either quote the header as a string, or pass it in as + # an underscored symbol, so the following will work: + # + # class Notifier < ApplicationMailer + # default 'Content-Transfer-Encoding' => '7bit', + # content_description: 'This is a description' + # end + # + # Finally, Action Mailer also supports passing Proc objects into the default hash, so you + # can define methods that evaluate as the message is being generated: + # + # class Notifier < ApplicationMailer + # default 'X-Special-Header' => Proc.new { my_method } + # + # private + # + # def my_method + # 'some complex call' + # end + # end + # + # Note that the proc is evaluated right at the start of the mail message generation, so if you + # set something in the defaults using a proc, and then set the same thing inside of your + # mailer method, it will get over written by the mailer method. + # + # It is also possible to set these default options that will be used in all mailers through + # the default_options= configuration in config/application.rb: + # + # config.action_mailer.default_options = { from: "no-reply@example.org" } + # + # = Callbacks + # + # You can specify callbacks using before_action and after_action for configuring your messages. + # This may be useful, for example, when you want to add default inline attachments for all + # messages sent out by a certain mailer class: + # + # class Notifier < ApplicationMailer + # before_action :add_inline_attachment! + # + # def welcome + # mail + # end + # + # private + # + # def add_inline_attachment! + # attachments.inline["footer.jpg"] = File.read('/path/to/filename.jpg') + # end + # end + # + # Callbacks in Action Mailer are implemented using + # AbstractController::Callbacks, so you can define and configure + # callbacks in the same manner that you would use callbacks in classes that + # inherit from ActionController::Base. + # + # Note that unless you have a specific reason to do so, you should prefer using before_action + # rather than after_action in your Action Mailer classes so that headers are parsed properly. + # + # = Previewing emails + # + # You can preview your email templates visually by adding a mailer preview file to the + # ActionMailer::Base.preview_path. Since most emails do something interesting + # with database data, you'll need to write some scenarios to load messages with fake data: + # + # class NotifierPreview < ActionMailer::Preview + # def welcome + # Notifier.welcome(User.first) + # end + # end + # + # Methods must return a Mail::Message object which can be generated by calling the mailer + # method without the additional deliver_now / deliver_later. The location of the + # mailer previews directory can be configured using the preview_path option which has a default + # of test/mailers/previews: + # + # config.action_mailer.preview_path = "#{Rails.root}/lib/mailer_previews" + # + # An overview of all previews is accessible at http://localhost:3000/rails/mailers + # on a running development server instance. + # + # Previews can also be intercepted in a similar manner as deliveries can be by registering + # a preview interceptor that has a previewing_email method: + # + # class CssInlineStyler + # def self.previewing_email(message) + # # inline CSS styles + # end + # end + # + # config.action_mailer.preview_interceptors :css_inline_styler + # + # Note that interceptors need to be registered both with register_interceptor + # and register_preview_interceptor if they should operate on both sending and + # previewing emails. + # + # = Configuration options + # + # These options are specified on the class level, like + # ActionMailer::Base.raise_delivery_errors = true + # + # * default_options - You can pass this in at a class level as well as within the class itself as + # per the above section. + # + # * logger - the logger is used for generating information on the mailing run if available. + # Can be set to +nil+ for no logging. Compatible with both Ruby's own +Logger+ and Log4r loggers. + # + # * smtp_settings - Allows detailed configuration for :smtp delivery method: + # * :address - Allows you to use a remote mail server. Just change it from its default + # "localhost" setting. + # * :port - On the off chance that your mail server doesn't run on port 25, you can change it. + # * :domain - If you need to specify a HELO domain, you can do it here. + # * :user_name - If your mail server requires authentication, set the username in this setting. + # * :password - If your mail server requires authentication, set the password in this setting. + # * :authentication - If your mail server requires authentication, you need to specify the + # authentication type here. + # This is a symbol and one of :plain (will send the password Base64 encoded), :login (will + # send the password Base64 encoded) or :cram_md5 (combines a Challenge/Response mechanism to exchange + # information and a cryptographic Message Digest 5 algorithm to hash important information) + # * :enable_starttls_auto - Detects if STARTTLS is enabled in your SMTP server and starts + # to use it. Defaults to true. + # * :openssl_verify_mode - When using TLS, you can set how OpenSSL checks the certificate. This is + # really useful if you need to validate a self-signed and/or a wildcard certificate. You can use the name + # of an OpenSSL verify constant ('none', 'peer', 'client_once', + # 'fail_if_no_peer_cert') or directly the constant (OpenSSL::SSL::VERIFY_NONE, + # OpenSSL::SSL::VERIFY_PEER, ...). + # + # * sendmail_settings - Allows you to override options for the :sendmail delivery method. + # * :location - The location of the sendmail executable. Defaults to /usr/sbin/sendmail. + # * :arguments - The command line arguments. Defaults to -i -t with -f sender@address + # added automatically before the message is sent. + # + # * file_settings - Allows you to override options for the :file delivery method. + # * :location - The directory into which emails will be written. Defaults to the application + # tmp/mails. + # + # * raise_delivery_errors - Whether or not errors should be raised if the email fails to be delivered. + # + # * delivery_method - Defines a delivery method. Possible values are :smtp (default), + # :sendmail, :test, and :file. Or you may provide a custom delivery method + # object e.g. +MyOwnDeliveryMethodClass+. See the Mail gem documentation on the interface you need to + # implement for a custom delivery agent. + # + # * perform_deliveries - Determines whether emails are actually sent from Action Mailer when you + # call .deliver on an email message or on an Action Mailer method. This is on by default but can + # be turned off to aid in functional testing. + # + # * deliveries - Keeps an array of all the emails sent out through the Action Mailer with + # delivery_method :test. Most useful for unit and functional testing. + class Base < AbstractController::Base + include DeliveryMethods + include Previews + + abstract! + + include AbstractController::Rendering + + include AbstractController::Logger + include AbstractController::Helpers + include AbstractController::Translation + include AbstractController::AssetPaths + include AbstractController::Callbacks + + include ActionView::Layouts + + PROTECTED_IVARS = AbstractController::Rendering::DEFAULT_PROTECTED_INSTANCE_VARIABLES + [:@_action_has_layout] + + def _protected_ivars # :nodoc: + PROTECTED_IVARS + end + + helper ActionMailer::MailHelper + + private_class_method :new #:nodoc: + + class_attribute :default_params + self.default_params = { + mime_version: "1.0", + charset: "UTF-8", + content_type: "text/plain", + parts_order: [ "text/plain", "text/enriched", "text/html" ] + }.freeze + + class << self + # Register one or more Observers which will be notified when mail is delivered. + def register_observers(*observers) + observers.flatten.compact.each { |observer| register_observer(observer) } + end + + # Register one or more Interceptors which will be called before mail is sent. + def register_interceptors(*interceptors) + interceptors.flatten.compact.each { |interceptor| register_interceptor(interceptor) } + end + + # Register an Observer which will be notified when mail is delivered. + # Either a class, string or symbol can be passed in as the Observer. + # If a string or symbol is passed in it will be camelized and constantized. + def register_observer(observer) + delivery_observer = case observer + when String, Symbol + observer.to_s.camelize.constantize + else + observer + end + + Mail.register_observer(delivery_observer) + end + + # Register an Interceptor which will be called before mail is sent. + # Either a class, string or symbol can be passed in as the Interceptor. + # If a string or symbol is passed in it will be camelized and constantized. + def register_interceptor(interceptor) + delivery_interceptor = case interceptor + when String, Symbol + interceptor.to_s.camelize.constantize + else + interceptor + end + + Mail.register_interceptor(delivery_interceptor) + end + + # Returns the name of current mailer. This method is also being used as a path for a view lookup. + # If this is an anonymous mailer, this method will return +anonymous+ instead. + def mailer_name + @mailer_name ||= anonymous? ? "anonymous" : name.underscore + end + # Allows to set the name of current mailer. + attr_writer :mailer_name + alias :controller_path :mailer_name + + # Sets the defaults through app configuration: + # + # config.action_mailer.default(from: "no-reply@example.org") + # + # Aliased by ::default_options= + def default(value = nil) + self.default_params = default_params.merge(value).freeze if value + default_params + end + # Allows to set defaults through app configuration: + # + # config.action_mailer.default_options = { from: "no-reply@example.org" } + alias :default_options= :default + + # Receives a raw email, parses it into an email object, decodes it, + # instantiates a new mailer, and passes the email object to the mailer + # object's +receive+ method. + # + # If you want your mailer to be able to process incoming messages, you'll + # need to implement a +receive+ method that accepts the raw email string + # as a parameter: + # + # class MyMailer < ActionMailer::Base + # def receive(mail) + # # ... + # end + # end + def receive(raw_mail) + ActiveSupport::Notifications.instrument("receive.action_mailer") do |payload| + mail = Mail.new(raw_mail) + set_payload_for_mail(payload, mail) + new.receive(mail) + end + end + + # Wraps an email delivery inside of ActiveSupport::Notifications instrumentation. + # + # This method is actually called by the Mail::Message object itself + # through a callback when you call :deliver on the Mail::Message, + # calling +deliver_mail+ directly and passing a Mail::Message will do + # nothing except tell the logger you sent the email. + def deliver_mail(mail) #:nodoc: + ActiveSupport::Notifications.instrument("deliver.action_mailer") do |payload| + set_payload_for_mail(payload, mail) + yield # Let Mail do the delivery actions + end + end + + def respond_to?(method, include_private = false) #:nodoc: + super || action_methods.include?(method.to_s) + end + + protected + + def set_payload_for_mail(payload, mail) #:nodoc: + payload[:mailer] = name + payload[:message_id] = mail.message_id + payload[:subject] = mail.subject + payload[:to] = mail.to + payload[:from] = mail.from + payload[:bcc] = mail.bcc if mail.bcc.present? + payload[:cc] = mail.cc if mail.cc.present? + payload[:date] = mail.date + payload[:mail] = mail.encoded + end + + def method_missing(method_name, *args) # :nodoc: + if action_methods.include?(method_name.to_s) + MessageDelivery.new(self, method_name, *args) + else + super + end + end + end + + attr_internal :message + + # Instantiate a new mailer object. If +method_name+ is not +nil+, the mailer + # will be initialized according to the named method. If not, the mailer will + # remain uninitialized (useful when you only need to invoke the "receive" + # method, for instance). + def initialize(method_name=nil, *args) + super() + @_mail_was_called = false + @_message = Mail.new + process(method_name, *args) if method_name + end + + def process(method_name, *args) #:nodoc: + payload = { + mailer: self.class.name, + action: method_name + } + + ActiveSupport::Notifications.instrument("process.action_mailer", payload) do + lookup_context.skip_default_locale! + + super + @_message = NullMail.new unless @_mail_was_called + end + end + + class NullMail #:nodoc: + def body; '' end + def header; {} end + + def respond_to?(string, include_all=false) + true + end + + def method_missing(*args) + nil + end + end + + # Returns the name of the mailer object. + def mailer_name + self.class.mailer_name + end + + # Allows you to pass random and unusual headers to the new Mail::Message + # object which will add them to itself. + # + # headers['X-Special-Domain-Specific-Header'] = "SecretValue" + # + # You can also pass a hash into headers of header field names and values, + # which will then be set on the Mail::Message object: + # + # headers 'X-Special-Domain-Specific-Header' => "SecretValue", + # 'In-Reply-To' => incoming.message_id + # + # The resulting Mail::Message will have the following in its header: + # + # X-Special-Domain-Specific-Header: SecretValue + # + # Note about replacing already defined headers: + # + # * +subject+ + # * +sender+ + # * +from+ + # * +to+ + # * +cc+ + # * +bcc+ + # * +reply-to+ + # * +orig-date+ + # * +message-id+ + # * +references+ + # + # Fields can only appear once in email headers while other fields such as + # X-Anything can appear multiple times. + # + # If you want to replace any header which already exists, first set it to + # +nil+ in order to reset the value otherwise another field will be added + # for the same header. + def headers(args = nil) + if args + @_message.headers(args) + else + @_message + end + end + + # Allows you to add attachments to an email, like so: + # + # mail.attachments['filename.jpg'] = File.read('/path/to/filename.jpg') + # + # If you do this, then Mail will take the file name and work out the mime type + # set the Content-Type, Content-Disposition, Content-Transfer-Encoding and + # base64 encode the contents of the attachment all for you. + # + # You can also specify overrides if you want by passing a hash instead of a string: + # + # mail.attachments['filename.jpg'] = {mime_type: 'application/x-gzip', + # content: File.read('/path/to/filename.jpg')} + # + # If you want to use a different encoding than Base64, you can pass an encoding in, + # but then it is up to you to pass in the content pre-encoded, and don't expect + # Mail to know how to decode this data: + # + # file_content = SpecialEncode(File.read('/path/to/filename.jpg')) + # mail.attachments['filename.jpg'] = {mime_type: 'application/x-gzip', + # encoding: 'SpecialEncoding', + # content: file_content } + # + # You can also search for specific attachments: + # + # # By Filename + # mail.attachments['filename.jpg'] # => Mail::Part object or nil + # + # # or by index + # mail.attachments[0] # => Mail::Part (first attachment) + # + def attachments + if @_mail_was_called + LateAttachmentsProxy.new(@_message.attachments) + else + @_message.attachments + end + end + + class LateAttachmentsProxy < SimpleDelegator + def inline; _raise_error end + def []=(_name, _content); _raise_error end + + private + def _raise_error + raise RuntimeError, "Can't add attachments after `mail` was called.\n" \ + "Make sure to use `attachments[]=` before calling `mail`." + end + end + + # The main method that creates the message and renders the email templates. There are + # two ways to call this method, with a block, or without a block. + # + # It accepts a headers hash. This hash allows you to specify + # the most used headers in an email message, these are: + # + # * +:subject+ - The subject of the message, if this is omitted, Action Mailer will + # ask the Rails I18n class for a translated +:subject+ in the scope of + # [mailer_scope, action_name] or if this is missing, will translate the + # humanized version of the +action_name+ + # * +:to+ - Who the message is destined for, can be a string of addresses, or an array + # of addresses. + # * +:from+ - Who the message is from + # * +:cc+ - Who you would like to Carbon-Copy on this email, can be a string of addresses, + # or an array of addresses. + # * +:bcc+ - Who you would like to Blind-Carbon-Copy on this email, can be a string of + # addresses, or an array of addresses. + # * +:reply_to+ - Who to set the Reply-To header of the email to. + # * +:date+ - The date to say the email was sent on. + # + # You can set default values for any of the above headers (except +:date+) + # by using the ::default class method: + # + # class Notifier < ActionMailer::Base + # default from: 'no-reply@test.lindsaar.net', + # bcc: 'email_logger@test.lindsaar.net', + # reply_to: 'bounces@test.lindsaar.net' + # end + # + # If you need other headers not listed above, you can either pass them in + # as part of the headers hash or use the headers['name'] = value + # method. + # + # When a +:return_path+ is specified as header, that value will be used as + # the 'envelope from' address for the Mail message. Setting this is useful + # when you want delivery notifications sent to a different address than the + # one in +:from+. Mail will actually use the +:return_path+ in preference + # to the +:sender+ in preference to the +:from+ field for the 'envelope + # from' value. + # + # If you do not pass a block to the +mail+ method, it will find all + # templates in the view paths using by default the mailer name and the + # method name that it is being called from, it will then create parts for + # each of these templates intelligently, making educated guesses on correct + # content type and sequence, and return a fully prepared Mail::Message + # ready to call :deliver on to send. + # + # For example: + # + # class Notifier < ActionMailer::Base + # default from: 'no-reply@test.lindsaar.net' + # + # def welcome + # mail(to: 'mikel@test.lindsaar.net') + # end + # end + # + # Will look for all templates at "app/views/notifier" with name "welcome". + # If no welcome template exists, it will raise an ActionView::MissingTemplate error. + # + # However, those can be customized: + # + # mail(template_path: 'notifications', template_name: 'another') + # + # And now it will look for all templates at "app/views/notifications" with name "another". + # + # If you do pass a block, you can render specific templates of your choice: + # + # mail(to: 'mikel@test.lindsaar.net') do |format| + # format.text + # format.html + # end + # + # You can even render plain text directly without using a template: + # + # mail(to: 'mikel@test.lindsaar.net') do |format| + # format.text { render plain: "Hello Mikel!" } + # format.html { render html: "

Hello Mikel!

".html_safe } + # end + # + # Which will render a +multipart/alternative+ email with +text/plain+ and + # +text/html+ parts. + # + # The block syntax also allows you to customize the part headers if desired: + # + # mail(to: 'mikel@test.lindsaar.net') do |format| + # format.text(content_transfer_encoding: "base64") + # format.html + # end + # + def mail(headers = {}, &block) + return @_message if @_mail_was_called && headers.blank? && !block + + m = @_message + + # At the beginning, do not consider class default for content_type + content_type = headers[:content_type] + + # Call all the procs (if any) + default_values = {} + self.class.default.each do |k,v| + default_values[k] = v.is_a?(Proc) ? instance_eval(&v) : v + end + + # Handle defaults + headers = headers.reverse_merge(default_values) + headers[:subject] ||= default_i18n_subject + + # Apply charset at the beginning so all fields are properly quoted + m.charset = charset = headers[:charset] + + # Set configure delivery behavior + wrap_delivery_behavior!(headers.delete(:delivery_method), headers.delete(:delivery_method_options)) + + # Assign all headers except parts_order, content_type and body + assignable = headers.except(:parts_order, :content_type, :body, :template_name, :template_path) + assignable.each { |k, v| m[k] = v } + + # Render the templates and blocks + responses = collect_responses(headers, &block) + @_mail_was_called = true + + create_parts_from_responses(m, responses) + + # Setup content type, reapply charset and handle parts order + m.content_type = set_content_type(m, content_type, headers[:content_type]) + m.charset = charset + + if m.multipart? + m.body.set_sort_order(headers[:parts_order]) + m.body.sort_parts! + end + + m + end + + protected + + # Used by #mail to set the content type of the message. + # + # It will use the given +user_content_type+, or multipart if the mail + # message has any attachments. If the attachments are inline, the content + # type will be "multipart/related", otherwise "multipart/mixed". + # + # If there is no content type passed in via headers, and there are no + # attachments, or the message is multipart, then the default content type is + # used. + def set_content_type(m, user_content_type, class_default) + params = m.content_type_parameters || {} + case + when user_content_type.present? + user_content_type + when m.has_attachments? + if m.attachments.detect { |a| a.inline? } + ["multipart", "related", params] + else + ["multipart", "mixed", params] + end + when m.multipart? + ["multipart", "alternative", params] + else + m.content_type || class_default + end + end + + # Translates the +subject+ using Rails I18n class under [mailer_scope, action_name] scope. + # If it does not find a translation for the +subject+ under the specified scope it will default to a + # humanized version of the action_name. + # If the subject has interpolations, you can pass them through the +interpolations+ parameter. + def default_i18n_subject(interpolations = {}) + mailer_scope = self.class.mailer_name.tr('/', '.') + I18n.t(:subject, interpolations.merge(scope: [mailer_scope, action_name], default: action_name.humanize)) + end + + def collect_responses(headers) #:nodoc: + responses = [] + + if block_given? + collector = ActionMailer::Collector.new(lookup_context) { render(action_name) } + yield(collector) + responses = collector.responses + elsif headers[:body] + responses << { + body: headers.delete(:body), + content_type: self.class.default[:content_type] || "text/plain" + } + else + templates_path = headers.delete(:template_path) || self.class.mailer_name + templates_name = headers.delete(:template_name) || action_name + + each_template(Array(templates_path), templates_name) do |template| + self.formats = template.formats + + responses << { + body: render(template: template), + content_type: template.type.to_s + } + end + end + + responses + end + + def each_template(paths, name, &block) #:nodoc: + templates = lookup_context.find_all(name, paths) + if templates.empty? + raise ActionView::MissingTemplate.new(paths, name, paths, false, 'mailer') + else + templates.uniq { |t| t.formats }.each(&block) + end + end + + def create_parts_from_responses(m, responses) #:nodoc: + if responses.size == 1 && !m.has_attachments? + responses[0].each { |k,v| m[k] = v } + elsif responses.size > 1 && m.has_attachments? + container = Mail::Part.new + container.content_type = "multipart/alternative" + responses.each { |r| insert_part(container, r, m.charset) } + m.add_part(container) + else + responses.each { |r| insert_part(m, r, m.charset) } + end + end + + def insert_part(container, response, charset) #:nodoc: + response[:charset] ||= charset + part = Mail::Part.new(response) + container.add_part(part) + end + + # Emails do not support relative path links. + def self.supports_path? + false + end + + ActiveSupport.run_load_hooks(:action_mailer, self) + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/action_mailer/collector.rb b/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/action_mailer/collector.rb new file mode 100644 index 0000000..e8883a8 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/action_mailer/collector.rb @@ -0,0 +1,30 @@ +require 'abstract_controller/collector' +require 'active_support/core_ext/hash/reverse_merge' +require 'active_support/core_ext/array/extract_options' + +module ActionMailer + class Collector + include AbstractController::Collector + attr_reader :responses + + def initialize(context, &block) + @context = context + @responses = [] + @default_render = block + end + + def any(*args, &block) + options = args.extract_options! + raise ArgumentError, "You have to supply at least one format" if args.empty? + args.each { |type| send(type, options.dup, &block) } + end + alias :all :any + + def custom(mime, options = {}) + options.reverse_merge!(content_type: mime.to_s) + @context.formats = [mime.to_sym] + options[:body] = block_given? ? yield : @default_render.call + @responses << options + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/action_mailer/delivery_job.rb b/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/action_mailer/delivery_job.rb new file mode 100644 index 0000000..169c461 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/action_mailer/delivery_job.rb @@ -0,0 +1,13 @@ +require 'active_job' + +module ActionMailer + # The ActionMailer::DeliveryJob class is used when you + # want to send emails outside of the request-response cycle. + class DeliveryJob < ActiveJob::Base # :nodoc: + queue_as :mailers + + def perform(mailer, mail_method, delivery_method, *args) # :nodoc: + mailer.constantize.public_send(mail_method, *args).send(delivery_method) + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/action_mailer/delivery_methods.rb b/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/action_mailer/delivery_methods.rb new file mode 100644 index 0000000..aedcd81 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/action_mailer/delivery_methods.rb @@ -0,0 +1,84 @@ +require 'tmpdir' + +module ActionMailer + # This module handles everything related to mail delivery, from registering + # new delivery methods to configuring the mail object to be sent. + module DeliveryMethods + extend ActiveSupport::Concern + + included do + class_attribute :delivery_methods, :delivery_method + + # Do not make this inheritable, because we always want it to propagate + cattr_accessor :raise_delivery_errors + self.raise_delivery_errors = true + + cattr_accessor :perform_deliveries + self.perform_deliveries = true + + self.delivery_methods = {}.freeze + self.delivery_method = :smtp + + add_delivery_method :smtp, Mail::SMTP, + address: "localhost", + port: 25, + domain: 'localhost.localdomain', + user_name: nil, + password: nil, + authentication: nil, + enable_starttls_auto: true + + add_delivery_method :file, Mail::FileDelivery, + location: defined?(Rails.root) ? "#{Rails.root}/tmp/mails" : "#{Dir.tmpdir}/mails" + + add_delivery_method :sendmail, Mail::Sendmail, + location: '/usr/sbin/sendmail', + arguments: '-i -t' + + add_delivery_method :test, Mail::TestMailer + end + + # Helpers for creating and wrapping delivery behavior, used by DeliveryMethods. + module ClassMethods + # Provides a list of emails that have been delivered by Mail::TestMailer + delegate :deliveries, :deliveries=, to: Mail::TestMailer + + # Adds a new delivery method through the given class using the given + # symbol as alias and the default options supplied. + # + # add_delivery_method :sendmail, Mail::Sendmail, + # location: '/usr/sbin/sendmail', + # arguments: '-i -t' + def add_delivery_method(symbol, klass, default_options={}) + class_attribute(:"#{symbol}_settings") unless respond_to?(:"#{symbol}_settings") + send(:"#{symbol}_settings=", default_options) + self.delivery_methods = delivery_methods.merge(symbol.to_sym => klass).freeze + end + + def wrap_delivery_behavior(mail, method=nil, options=nil) # :nodoc: + method ||= self.delivery_method + mail.delivery_handler = self + + case method + when NilClass + raise "Delivery method cannot be nil" + when Symbol + if klass = delivery_methods[method] + mail.delivery_method(klass, (send(:"#{method}_settings") || {}).merge(options || {})) + else + raise "Invalid delivery method #{method.inspect}" + end + else + mail.delivery_method(method) + end + + mail.perform_deliveries = perform_deliveries + mail.raise_delivery_errors = raise_delivery_errors + end + end + + def wrap_delivery_behavior!(*args) # :nodoc: + self.class.wrap_delivery_behavior(message, *args) + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/action_mailer/gem_version.rb b/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/action_mailer/gem_version.rb new file mode 100644 index 0000000..16c36b6 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/action_mailer/gem_version.rb @@ -0,0 +1,15 @@ +module ActionMailer + # Returns the version of the currently loaded Action Mailer as a Gem::Version + def self.gem_version + Gem::Version.new VERSION::STRING + end + + module VERSION + MAJOR = 4 + MINOR = 2 + TINY = 6 + PRE = nil + + STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".") + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/action_mailer/inline_preview_interceptor.rb b/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/action_mailer/inline_preview_interceptor.rb new file mode 100644 index 0000000..a6744a0 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/action_mailer/inline_preview_interceptor.rb @@ -0,0 +1,61 @@ +require 'base64' + +module ActionMailer + # Implements a mailer preview interceptor that converts image tag src attributes + # that use inline cid: style urls to data: style urls so that they are visible + # when previewing a HTML email in a web browser. + # + # This interceptor is not enabled by default, to use it just register it like any + # other mailer preview interceptor: + # + # ActionMailer::Base.register_preview_interceptor(ActionMailer::InlinePreviewInterceptor) + # + class InlinePreviewInterceptor + PATTERN = /src=(?:"cid:[^"]+"|'cid:[^']+')/i + + include Base64 + + def self.previewing_email(message) #:nodoc: + new(message).transform! + end + + def initialize(message) #:nodoc: + @message = message + end + + def transform! #:nodoc: + return message if html_part.blank? + + html_source.gsub!(PATTERN) do |match| + if part = find_part(match[9..-2]) + %[src="#{data_url(part)}"] + else + match + end + end + + message + end + + private + def message + @message + end + + def html_part + @html_part ||= message.html_part + end + + def html_source + html_part.body.raw_source + end + + def data_url(part) + "data:#{part.mime_type};base64,#{strict_encode64(part.body.raw_source)}" + end + + def find_part(cid) + message.all_parts.find{ |p| p.attachment? && p.cid == cid } + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/action_mailer/log_subscriber.rb b/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/action_mailer/log_subscriber.rb new file mode 100644 index 0000000..5b57c75 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/action_mailer/log_subscriber.rb @@ -0,0 +1,39 @@ +require 'active_support/log_subscriber' + +module ActionMailer + # Implements the ActiveSupport::LogSubscriber for logging notifications when + # email is delivered and received. + class LogSubscriber < ActiveSupport::LogSubscriber + # An email was delivered. + def deliver(event) + info do + recipients = Array(event.payload[:to]).join(', ') + "\nSent mail to #{recipients} (#{event.duration.round(1)}ms)" + end + + debug { event.payload[:mail] } + end + + # An email was received. + def receive(event) + info { "\nReceived mail (#{event.duration.round(1)}ms)" } + debug { event.payload[:mail] } + end + + # An email was generated. + def process(event) + debug do + mailer = event.payload[:mailer] + action = event.payload[:action] + "\n#{mailer}##{action}: processed outbound mail in #{event.duration.round(1)}ms" + end + end + + # Use the logger configured for ActionMailer::Base + def logger + ActionMailer::Base.logger + end + end +end + +ActionMailer::LogSubscriber.attach_to :action_mailer diff --git a/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/action_mailer/mail_helper.rb b/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/action_mailer/mail_helper.rb new file mode 100644 index 0000000..cc7935a --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/action_mailer/mail_helper.rb @@ -0,0 +1,58 @@ +module ActionMailer + # Provides helper methods for ActionMailer::Base that can be used for easily + # formatting messages, accessing mailer or message instances, and the + # attachments list. + module MailHelper + # Take the text and format it, indented two spaces for each line, and + # wrapped at 72 columns. + def block_format(text) + formatted = text.split(/\n\r?\n/).collect { |paragraph| + format_paragraph(paragraph) + }.join("\n\n") + + # Make list points stand on their own line + formatted.gsub!(/[ ]*([*]+) ([^*]*)/) { " #{$1} #{$2.strip}\n" } + formatted.gsub!(/[ ]*([#]+) ([^#]*)/) { " #{$1} #{$2.strip}\n" } + + formatted + end + + # Access the mailer instance. + def mailer + @_controller + end + + # Access the message instance. + def message + @_message + end + + # Access the message attachments list. + def attachments + mailer.attachments + end + + # Returns +text+ wrapped at +len+ columns and indented +indent+ spaces. + # + # my_text = 'Here is a sample text with more than 40 characters' + # + # format_paragraph(my_text, 25, 4) + # # => " Here is a sample text with\n more than 40 characters" + def format_paragraph(text, len = 72, indent = 2) + sentences = [[]] + + text.split.each do |word| + if sentences.first.present? && (sentences.last + [word]).join(' ').length > len + sentences << [word] + else + sentences.last << word + end + end + + indentation = " " * indent + sentences.map! { |sentence| + "#{indentation}#{sentence.join(' ')}" + }.join "\n" + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/action_mailer/message_delivery.rb b/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/action_mailer/message_delivery.rb new file mode 100644 index 0000000..b5dc2d7 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/action_mailer/message_delivery.rb @@ -0,0 +1,115 @@ +require 'delegate' +require 'active_support/core_ext/string/filters' + +module ActionMailer + + # The ActionMailer::MessageDelivery class is used by + # ActionMailer::Base when creating a new mailer. + # MessageDelivery is a wrapper (+Delegator+ subclass) around a lazy + # created Mail::Message. You can get direct access to the + # Mail::Message, deliver the email or schedule the email to be sent + # through Active Job. + # + # Notifier.welcome(User.first) # an ActionMailer::MessageDelivery object + # Notifier.welcome(User.first).deliver_now # sends the email + # Notifier.welcome(User.first).deliver_later # enqueue email delivery as a job through Active Job + # Notifier.welcome(User.first).message # a Mail::Message object + class MessageDelivery < Delegator + def initialize(mailer, mail_method, *args) #:nodoc: + @mailer = mailer + @mail_method = mail_method + @args = args + end + + def __getobj__ #:nodoc: + @obj ||= @mailer.send(:new, @mail_method, *@args).message + end + + def __setobj__(obj) #:nodoc: + @obj = obj + end + + # Returns the Mail::Message object + def message + __getobj__ + end + + # Enqueues the email to be delivered through Active Job. When the + # job runs it will send the email using +deliver_now!+. That means + # that the message will be sent bypassing checking +perform_deliveries+ + # and +raise_delivery_errors+, so use with caution. + # + # Notifier.welcome(User.first).deliver_later! + # Notifier.welcome(User.first).deliver_later!(wait: 1.hour) + # Notifier.welcome(User.first).deliver_later!(wait_until: 10.hours.from_now) + # + # Options: + # + # * :wait - Enqueue the email to be delivered with a delay + # * :wait_until - Enqueue the email to be delivered at (after) a specific date / time + # * :queue - Enqueue the email on the specified queue + def deliver_later!(options={}) + enqueue_delivery :deliver_now!, options + end + + # Enqueues the email to be delivered through Active Job. When the + # job runs it will send the email using +deliver_now+. + # + # Notifier.welcome(User.first).deliver_later + # Notifier.welcome(User.first).deliver_later(wait: 1.hour) + # Notifier.welcome(User.first).deliver_later(wait_until: 10.hours.from_now) + # + # Options: + # + # * :wait - Enqueue the email to be delivered with a delay + # * :wait_until - Enqueue the email to be delivered at (after) a specific date / time + # * :queue - Enqueue the email on the specified queue + def deliver_later(options={}) + enqueue_delivery :deliver_now, options + end + + # Delivers an email without checking +perform_deliveries+ and +raise_delivery_errors+, + # so use with caution. + # + # Notifier.welcome(User.first).deliver_now! + # + def deliver_now! + message.deliver! + end + + # Delivers an email: + # + # Notifier.welcome(User.first).deliver_now + # + def deliver_now + message.deliver + end + + def deliver! #:nodoc: + ActiveSupport::Deprecation.warn(<<-MSG.squish) + `#deliver!` is deprecated and will be removed in Rails 5. Use + `#deliver_now!` to deliver immediately or `#deliver_later!` to + deliver through Active Job. + MSG + + deliver_now! + end + + def deliver #:nodoc: + ActiveSupport::Deprecation.warn(<<-MSG.squish) + `#deliver` is deprecated and will be removed in Rails 5. Use + `#deliver_now` to deliver immediately or `#deliver_later` to + deliver through Active Job. + MSG + + deliver_now + end + + private + + def enqueue_delivery(delivery_method, options={}) + args = @mailer.name, @mail_method.to_s, delivery_method.to_s, *@args + ActionMailer::DeliveryJob.set(options).perform_later(*args) + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/action_mailer/preview.rb b/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/action_mailer/preview.rb new file mode 100644 index 0000000..44cf666 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/action_mailer/preview.rb @@ -0,0 +1,118 @@ +require 'active_support/descendants_tracker' + +module ActionMailer + module Previews #:nodoc: + extend ActiveSupport::Concern + + included do + # Set the location of mailer previews through app configuration: + # + # config.action_mailer.preview_path = "#{Rails.root}/lib/mailer_previews" + # + mattr_accessor :preview_path, instance_writer: false + + # Enable or disable mailer previews through app configuration: + # + # config.action_mailer.show_previews = true + # + # Defaults to true for development environment + # + mattr_accessor :show_previews, instance_writer: false + + # :nodoc: + mattr_accessor :preview_interceptors, instance_writer: false + self.preview_interceptors = [] + end + + module ClassMethods + # Register one or more Interceptors which will be called before mail is previewed. + def register_preview_interceptors(*interceptors) + interceptors.flatten.compact.each { |interceptor| register_preview_interceptor(interceptor) } + end + + # Register an Interceptor which will be called before mail is previewed. + # Either a class or a string can be passed in as the Interceptor. If a + # string is passed in it will be constantized. + def register_preview_interceptor(interceptor) + preview_interceptor = case interceptor + when String, Symbol + interceptor.to_s.camelize.constantize + else + interceptor + end + + unless preview_interceptors.include?(preview_interceptor) + preview_interceptors << preview_interceptor + end + end + end + end + + class Preview + extend ActiveSupport::DescendantsTracker + + class << self + # Returns all mailer preview classes + def all + load_previews if descendants.empty? + descendants + end + + # Returns the mail object for the given email name. The registered preview + # interceptors will be informed so that they can transform the message + # as they would if the mail was actually being delivered. + def call(email) + preview = self.new + message = preview.public_send(email) + inform_preview_interceptors(message) + message + end + + # Returns all of the available email previews + def emails + public_instance_methods(false).map(&:to_s).sort + end + + # Returns true if the email exists + def email_exists?(email) + emails.include?(email) + end + + # Returns true if the preview exists + def exists?(preview) + all.any?{ |p| p.preview_name == preview } + end + + # Find a mailer preview by its underscored class name + def find(preview) + all.find{ |p| p.preview_name == preview } + end + + # Returns the underscored name of the mailer preview without the suffix + def preview_name + name.sub(/Preview$/, '').underscore + end + + protected + def load_previews #:nodoc: + if preview_path + Dir["#{preview_path}/**/*_preview.rb"].each{ |file| require_dependency file } + end + end + + def preview_path #:nodoc: + Base.preview_path + end + + def show_previews #:nodoc: + Base.show_previews + end + + def inform_preview_interceptors(message) #:nodoc: + Base.preview_interceptors.each do |interceptor| + interceptor.previewing_email(message) + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/action_mailer/railtie.rb b/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/action_mailer/railtie.rb new file mode 100644 index 0000000..05a3ac6 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/action_mailer/railtie.rb @@ -0,0 +1,64 @@ +require 'active_job/railtie' +require "action_mailer" +require "rails" +require "abstract_controller/railties/routes_helpers" + +module ActionMailer + class Railtie < Rails::Railtie # :nodoc: + config.action_mailer = ActiveSupport::OrderedOptions.new + config.eager_load_namespaces << ActionMailer + + initializer "action_mailer.logger" do + ActiveSupport.on_load(:action_mailer) { self.logger ||= Rails.logger } + end + + initializer "action_mailer.set_configs" do |app| + paths = app.config.paths + options = app.config.action_mailer + + options.assets_dir ||= paths["public"].first + options.javascripts_dir ||= paths["public/javascripts"].first + options.stylesheets_dir ||= paths["public/stylesheets"].first + options.show_previews = Rails.env.development? if options.show_previews.nil? + + if options.show_previews + options.preview_path ||= defined?(Rails.root) ? "#{Rails.root}/test/mailers/previews" : nil + end + + # make sure readers methods get compiled + options.asset_host ||= app.config.asset_host + options.relative_url_root ||= app.config.relative_url_root + + ActiveSupport.on_load(:action_mailer) do + include AbstractController::UrlFor + extend ::AbstractController::Railties::RoutesHelpers.with(app.routes, false) + include app.routes.mounted_helpers + + register_interceptors(options.delete(:interceptors)) + register_preview_interceptors(options.delete(:preview_interceptors)) + register_observers(options.delete(:observers)) + + options.each { |k,v| send("#{k}=", v) } + + if options.show_previews + app.routes.append do + get '/rails/mailers' => "rails/mailers#index" + get '/rails/mailers/*path' => "rails/mailers#preview" + end + end + end + end + + initializer "action_mailer.compile_config_methods" do + ActiveSupport.on_load(:action_mailer) do + config.compile_methods! if config.respond_to?(:compile_methods!) + end + end + + config.after_initialize do + if ActionMailer::Base.preview_path + ActiveSupport::Dependencies.autoload_paths << ActionMailer::Base.preview_path + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/action_mailer/test_case.rb b/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/action_mailer/test_case.rb new file mode 100644 index 0000000..766215c --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/action_mailer/test_case.rb @@ -0,0 +1,104 @@ +require 'active_support/test_case' +require 'rails-dom-testing' + +module ActionMailer + class NonInferrableMailerError < ::StandardError + def initialize(name) + super "Unable to determine the mailer to test from #{name}. " + + "You'll need to specify it using tests YourMailer in your " + + "test case definition" + end + end + + class TestCase < ActiveSupport::TestCase + module Behavior + extend ActiveSupport::Concern + + include ActiveSupport::Testing::ConstantLookup + include TestHelper + include Rails::Dom::Testing::Assertions::SelectorAssertions + include Rails::Dom::Testing::Assertions::DomAssertions + + included do + class_attribute :_mailer_class + setup :initialize_test_deliveries + setup :set_expected_mail + teardown :restore_test_deliveries + end + + module ClassMethods + def tests(mailer) + case mailer + when String, Symbol + self._mailer_class = mailer.to_s.camelize.constantize + when Module + self._mailer_class = mailer + else + raise NonInferrableMailerError.new(mailer) + end + end + + def mailer_class + if mailer = self._mailer_class + mailer + else + tests determine_default_mailer(name) + end + end + + def determine_default_mailer(name) + mailer = determine_constant_from_test_name(name) do |constant| + Class === constant && constant < ActionMailer::Base + end + raise NonInferrableMailerError.new(name) if mailer.nil? + mailer + end + end + + protected + + def initialize_test_deliveries + set_delivery_method :test + @old_perform_deliveries = ActionMailer::Base.perform_deliveries + ActionMailer::Base.perform_deliveries = true + end + + def restore_test_deliveries + restore_delivery_method + ActionMailer::Base.perform_deliveries = @old_perform_deliveries + ActionMailer::Base.deliveries.clear + end + + def set_delivery_method(method) + @old_delivery_method = ActionMailer::Base.delivery_method + ActionMailer::Base.delivery_method = method + end + + def restore_delivery_method + ActionMailer::Base.delivery_method = @old_delivery_method + end + + def set_expected_mail + @expected = Mail.new + @expected.content_type ["text", "plain", { "charset" => charset }] + @expected.mime_version = '1.0' + end + + private + + def charset + "UTF-8" + end + + def encode(subject) + Mail::Encodings.q_value_encode(subject, charset) + end + + def read_fixture(action) + IO.readlines(File.join(Rails.root, 'test', 'fixtures', self.class.mailer_class.name.underscore, action)) + end + end + + include Behavior + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/action_mailer/test_helper.rb b/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/action_mailer/test_helper.rb new file mode 100644 index 0000000..54e75f1 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/action_mailer/test_helper.rb @@ -0,0 +1,62 @@ +module ActionMailer + # Provides helper methods for testing Action Mailer, including #assert_emails + # and #assert_no_emails + module TestHelper + # Asserts that the number of emails sent matches the given number. + # + # def test_emails + # assert_emails 0 + # ContactMailer.welcome.deliver_now + # assert_emails 1 + # ContactMailer.welcome.deliver_now + # assert_emails 2 + # end + # + # If a block is passed, that block should cause the specified number of + # emails to be sent. + # + # def test_emails_again + # assert_emails 1 do + # ContactMailer.welcome.deliver_now + # end + # + # assert_emails 2 do + # ContactMailer.welcome.deliver_now + # ContactMailer.welcome.deliver_now + # end + # end + def assert_emails(number) + if block_given? + original_count = ActionMailer::Base.deliveries.size + yield + new_count = ActionMailer::Base.deliveries.size + assert_equal number, new_count - original_count, "#{number} emails expected, but #{new_count - original_count} were sent" + else + assert_equal number, ActionMailer::Base.deliveries.size + end + end + + # Assert that no emails have been sent. + # + # def test_emails + # assert_no_emails + # ContactMailer.welcome.deliver_now + # assert_emails 1 + # end + # + # If a block is passed, that block should not cause any emails to be sent. + # + # def test_emails_again + # assert_no_emails do + # # No emails should be sent from this block + # end + # end + # + # Note: This assertion is simply a shortcut for: + # + # assert_emails 0 + def assert_no_emails(&block) + assert_emails 0, &block + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/action_mailer/version.rb b/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/action_mailer/version.rb new file mode 100644 index 0000000..06f80a8 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/action_mailer/version.rb @@ -0,0 +1,9 @@ +require_relative 'gem_version' + +module ActionMailer + # Returns the version of the currently loaded Action Mailer as a + # Gem::Version. + def self.version + gem_version + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/rails/generators/mailer/USAGE b/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/rails/generators/mailer/USAGE new file mode 100644 index 0000000..323bb8a --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/rails/generators/mailer/USAGE @@ -0,0 +1,17 @@ +Description: +============ + Stubs out a new mailer and its views. Passes the mailer name, either + CamelCased or under_scored, and an optional list of emails as arguments. + + This generates a mailer class in app/mailers and invokes your template + engine and test framework generators. + +Example: +======== + rails generate mailer Notifications signup forgot_password invoice + + creates a Notifications mailer class, views, and test: + Mailer: app/mailers/notifications.rb + Views: app/views/notifications/signup.text.erb [...] + Test: test/mailers/notifications_test.rb + diff --git a/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/rails/generators/mailer/mailer_generator.rb b/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/rails/generators/mailer/mailer_generator.rb new file mode 100644 index 0000000..83f8a67 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/rails/generators/mailer/mailer_generator.rb @@ -0,0 +1,19 @@ +module Rails + module Generators + class MailerGenerator < NamedBase + source_root File.expand_path("../templates", __FILE__) + + argument :actions, type: :array, default: [], banner: "method method" + check_class_collision + + def create_mailer_file + template "mailer.rb", File.join('app/mailers', class_path, "#{file_name}.rb") + if self.behavior == :invoke + template "application_mailer.rb", 'app/mailers/application_mailer.rb' + end + end + + hook_for :template_engine, :test_framework + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/rails/generators/mailer/templates/application_mailer.rb b/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/rails/generators/mailer/templates/application_mailer.rb new file mode 100644 index 0000000..d25d889 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/rails/generators/mailer/templates/application_mailer.rb @@ -0,0 +1,4 @@ +class ApplicationMailer < ActionMailer::Base + default from: "from@example.com" + layout 'mailer' +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/rails/generators/mailer/templates/mailer.rb b/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/rails/generators/mailer/templates/mailer.rb new file mode 100644 index 0000000..bce64a5 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionmailer-4.2.6/lib/rails/generators/mailer/templates/mailer.rb @@ -0,0 +1,17 @@ +<% module_namespacing do -%> +class <%= class_name %> < ApplicationMailer +<% actions.each do |action| -%> + + # Subject can be set in your I18n file at config/locales/en.yml + # with the following lookup: + # + # en.<%= file_path.tr("/",".") %>.<%= action %>.subject + # + def <%= action %> + @greeting = "Hi" + + mail to: "to@example.org" + end +<% end -%> +end +<% end -%> diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/CHANGELOG.md b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/CHANGELOG.md new file mode 100644 index 0000000..ea84d5b --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/CHANGELOG.md @@ -0,0 +1,621 @@ +## Rails 4.2.6 (March 07, 2016) ## + +* No changes. + + +## Rails 4.2.5.2 (February 26, 2016) ## + +* Do not allow render with unpermitted parameter. + + Fixes CVE-2016-2098. + + *Arthur Neves* + + +## Rails 4.2.5.1 (January 25, 2015) ## + +* No changes. + + +## Rails 4.2.5 (November 12, 2015) ## + +* `ActionController::TestCase` can teardown gracefully if an error is raised + early in the `setup` chain. + + *Yves Senn* + +* Parse RSS/ATOM responses as XML, not HTML. + + *Alexander Kaupanin* + +* Fix regression in mounted engine named routes generation for app deployed to + a subdirectory. `relative_url_root` was prepended to the path twice (e.g. + "/subdir/subdir/engine_path" instead of "/subdir/engine_path") + + Fixes #20920. Fixes #21459. + + *Matthew Erhard* + +* `url_for` does not modify its arguments when generating polymorphic URLs. + + *Bernerd Schaefer* + +* Update `ActionController::TestSession#fetch` to behave more like + `ActionDispatch::Request::Session#fetch` when using non-string keys. + + *Jeremy Friesen* + + +## Rails 4.2.4 (August 24, 2015) ## + +* ActionController::TestSession now accepts a default value as well as + a block for generating a default value based off the key provided. + + This fixes calls to session#fetch in ApplicationController instances that + take more two arguments or a block from raising `ArgumentError: wrong + number of arguments (2 for 1)` when performing controller tests. + + *Matthew Gerrior* + +* Fix to keep original header instance in `ActionDispatch::SSL` + + `ActionDispatch::SSL` changes headers to `Hash`. + So some headers will be broken if there are some middlewares + on `ActionDispatch::SSL` and if it uses `Rack::Utils::HeaderHash`. + + *Fumiaki Matsushima* + + +## Rails 4.2.3 (June 25, 2015) ## + +* Fix rake routes not showing the right format when + nesting multiple routes. + + See #18373. + + *Ravil Bayramgalin* + +* Fix regression where a gzip file response would have a Content-type, + even when it was a 304 status code. + + See #19271. + + *Kohei Suzuki* + +* Fix handling of empty X_FORWARDED_HOST header in raw_host_with_port + + Previously, an empty X_FORWARDED_HOST header would cause + Actiondispatch::Http:URL.raw_host_with_port to return nil, causing + Actiondispatch::Http:URL.host to raise a NoMethodError. + + *Adam Forsyth* + +* Fallback to `ENV['RAILS_RELATIVE_URL_ROOT']` in `url_for`. + + Fixed an issue where the `RAILS_RELATIVE_URL_ROOT` environment variable is not + prepended to the path when `url_for` is called. If `SCRIPT_NAME` (used by Rack) + is set, it takes precedence. + + Fixes #5122. + + *Yasyf Mohamedali* + +* Fix regression in functional tests. Responses should have default headers + assigned. + + See #18423. + + *Jeremy Kemper*, *Yves Senn* + + +## Rails 4.2.2 (June 16, 2015) ## + +* No Changes * + + +## Rails 4.2.1 (March 19, 2015) ## + +* Non-string authenticity tokens do not raise NoMethodError when decoding + the masked token. + + *Ville Lautanala* + +* Explicitly ignored wildcard verbs when searching for HEAD routes before fallback + + Fixes an issue where a mounted rack app at root would intercept the HEAD + request causing an incorrect behavior during the fall back to GET requests. + + Example: + ```ruby + draw do + get '/home' => 'test#index' + mount rack_app, at: '/' + end + head '/home' + assert_response :success + ``` + In this case, a HEAD request runs through the routes the first time and fails + to match anything. Then, it runs through the list with the fallback and matches + `get '/home'`. The original behavior would match the rack app in the first pass. + + *Terence Sun* + +* Preserve default format when generating URLs + + Fixes an issue that would cause the format set in default_url_options to be + lost when generating URLs with fewer positional arguments than parameters in + the route definition. + + Backport of #18627 + + *Tekin Suleyman*, *Dominic Baggott* + +* Default headers, removed in controller actions, are no longer reapplied on + the test response. + + *Jonas Baumann* + +* Ensure `append_info_to_payload` is called even if an exception is raised. + + Fixes an issue where when an exception is raised in the request the additonal + payload data is not available. + + See: + * #14903 + * https://github.com/roidrage/lograge/issues/37 + + *Dieter Komendera*, *Margus Pärt* + +* Correctly rely on the response's status code to handle calls to `head`. + + *Robin Dupret* + +* Using `head` method returns empty response_body instead + of returning a single space " ". + + The old behavior was added as a workaround for a bug in an early + version of Safari, where the HTTP headers are not returned correctly + if the response body has a 0-length. This is been fixed since and + the workaround is no longer necessary. + + Fixes #18253. + + *Prathamesh Sonpatki* + +* Fix how polymorphic routes works with objects that implement `to_model`. + + *Travis Grathwell* + +* Fixed handling of positional url helper arguments when `format: false`. + + Fixes #17819. + + *Andrew White*, *Tatiana Soukiassian* + +* Fixed usage of optional scopes in URL helpers. + + *Alex Robbin* + + +## Rails 4.2.0 (December 20, 2014) ## + +* Add `ActionController::Parameters#to_unsafe_h` to return an unfiltered + `Hash` representation of Parameters object. This is now a preferred way to + retrieve unfiltered parameters as we will stop inheriting `AC::Parameters` + object in Rails 5.0. + + *Prem Sichanugrist* + +* Restore handling of a bare `Authorization` header, without `token=` + prefix. + + Fixes #17108. + + *Guo Xiang Tan* + +* Deprecate use of string keys in URL helpers. + + Use symbols instead. + Fixes #16958. + + *Byron Bischoff*, *Melanie Gilman* + +* Deprecate the `only_path` option on `*_path` helpers. + + In cases where this option is set to `true`, the option is redundant and can + be safely removed; otherwise, the corresponding `*_url` helper should be + used instead. + + Fixes #17294. + + *Dan Olson*, *Godfrey Chan* + +* Improve Journey compliance to RFC 3986. + + The scanner in Journey failed to recognize routes that use literals + from the sub-delims section of RFC 3986. It's now able to parse those + authorized delimiters and route as expected. + + Fixes #17212. + + *Nicolas Cavigneaux* + +* Deprecate implicit Array conversion for Response objects. It was added + (using `#to_ary`) so we could conveniently use implicit splatting: + + status, headers, body = response + + But it also means `response + response` works and `[response].flatten` + cascades down to the Rack body. Nonsense behavior. Instead, rely on + explicit conversion and splatting with `#to_a`: + + status, header, body = *response + + *Jeremy Kemper* + +* Don't rescue `IPAddr::InvalidAddressError`. + + `IPAddr::InvalidAddressError` does not exist in Ruby 1.9.3 + and fails for JRuby in 1.9 mode. + + *Peter Suschlik* + +* Fix bug where the router would ignore any constraints added to redirect + routes. + + Fixes #16605. + + *Agis Anastasopoulos* + +* Allow `config.action_dispatch.trusted_proxies` to accept an IPAddr object. + + Example: + + # config/environments/production.rb + config.action_dispatch.trusted_proxies = IPAddr.new('4.8.15.0/16') + + *Sam Aarons* + +* Avoid duplicating routes for HEAD requests. + + Instead of duplicating the routes, we will first match the HEAD request to + HEAD routes. If no match is found, we will then map the HEAD request to + GET routes. + + *Guo Xiang Tan*, *Andrew White* + +* Requests that hit `ActionDispatch::Static` can now take advantage + of gzipped assets on disk. By default a gzip asset will be served if + the client supports gzip and a compressed file is on disk. + + *Richard Schneeman* + +* `ActionController::Parameters` will stop inheriting from `Hash` and + `HashWithIndifferentAccess` in the next major release. If you use any method + that is not available on `ActionController::Parameters` you should consider + calling `#to_h` to convert it to a `Hash` first before calling that method. + + *Prem Sichanugrist* + +* `ActionController::Parameters#to_h` now returns a `Hash` with unpermitted + keys removed. This change is to reflect on a security concern where some + method performed on an `ActionController::Parameters` may yield a `Hash` + object which does not maintain `permitted?` status. If you would like to + get a `Hash` with all the keys intact, duplicate and mark it as permitted + before calling `#to_h`. + + params = ActionController::Parameters.new({ + name: 'Senjougahara Hitagi', + oddity: 'Heavy stone crab' + }) + params.to_h + # => {} + + unsafe_params = params.dup.permit! + unsafe_params.to_h + # => {"name"=>"Senjougahara Hitagi", "oddity"=>"Heavy stone crab"} + + safe_params = params.permit(:name) + safe_params.to_h + # => {"name"=>"Senjougahara Hitagi"} + + This change is consider a stopgap as we cannot change the code to stop + `ActionController::Parameters` to inherit from `HashWithIndifferentAccess` + in the next minor release. + + *Prem Sichanugrist* + +* Deprecated `TagAssertions`. + + *Kasper Timm Hansen* + +* Use the Active Support JSON encoder for cookie jars using the `:json` or + `:hybrid` serializer. This allows you to serialize custom Ruby objects into + cookies by defining the `#as_json` hook on such objects. + + Fixes #16520. + + *Godfrey Chan* + +* Add `config.action_dispatch.cookies_digest` option for setting custom + digest. The default remains the same - 'SHA1'. + + *Åukasz StrzaÅ‚kowski* + +* Move `respond_with` (and the class-level `respond_to`) to + the `responders` gem. + + *José Valim* + +* When your templates change, browser caches bust automatically. + + New default: the template digest is automatically included in your ETags. + When you call `fresh_when @post`, the digest for `posts/show.html.erb` + is mixed in so future changes to the HTML will blow HTTP caches for you. + This makes it easy to HTTP-cache many more of your actions. + + If you render a different template, you can now pass the `:template` + option to include its digest instead: + + fresh_when @post, template: 'widgets/show' + + Pass `template: false` to skip the lookup. To turn this off entirely, set: + + config.action_controller.etag_with_template_digest = false + + *Jeremy Kemper* + +* Remove deprecated `AbstractController::Helpers::ClassMethods::MissingHelperError` + in favor of `AbstractController::Helpers::MissingHelperError`. + + *Yves Senn* + +* Fix `assert_template` not being able to assert that no files were rendered. + + *Guo Xiang Tan* + +* Extract source code for the entire exception stack trace for + better debugging and diagnosis. + + *Ryan Dao* + +* Allows ActionDispatch::Request::LOCALHOST to match any IPv4 127.0.0.0/8 + loopback address. + + *Earl St Sauver*, *Sven Riedel* + +* Preserve original path in `ShowExceptions` middleware by stashing it as + `env["action_dispatch.original_path"]` + + `ActionDispatch::ShowExceptions` overwrites `PATH_INFO` with the status code + for the exception defined in `ExceptionWrapper`, so the path + the user was visiting when an exception occurred was not previously + available to any custom exceptions_app. The original `PATH_INFO` is now + stashed in `env["action_dispatch.original_path"]`. + + *Grey Baker* + +* Use `String#bytesize` instead of `String#size` when checking for cookie + overflow. + + *Agis Anastasopoulos* + +* `render nothing: true` or rendering a `nil` body no longer add a single + space to the response body. + + The old behavior was added as a workaround for a bug in an early version of + Safari, where the HTTP headers are not returned correctly if the response + body has a 0-length. This is been fixed since and the workaround is no + longer necessary. + + Use `render body: ' '` if the old behavior is desired. + + See #14883 for details. + + *Godfrey Chan* + +* Prepend a JS comment to JSONP callbacks. Addresses CVE-2014-4671 + ("Rosetta Flash"). + + *Greg Campbell* + +* Because URI paths may contain non US-ASCII characters we need to force + the encoding of any unescaped URIs to UTF-8 if they are US-ASCII. + This essentially replicates the functionality of the monkey patch to + URI.parser.unescape in active_support/core_ext/uri.rb. + + Fixes #16104. + + *Karl Entwistle* + +* Generate shallow paths for all children of shallow resources. + + Fixes #15783. + + *Seb Jacobs* + +* JSONP responses are now rendered with the `text/javascript` content type + when rendering through a `respond_to` block. + + Fixes #15081. + + *Lucas Mazza* + +* Add `config.action_controller.always_permitted_parameters` to configure which + parameters are permitted globally. The default value of this configuration is + `['controller', 'action']`. + + *Gary S. Weaver*, *Rafael Chacon* + +* Fix env['PATH_INFO'] missing leading slash when a rack app mounted at '/'. + + Fixes #15511. + + *Larry Lv* + +* ActionController::Parameters#require now accepts `false` values. + + Fixes #15685. + + *Sergio Romano* + +* With authorization header `Authorization: Token token=`, `authenticate` now + recognize token as nil, instead of "token". + + Fixes #14846. + + *Larry Lv* + +* Ensure the controller is always notified as soon as the client disconnects + during live streaming, even when the controller is blocked on a write. + + *Nicholas Jakobsen*, *Matthew Draper* + +* Routes specifying 'to:' must be a string that contains a "#" or a rack + application. Use of a symbol should be replaced with `action: symbol`. + Use of a string without a "#" should be replaced with `controller: string`. + + *Aaron Patterson* + +* Fix URL generation with `:trailing_slash` such that it does not add + a trailing slash after `.:format` + + *Dan Langevin* + +* Build full URI as string when processing path in integration tests for + performance reasons. One consequence of this is that the leading slash + is now required in integration test `process` helpers, whereas previously + it could be omitted. The fact that this worked was a unintended consequence + of the implementation and was never an intentional feature. + + *Guo Xiang Tan* + +* Fix `'Stack level too deep'` when rendering `head :ok` in an action method + called 'status' in a controller. + + Fixes #13905. + + *Christiaan Van den Poel* + +* Add MKCALENDAR HTTP method (RFC 4791). + + *Sergey Karpesh* + +* Instrument fragment cache metrics. + + Adds `:controller`: and `:action` keys to the instrumentation payload + for the `*_fragment.action_controller` notifications. This allows tracking + e.g. the fragment cache hit rates for each controller action. + + *Daniel Schierbeck* + +* Always use the provided port if the protocol is relative. + + Fixes #15043. + + *Guilherme Cavalcanti*, *Andrew White* + +* Moved `params[request_forgery_protection_token]` into its own method + and improved tests. + + Fixes #11316. + + *Tom Kadwill* + +* Added verification of route constraints given as a Proc or an object responding + to `:matches?`. Previously, when given an non-complying object, it would just + silently fail to enforce the constraint. It will now raise an `ArgumentError` + when setting up the routes. + + *Xavier Defrang* + +* Properly treat the entire IPv6 User Local Address space as private for + purposes of remote IP detection. Also handle uppercase private IPv6 + addresses. + + Fixes #12638. + + *Caleb Spare* + +* Fixed an issue with migrating legacy json cookies. + + Previously, the `VerifyAndUpgradeLegacySignedMessage` assumes all incoming + cookies are marshal-encoded. This is not the case when `secret_token` is + used in conjunction with the `:json` or `:hybrid` serializer. + + In those case, when upgrading to use `secret_key_base`, this would cause a + `TypeError: incompatible marshal file format` and a 500 error for the user. + + Fixes #14774. + + *Godfrey Chan* + +* Make URL escaping more consistent: + + 1. Escape '%' characters in URLs - only unescaped data should be passed to URL helpers + 2. Add an `escape_segment` helper to `Router::Utils` that escapes '/' characters + 3. Use `escape_segment` rather than `escape_fragment` in optimized URL generation + 4. Use `escape_segment` rather than `escape_path` in URL generation + + For point 4 there are two exceptions. Firstly, when a route uses wildcard segments + (e.g. `*foo`) then we use `escape_path` as the value may contain '/' characters. This + means that wildcard routes can't be optimized. Secondly, if a `:controller` segment + is used in the path then this uses `escape_path` as the controller may be namespaced. + + Fixes #14629, #14636 and #14070. + + *Andrew White*, *Edho Arief* + +* Add alias `ActionDispatch::Http::UploadedFile#to_io` to + `ActionDispatch::Http::UploadedFile#tempfile`. + + *Tim Linquist* + +* Returns null type format when format is not know and controller is using `any` + format block. + + Fixes #14462. + + *Rafael Mendonça França* + +* Improve routing error page with fuzzy matching search. + + *Winston* + +* Only make deeply nested routes shallow when parent is shallow. + + Fixes #14684. + + *Andrew White*, *James Coglan* + +* Append link to bad code to backtrace when exception is `SyntaxError`. + + *Boris Kuznetsov* + +* Swapped the parameters of assert_equal in `assert_select` so that the + proper values were printed correctly. + + Fixes #14422. + + *Vishal Lal* + +* The method `shallow?` returns false if the parent resource is a singleton so + we need to check if we're not inside a nested scope before copying the :path + and :as options to their shallow equivalents. + + Fixes #14388. + + *Andrew White* + +* Make logging of CSRF failures optional (but on by default) with the + `log_warning_on_csrf_failure` configuration setting in + `ActionController::RequestForgeryProtection`. + + *John Barton* + +* Fix URL generation in controller tests with request-dependent + `default_url_options` methods. + + *Tony Wooster* + +Please check [4-1-stable](https://github.com/rails/rails/blob/4-1-stable/actionpack/CHANGELOG.md) for previous changes. diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/MIT-LICENSE b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/MIT-LICENSE new file mode 100644 index 0000000..d58dd9e --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/MIT-LICENSE @@ -0,0 +1,21 @@ +Copyright (c) 2004-2014 David Heinemeier Hansson + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/README.rdoc b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/README.rdoc new file mode 100644 index 0000000..f67df79 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/README.rdoc @@ -0,0 +1,58 @@ += Action Pack -- From request to response + +Action Pack is a framework for handling and responding to web requests. It +provides mechanisms for *routing* (mapping request URLs to actions), defining +*controllers* that implement actions, and generating responses by rendering +*views*, which are templates of various formats. In short, Action Pack +provides the view and controller layers in the MVC paradigm. + +It consists of several modules: + +* Action Dispatch, which parses information about the web request, handles + routing as defined by the user, and does advanced processing related to HTTP + such as MIME-type negotiation, decoding parameters in POST, PATCH, or PUT bodies, + handling HTTP caching logic, cookies and sessions. + +* Action Controller, which provides a base controller class that can be + subclassed to implement filters and actions to handle requests. The result + of an action is typically content generated from views. + +With the Ruby on Rails framework, users only directly interface with the +Action Controller module. Necessary Action Dispatch functionality is activated +by default and Action View rendering is implicitly triggered by Action +Controller. However, these modules are designed to function on their own and +can be used outside of Rails. + + +== Download and installation + +The latest version of Action Pack can be installed with RubyGems: + + % [sudo] gem install actionpack + +Source code can be downloaded as part of the Rails project on GitHub + +* https://github.com/rails/rails/tree/4-2-stable/actionpack + + +== License + +Action Pack is released under the MIT license: + +* http://www.opensource.org/licenses/MIT + + +== Support + +API documentation is at + +* http://api.rubyonrails.org + +Bug reports can be filed for the Ruby on Rails project here: + +* https://github.com/rails/rails/issues + +Feature requests should be discussed on the rails-core mailing list here: + +* https://groups.google.com/forum/?fromgroups#!forum/rubyonrails-core + diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/abstract_controller.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/abstract_controller.rb new file mode 100644 index 0000000..fe9802e --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/abstract_controller.rb @@ -0,0 +1,20 @@ +require 'action_pack' +require 'active_support/rails' +require 'active_support/core_ext/module/attr_internal' +require 'active_support/core_ext/module/anonymous' +require 'active_support/i18n' + +module AbstractController + extend ActiveSupport::Autoload + + autoload :Base + autoload :Callbacks + autoload :Collector + autoload :DoubleRenderError, "abstract_controller/rendering" + autoload :Helpers + autoload :Logger + autoload :Rendering + autoload :Translation + autoload :AssetPaths + autoload :UrlFor +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/abstract_controller/asset_paths.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/abstract_controller/asset_paths.rb new file mode 100644 index 0000000..e617022 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/abstract_controller/asset_paths.rb @@ -0,0 +1,10 @@ +module AbstractController + module AssetPaths #:nodoc: + extend ActiveSupport::Concern + + included do + config_accessor :asset_host, :assets_dir, :javascripts_dir, + :stylesheets_dir, :default_asset_host_protocol, :relative_url_root + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/abstract_controller/base.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/abstract_controller/base.rb new file mode 100644 index 0000000..4026dab --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/abstract_controller/base.rb @@ -0,0 +1,269 @@ +require 'erubis' +require 'set' +require 'active_support/configurable' +require 'active_support/descendants_tracker' +require 'active_support/core_ext/module/anonymous' + +module AbstractController + class Error < StandardError #:nodoc: + end + + # Raised when a non-existing controller action is triggered. + class ActionNotFound < StandardError + end + + # AbstractController::Base is a low-level API. Nobody should be + # using it directly, and subclasses (like ActionController::Base) are + # expected to provide their own +render+ method, since rendering means + # different things depending on the context. + class Base + attr_internal :response_body + attr_internal :action_name + attr_internal :formats + + include ActiveSupport::Configurable + extend ActiveSupport::DescendantsTracker + + undef_method :not_implemented + class << self + attr_reader :abstract + alias_method :abstract?, :abstract + + # Define a controller as abstract. See internal_methods for more + # details. + def abstract! + @abstract = true + end + + def inherited(klass) # :nodoc: + # Define the abstract ivar on subclasses so that we don't get + # uninitialized ivar warnings + unless klass.instance_variable_defined?(:@abstract) + klass.instance_variable_set(:@abstract, false) + end + super + end + + # A list of all internal methods for a controller. This finds the first + # abstract superclass of a controller, and gets a list of all public + # instance methods on that abstract class. Public instance methods of + # a controller would normally be considered action methods, so methods + # declared on abstract classes are being removed. + # (ActionController::Metal and ActionController::Base are defined as abstract) + def internal_methods + controller = self + + controller = controller.superclass until controller.abstract? + controller.public_instance_methods(true) + end + + # The list of hidden actions. Defaults to an empty array. + # This can be modified by other modules or subclasses + # to specify particular actions as hidden. + # + # ==== Returns + # * Array - An array of method names that should not be considered actions. + def hidden_actions + [] + end + + # A list of method names that should be considered actions. This + # includes all public instance methods on a controller, less + # any internal methods (see #internal_methods), adding back in + # any methods that are internal, but still exist on the class + # itself. Finally, #hidden_actions are removed. + # + # ==== Returns + # * Set - A set of all methods that should be considered actions. + def action_methods + @action_methods ||= begin + # All public instance methods of this class, including ancestors + methods = (public_instance_methods(true) - + # Except for public instance methods of Base and its ancestors + internal_methods + + # Be sure to include shadowed public instance methods of this class + public_instance_methods(false)).uniq.map { |x| x.to_s } - + # And always exclude explicitly hidden actions + hidden_actions.to_a + + # Clear out AS callback method pollution + Set.new(methods.reject { |method| method =~ /_one_time_conditions/ }) + end + end + + # action_methods are cached and there is sometimes need to refresh + # them. clear_action_methods! allows you to do that, so next time + # you run action_methods, they will be recalculated + def clear_action_methods! + @action_methods = nil + end + + # Returns the full controller name, underscored, without the ending Controller. + # For instance, MyApp::MyPostsController would return "my_app/my_posts" for + # controller_path. + # + # ==== Returns + # * String + def controller_path + @controller_path ||= name.sub(/Controller$/, '').underscore unless anonymous? + end + + # Refresh the cached action_methods when a new action_method is added. + def method_added(name) + super + clear_action_methods! + end + end + + abstract! + + # Calls the action going through the entire action dispatch stack. + # + # The actual method that is called is determined by calling + # #method_for_action. If no method can handle the action, then an + # AbstractController::ActionNotFound error is raised. + # + # ==== Returns + # * self + def process(action, *args) + @_action_name = action.to_s + + unless action_name = _find_action_name(@_action_name) + raise ActionNotFound, "The action '#{action}' could not be found for #{self.class.name}" + end + + @_response_body = nil + + process_action(action_name, *args) + end + + # Delegates to the class' #controller_path + def controller_path + self.class.controller_path + end + + # Delegates to the class' #action_methods + def action_methods + self.class.action_methods + end + + # Returns true if a method for the action is available and + # can be dispatched, false otherwise. + # + # Notice that action_methods.include?("foo") may return + # false and available_action?("foo") returns true because + # this method considers actions that are also available + # through other means, for example, implicit render ones. + # + # ==== Parameters + # * action_name - The name of an action to be tested + # + # ==== Returns + # * TrueClass, FalseClass + def available_action?(action_name) + _find_action_name(action_name).present? + end + + # Returns true if the given controller is capable of rendering + # a path. A subclass of +AbstractController::Base+ + # may return false. An Email controller for example does not + # support paths, only full URLs. + def self.supports_path? + true + end + + private + + # Returns true if the name can be considered an action because + # it has a method defined in the controller. + # + # ==== Parameters + # * name - The name of an action to be tested + # + # ==== Returns + # * TrueClass, FalseClass + # + # :api: private + def action_method?(name) + self.class.action_methods.include?(name) + end + + # Call the action. Override this in a subclass to modify the + # behavior around processing an action. This, and not #process, + # is the intended way to override action dispatching. + # + # Notice that the first argument is the method to be dispatched + # which is *not* necessarily the same as the action name. + def process_action(method_name, *args) + send_action(method_name, *args) + end + + # Actually call the method associated with the action. Override + # this method if you wish to change how action methods are called, + # not to add additional behavior around it. For example, you would + # override #send_action if you want to inject arguments into the + # method. + alias send_action send + + # If the action name was not found, but a method called "action_missing" + # was found, #method_for_action will return "_handle_action_missing". + # This method calls #action_missing with the current action name. + def _handle_action_missing(*args) + action_missing(@_action_name, *args) + end + + # Takes an action name and returns the name of the method that will + # handle the action. + # + # It checks if the action name is valid and returns false otherwise. + # + # See method_for_action for more information. + # + # ==== Parameters + # * action_name - An action name to find a method name for + # + # ==== Returns + # * string - The name of the method that handles the action + # * false - No valid method name could be found. + # Raise AbstractController::ActionNotFound. + def _find_action_name(action_name) + _valid_action_name?(action_name) && method_for_action(action_name) + end + + # Takes an action name and returns the name of the method that will + # handle the action. In normal cases, this method returns the same + # name as it receives. By default, if #method_for_action receives + # a name that is not an action, it will look for an #action_missing + # method and return "_handle_action_missing" if one is found. + # + # Subclasses may override this method to add additional conditions + # that should be considered an action. For instance, an HTTP controller + # with a template matching the action name is considered to exist. + # + # If you override this method to handle additional cases, you may + # also provide a method (like _handle_method_missing) to handle + # the case. + # + # If none of these conditions are true, and method_for_action + # returns nil, an AbstractController::ActionNotFound exception will be raised. + # + # ==== Parameters + # * action_name - An action name to find a method name for + # + # ==== Returns + # * string - The name of the method that handles the action + # * nil - No method name could be found. + def method_for_action(action_name) + if action_method?(action_name) + action_name + elsif respond_to?(:action_missing, true) + "_handle_action_missing" + end + end + + # Checks if the action name is valid and returns false otherwise. + def _valid_action_name?(action_name) + !action_name.to_s.include? File::SEPARATOR + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/abstract_controller/callbacks.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/abstract_controller/callbacks.rb new file mode 100644 index 0000000..ca5c80c --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/abstract_controller/callbacks.rb @@ -0,0 +1,196 @@ +module AbstractController + module Callbacks + extend ActiveSupport::Concern + + # Uses ActiveSupport::Callbacks as the base functionality. For + # more details on the whole callback system, read the documentation + # for ActiveSupport::Callbacks. + include ActiveSupport::Callbacks + + included do + define_callbacks :process_action, + terminator: ->(controller,_) { controller.response_body }, + skip_after_callbacks_if_terminated: true + end + + # Override AbstractController::Base's process_action to run the + # process_action callbacks around the normal behavior. + def process_action(*args) + run_callbacks(:process_action) do + super + end + end + + module ClassMethods + # If :only or :except are used, convert the options into the + # :unless and :if options of ActiveSupport::Callbacks. + # The basic idea is that :only => :index gets converted to + # :if => proc {|c| c.action_name == "index" }. + # + # ==== Options + # * only - The callback should be run only for this action + # * except - The callback should be run for all actions except this action + def _normalize_callback_options(options) + _normalize_callback_option(options, :only, :if) + _normalize_callback_option(options, :except, :unless) + end + + def _normalize_callback_option(options, from, to) # :nodoc: + if from = options[from] + from = Array(from).map {|o| "action_name == '#{o}'"}.join(" || ") + options[to] = Array(options[to]).unshift(from) + end + end + + # Skip before, after, and around action callbacks matching any of the names. + # + # ==== Parameters + # * names - A list of valid names that could be used for + # callbacks. Note that skipping uses Ruby equality, so it's + # impossible to skip a callback defined using an anonymous proc + # using #skip_action_callback + def skip_action_callback(*names) + skip_before_action(*names) + skip_after_action(*names) + skip_around_action(*names) + end + alias_method :skip_filter, :skip_action_callback + + # Take callback names and an optional callback proc, normalize them, + # then call the block with each callback. This allows us to abstract + # the normalization across several methods that use it. + # + # ==== Parameters + # * callbacks - An array of callbacks, with an optional + # options hash as the last parameter. + # * block - A proc that should be added to the callbacks. + # + # ==== Block Parameters + # * name - The callback to be added + # * options - A hash of options to be used when adding the callback + def _insert_callbacks(callbacks, block = nil) + options = callbacks.extract_options! + _normalize_callback_options(options) + callbacks.push(block) if block + callbacks.each do |callback| + yield callback, options + end + end + + ## + # :method: before_action + # + # :call-seq: before_action(names, block) + # + # Append a callback before actions. See _insert_callbacks for parameter details. + + ## + # :method: prepend_before_action + # + # :call-seq: prepend_before_action(names, block) + # + # Prepend a callback before actions. See _insert_callbacks for parameter details. + + ## + # :method: skip_before_action + # + # :call-seq: skip_before_action(names) + # + # Skip a callback before actions. See _insert_callbacks for parameter details. + + ## + # :method: append_before_action + # + # :call-seq: append_before_action(names, block) + # + # Append a callback before actions. See _insert_callbacks for parameter details. + + ## + # :method: after_action + # + # :call-seq: after_action(names, block) + # + # Append a callback after actions. See _insert_callbacks for parameter details. + + ## + # :method: prepend_after_action + # + # :call-seq: prepend_after_action(names, block) + # + # Prepend a callback after actions. See _insert_callbacks for parameter details. + + ## + # :method: skip_after_action + # + # :call-seq: skip_after_action(names) + # + # Skip a callback after actions. See _insert_callbacks for parameter details. + + ## + # :method: append_after_action + # + # :call-seq: append_after_action(names, block) + # + # Append a callback after actions. See _insert_callbacks for parameter details. + + ## + # :method: around_action + # + # :call-seq: around_action(names, block) + # + # Append a callback around actions. See _insert_callbacks for parameter details. + + ## + # :method: prepend_around_action + # + # :call-seq: prepend_around_action(names, block) + # + # Prepend a callback around actions. See _insert_callbacks for parameter details. + + ## + # :method: skip_around_action + # + # :call-seq: skip_around_action(names) + # + # Skip a callback around actions. See _insert_callbacks for parameter details. + + ## + # :method: append_around_action + # + # :call-seq: append_around_action(names, block) + # + # Append a callback around actions. See _insert_callbacks for parameter details. + + # set up before_action, prepend_before_action, skip_before_action, etc. + # for each of before, after, and around. + [:before, :after, :around].each do |callback| + define_method "#{callback}_action" do |*names, &blk| + _insert_callbacks(names, blk) do |name, options| + set_callback(:process_action, callback, name, options) + end + end + alias_method :"#{callback}_filter", :"#{callback}_action" + + define_method "prepend_#{callback}_action" do |*names, &blk| + _insert_callbacks(names, blk) do |name, options| + set_callback(:process_action, callback, name, options.merge(:prepend => true)) + end + end + alias_method :"prepend_#{callback}_filter", :"prepend_#{callback}_action" + + # Skip a before, after or around callback. See _insert_callbacks + # for details on the allowed parameters. + define_method "skip_#{callback}_action" do |*names| + _insert_callbacks(names) do |name, options| + skip_callback(:process_action, callback, name, options) + end + end + alias_method :"skip_#{callback}_filter", :"skip_#{callback}_action" + + # *_action is the same as append_*_action + alias_method :"append_#{callback}_action", :"#{callback}_action" + alias_method :"append_#{callback}_filter", :"#{callback}_action" + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/abstract_controller/collector.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/abstract_controller/collector.rb new file mode 100644 index 0000000..ddd56b3 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/abstract_controller/collector.rb @@ -0,0 +1,46 @@ +require "action_dispatch/http/mime_type" + +module AbstractController + module Collector + def self.generate_method_for_mime(mime) + sym = mime.is_a?(Symbol) ? mime : mime.to_sym + const = sym.upcase + class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def #{sym}(*args, &block) # def html(*args, &block) + custom(Mime::#{const}, *args, &block) # custom(Mime::HTML, *args, &block) + end # end + RUBY + end + + Mime::SET.each do |mime| + generate_method_for_mime(mime) + end + + Mime::Type.register_callback do |mime| + generate_method_for_mime(mime) unless self.instance_methods.include?(mime.to_sym) + end + + protected + + def method_missing(symbol, &block) + const_name = symbol.upcase + + unless Mime.const_defined?(const_name) + raise NoMethodError, "To respond to a custom format, register it as a MIME type first: " \ + "http://guides.rubyonrails.org/action_controller_overview.html#restful-downloads. " \ + "If you meant to respond to a variant like :tablet or :phone, not a custom format, " \ + "be sure to nest your variant response within a format response: " \ + "format.html { |html| html.tablet { ... } }" + end + + mime_constant = Mime.const_get(const_name) + + if Mime::SET.include?(mime_constant) + AbstractController::Collector.generate_method_for_mime(mime_constant) + send(symbol, &block) + else + super + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/abstract_controller/helpers.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/abstract_controller/helpers.rb new file mode 100644 index 0000000..df7382f --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/abstract_controller/helpers.rb @@ -0,0 +1,194 @@ +require 'active_support/dependencies' + +module AbstractController + module Helpers + extend ActiveSupport::Concern + + included do + class_attribute :_helpers + self._helpers = Module.new + + class_attribute :_helper_methods + self._helper_methods = Array.new + end + + class MissingHelperError < LoadError + def initialize(error, path) + @error = error + @path = "helpers/#{path}.rb" + set_backtrace error.backtrace + + if error.path =~ /^#{path}(\.rb)?$/ + super("Missing helper file helpers/%s.rb" % path) + else + raise error + end + end + end + + module ClassMethods + # When a class is inherited, wrap its helper module in a new module. + # This ensures that the parent class's module can be changed + # independently of the child class's. + def inherited(klass) + helpers = _helpers + klass._helpers = Module.new { include helpers } + klass.class_eval { default_helper_module! } unless klass.anonymous? + super + end + + # Declare a controller method as a helper. For example, the following + # makes the +current_user+ controller method available to the view: + # class ApplicationController < ActionController::Base + # helper_method :current_user, :logged_in? + # + # def current_user + # @current_user ||= User.find_by(id: session[:user]) + # end + # + # def logged_in? + # current_user != nil + # end + # end + # + # In a view: + # <% if logged_in? -%>Welcome, <%= current_user.name %><% end -%> + # + # ==== Parameters + # * method[, method] - A name or names of a method on the controller + # to be made available on the view. + def helper_method(*meths) + meths.flatten! + self._helper_methods += meths + + meths.each do |meth| + _helpers.class_eval <<-ruby_eval, __FILE__, __LINE__ + 1 + def #{meth}(*args, &blk) # def current_user(*args, &blk) + controller.send(%(#{meth}), *args, &blk) # controller.send(:current_user, *args, &blk) + end # end + ruby_eval + end + end + + # The +helper+ class method can take a series of helper module names, a block, or both. + # + # ==== Options + # * *args - Module, Symbol, String + # * block - A block defining helper methods + # + # When the argument is a module it will be included directly in the template class. + # helper FooHelper # => includes FooHelper + # + # When the argument is a string or symbol, the method will provide the "_helper" suffix, require the file + # and include the module in the template class. The second form illustrates how to include custom helpers + # when working with namespaced controllers, or other cases where the file containing the helper definition is not + # in one of Rails' standard load paths: + # helper :foo # => requires 'foo_helper' and includes FooHelper + # helper 'resources/foo' # => requires 'resources/foo_helper' and includes Resources::FooHelper + # + # Additionally, the +helper+ class method can receive and evaluate a block, making the methods defined available + # to the template. + # + # # One line + # helper { def hello() "Hello, world!" end } + # + # # Multi-line + # helper do + # def foo(bar) + # "#{bar} is the very best" + # end + # end + # + # Finally, all the above styles can be mixed together, and the +helper+ method can be invoked with a mix of + # +symbols+, +strings+, +modules+ and blocks. + # + # helper(:three, BlindHelper) { def mice() 'mice' end } + # + def helper(*args, &block) + modules_for_helpers(args).each do |mod| + add_template_helper(mod) + end + + _helpers.module_eval(&block) if block_given? + end + + # Clears up all existing helpers in this class, only keeping the helper + # with the same name as this class. + def clear_helpers + inherited_helper_methods = _helper_methods + self._helpers = Module.new + self._helper_methods = Array.new + + inherited_helper_methods.each { |meth| helper_method meth } + default_helper_module! unless anonymous? + end + + # Returns a list of modules, normalized from the acceptable kinds of + # helpers with the following behavior: + # + # String or Symbol:: :FooBar or "FooBar" becomes "foo_bar_helper", + # and "foo_bar_helper.rb" is loaded using require_dependency. + # + # Module:: No further processing + # + # After loading the appropriate files, the corresponding modules + # are returned. + # + # ==== Parameters + # * args - An array of helpers + # + # ==== Returns + # * Array - A normalized list of modules for the list of + # helpers provided. + def modules_for_helpers(args) + args.flatten.map! do |arg| + case arg + when String, Symbol + file_name = "#{arg.to_s.underscore}_helper" + begin + require_dependency(file_name) + rescue LoadError => e + raise AbstractController::Helpers::MissingHelperError.new(e, file_name) + end + + mod_name = file_name.camelize + begin + mod_name.constantize + rescue LoadError + # dependencies.rb gives a similar error message but its wording is + # not as clear because it mentions autoloading. To the user all it + # matters is that a helper module couldn't be loaded, autoloading + # is an internal mechanism that should not leak. + raise NameError, "Couldn't find #{mod_name}, expected it to be defined in helpers/#{file_name}.rb" + end + when Module + arg + else + raise ArgumentError, "helper must be a String, Symbol, or Module" + end + end + end + + private + # Makes all the (instance) methods in the helper module available to templates + # rendered through this controller. + # + # ==== Parameters + # * module - The module to include into the current helper module + # for the class + def add_template_helper(mod) + _helpers.module_eval { include mod } + end + + def default_helper_module! + module_name = name.sub(/Controller$/, '') + module_path = module_name.underscore + helper module_path + rescue MissingSourceFile => e + raise e unless e.is_missing? "helpers/#{module_path}_helper" + rescue NameError => e + raise e unless e.missing_name? "#{module_name}Helper" + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/abstract_controller/logger.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/abstract_controller/logger.rb new file mode 100644 index 0000000..c31ea6c --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/abstract_controller/logger.rb @@ -0,0 +1,12 @@ +require "active_support/benchmarkable" + +module AbstractController + module Logger #:nodoc: + extend ActiveSupport::Concern + + included do + config_accessor :logger + include ActiveSupport::Benchmarkable + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/abstract_controller/railties/routes_helpers.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/abstract_controller/railties/routes_helpers.rb new file mode 100644 index 0000000..568c47e --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/abstract_controller/railties/routes_helpers.rb @@ -0,0 +1,18 @@ +module AbstractController + module Railties + module RoutesHelpers + def self.with(routes, include_path_helpers = true) + Module.new do + define_method(:inherited) do |klass| + super(klass) + if namespace = klass.parents.detect { |m| m.respond_to?(:railtie_routes_url_helpers) } + klass.send(:include, namespace.railtie_routes_url_helpers(include_path_helpers)) + else + klass.send(:include, routes.url_helpers(include_path_helpers)) + end + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/abstract_controller/rendering.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/abstract_controller/rendering.rb new file mode 100644 index 0000000..b47c8a1 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/abstract_controller/rendering.rb @@ -0,0 +1,126 @@ +require 'active_support/concern' +require 'active_support/core_ext/class/attribute' +require 'action_view' +require 'action_view/view_paths' +require 'set' + +module AbstractController + class DoubleRenderError < Error + DEFAULT_MESSAGE = "Render and/or redirect were called multiple times in this action. Please note that you may only call render OR redirect, and at most once per action. Also note that neither redirect nor render terminate execution of the action, so if you want to exit an action after redirecting, you need to do something like \"redirect_to(...) and return\"." + + def initialize(message = nil) + super(message || DEFAULT_MESSAGE) + end + end + + module Rendering + extend ActiveSupport::Concern + include ActionView::ViewPaths + + # Normalize arguments, options and then delegates render_to_body and + # sticks the result in self.response_body. + # :api: public + def render(*args, &block) + options = _normalize_render(*args, &block) + self.response_body = render_to_body(options) + _process_format(rendered_format, options) if rendered_format + self.response_body + end + + # Raw rendering of a template to a string. + # + # It is similar to render, except that it does not + # set the response_body and it should be guaranteed + # to always return a string. + # + # If a component extends the semantics of response_body + # (as Action Controller extends it to be anything that + # responds to the method each), this method needs to be + # overridden in order to still return a string. + # :api: plugin + def render_to_string(*args, &block) + options = _normalize_render(*args, &block) + render_to_body(options) + end + + # Performs the actual template rendering. + # :api: public + def render_to_body(options = {}) + end + + # Returns Content-Type of rendered content + # :api: public + def rendered_format + Mime::TEXT + end + + DEFAULT_PROTECTED_INSTANCE_VARIABLES = Set.new %w( + @_action_name @_response_body @_formats @_prefixes @_config + @_view_context_class @_view_renderer @_lookup_context + @_routes @_db_runtime + ).map(&:to_sym) + + # This method should return a hash with assigns. + # You can overwrite this configuration per controller. + # :api: public + def view_assigns + protected_vars = _protected_ivars + variables = instance_variables + + variables.reject! { |s| protected_vars.include? s } + variables.each_with_object({}) { |name, hash| + hash[name.slice(1, name.length)] = instance_variable_get(name) + } + end + + # Normalize args by converting render "foo" to render :action => "foo" and + # render "foo/bar" to render :file => "foo/bar". + # :api: plugin + def _normalize_args(action=nil, options={}) + if action.respond_to?(:permitted?) + if action.permitted? + action + else + raise ArgumentError, "render parameters are not permitted" + end + elsif action.is_a?(Hash) + action + else + options + end + end + + # Normalize options. + # :api: plugin + def _normalize_options(options) + options + end + + # Process extra options. + # :api: plugin + def _process_options(options) + options + end + + # Process the rendered format. + # :api: private + def _process_format(format, options = {}) + end + + # Normalize args and options. + # :api: private + def _normalize_render(*args, &block) + options = _normalize_args(*args, &block) + #TODO: remove defined? when we restore AP <=> AV dependency + if defined?(request) && request && request.variant.present? + options[:variant] = request.variant + end + _normalize_options(options) + options + end + + def _protected_ivars # :nodoc: + DEFAULT_PROTECTED_INSTANCE_VARIABLES + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/abstract_controller/translation.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/abstract_controller/translation.rb new file mode 100644 index 0000000..02028d8 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/abstract_controller/translation.rb @@ -0,0 +1,28 @@ +module AbstractController + module Translation + # Delegates to I18n.translate. Also aliased as t. + # + # When the given key starts with a period, it will be scoped by the current + # controller and action. So if you call translate(".foo") from + # PeopleController#index, it will convert the call to + # I18n.translate("people.index.foo"). This makes it less repetitive + # to translate many keys within the same controller / action and gives you a + # simple framework for scoping them consistently. + def translate(*args) + key = args.first + if key.is_a?(String) && (key[0] == '.') + key = "#{ controller_path.tr('/', '.') }.#{ action_name }#{ key }" + args[0] = key + end + + I18n.translate(*args) + end + alias :t :translate + + # Delegates to I18n.localize. Also aliased as l. + def localize(*args) + I18n.localize(*args) + end + alias :l :localize + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/abstract_controller/url_for.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/abstract_controller/url_for.rb new file mode 100644 index 0000000..72d07b0 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/abstract_controller/url_for.rb @@ -0,0 +1,33 @@ +module AbstractController + # Includes +url_for+ into the host class (e.g. an abstract controller or mailer). The class + # has to provide a +RouteSet+ by implementing the _routes methods. Otherwise, an + # exception will be raised. + # + # Note that this module is completely decoupled from HTTP - the only requirement is a valid + # _routes implementation. + module UrlFor + extend ActiveSupport::Concern + include ActionDispatch::Routing::UrlFor + + def _routes + raise "In order to use #url_for, you must include routing helpers explicitly. " \ + "For instance, `include Rails.application.routes.url_helpers`." + end + + module ClassMethods + def _routes + nil + end + + def action_methods + @action_methods ||= begin + if _routes + super - _routes.named_routes.helper_names + else + super + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller.rb new file mode 100644 index 0000000..91ac7ee --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller.rb @@ -0,0 +1,58 @@ +require 'active_support/rails' +require 'abstract_controller' +require 'action_dispatch' +require 'action_controller/metal/live' +require 'action_controller/metal/strong_parameters' + +module ActionController + extend ActiveSupport::Autoload + + autoload :Base + autoload :Caching + autoload :Metal + autoload :Middleware + + autoload_under "metal" do + autoload :Compatibility + autoload :ConditionalGet + autoload :Cookies + autoload :DataStreaming + autoload :EtagWithTemplateDigest + autoload :Flash + autoload :ForceSSL + autoload :Head + autoload :Helpers + autoload :HideActions + autoload :HttpAuthentication + autoload :ImplicitRender + autoload :Instrumentation + autoload :MimeResponds + autoload :ParamsWrapper + autoload :RackDelegation + autoload :Redirecting + autoload :Renderers + autoload :Rendering + autoload :RequestForgeryProtection + autoload :Rescue + autoload :Streaming + autoload :StrongParameters + autoload :Testing + autoload :UrlFor + end + + autoload :TestCase, 'action_controller/test_case' + autoload :TemplateAssertions, 'action_controller/test_case' + + def self.eager_load! + super + ActionController::Caching.eager_load! + end +end + +# Common Active Support usage in Action Controller +require 'active_support/core_ext/module/attribute_accessors' +require 'active_support/core_ext/load_error' +require 'active_support/core_ext/module/attr_internal' +require 'active_support/core_ext/name_error' +require 'active_support/core_ext/uri' +require 'active_support/inflector' diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/base.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/base.rb new file mode 100644 index 0000000..4a612a8 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/base.rb @@ -0,0 +1,268 @@ +require 'action_view' +require "action_controller/log_subscriber" +require "action_controller/metal/params_wrapper" + +module ActionController + # Action Controllers are the core of a web request in \Rails. They are made up of one or more actions that are executed + # on request and then either it renders a template or redirects to another action. An action is defined as a public method + # on the controller, which will automatically be made accessible to the web-server through \Rails Routes. + # + # By default, only the ApplicationController in a \Rails application inherits from ActionController::Base. All other + # controllers in turn inherit from ApplicationController. This gives you one class to configure things such as + # request forgery protection and filtering of sensitive request parameters. + # + # A sample controller could look like this: + # + # class PostsController < ApplicationController + # def index + # @posts = Post.all + # end + # + # def create + # @post = Post.create params[:post] + # redirect_to posts_path + # end + # end + # + # Actions, by default, render a template in the app/views directory corresponding to the name of the controller and action + # after executing code in the action. For example, the +index+ action of the PostsController would render the + # template app/views/posts/index.html.erb by default after populating the @posts instance variable. + # + # Unlike index, the create action will not render a template. After performing its main purpose (creating a + # new post), it initiates a redirect instead. This redirect works by returning an external + # "302 Moved" HTTP response that takes the user to the index action. + # + # These two methods represent the two basic action archetypes used in Action Controllers. Get-and-show and do-and-redirect. + # Most actions are variations on these themes. + # + # == Requests + # + # For every request, the router determines the value of the +controller+ and +action+ keys. These determine which controller + # and action are called. The remaining request parameters, the session (if one is available), and the full request with + # all the HTTP headers are made available to the action through accessor methods. Then the action is performed. + # + # The full request object is available via the request accessor and is primarily used to query for HTTP headers: + # + # def server_ip + # location = request.env["REMOTE_ADDR"] + # render plain: "This server hosted at #{location}" + # end + # + # == Parameters + # + # All request parameters, whether they come from a GET or POST request, or from the URL, are available through the params method + # which returns a hash. For example, an action that was performed through /posts?category=All&limit=5 will include + # { "category" => "All", "limit" => "5" } in params. + # + # It's also possible to construct multi-dimensional parameter hashes by specifying keys using brackets, such as: + # + # + # + # + # A request stemming from a form holding these inputs will include { "post" => { "name" => "david", "address" => "hyacintvej" } }. + # If the address input had been named post[address][street], the params would have included + # { "post" => { "address" => { "street" => "hyacintvej" } } }. There's no limit to the depth of the nesting. + # + # == Sessions + # + # Sessions allow you to store objects in between requests. This is useful for objects that are not yet ready to be persisted, + # such as a Signup object constructed in a multi-paged process, or objects that don't change much and are needed all the time, such + # as a User object for a system that requires login. The session should not be used, however, as a cache for objects where it's likely + # they could be changed unknowingly. It's usually too much work to keep it all synchronized -- something databases already excel at. + # + # You can place objects in the session by using the session method, which accesses a hash: + # + # session[:person] = Person.authenticate(user_name, password) + # + # And retrieved again through the same hash: + # + # Hello #{session[:person]} + # + # For removing objects from the session, you can either assign a single key to +nil+: + # + # # removes :person from session + # session[:person] = nil + # + # or you can remove the entire session with +reset_session+. + # + # Sessions are stored by default in a browser cookie that's cryptographically signed, but unencrypted. + # This prevents the user from tampering with the session but also allows them to see its contents. + # + # Do not put secret information in cookie-based sessions! + # + # == Responses + # + # Each action results in a response, which holds the headers and document to be sent to the user's browser. The actual response + # object is generated automatically through the use of renders and redirects and requires no user intervention. + # + # == Renders + # + # Action Controller sends content to the user by using one of five rendering methods. The most versatile and common is the rendering + # of a template. Included in the Action Pack is the Action View, which enables rendering of ERB templates. It's automatically configured. + # The controller passes objects to the view by assigning instance variables: + # + # def show + # @post = Post.find(params[:id]) + # end + # + # Which are then automatically available to the view: + # + # Title: <%= @post.title %> + # + # You don't have to rely on the automated rendering. For example, actions that could result in the rendering of different templates + # will use the manual rendering methods: + # + # def search + # @results = Search.find(params[:query]) + # case @results.count + # when 0 then render action: "no_results" + # when 1 then render action: "show" + # when 2..10 then render action: "show_many" + # end + # end + # + # Read more about writing ERB and Builder templates in ActionView::Base. + # + # == Redirects + # + # Redirects are used to move from one action to another. For example, after a create action, which stores a blog entry to the + # database, we might like to show the user the new entry. Because we're following good DRY principles (Don't Repeat Yourself), we're + # going to reuse (and redirect to) a show action that we'll assume has already been created. The code might look like this: + # + # def create + # @entry = Entry.new(params[:entry]) + # if @entry.save + # # The entry was saved correctly, redirect to show + # redirect_to action: 'show', id: @entry.id + # else + # # things didn't go so well, do something else + # end + # end + # + # In this case, after saving our new entry to the database, the user is redirected to the show method, which is then executed. + # Note that this is an external HTTP-level redirection which will cause the browser to make a second request (a GET to the show action), + # and not some internal re-routing which calls both "create" and then "show" within one request. + # + # Learn more about redirect_to and what options you have in ActionController::Redirecting. + # + # == Calling multiple redirects or renders + # + # An action may contain only a single render or a single redirect. Attempting to try to do either again will result in a DoubleRenderError: + # + # def do_something + # redirect_to action: "elsewhere" + # render action: "overthere" # raises DoubleRenderError + # end + # + # If you need to redirect on the condition of something, then be sure to add "and return" to halt execution. + # + # def do_something + # redirect_to(action: "elsewhere") and return if monkeys.nil? + # render action: "overthere" # won't be called if monkeys is nil + # end + # + class Base < Metal + abstract! + + # We document the request and response methods here because albeit they are + # implemented in ActionController::Metal, the type of the returned objects + # is unknown at that level. + + ## + # :method: request + # + # Returns an ActionDispatch::Request instance that represents the + # current request. + + ## + # :method: response + # + # Returns an ActionDispatch::Response that represents the current + # response. + + # Shortcut helper that returns all the modules included in + # ActionController::Base except the ones passed as arguments: + # + # class MyBaseController < ActionController::Metal + # ActionController::Base.without_modules(:ParamsWrapper, :Streaming).each do |left| + # include left + # end + # end + # + # This gives better control over what you want to exclude and makes it + # easier to create a bare controller class, instead of listing the modules + # required manually. + def self.without_modules(*modules) + modules = modules.map do |m| + m.is_a?(Symbol) ? ActionController.const_get(m) : m + end + + MODULES - modules + end + + MODULES = [ + AbstractController::Rendering, + AbstractController::Translation, + AbstractController::AssetPaths, + + Helpers, + HideActions, + UrlFor, + Redirecting, + ActionView::Layouts, + Rendering, + Renderers::All, + ConditionalGet, + EtagWithTemplateDigest, + RackDelegation, + Caching, + MimeResponds, + ImplicitRender, + StrongParameters, + + Cookies, + Flash, + RequestForgeryProtection, + ForceSSL, + Streaming, + DataStreaming, + HttpAuthentication::Basic::ControllerMethods, + HttpAuthentication::Digest::ControllerMethods, + HttpAuthentication::Token::ControllerMethods, + + # Before callbacks should also be executed the earliest as possible, so + # also include them at the bottom. + AbstractController::Callbacks, + + # Append rescue at the bottom to wrap as much as possible. + Rescue, + + # Add instrumentations hooks at the bottom, to ensure they instrument + # all the methods properly. + Instrumentation, + + # Params wrapper should come before instrumentation so they are + # properly showed in logs + ParamsWrapper + ] + + MODULES.each do |mod| + include mod + end + + # Define some internal variables that should not be propagated to the view. + PROTECTED_IVARS = AbstractController::Rendering::DEFAULT_PROTECTED_INSTANCE_VARIABLES + [ + :@_status, :@_headers, :@_params, :@_env, :@_response, :@_request, + :@_view_runtime, :@_stream, :@_url_options, :@_action_has_layout ] + + def _protected_ivars # :nodoc: + PROTECTED_IVARS + end + + def self.protected_instance_variables + PROTECTED_IVARS + end + + ActiveSupport.run_load_hooks(:action_controller, self) + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/caching.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/caching.rb new file mode 100644 index 0000000..de85e0c --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/caching.rb @@ -0,0 +1,89 @@ +require 'fileutils' +require 'uri' +require 'set' + +module ActionController + # \Caching is a cheap way of speeding up slow applications by keeping the result of + # calculations, renderings, and database calls around for subsequent requests. + # + # You can read more about each approach by clicking the modules below. + # + # Note: To turn off all caching, set + # config.action_controller.perform_caching = false + # + # == \Caching stores + # + # All the caching stores from ActiveSupport::Cache are available to be used as backends + # for Action Controller caching. + # + # Configuration examples (FileStore is the default): + # + # config.action_controller.cache_store = :memory_store + # config.action_controller.cache_store = :file_store, '/path/to/cache/directory' + # config.action_controller.cache_store = :mem_cache_store, 'localhost' + # config.action_controller.cache_store = :mem_cache_store, Memcached::Rails.new('localhost:11211') + # config.action_controller.cache_store = MyOwnStore.new('parameter') + module Caching + extend ActiveSupport::Concern + extend ActiveSupport::Autoload + + eager_autoload do + autoload :Fragments + end + + module ConfigMethods + def cache_store + config.cache_store + end + + def cache_store=(store) + config.cache_store = ActiveSupport::Cache.lookup_store(store) + end + + private + def cache_configured? + perform_caching && cache_store + end + end + + include RackDelegation + include AbstractController::Callbacks + + include ConfigMethods + include Fragments + + included do + extend ConfigMethods + + config_accessor :default_static_extension + self.default_static_extension ||= '.html' + + config_accessor :perform_caching + self.perform_caching = true if perform_caching.nil? + + class_attribute :_view_cache_dependencies + self._view_cache_dependencies = [] + helper_method :view_cache_dependencies if respond_to?(:helper_method) + end + + module ClassMethods + def view_cache_dependency(&dependency) + self._view_cache_dependencies += [dependency] + end + end + + def view_cache_dependencies + self.class._view_cache_dependencies.map { |dep| instance_exec(&dep) }.compact + end + + protected + # Convenience accessor. + def cache(key, options = {}, &block) + if cache_configured? + cache_store.fetch(ActiveSupport::Cache.expand_cache_key(key, :controller), options, &block) + else + yield + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/caching/fragments.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/caching/fragments.rb new file mode 100644 index 0000000..2694d4c --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/caching/fragments.rb @@ -0,0 +1,103 @@ +module ActionController + module Caching + # Fragment caching is used for caching various blocks within + # views without caching the entire action as a whole. This is + # useful when certain elements of an action change frequently or + # depend on complicated state while other parts rarely change or + # can be shared amongst multiple parties. The caching is done using + # the +cache+ helper available in the Action View. See + # ActionView::Helpers::CacheHelper for more information. + # + # While it's strongly recommended that you use key-based cache + # expiration (see links in CacheHelper for more information), + # it is also possible to manually expire caches. For example: + # + # expire_fragment('name_of_cache') + module Fragments + # Given a key (as described in +expire_fragment+), returns + # a key suitable for use in reading, writing, or expiring a + # cached fragment. All keys are prefixed with views/ and uses + # ActiveSupport::Cache.expand_cache_key for the expansion. + def fragment_cache_key(key) + ActiveSupport::Cache.expand_cache_key(key.is_a?(Hash) ? url_for(key).split("://").last : key, :views) + end + + # Writes +content+ to the location signified by + # +key+ (see +expire_fragment+ for acceptable formats). + def write_fragment(key, content, options = nil) + return content unless cache_configured? + + key = fragment_cache_key(key) + instrument_fragment_cache :write_fragment, key do + content = content.to_str + cache_store.write(key, content, options) + end + content + end + + # Reads a cached fragment from the location signified by +key+ + # (see +expire_fragment+ for acceptable formats). + def read_fragment(key, options = nil) + return unless cache_configured? + + key = fragment_cache_key(key) + instrument_fragment_cache :read_fragment, key do + result = cache_store.read(key, options) + result.respond_to?(:html_safe) ? result.html_safe : result + end + end + + # Check if a cached fragment from the location signified by + # +key+ exists (see +expire_fragment+ for acceptable formats). + def fragment_exist?(key, options = nil) + return unless cache_configured? + key = fragment_cache_key(key) + + instrument_fragment_cache :exist_fragment?, key do + cache_store.exist?(key, options) + end + end + + # Removes fragments from the cache. + # + # +key+ can take one of three forms: + # + # * String - This would normally take the form of a path, like + # pages/45/notes. + # * Hash - Treated as an implicit call to +url_for+, like + # { controller: 'pages', action: 'notes', id: 45} + # * Regexp - Will remove any fragment that matches, so + # %r{pages/\d*/notes} might remove all notes. Make sure you + # don't use anchors in the regex (^ or $) because + # the actual filename matched looks like + # ./cache/filename/path.cache. Note: Regexp expiration is + # only supported on caches that can iterate over all keys (unlike + # memcached). + # + # +options+ is passed through to the cache store's +delete+ + # method (or delete_matched, for Regexp keys). + def expire_fragment(key, options = nil) + return unless cache_configured? + key = fragment_cache_key(key) unless key.is_a?(Regexp) + + instrument_fragment_cache :expire_fragment, key do + if key.is_a?(Regexp) + cache_store.delete_matched(key, options) + else + cache_store.delete(key, options) + end + end + end + + def instrument_fragment_cache(name, key) # :nodoc: + payload = { + controller: controller_name, + action: action_name, + key: key + } + + ActiveSupport::Notifications.instrument("#{name}.action_controller", payload) { yield } + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/log_subscriber.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/log_subscriber.rb new file mode 100644 index 0000000..d3f93a5 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/log_subscriber.rb @@ -0,0 +1,83 @@ +module ActionController + class LogSubscriber < ActiveSupport::LogSubscriber + INTERNAL_PARAMS = %w(controller action format _method only_path) + + def start_processing(event) + return unless logger.info? + + payload = event.payload + params = payload[:params].except(*INTERNAL_PARAMS) + format = payload[:format] + format = format.to_s.upcase if format.is_a?(Symbol) + + info "Processing by #{payload[:controller]}##{payload[:action]} as #{format}" + info " Parameters: #{params.inspect}" unless params.empty? + end + + def process_action(event) + info do + payload = event.payload + additions = ActionController::Base.log_process_action(payload) + + status = payload[:status] + if status.nil? && payload[:exception].present? + exception_class_name = payload[:exception].first + status = ActionDispatch::ExceptionWrapper.status_code_for_exception(exception_class_name) + end + message = "Completed #{status} #{Rack::Utils::HTTP_STATUS_CODES[status]} in #{event.duration.round}ms" + message << " (#{additions.join(" | ")})" unless additions.blank? + message + end + end + + def halted_callback(event) + info { "Filter chain halted as #{event.payload[:filter].inspect} rendered or redirected" } + end + + def send_file(event) + info { "Sent file #{event.payload[:path]} (#{event.duration.round(1)}ms)" } + end + + def redirect_to(event) + info { "Redirected to #{event.payload[:location]}" } + end + + def send_data(event) + info { "Sent data #{event.payload[:filename]} (#{event.duration.round(1)}ms)" } + end + + def unpermitted_parameters(event) + debug do + unpermitted_keys = event.payload[:keys] + "Unpermitted parameter#{'s' if unpermitted_keys.size > 1}: #{unpermitted_keys.join(", ")}" + end + end + + def deep_munge(event) + debug do + "Value for params[:#{event.payload[:keys].join('][:')}] was set "\ + "to nil, because it was one of [], [null] or [null, null, ...]. "\ + "Go to http://guides.rubyonrails.org/security.html#unsafe-query-generation "\ + "for more information."\ + end + end + + %w(write_fragment read_fragment exist_fragment? + expire_fragment expire_page write_page).each do |method| + class_eval <<-METHOD, __FILE__, __LINE__ + 1 + def #{method}(event) + return unless logger.info? + key_or_path = event.payload[:key] || event.payload[:path] + human_name = #{method.to_s.humanize.inspect} + info("\#{human_name} \#{key_or_path} (\#{event.duration.round(1)}ms)") + end + METHOD + end + + def logger + ActionController::Base.logger + end + end +end + +ActionController::LogSubscriber.attach_to :action_controller diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal.rb new file mode 100644 index 0000000..993f8e1 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal.rb @@ -0,0 +1,241 @@ +require 'active_support/core_ext/array/extract_options' +require 'action_dispatch/middleware/stack' + +module ActionController + # Extend ActionDispatch middleware stack to make it aware of options + # allowing the following syntax in controllers: + # + # class PostsController < ApplicationController + # use AuthenticationMiddleware, except: [:index, :show] + # end + # + class MiddlewareStack < ActionDispatch::MiddlewareStack #:nodoc: + class Middleware < ActionDispatch::MiddlewareStack::Middleware #:nodoc: + def initialize(klass, *args, &block) + options = args.extract_options! + @only = Array(options.delete(:only)).map(&:to_s) + @except = Array(options.delete(:except)).map(&:to_s) + args << options unless options.empty? + super + end + + def valid?(action) + if @only.present? + @only.include?(action) + elsif @except.present? + !@except.include?(action) + else + true + end + end + end + + def build(action, app = Proc.new) + action = action.to_s + + middlewares.reverse.inject(app) do |a, middleware| + middleware.valid?(action) ? middleware.build(a) : a + end + end + end + + # ActionController::Metal is the simplest possible controller, providing a + # valid Rack interface without the additional niceties provided by + # ActionController::Base. + # + # A sample metal controller might look like this: + # + # class HelloController < ActionController::Metal + # def index + # self.response_body = "Hello World!" + # end + # end + # + # And then to route requests to your metal controller, you would add + # something like this to config/routes.rb: + # + # get 'hello', to: HelloController.action(:index) + # + # The +action+ method returns a valid Rack application for the \Rails + # router to dispatch to. + # + # == Rendering Helpers + # + # ActionController::Metal by default provides no utilities for rendering + # views, partials, or other responses aside from explicitly calling of + # response_body=, content_type=, and status=. To + # add the render helpers you're used to having in a normal controller, you + # can do the following: + # + # class HelloController < ActionController::Metal + # include AbstractController::Rendering + # include ActionView::Layouts + # append_view_path "#{Rails.root}/app/views" + # + # def index + # render "hello/index" + # end + # end + # + # == Redirection Helpers + # + # To add redirection helpers to your metal controller, do the following: + # + # class HelloController < ActionController::Metal + # include ActionController::Redirecting + # include Rails.application.routes.url_helpers + # + # def index + # redirect_to root_url + # end + # end + # + # == Other Helpers + # + # You can refer to the modules included in ActionController::Base to see + # other features you can bring into your metal controller. + # + class Metal < AbstractController::Base + abstract! + + attr_internal_writer :env + + def env + @_env ||= {} + end + + # Returns the last part of the controller's name, underscored, without the ending + # Controller. For instance, PostsController returns posts. + # Namespaces are left out, so Admin::PostsController returns posts as well. + # + # ==== Returns + # * string + def self.controller_name + @controller_name ||= name.demodulize.sub(/Controller$/, '').underscore + end + + # Delegates to the class' controller_name + def controller_name + self.class.controller_name + end + + # The details below can be overridden to support a specific + # Request and Response object. The default ActionController::Base + # implementation includes RackDelegation, which makes a request + # and response object available. You might wish to control the + # environment and response manually for performance reasons. + + attr_internal :headers, :response, :request + delegate :session, :to => "@_request" + + def initialize + @_headers = {"Content-Type" => "text/html"} + @_status = 200 + @_request = nil + @_response = nil + @_routes = nil + super + end + + def params + @_params ||= request.parameters + end + + def params=(val) + @_params = val + end + + # Basic implementations for content_type=, location=, and headers are + # provided to reduce the dependency on the RackDelegation module + # in Renderer and Redirector. + + def content_type=(type) + headers["Content-Type"] = type.to_s + end + + def content_type + headers["Content-Type"] + end + + def location + headers["Location"] + end + + def location=(url) + headers["Location"] = url + end + + # Basic url_for that can be overridden for more robust functionality + def url_for(string) + string + end + + def status + @_status + end + alias :response_code :status # :nodoc: + + def status=(status) + @_status = Rack::Utils.status_code(status) + end + + def response_body=(body) + body = [body] unless body.nil? || body.respond_to?(:each) + super + end + + # Tests if render or redirect has already happened. + def performed? + response_body || (response && response.committed?) + end + + def dispatch(name, request) #:nodoc: + @_request = request + @_env = request.env + @_env['action_controller.instance'] = self + process(name) + to_a + end + + def to_a #:nodoc: + response ? response.to_a : [status, headers, response_body] + end + + class_attribute :middleware_stack + self.middleware_stack = ActionController::MiddlewareStack.new + + def self.inherited(base) # :nodoc: + base.middleware_stack = middleware_stack.dup + super + end + + # Pushes the given Rack middleware and its arguments to the bottom of the + # middleware stack. + def self.use(*args, &block) + middleware_stack.use(*args, &block) + end + + # Alias for +middleware_stack+. + def self.middleware + middleware_stack + end + + # Makes the controller a Rack endpoint that runs the action in the given + # +env+'s +action_dispatch.request.path_parameters+ key. + def self.call(env) + req = ActionDispatch::Request.new env + action(req.path_parameters[:action]).call(env) + end + + # Returns a Rack endpoint for the given action name. + def self.action(name, klass = ActionDispatch::Request) + if middleware_stack.any? + middleware_stack.build(name) do |env| + new.dispatch(name, klass.new(env)) + end + else + lambda { |env| new.dispatch(name, klass.new(env)) } + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/conditional_get.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/conditional_get.rb new file mode 100644 index 0000000..b210ee3 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/conditional_get.rb @@ -0,0 +1,200 @@ +require 'active_support/core_ext/hash/keys' + +module ActionController + module ConditionalGet + extend ActiveSupport::Concern + + include RackDelegation + include Head + + included do + class_attribute :etaggers + self.etaggers = [] + end + + module ClassMethods + # Allows you to consider additional controller-wide information when generating an ETag. + # For example, if you serve pages tailored depending on who's logged in at the moment, you + # may want to add the current user id to be part of the ETag to prevent authorized displaying + # of cached pages. + # + # class InvoicesController < ApplicationController + # etag { current_user.try :id } + # + # def show + # # Etag will differ even for the same invoice when it's viewed by a different current_user + # @invoice = Invoice.find(params[:id]) + # fresh_when(@invoice) + # end + # end + def etag(&etagger) + self.etaggers += [etagger] + end + end + + # Sets the +etag+, +last_modified+, or both on the response and renders a + # 304 Not Modified response if the request is already fresh. + # + # === Parameters: + # + # * :etag. + # * :last_modified. + # * :public By default the Cache-Control header is private, set this to + # +true+ if you want your application to be cachable by other devices (proxy caches). + # * :template By default, the template digest for the current + # controller/action is included in ETags. If the action renders a + # different template, you can include its digest instead. If the action + # doesn't render a template at all, you can pass template: false + # to skip any attempt to check for a template digest. + # + # === Example: + # + # def show + # @article = Article.find(params[:id]) + # fresh_when(etag: @article, last_modified: @article.created_at, public: true) + # end + # + # This will render the show template if the request isn't sending a matching ETag or + # If-Modified-Since header and just a 304 Not Modified response if there's a match. + # + # You can also just pass a record where +last_modified+ will be set by calling + # +updated_at+ and the +etag+ by passing the object itself. + # + # def show + # @article = Article.find(params[:id]) + # fresh_when(@article) + # end + # + # When passing a record, you can still set whether the public header: + # + # def show + # @article = Article.find(params[:id]) + # fresh_when(@article, public: true) + # end + # + # When rendering a different template than the default controller/action + # style, you can indicate which digest to include in the ETag: + # + # before_action { fresh_when @article, template: 'widgets/show' } + # + def fresh_when(record_or_options, additional_options = {}) + if record_or_options.is_a? Hash + options = record_or_options + options.assert_valid_keys(:etag, :last_modified, :public, :template) + else + record = record_or_options + options = { etag: record, last_modified: record.try(:updated_at) }.merge!(additional_options) + end + + response.etag = combine_etags(options) if options[:etag] || options[:template] + response.last_modified = options[:last_modified] if options[:last_modified] + response.cache_control[:public] = true if options[:public] + + head :not_modified if request.fresh?(response) + end + + # Sets the +etag+ and/or +last_modified+ on the response and checks it against + # the client request. If the request doesn't match the options provided, the + # request is considered stale and should be generated from scratch. Otherwise, + # it's fresh and we don't need to generate anything and a reply of 304 Not Modified is sent. + # + # === Parameters: + # + # * :etag. + # * :last_modified. + # * :public By default the Cache-Control header is private, set this to + # +true+ if you want your application to be cachable by other devices (proxy caches). + # * :template By default, the template digest for the current + # controller/action is included in ETags. If the action renders a + # different template, you can include its digest instead. If the action + # doesn't render a template at all, you can pass template: false + # to skip any attempt to check for a template digest. + # + # === Example: + # + # def show + # @article = Article.find(params[:id]) + # + # if stale?(etag: @article, last_modified: @article.created_at) + # @statistics = @article.really_expensive_call + # respond_to do |format| + # # all the supported formats + # end + # end + # end + # + # You can also just pass a record where +last_modified+ will be set by calling + # +updated_at+ and the +etag+ by passing the object itself. + # + # def show + # @article = Article.find(params[:id]) + # + # if stale?(@article) + # @statistics = @article.really_expensive_call + # respond_to do |format| + # # all the supported formats + # end + # end + # end + # + # When passing a record, you can still set whether the public header: + # + # def show + # @article = Article.find(params[:id]) + # + # if stale?(@article, public: true) + # @statistics = @article.really_expensive_call + # respond_to do |format| + # # all the supported formats + # end + # end + # end + # + # When rendering a different template than the default controller/action + # style, you can indicate which digest to include in the ETag: + # + # def show + # super if stale? @article, template: 'widgets/show' + # end + # + def stale?(record_or_options, additional_options = {}) + fresh_when(record_or_options, additional_options) + !request.fresh?(response) + end + + # Sets a HTTP 1.1 Cache-Control header. Defaults to issuing a +private+ + # instruction, so that intermediate caches must not cache the response. + # + # expires_in 20.minutes + # expires_in 3.hours, public: true + # expires_in 3.hours, public: true, must_revalidate: true + # + # This method will overwrite an existing Cache-Control header. + # See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html for more possibilities. + # + # The method will also ensure a HTTP Date header for client compatibility. + def expires_in(seconds, options = {}) + response.cache_control.merge!( + :max_age => seconds, + :public => options.delete(:public), + :must_revalidate => options.delete(:must_revalidate) + ) + options.delete(:private) + + response.cache_control[:extras] = options.map {|k,v| "#{k}=#{v}"} + response.date = Time.now unless response.date? + end + + # Sets a HTTP 1.1 Cache-Control header of no-cache so no caching should + # occur by the browser or intermediate caches (like caching proxy servers). + def expires_now + response.cache_control.replace(:no_cache => true) + end + + private + def combine_etags(options) + etags = etaggers.map { |etagger| instance_exec(options, &etagger) }.compact + etags.unshift options[:etag] + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/cookies.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/cookies.rb new file mode 100644 index 0000000..d787f01 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/cookies.rb @@ -0,0 +1,16 @@ +module ActionController #:nodoc: + module Cookies + extend ActiveSupport::Concern + + include RackDelegation + + included do + helper_method :cookies + end + + private + def cookies + request.cookie_jar + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/data_streaming.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/data_streaming.rb new file mode 100644 index 0000000..1abd8d3 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/data_streaming.rb @@ -0,0 +1,171 @@ +require 'action_controller/metal/exceptions' + +module ActionController #:nodoc: + # Methods for sending arbitrary data and for streaming files to the browser, + # instead of rendering. + module DataStreaming + extend ActiveSupport::Concern + + include ActionController::Rendering + + DEFAULT_SEND_FILE_TYPE = 'application/octet-stream'.freeze #:nodoc: + DEFAULT_SEND_FILE_DISPOSITION = 'attachment'.freeze #:nodoc: + + protected + # Sends the file. This uses a server-appropriate method (such as X-Sendfile) + # via the Rack::Sendfile middleware. The header to use is set via + # +config.action_dispatch.x_sendfile_header+. + # Your server can also configure this for you by setting the X-Sendfile-Type header. + # + # Be careful to sanitize the path parameter if it is coming from a web + # page. send_file(params[:path]) allows a malicious user to + # download any file on your server. + # + # Options: + # * :filename - suggests a filename for the browser to use. + # Defaults to File.basename(path). + # * :type - specifies an HTTP content type. + # You can specify either a string or a symbol for a registered type register with + # Mime::Type.register, for example :json + # If omitted, type will be guessed from the file extension specified in :filename. + # If no content type is registered for the extension, default type 'application/octet-stream' will be used. + # * :disposition - specifies whether the file will be shown inline or downloaded. + # Valid values are 'inline' and 'attachment' (default). + # * :status - specifies the status code to send with the response. Defaults to 200. + # * :url_based_filename - set to +true+ if you want the browser guess the filename from + # the URL, which is necessary for i18n filenames on certain browsers + # (setting :filename overrides this option). + # + # The default Content-Type and Content-Disposition headers are + # set to download arbitrary binary files in as many browsers as + # possible. IE versions 4, 5, 5.5, and 6 are all known to have + # a variety of quirks (especially when downloading over SSL). + # + # Simple download: + # + # send_file '/path/to.zip' + # + # Show a JPEG in the browser: + # + # send_file '/path/to.jpeg', type: 'image/jpeg', disposition: 'inline' + # + # Show a 404 page in the browser: + # + # send_file '/path/to/404.html', type: 'text/html; charset=utf-8', status: 404 + # + # Read about the other Content-* HTTP headers if you'd like to + # provide the user with more information (such as Content-Description) in + # http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.11. + # + # Also be aware that the document may be cached by proxies and browsers. + # The Pragma and Cache-Control headers declare how the file may be cached + # by intermediaries. They default to require clients to validate with + # the server before releasing cached responses. See + # http://www.mnot.net/cache_docs/ for an overview of web caching and + # http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9 + # for the Cache-Control header spec. + def send_file(path, options = {}) #:doc: + raise MissingFile, "Cannot read file #{path}" unless File.file?(path) and File.readable?(path) + + options[:filename] ||= File.basename(path) unless options[:url_based_filename] + send_file_headers! options + + self.status = options[:status] || 200 + self.content_type = options[:content_type] if options.key?(:content_type) + self.response_body = FileBody.new(path) + end + + # Avoid having to pass an open file handle as the response body. + # Rack::Sendfile will usually intercept the response and uses + # the path directly, so there is no reason to open the file. + class FileBody #:nodoc: + attr_reader :to_path + + def initialize(path) + @to_path = path + end + + # Stream the file's contents if Rack::Sendfile isn't present. + def each + File.open(to_path, 'rb') do |file| + while chunk = file.read(16384) + yield chunk + end + end + end + end + + # Sends the given binary data to the browser. This method is similar to + # render plain: data, but also allows you to specify whether + # the browser should display the response as a file attachment (i.e. in a + # download dialog) or as inline data. You may also set the content type, + # the apparent file name, and other things. + # + # Options: + # * :filename - suggests a filename for the browser to use. + # * :type - specifies an HTTP content type. Defaults to 'application/octet-stream'. You can specify + # either a string or a symbol for a registered type register with Mime::Type.register, for example :json + # If omitted, type will be guessed from the file extension specified in :filename. + # If no content type is registered for the extension, default type 'application/octet-stream' will be used. + # * :disposition - specifies whether the file will be shown inline or downloaded. + # Valid values are 'inline' and 'attachment' (default). + # * :status - specifies the status code to send with the response. Defaults to 200. + # + # Generic data download: + # + # send_data buffer + # + # Download a dynamically-generated tarball: + # + # send_data generate_tgz('dir'), filename: 'dir.tgz' + # + # Display an image Active Record in the browser: + # + # send_data image.data, type: image.content_type, disposition: 'inline' + # + # See +send_file+ for more information on HTTP Content-* headers and caching. + def send_data(data, options = {}) #:doc: + send_file_headers! options + render options.slice(:status, :content_type).merge(:text => data) + end + + private + def send_file_headers!(options) + type_provided = options.has_key?(:type) + + content_type = options.fetch(:type, DEFAULT_SEND_FILE_TYPE) + raise ArgumentError, ":type option required" if content_type.nil? + + if content_type.is_a?(Symbol) + extension = Mime[content_type] + raise ArgumentError, "Unknown MIME type #{options[:type]}" unless extension + self.content_type = extension + else + if !type_provided && options[:filename] + # If type wasn't provided, try guessing from file extension. + content_type = Mime::Type.lookup_by_extension(File.extname(options[:filename]).downcase.delete('.')) || content_type + end + self.content_type = content_type + end + + disposition = options.fetch(:disposition, DEFAULT_SEND_FILE_DISPOSITION) + unless disposition.nil? + disposition = disposition.to_s + disposition += %(; filename="#{options[:filename]}") if options[:filename] + headers['Content-Disposition'] = disposition + end + + headers['Content-Transfer-Encoding'] = 'binary' + + response.sending_file = true + + # Fix a problem with IE 6.0 on opening downloaded files: + # If Cache-Control: no-cache is set (which Rails does by default), + # IE removes the file it just downloaded from its cache immediately + # after it displays the "open/save" dialog, which means that if you + # hit "open" the file isn't there anymore when the application that + # is called for handling the download is run, so let's workaround that + response.cache_control[:public] ||= false + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/etag_with_template_digest.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/etag_with_template_digest.rb new file mode 100644 index 0000000..f9303ef --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/etag_with_template_digest.rb @@ -0,0 +1,50 @@ +module ActionController + # When our views change, they should bubble up into HTTP cache freshness + # and bust browser caches. So the template digest for the current action + # is automatically included in the ETag. + # + # Enabled by default for apps that use Action View. Disable by setting + # + # config.action_controller.etag_with_template_digest = false + # + # Override the template to digest by passing +:template+ to +fresh_when+ + # and +stale?+ calls. For example: + # + # # We're going to render widgets/show, not posts/show + # fresh_when @post, template: 'widgets/show' + # + # # We're not going to render a template, so omit it from the ETag. + # fresh_when @post, template: false + # + module EtagWithTemplateDigest + extend ActiveSupport::Concern + + include ActionController::ConditionalGet + + included do + class_attribute :etag_with_template_digest + self.etag_with_template_digest = true + + ActiveSupport.on_load :action_view, yield: true do |action_view_base| + etag do |options| + determine_template_etag(options) if etag_with_template_digest + end + end + end + + private + def determine_template_etag(options) + if template = pick_template_for_etag(options) + lookup_and_digest_template(template) + end + end + + def pick_template_for_etag(options) + options.fetch(:template) { "#{controller_name}/#{action_name}" } + end + + def lookup_and_digest_template(template) + ActionView::Digestor.digest name: template, finder: lookup_context + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/exceptions.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/exceptions.rb new file mode 100644 index 0000000..18e0037 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/exceptions.rb @@ -0,0 +1,59 @@ +module ActionController + class ActionControllerError < StandardError #:nodoc: + end + + class BadRequest < ActionControllerError #:nodoc: + attr_reader :original_exception + + def initialize(type = nil, e = nil) + return super() unless type && e + + super("Invalid #{type} parameters: #{e.message}") + @original_exception = e + set_backtrace e.backtrace + end + end + + class RenderError < ActionControllerError #:nodoc: + end + + class RoutingError < ActionControllerError #:nodoc: + attr_reader :failures + def initialize(message, failures=[]) + super(message) + @failures = failures + end + end + + class ActionController::UrlGenerationError < ActionControllerError #:nodoc: + end + + class MethodNotAllowed < ActionControllerError #:nodoc: + def initialize(*allowed_methods) + super("Only #{allowed_methods.to_sentence(:locale => :en)} requests are allowed.") + end + end + + class NotImplemented < MethodNotAllowed #:nodoc: + end + + class UnknownController < ActionControllerError #:nodoc: + end + + class MissingFile < ActionControllerError #:nodoc: + end + + class SessionOverflowError < ActionControllerError #:nodoc: + DEFAULT_MESSAGE = 'Your session data is larger than the data column in which it is to be stored. You must increase the size of your data column if you intend to store large data.' + + def initialize(message = nil) + super(message || DEFAULT_MESSAGE) + end + end + + class UnknownHttpMethod < ActionControllerError #:nodoc: + end + + class UnknownFormat < ActionControllerError #:nodoc: + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/flash.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/flash.rb new file mode 100644 index 0000000..6535128 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/flash.rb @@ -0,0 +1,60 @@ +module ActionController #:nodoc: + module Flash + extend ActiveSupport::Concern + + included do + class_attribute :_flash_types, instance_accessor: false + self._flash_types = [] + + delegate :flash, to: :request + add_flash_types(:alert, :notice) + end + + module ClassMethods + # Creates new flash types. You can pass as many types as you want to create + # flash types other than the default alert and notice in + # your controllers and views. For instance: + # + # # in application_controller.rb + # class ApplicationController < ActionController::Base + # add_flash_types :warning + # end + # + # # in your controller + # redirect_to user_path(@user), warning: "Incomplete profile" + # + # # in your view + # <%= warning %> + # + # This method will automatically define a new method for each of the given + # names, and it will be available in your views. + def add_flash_types(*types) + types.each do |type| + next if _flash_types.include?(type) + + define_method(type) do + request.flash[type] + end + helper_method type + + self._flash_types += [type] + end + end + end + + protected + def redirect_to(options = {}, response_status_and_flash = {}) #:doc: + self.class._flash_types.each do |flash_type| + if type = response_status_and_flash.delete(flash_type) + flash[flash_type] = type + end + end + + if other_flashes = response_status_and_flash.delete(:flash) + flash.update(other_flashes) + end + + super(options, response_status_and_flash) + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/force_ssl.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/force_ssl.rb new file mode 100644 index 0000000..d920668 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/force_ssl.rb @@ -0,0 +1,97 @@ +require 'active_support/core_ext/hash/except' +require 'active_support/core_ext/hash/slice' + +module ActionController + # This module provides a method which will redirect browser to use HTTPS + # protocol. This will ensure that user's sensitive information will be + # transferred safely over the internet. You _should_ always force browser + # to use HTTPS when you're transferring sensitive information such as + # user authentication, account information, or credit card information. + # + # Note that if you are really concerned about your application security, + # you might consider using +config.force_ssl+ in your config file instead. + # That will ensure all the data transferred via HTTPS protocol and prevent + # user from getting session hijacked when accessing the site under unsecured + # HTTP protocol. + module ForceSSL + extend ActiveSupport::Concern + include AbstractController::Callbacks + + ACTION_OPTIONS = [:only, :except, :if, :unless] + URL_OPTIONS = [:protocol, :host, :domain, :subdomain, :port, :path] + REDIRECT_OPTIONS = [:status, :flash, :alert, :notice] + + module ClassMethods + # Force the request to this particular controller or specified actions to be + # under HTTPS protocol. + # + # If you need to disable this for any reason (e.g. development) then you can use + # an +:if+ or +:unless+ condition. + # + # class AccountsController < ApplicationController + # force_ssl if: :ssl_configured? + # + # def ssl_configured? + # !Rails.env.development? + # end + # end + # + # ==== URL Options + # You can pass any of the following options to affect the redirect url + # * host - Redirect to a different host name + # * subdomain - Redirect to a different subdomain + # * domain - Redirect to a different domain + # * port - Redirect to a non-standard port + # * path - Redirect to a different path + # + # ==== Redirect Options + # You can pass any of the following options to affect the redirect status and response + # * status - Redirect with a custom status (default is 301 Moved Permanently) + # * flash - Set a flash message when redirecting + # * alert - Set an alert message when redirecting + # * notice - Set a notice message when redirecting + # + # ==== Action Options + # You can pass any of the following options to affect the before_action callback + # * only - The callback should be run only for this action + # * except - The callback should be run for all actions except this action + # * if - A symbol naming an instance method or a proc; the callback + # will be called only when it returns a true value. + # * unless - A symbol naming an instance method or a proc; the callback + # will be called only when it returns a false value. + def force_ssl(options = {}) + action_options = options.slice(*ACTION_OPTIONS) + redirect_options = options.except(*ACTION_OPTIONS) + before_action(action_options) do + force_ssl_redirect(redirect_options) + end + end + end + + # Redirect the existing request to use the HTTPS protocol. + # + # ==== Parameters + # * host_or_options - Either a host name or any of the url & redirect options + # available to the force_ssl method. + def force_ssl_redirect(host_or_options = nil) + unless request.ssl? + options = { + :protocol => 'https://', + :host => request.host, + :path => request.fullpath, + :status => :moved_permanently + } + + if host_or_options.is_a?(Hash) + options.merge!(host_or_options) + elsif host_or_options + options[:host] = host_or_options + end + + secure_url = ActionDispatch::Http::URL.url_for(options.slice(*URL_OPTIONS)) + flash.keep if respond_to?(:flash) + redirect_to secure_url, options.slice(*REDIRECT_OPTIONS) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/head.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/head.rb new file mode 100644 index 0000000..70f42bf --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/head.rb @@ -0,0 +1,58 @@ +module ActionController + module Head + # Returns a response that has no content (merely headers). The options + # argument is interpreted to be a hash of header names and values. + # This allows you to easily return a response that consists only of + # significant headers: + # + # head :created, location: person_path(@person) + # + # head :created, location: @person + # + # It can also be used to return exceptional conditions: + # + # return head(:method_not_allowed) unless request.post? + # return head(:bad_request) unless valid_request? + # render + # + # See Rack::Utils::SYMBOL_TO_STATUS_CODE for a full list of valid +status+ symbols. + def head(status, options = {}) + options, status = status, nil if status.is_a?(Hash) + status ||= options.delete(:status) || :ok + location = options.delete(:location) + content_type = options.delete(:content_type) + + options.each do |key, value| + headers[key.to_s.dasherize.split('-').each { |v| v[0] = v[0].chr.upcase }.join('-')] = value.to_s + end + + self.status = status + self.location = url_for(location) if location + + self.response_body = "" + + if include_content?(self.response_code) + self.content_type = content_type || (Mime[formats.first] if formats) + self.response.charset = false if self.response + else + headers.delete('Content-Type') + headers.delete('Content-Length') + end + + true + end + + private + # :nodoc: + def include_content?(status) + case status + when 100..199 + false + when 204, 205, 304 + false + else + true + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/helpers.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/helpers.rb new file mode 100644 index 0000000..a9c3e43 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/helpers.rb @@ -0,0 +1,113 @@ +module ActionController + # The \Rails framework provides a large number of helpers for working with assets, dates, forms, + # numbers and model objects, to name a few. These helpers are available to all templates + # by default. + # + # In addition to using the standard template helpers provided, creating custom helpers to + # extract complicated logic or reusable functionality is strongly encouraged. By default, each controller + # will include all helpers. These helpers are only accessible on the controller through .helpers + # + # In previous versions of \Rails the controller will include a helper whose + # name matches that of the controller, e.g., MyController will automatically + # include MyHelper. To return old behavior set +config.action_controller.include_all_helpers+ to +false+. + # + # Additional helpers can be specified using the +helper+ class method in ActionController::Base or any + # controller which inherits from it. + # + # The +to_s+ method from the \Time class can be wrapped in a helper method to display a custom message if + # a \Time object is blank: + # + # module FormattedTimeHelper + # def format_time(time, format=:long, blank_message=" ") + # time.blank? ? blank_message : time.to_s(format) + # end + # end + # + # FormattedTimeHelper can now be included in a controller, using the +helper+ class method: + # + # class EventsController < ActionController::Base + # helper FormattedTimeHelper + # def index + # @events = Event.all + # end + # end + # + # Then, in any view rendered by EventController, the format_time method can be called: + # + # <% @events.each do |event| -%> + #

+ # <%= format_time(event.time, :short, "N/A") %> | <%= event.name %> + #

+ # <% end -%> + # + # Finally, assuming we have two event instances, one which has a time and one which does not, + # the output might look like this: + # + # 23 Aug 11:30 | Carolina Railhawks Soccer Match + # N/A | Carolina Railhaws Training Workshop + # + module Helpers + extend ActiveSupport::Concern + + class << self; attr_accessor :helpers_path; end + include AbstractController::Helpers + + included do + class_attribute :helpers_path, :include_all_helpers + self.helpers_path ||= [] + self.include_all_helpers = true + end + + module ClassMethods + # Declares helper accessors for controller attributes. For example, the + # following adds new +name+ and name= instance methods to a + # controller and makes them available to the view: + # attr_accessor :name + # helper_attr :name + # + # ==== Parameters + # * attrs - Names of attributes to be converted into helpers. + def helper_attr(*attrs) + attrs.flatten.each { |attr| helper_method(attr, "#{attr}=") } + end + + # Provides a proxy to access helpers methods from outside the view. + def helpers + @helper_proxy ||= begin + proxy = ActionView::Base.new + proxy.config = config.inheritable_copy + proxy.extend(_helpers) + end + end + + # Overwrite modules_for_helpers to accept :all as argument, which loads + # all helpers in helpers_path. + # + # ==== Parameters + # * args - A list of helpers + # + # ==== Returns + # * array - A normalized list of modules for the list of helpers provided. + def modules_for_helpers(args) + args += all_application_helpers if args.delete(:all) + super(args) + end + + def all_helpers_from_path(path) + helpers = Array(path).flat_map do |_path| + extract = /^#{Regexp.quote(_path.to_s)}\/?(.*)_helper.rb$/ + names = Dir["#{_path}/**/*_helper.rb"].map { |file| file.sub(extract, '\1') } + names.sort! + end + helpers.uniq! + helpers + end + + private + # Extract helper names from files in app/helpers/**/*_helper.rb + def all_application_helpers + all_helpers_from_path(helpers_path) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/hide_actions.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/hide_actions.rb new file mode 100644 index 0000000..af36ffa --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/hide_actions.rb @@ -0,0 +1,40 @@ + +module ActionController + # Adds the ability to prevent public methods on a controller to be called as actions. + module HideActions + extend ActiveSupport::Concern + + included do + class_attribute :hidden_actions + self.hidden_actions = Set.new.freeze + end + + private + + # Overrides AbstractController::Base#action_method? to return false if the + # action name is in the list of hidden actions. + def method_for_action(action_name) + self.class.visible_action?(action_name) && super + end + + module ClassMethods + # Sets all of the actions passed in as hidden actions. + # + # ==== Parameters + # * args - A list of actions + def hide_action(*args) + self.hidden_actions = hidden_actions.dup.merge(args.map(&:to_s)).freeze + end + + def visible_action?(action_name) + not hidden_actions.include?(action_name) + end + + # Overrides AbstractController::Base#action_methods to remove any methods + # that are listed as hidden methods. + def action_methods + @action_methods ||= Set.new(super.reject { |name| hidden_actions.include?(name) }).freeze + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/http_authentication.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/http_authentication.rb new file mode 100644 index 0000000..2777d0f --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/http_authentication.rb @@ -0,0 +1,512 @@ +require 'base64' +require 'active_support/security_utils' + +module ActionController + # Makes it dead easy to do HTTP Basic, Digest and Token authentication. + module HttpAuthentication + # Makes it dead easy to do HTTP \Basic authentication. + # + # === Simple \Basic example + # + # class PostsController < ApplicationController + # http_basic_authenticate_with name: "dhh", password: "secret", except: :index + # + # def index + # render plain: "Everyone can see me!" + # end + # + # def edit + # render plain: "I'm only accessible if you know the password" + # end + # end + # + # === Advanced \Basic example + # + # Here is a more advanced \Basic example where only Atom feeds and the XML API is protected by HTTP authentication, + # the regular HTML interface is protected by a session approach: + # + # class ApplicationController < ActionController::Base + # before_action :set_account, :authenticate + # + # protected + # def set_account + # @account = Account.find_by(url_name: request.subdomains.first) + # end + # + # def authenticate + # case request.format + # when Mime::XML, Mime::ATOM + # if user = authenticate_with_http_basic { |u, p| @account.users.authenticate(u, p) } + # @current_user = user + # else + # request_http_basic_authentication + # end + # else + # if session_authenticated? + # @current_user = @account.users.find(session[:authenticated][:user_id]) + # else + # redirect_to(login_url) and return false + # end + # end + # end + # end + # + # In your integration tests, you can do something like this: + # + # def test_access_granted_from_xml + # @request.env['HTTP_AUTHORIZATION'] = ActionController::HttpAuthentication::Basic.encode_credentials(users(:dhh).name, users(:dhh).password) + # get "/notes/1.xml" + # + # assert_equal 200, status + # end + module Basic + extend self + + module ControllerMethods + extend ActiveSupport::Concern + + module ClassMethods + def http_basic_authenticate_with(options = {}) + before_action(options.except(:name, :password, :realm)) do + authenticate_or_request_with_http_basic(options[:realm] || "Application") do |name, password| + # This comparison uses & so that it doesn't short circuit and + # uses `variable_size_secure_compare` so that length information + # isn't leaked. + ActiveSupport::SecurityUtils.variable_size_secure_compare(name, options[:name]) & + ActiveSupport::SecurityUtils.variable_size_secure_compare(password, options[:password]) + end + end + end + end + + def authenticate_or_request_with_http_basic(realm = "Application", &login_procedure) + authenticate_with_http_basic(&login_procedure) || request_http_basic_authentication(realm) + end + + def authenticate_with_http_basic(&login_procedure) + HttpAuthentication::Basic.authenticate(request, &login_procedure) + end + + def request_http_basic_authentication(realm = "Application") + HttpAuthentication::Basic.authentication_request(self, realm) + end + end + + def authenticate(request, &login_procedure) + if has_basic_credentials?(request) + login_procedure.call(*user_name_and_password(request)) + end + end + + def has_basic_credentials?(request) + request.authorization.present? && (auth_scheme(request) == 'Basic') + end + + def user_name_and_password(request) + decode_credentials(request).split(':', 2) + end + + def decode_credentials(request) + ::Base64.decode64(auth_param(request) || '') + end + + def auth_scheme(request) + request.authorization.split(' ', 2).first + end + + def auth_param(request) + request.authorization.split(' ', 2).second + end + + def encode_credentials(user_name, password) + "Basic #{::Base64.strict_encode64("#{user_name}:#{password}")}" + end + + def authentication_request(controller, realm) + controller.headers["WWW-Authenticate"] = %(Basic realm="#{realm.gsub(/"/, "")}") + controller.status = 401 + controller.response_body = "HTTP Basic: Access denied.\n" + end + end + + # Makes it dead easy to do HTTP \Digest authentication. + # + # === Simple \Digest example + # + # require 'digest/md5' + # class PostsController < ApplicationController + # REALM = "SuperSecret" + # USERS = {"dhh" => "secret", #plain text password + # "dap" => Digest::MD5.hexdigest(["dap",REALM,"secret"].join(":"))} #ha1 digest password + # + # before_action :authenticate, except: [:index] + # + # def index + # render plain: "Everyone can see me!" + # end + # + # def edit + # render plain: "I'm only accessible if you know the password" + # end + # + # private + # def authenticate + # authenticate_or_request_with_http_digest(REALM) do |username| + # USERS[username] + # end + # end + # end + # + # === Notes + # + # The +authenticate_or_request_with_http_digest+ block must return the user's password + # or the ha1 digest hash so the framework can appropriately hash to check the user's + # credentials. Returning +nil+ will cause authentication to fail. + # + # Storing the ha1 hash: MD5(username:realm:password), is better than storing a plain password. If + # the password file or database is compromised, the attacker would be able to use the ha1 hash to + # authenticate as the user at this +realm+, but would not have the user's password to try using at + # other sites. + # + # In rare instances, web servers or front proxies strip authorization headers before + # they reach your application. You can debug this situation by logging all environment + # variables, and check for HTTP_AUTHORIZATION, amongst others. + module Digest + extend self + + module ControllerMethods + def authenticate_or_request_with_http_digest(realm = "Application", &password_procedure) + authenticate_with_http_digest(realm, &password_procedure) || request_http_digest_authentication(realm) + end + + # Authenticate with HTTP Digest, returns true or false + def authenticate_with_http_digest(realm = "Application", &password_procedure) + HttpAuthentication::Digest.authenticate(request, realm, &password_procedure) + end + + # Render output including the HTTP Digest authentication header + def request_http_digest_authentication(realm = "Application", message = nil) + HttpAuthentication::Digest.authentication_request(self, realm, message) + end + end + + # Returns false on a valid response, true otherwise + def authenticate(request, realm, &password_procedure) + request.authorization && validate_digest_response(request, realm, &password_procedure) + end + + # Returns false unless the request credentials response value matches the expected value. + # First try the password as a ha1 digest password. If this fails, then try it as a plain + # text password. + def validate_digest_response(request, realm, &password_procedure) + secret_key = secret_token(request) + credentials = decode_credentials_header(request) + valid_nonce = validate_nonce(secret_key, request, credentials[:nonce]) + + if valid_nonce && realm == credentials[:realm] && opaque(secret_key) == credentials[:opaque] + password = password_procedure.call(credentials[:username]) + return false unless password + + method = request.env['rack.methodoverride.original_method'] || request.env['REQUEST_METHOD'] + uri = credentials[:uri] + + [true, false].any? do |trailing_question_mark| + [true, false].any? do |password_is_ha1| + _uri = trailing_question_mark ? uri + "?" : uri + expected = expected_response(method, _uri, credentials, password, password_is_ha1) + expected == credentials[:response] + end + end + end + end + + # Returns the expected response for a request of +http_method+ to +uri+ with the decoded +credentials+ and the expected +password+ + # Optional parameter +password_is_ha1+ is set to +true+ by default, since best practice is to store ha1 digest instead + # of a plain-text password. + def expected_response(http_method, uri, credentials, password, password_is_ha1=true) + ha1 = password_is_ha1 ? password : ha1(credentials, password) + ha2 = ::Digest::MD5.hexdigest([http_method.to_s.upcase, uri].join(':')) + ::Digest::MD5.hexdigest([ha1, credentials[:nonce], credentials[:nc], credentials[:cnonce], credentials[:qop], ha2].join(':')) + end + + def ha1(credentials, password) + ::Digest::MD5.hexdigest([credentials[:username], credentials[:realm], password].join(':')) + end + + def encode_credentials(http_method, credentials, password, password_is_ha1) + credentials[:response] = expected_response(http_method, credentials[:uri], credentials, password, password_is_ha1) + "Digest " + credentials.sort_by {|x| x[0].to_s }.map {|v| "#{v[0]}='#{v[1]}'" }.join(', ') + end + + def decode_credentials_header(request) + decode_credentials(request.authorization) + end + + def decode_credentials(header) + ActiveSupport::HashWithIndifferentAccess[header.to_s.gsub(/^Digest\s+/, '').split(',').map do |pair| + key, value = pair.split('=', 2) + [key.strip, value.to_s.gsub(/^"|"$/,'').delete('\'')] + end] + end + + def authentication_header(controller, realm) + secret_key = secret_token(controller.request) + nonce = self.nonce(secret_key) + opaque = opaque(secret_key) + controller.headers["WWW-Authenticate"] = %(Digest realm="#{realm}", qop="auth", algorithm=MD5, nonce="#{nonce}", opaque="#{opaque}") + end + + def authentication_request(controller, realm, message = nil) + message ||= "HTTP Digest: Access denied.\n" + authentication_header(controller, realm) + controller.status = 401 + controller.response_body = message + end + + def secret_token(request) + key_generator = request.env["action_dispatch.key_generator"] + http_auth_salt = request.env["action_dispatch.http_auth_salt"] + key_generator.generate_key(http_auth_salt) + end + + # Uses an MD5 digest based on time to generate a value to be used only once. + # + # A server-specified data string which should be uniquely generated each time a 401 response is made. + # It is recommended that this string be base64 or hexadecimal data. + # Specifically, since the string is passed in the header lines as a quoted string, the double-quote character is not allowed. + # + # The contents of the nonce are implementation dependent. + # The quality of the implementation depends on a good choice. + # A nonce might, for example, be constructed as the base 64 encoding of + # + # time-stamp H(time-stamp ":" ETag ":" private-key) + # + # where time-stamp is a server-generated time or other non-repeating value, + # ETag is the value of the HTTP ETag header associated with the requested entity, + # and private-key is data known only to the server. + # With a nonce of this form a server would recalculate the hash portion after receiving the client authentication header and + # reject the request if it did not match the nonce from that header or + # if the time-stamp value is not recent enough. In this way the server can limit the time of the nonce's validity. + # The inclusion of the ETag prevents a replay request for an updated version of the resource. + # (Note: including the IP address of the client in the nonce would appear to offer the server the ability + # to limit the reuse of the nonce to the same client that originally got it. + # However, that would break proxy farms, where requests from a single user often go through different proxies in the farm. + # Also, IP address spoofing is not that hard.) + # + # An implementation might choose not to accept a previously used nonce or a previously used digest, in order to + # protect against a replay attack. Or, an implementation might choose to use one-time nonces or digests for + # POST, PUT, or PATCH requests and a time-stamp for GET requests. For more details on the issues involved see Section 4 + # of this document. + # + # The nonce is opaque to the client. Composed of Time, and hash of Time with secret + # key from the Rails session secret generated upon creation of project. Ensures + # the time cannot be modified by client. + def nonce(secret_key, time = Time.now) + t = time.to_i + hashed = [t, secret_key] + digest = ::Digest::MD5.hexdigest(hashed.join(":")) + ::Base64.strict_encode64("#{t}:#{digest}") + end + + # Might want a shorter timeout depending on whether the request + # is a PATCH, PUT, or POST, and if client is browser or web service. + # Can be much shorter if the Stale directive is implemented. This would + # allow a user to use new nonce without prompting user again for their + # username and password. + def validate_nonce(secret_key, request, value, seconds_to_timeout=5*60) + return false if value.nil? + t = ::Base64.decode64(value).split(":").first.to_i + nonce(secret_key, t) == value && (t - Time.now.to_i).abs <= seconds_to_timeout + end + + # Opaque based on random generation - but changing each request? + def opaque(secret_key) + ::Digest::MD5.hexdigest(secret_key) + end + + end + + # Makes it dead easy to do HTTP Token authentication. + # + # Simple Token example: + # + # class PostsController < ApplicationController + # TOKEN = "secret" + # + # before_action :authenticate, except: [ :index ] + # + # def index + # render plain: "Everyone can see me!" + # end + # + # def edit + # render plain: "I'm only accessible if you know the password" + # end + # + # private + # def authenticate + # authenticate_or_request_with_http_token do |token, options| + # token == TOKEN + # end + # end + # end + # + # + # Here is a more advanced Token example where only Atom feeds and the XML API is protected by HTTP token authentication, + # the regular HTML interface is protected by a session approach: + # + # class ApplicationController < ActionController::Base + # before_action :set_account, :authenticate + # + # protected + # def set_account + # @account = Account.find_by(url_name: request.subdomains.first) + # end + # + # def authenticate + # case request.format + # when Mime::XML, Mime::ATOM + # if user = authenticate_with_http_token { |t, o| @account.users.authenticate(t, o) } + # @current_user = user + # else + # request_http_token_authentication + # end + # else + # if session_authenticated? + # @current_user = @account.users.find(session[:authenticated][:user_id]) + # else + # redirect_to(login_url) and return false + # end + # end + # end + # end + # + # + # In your integration tests, you can do something like this: + # + # def test_access_granted_from_xml + # get( + # "/notes/1.xml", nil, + # 'HTTP_AUTHORIZATION' => ActionController::HttpAuthentication::Token.encode_credentials(users(:dhh).token) + # ) + # + # assert_equal 200, status + # end + # + # + # On shared hosts, Apache sometimes doesn't pass authentication headers to + # FCGI instances. If your environment matches this description and you cannot + # authenticate, try this rule in your Apache setup: + # + # RewriteRule ^(.*)$ dispatch.fcgi [E=X-HTTP_AUTHORIZATION:%{HTTP:Authorization},QSA,L] + module Token + TOKEN_KEY = 'token=' + TOKEN_REGEX = /^Token / + AUTHN_PAIR_DELIMITERS = /(?:,|;|\t+)/ + extend self + + module ControllerMethods + def authenticate_or_request_with_http_token(realm = "Application", &login_procedure) + authenticate_with_http_token(&login_procedure) || request_http_token_authentication(realm) + end + + def authenticate_with_http_token(&login_procedure) + Token.authenticate(self, &login_procedure) + end + + def request_http_token_authentication(realm = "Application") + Token.authentication_request(self, realm) + end + end + + # If token Authorization header is present, call the login + # procedure with the present token and options. + # + # [controller] + # ActionController::Base instance for the current request. + # + # [login_procedure] + # Proc to call if a token is present. The Proc should take two arguments: + # + # authenticate(controller) { |token, options| ... } + # + # Returns the return value of login_procedure if a + # token is found. Returns nil if no token is found. + + def authenticate(controller, &login_procedure) + token, options = token_and_options(controller.request) + unless token.blank? + login_procedure.call(token, options) + end + end + + # Parses the token and options out of the token authorization header. If + # the header looks like this: + # Authorization: Token token="abc", nonce="def" + # Then the returned token is "abc", and the options is {nonce: "def"} + # + # request - ActionDispatch::Request instance with the current headers. + # + # Returns an Array of [String, Hash] if a token is present. + # Returns nil if no token is found. + def token_and_options(request) + authorization_request = request.authorization.to_s + if authorization_request[TOKEN_REGEX] + params = token_params_from authorization_request + [params.shift[1], Hash[params].with_indifferent_access] + end + end + + def token_params_from(auth) + rewrite_param_values params_array_from raw_params auth + end + + # Takes raw_params and turns it into an array of parameters + def params_array_from(raw_params) + raw_params.map { |param| param.split %r/=(.+)?/ } + end + + # This removes the " characters wrapping the value. + def rewrite_param_values(array_params) + array_params.each { |param| (param[1] || "").gsub! %r/^"|"$/, '' } + end + + # This method takes an authorization body and splits up the key-value + # pairs by the standardized :, ;, or \t + # delimiters defined in +AUTHN_PAIR_DELIMITERS+. + def raw_params(auth) + _raw_params = auth.sub(TOKEN_REGEX, '').split(/\s*#{AUTHN_PAIR_DELIMITERS}\s*/) + + if !(_raw_params.first =~ %r{\A#{TOKEN_KEY}}) + _raw_params[0] = "#{TOKEN_KEY}#{_raw_params.first}" + end + + _raw_params + end + + # Encodes the given token and options into an Authorization header value. + # + # token - String token. + # options - optional Hash of the options. + # + # Returns String. + def encode_credentials(token, options = {}) + values = ["#{TOKEN_KEY}#{token.to_s.inspect}"] + options.map do |key, value| + "#{key}=#{value.to_s.inspect}" + end + "Token #{values * ", "}" + end + + # Sets a WWW-Authenticate to let the client know a token is desired. + # + # controller - ActionController::Base instance for the outgoing response. + # realm - String realm to use in the header. + # + # Returns nothing. + def authentication_request(controller, realm) + controller.headers["WWW-Authenticate"] = %(Token realm="#{realm.gsub(/"/, "")}") + controller.__send__ :render, :text => "HTTP Token: Access denied.\n", :status => :unauthorized + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/implicit_render.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/implicit_render.rb new file mode 100644 index 0000000..ae04b53 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/implicit_render.rb @@ -0,0 +1,19 @@ +module ActionController + module ImplicitRender + def send_action(method, *args) + ret = super + default_render unless performed? + ret + end + + def default_render(*args) + render(*args) + end + + def method_for_action(action_name) + super || if template_exists?(action_name.to_s, _prefixes) + "default_render" + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/instrumentation.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/instrumentation.rb new file mode 100644 index 0000000..a3e1a71 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/instrumentation.rb @@ -0,0 +1,109 @@ +require 'benchmark' +require 'abstract_controller/logger' + +module ActionController + # Adds instrumentation to several ends in ActionController::Base. It also provides + # some hooks related with process_action, this allows an ORM like Active Record + # and/or DataMapper to plug in ActionController and show related information. + # + # Check ActiveRecord::Railties::ControllerRuntime for an example. + module Instrumentation + extend ActiveSupport::Concern + + include AbstractController::Logger + include ActionController::RackDelegation + + attr_internal :view_runtime + + def process_action(*args) + raw_payload = { + :controller => self.class.name, + :action => self.action_name, + :params => request.filtered_parameters, + :format => request.format.try(:ref), + :method => request.request_method, + :path => (request.fullpath rescue "unknown") + } + + ActiveSupport::Notifications.instrument("start_processing.action_controller", raw_payload.dup) + + ActiveSupport::Notifications.instrument("process_action.action_controller", raw_payload) do |payload| + begin + result = super + payload[:status] = response.status + result + ensure + append_info_to_payload(payload) + end + end + end + + def render(*args) + render_output = nil + self.view_runtime = cleanup_view_runtime do + Benchmark.ms { render_output = super } + end + render_output + end + + def send_file(path, options={}) + ActiveSupport::Notifications.instrument("send_file.action_controller", + options.merge(:path => path)) do + super + end + end + + def send_data(data, options = {}) + ActiveSupport::Notifications.instrument("send_data.action_controller", options) do + super + end + end + + def redirect_to(*args) + ActiveSupport::Notifications.instrument("redirect_to.action_controller") do |payload| + result = super + payload[:status] = response.status + payload[:location] = response.filtered_location + result + end + end + + private + + # A hook invoked every time a before callback is halted. + def halted_callback_hook(filter) + ActiveSupport::Notifications.instrument("halted_callback.action_controller", :filter => filter) + end + + # A hook which allows you to clean up any time taken into account in + # views wrongly, like database querying time. + # + # def cleanup_view_runtime + # super - time_taken_in_something_expensive + # end + # + # :api: plugin + def cleanup_view_runtime #:nodoc: + yield + end + + # Every time after an action is processed, this method is invoked + # with the payload, so you can add more information. + # :api: plugin + def append_info_to_payload(payload) #:nodoc: + payload[:view_runtime] = view_runtime + end + + module ClassMethods + # A hook which allows other frameworks to log what happened during + # controller process action. This method should return an array + # with the messages to be added. + # :api: plugin + def log_process_action(payload) #:nodoc: + messages, view_runtime = [], payload[:view_runtime] + messages << ("Views: %.1fms" % view_runtime.to_f) if view_runtime + messages + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/live.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/live.rb new file mode 100644 index 0000000..1e13b37 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/live.rb @@ -0,0 +1,328 @@ +require 'action_dispatch/http/response' +require 'delegate' +require 'active_support/json' + +module ActionController + # Mix this module in to your controller, and all actions in that controller + # will be able to stream data to the client as it's written. + # + # class MyController < ActionController::Base + # include ActionController::Live + # + # def stream + # response.headers['Content-Type'] = 'text/event-stream' + # 100.times { + # response.stream.write "hello world\n" + # sleep 1 + # } + # ensure + # response.stream.close + # end + # end + # + # There are a few caveats with this use. You *cannot* write headers after the + # response has been committed (Response#committed? will return truthy). + # Calling +write+ or +close+ on the response stream will cause the response + # object to be committed. Make sure all headers are set before calling write + # or close on your stream. + # + # You *must* call close on your stream when you're finished, otherwise the + # socket may be left open forever. + # + # The final caveat is that your actions are executed in a separate thread than + # the main thread. Make sure your actions are thread safe, and this shouldn't + # be a problem (don't share state across threads, etc). + module Live + # This class provides the ability to write an SSE (Server Sent Event) + # to an IO stream. The class is initialized with a stream and can be used + # to either write a JSON string or an object which can be converted to JSON. + # + # Writing an object will convert it into standard SSE format with whatever + # options you have configured. You may choose to set the following options: + # + # 1) Event. If specified, an event with this name will be dispatched on + # the browser. + # 2) Retry. The reconnection time in milliseconds used when attempting + # to send the event. + # 3) Id. If the connection dies while sending an SSE to the browser, then + # the server will receive a +Last-Event-ID+ header with value equal to +id+. + # + # After setting an option in the constructor of the SSE object, all future + # SSEs sent across the stream will use those options unless overridden. + # + # Example Usage: + # + # class MyController < ActionController::Base + # include ActionController::Live + # + # def index + # response.headers['Content-Type'] = 'text/event-stream' + # sse = SSE.new(response.stream, retry: 300, event: "event-name") + # sse.write({ name: 'John'}) + # sse.write({ name: 'John'}, id: 10) + # sse.write({ name: 'John'}, id: 10, event: "other-event") + # sse.write({ name: 'John'}, id: 10, event: "other-event", retry: 500) + # ensure + # sse.close + # end + # end + # + # Note: SSEs are not currently supported by IE. However, they are supported + # by Chrome, Firefox, Opera, and Safari. + class SSE + + WHITELISTED_OPTIONS = %w( retry event id ) + + def initialize(stream, options = {}) + @stream = stream + @options = options + end + + def close + @stream.close + end + + def write(object, options = {}) + case object + when String + perform_write(object, options) + else + perform_write(ActiveSupport::JSON.encode(object), options) + end + end + + private + + def perform_write(json, options) + current_options = @options.merge(options).stringify_keys + + WHITELISTED_OPTIONS.each do |option_name| + if (option_value = current_options[option_name]) + @stream.write "#{option_name}: #{option_value}\n" + end + end + + message = json.gsub(/\n/, "\ndata: ") + @stream.write "data: #{message}\n\n" + end + end + + class ClientDisconnected < RuntimeError + end + + class Buffer < ActionDispatch::Response::Buffer #:nodoc: + include MonitorMixin + + # Ignore that the client has disconnected. + # + # If this value is `true`, calling `write` after the client + # disconnects will result in the written content being silently + # discarded. If this value is `false` (the default), a + # ClientDisconnected exception will be raised. + attr_accessor :ignore_disconnect + + def initialize(response) + @error_callback = lambda { true } + @cv = new_cond + @aborted = false + @ignore_disconnect = false + super(response, SizedQueue.new(10)) + end + + def write(string) + unless @response.committed? + @response.headers["Cache-Control"] = "no-cache" + @response.headers.delete "Content-Length" + end + + super + + unless connected? + @buf.clear + + unless @ignore_disconnect + # Raise ClientDisconnected, which is a RuntimeError (not an + # IOError), because that's more appropriate for something beyond + # the developer's control. + raise ClientDisconnected, "client disconnected" + end + end + end + + def each + @response.sending! + while str = @buf.pop + yield str + end + @response.sent! + end + + # Write a 'close' event to the buffer; the producer/writing thread + # uses this to notify us that it's finished supplying content. + # + # See also #abort. + def close + synchronize do + super + @buf.push nil + @cv.broadcast + end + end + + # Inform the producer/writing thread that the client has + # disconnected; the reading thread is no longer interested in + # anything that's being written. + # + # See also #close. + def abort + synchronize do + @aborted = true + @buf.clear + end + end + + # Is the client still connected and waiting for content? + # + # The result of calling `write` when this is `false` is determined + # by `ignore_disconnect`. + def connected? + !@aborted + end + + def await_close + synchronize do + @cv.wait_until { @closed } + end + end + + def on_error(&block) + @error_callback = block + end + + def call_on_error + @error_callback.call + end + end + + class Response < ActionDispatch::Response #:nodoc: all + class Header < DelegateClass(Hash) # :nodoc: + def initialize(response, header) + @response = response + super(header) + end + + def []=(k,v) + if @response.committed? + raise ActionDispatch::IllegalStateError, 'header already sent' + end + + super + end + + def merge(other) + self.class.new @response, __getobj__.merge(other) + end + + def to_hash + __getobj__.dup + end + end + + private + + def before_committed + super + jar = request.cookie_jar + # The response can be committed multiple times + jar.write self unless committed? + end + + def before_sending + super + request.cookie_jar.commit! + headers.freeze + end + + def build_buffer(response, body) + buf = Live::Buffer.new response + body.each { |part| buf.write part } + buf + end + + def merge_default_headers(original, default) + Header.new self, super + end + + def handle_conditional_get! + super unless committed? + end + end + + def process(name) + t1 = Thread.current + locals = t1.keys.map { |key| [key, t1[key]] } + + error = nil + # This processes the action in a child thread. It lets us return the + # response code and headers back up the rack stack, and still process + # the body in parallel with sending data to the client + Thread.new { + t2 = Thread.current + t2.abort_on_exception = true + + # Since we're processing the view in a different thread, copy the + # thread locals from the main thread to the child thread. :'( + locals.each { |k,v| t2[k] = v } + + begin + super(name) + rescue => e + if @_response.committed? + begin + @_response.stream.write(ActionView::Base.streaming_completion_on_exception) if request.format == :html + @_response.stream.call_on_error + rescue => exception + log_error(exception) + ensure + log_error(e) + @_response.stream.close + end + else + error = e + end + ensure + @_response.commit! + end + } + + @_response.await_commit + raise error if error + end + + def log_error(exception) + logger = ActionController::Base.logger + return unless logger + + logger.fatal do + message = "\n#{exception.class} (#{exception.message}):\n" + message << exception.annoted_source_code.to_s if exception.respond_to?(:annoted_source_code) + message << " " << exception.backtrace.join("\n ") + "#{message}\n\n" + end + end + + def response_body=(body) + super + response.close if response + end + + def set_response!(request) + if request.env["HTTP_VERSION"] == "HTTP/1.0" + super + else + @_response = Live::Response.new + @_response.request = request + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/mime_responds.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/mime_responds.rb new file mode 100644 index 0000000..54216b9 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/mime_responds.rb @@ -0,0 +1,326 @@ +require 'abstract_controller/collector' + +module ActionController #:nodoc: + module MimeResponds + extend ActiveSupport::Concern + + # :stopdoc: + module ClassMethods + def respond_to(*) + raise NoMethodError, "The controller-level `respond_to' feature has " \ + "been extracted to the `responders` gem. Add it to your Gemfile to " \ + "continue using this feature:\n" \ + " gem 'responders', '~> 2.0'\n" \ + "Consult the Rails upgrade guide for details." + end + end + + def respond_with(*) + raise NoMethodError, "The `respond_with' feature has been extracted " \ + "to the `responders` gem. Add it to your Gemfile to continue using " \ + "this feature:\n" \ + " gem 'responders', '~> 2.0'\n" \ + "Consult the Rails upgrade guide for details." + end + # :startdoc: + + # Without web-service support, an action which collects the data for displaying a list of people + # might look something like this: + # + # def index + # @people = Person.all + # end + # + # Here's the same action, with web-service support baked in: + # + # def index + # @people = Person.all + # + # respond_to do |format| + # format.html + # format.xml { render xml: @people } + # end + # end + # + # What that says is, "if the client wants HTML in response to this action, just respond as we + # would have before, but if the client wants XML, return them the list of people in XML format." + # (Rails determines the desired response format from the HTTP Accept header submitted by the client.) + # + # Supposing you have an action that adds a new person, optionally creating their company + # (by name) if it does not already exist, without web-services, it might look like this: + # + # def create + # @company = Company.find_or_create_by(name: params[:company][:name]) + # @person = @company.people.create(params[:person]) + # + # redirect_to(person_list_url) + # end + # + # Here's the same action, with web-service support baked in: + # + # def create + # company = params[:person].delete(:company) + # @company = Company.find_or_create_by(name: company[:name]) + # @person = @company.people.create(params[:person]) + # + # respond_to do |format| + # format.html { redirect_to(person_list_url) } + # format.js + # format.xml { render xml: @person.to_xml(include: @company) } + # end + # end + # + # If the client wants HTML, we just redirect them back to the person list. If they want JavaScript, + # then it is an Ajax request and we render the JavaScript template associated with this action. + # Lastly, if the client wants XML, we render the created person as XML, but with a twist: we also + # include the person's company in the rendered XML, so you get something like this: + # + # + # ... + # ... + # + # ... + # ... + # ... + # + # + # + # Note, however, the extra bit at the top of that action: + # + # company = params[:person].delete(:company) + # @company = Company.find_or_create_by(name: company[:name]) + # + # This is because the incoming XML document (if a web-service request is in process) can only contain a + # single root-node. So, we have to rearrange things so that the request looks like this (url-encoded): + # + # person[name]=...&person[company][name]=...&... + # + # And, like this (xml-encoded): + # + # + # ... + # + # ... + # + # + # + # In other words, we make the request so that it operates on a single entity's person. Then, in the action, + # we extract the company data from the request, find or create the company, and then create the new person + # with the remaining data. + # + # Note that you can define your own XML parameter parser which would allow you to describe multiple entities + # in a single request (i.e., by wrapping them all in a single root node), but if you just go with the flow + # and accept Rails' defaults, life will be much easier. + # + # If you need to use a MIME type which isn't supported by default, you can register your own handlers in + # config/initializers/mime_types.rb as follows. + # + # Mime::Type.register "image/jpg", :jpg + # + # Respond to also allows you to specify a common block for different formats by using any: + # + # def index + # @people = Person.all + # + # respond_to do |format| + # format.html + # format.any(:xml, :json) { render request.format.to_sym => @people } + # end + # end + # + # In the example above, if the format is xml, it will render: + # + # render xml: @people + # + # Or if the format is json: + # + # render json: @people + # + # Formats can have different variants. + # + # The request variant is a specialization of the request format, like :tablet, + # :phone, or :desktop. + # + # We often want to render different html/json/xml templates for phones, + # tablets, and desktop browsers. Variants make it easy. + # + # You can set the variant in a +before_action+: + # + # request.variant = :tablet if request.user_agent =~ /iPad/ + # + # Respond to variants in the action just like you respond to formats: + # + # respond_to do |format| + # format.html do |variant| + # variant.tablet # renders app/views/projects/show.html+tablet.erb + # variant.phone { extra_setup; render ... } + # variant.none { special_setup } # executed only if there is no variant set + # end + # end + # + # Provide separate templates for each format and variant: + # + # app/views/projects/show.html.erb + # app/views/projects/show.html+tablet.erb + # app/views/projects/show.html+phone.erb + # + # When you're not sharing any code within the format, you can simplify defining variants + # using the inline syntax: + # + # respond_to do |format| + # format.js { render "trash" } + # format.html.phone { redirect_to progress_path } + # format.html.none { render "trash" } + # end + # + # Variants also support common `any`/`all` block that formats have. + # + # It works for both inline: + # + # respond_to do |format| + # format.html.any { render text: "any" } + # format.html.phone { render text: "phone" } + # end + # + # and block syntax: + # + # respond_to do |format| + # format.html do |variant| + # variant.any(:tablet, :phablet){ render text: "any" } + # variant.phone { render text: "phone" } + # end + # end + # + # You can also set an array of variants: + # + # request.variant = [:tablet, :phone] + # + # which will work similarly to formats and MIME types negotiation. If there will be no + # :tablet variant declared, :phone variant will be picked: + # + # respond_to do |format| + # format.html.none + # format.html.phone # this gets rendered + # end + # + # Be sure to check the documentation of ActionController::MimeResponds.respond_to + # for more examples. + def respond_to(*mimes) + raise ArgumentError, "respond_to takes either types or a block, never both" if mimes.any? && block_given? + + collector = Collector.new(mimes, request.variant) + yield collector if block_given? + + if format = collector.negotiate_format(request) + _process_format(format) + response = collector.response + response ? response.call : render({}) + else + raise ActionController::UnknownFormat + end + end + + # A container for responses available from the current controller for + # requests for different mime-types sent to a particular action. + # + # The public controller methods +respond_to+ may be called with a block + # that is used to define responses to different mime-types, e.g. + # for +respond_to+ : + # + # respond_to do |format| + # format.html + # format.xml { render xml: @people } + # end + # + # In this usage, the argument passed to the block (+format+ above) is an + # instance of the ActionController::MimeResponds::Collector class. This + # object serves as a container in which available responses can be stored by + # calling any of the dynamically generated, mime-type-specific methods such + # as +html+, +xml+ etc on the Collector. Each response is represented by a + # corresponding block if present. + # + # A subsequent call to #negotiate_format(request) will enable the Collector + # to determine which specific mime-type it should respond with for the current + # request, with this response then being accessible by calling #response. + class Collector + include AbstractController::Collector + attr_accessor :format + + def initialize(mimes, variant = nil) + @responses = {} + @variant = variant + + mimes.each { |mime| @responses["Mime::#{mime.upcase}".constantize] = nil } + end + + def any(*args, &block) + if args.any? + args.each { |type| send(type, &block) } + else + custom(Mime::ALL, &block) + end + end + alias :all :any + + def custom(mime_type, &block) + mime_type = Mime::Type.lookup(mime_type.to_s) unless mime_type.is_a?(Mime::Type) + @responses[mime_type] ||= if block_given? + block + else + VariantCollector.new(@variant) + end + end + + def response + response = @responses.fetch(format, @responses[Mime::ALL]) + if response.is_a?(VariantCollector) # `format.html.phone` - variant inline syntax + response.variant + elsif response.nil? || response.arity == 0 # `format.html` - just a format, call its block + response + else # `format.html{ |variant| variant.phone }` - variant block syntax + variant_collector = VariantCollector.new(@variant) + response.call(variant_collector) # call format block with variants collector + variant_collector.variant + end + end + + def negotiate_format(request) + @format = request.negotiate_mime(@responses.keys) + end + + class VariantCollector #:nodoc: + def initialize(variant = nil) + @variant = variant + @variants = {} + end + + def any(*args, &block) + if block_given? + if args.any? && args.none?{ |a| a == @variant } + args.each{ |v| @variants[v] = block } + else + @variants[:any] = block + end + end + end + alias :all :any + + def method_missing(name, *args, &block) + @variants[name] = block if block_given? + end + + def variant + if @variant.nil? + @variants[:none] || @variants[:any] + elsif (@variants.keys & @variant).any? + @variant.each do |v| + return @variants[v] if @variants.key?(v) + end + else + @variants[:any] + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/params_wrapper.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/params_wrapper.rb new file mode 100644 index 0000000..4d41d6b --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/params_wrapper.rb @@ -0,0 +1,285 @@ +require 'active_support/core_ext/hash/slice' +require 'active_support/core_ext/hash/except' +require 'active_support/core_ext/module/anonymous' +require 'active_support/core_ext/struct' +require 'action_dispatch/http/mime_type' + +module ActionController + # Wraps the parameters hash into a nested hash. This will allow clients to + # submit requests without having to specify any root elements. + # + # This functionality is enabled in +config/initializers/wrap_parameters.rb+ + # and can be customized. If you are upgrading to \Rails 3.1, this file will + # need to be created for the functionality to be enabled. + # + # You could also turn it on per controller by setting the format array to + # a non-empty array: + # + # class UsersController < ApplicationController + # wrap_parameters format: [:json, :xml, :url_encoded_form, :multipart_form] + # end + # + # If you enable +ParamsWrapper+ for +:json+ format, instead of having to + # send JSON parameters like this: + # + # {"user": {"name": "Konata"}} + # + # You can send parameters like this: + # + # {"name": "Konata"} + # + # And it will be wrapped into a nested hash with the key name matching the + # controller's name. For example, if you're posting to +UsersController+, + # your new +params+ hash will look like this: + # + # {"name" => "Konata", "user" => {"name" => "Konata"}} + # + # You can also specify the key in which the parameters should be wrapped to, + # and also the list of attributes it should wrap by using either +:include+ or + # +:exclude+ options like this: + # + # class UsersController < ApplicationController + # wrap_parameters :person, include: [:username, :password] + # end + # + # On ActiveRecord models with no +:include+ or +:exclude+ option set, + # it will only wrap the parameters returned by the class method + # attribute_names. + # + # If you're going to pass the parameters to an +ActiveModel+ object (such as + # User.new(params[:user])), you might consider passing the model class to + # the method instead. The +ParamsWrapper+ will actually try to determine the + # list of attribute names from the model and only wrap those attributes: + # + # class UsersController < ApplicationController + # wrap_parameters Person + # end + # + # You still could pass +:include+ and +:exclude+ to set the list of attributes + # you want to wrap. + # + # By default, if you don't specify the key in which the parameters would be + # wrapped to, +ParamsWrapper+ will actually try to determine if there's + # a model related to it or not. This controller, for example: + # + # class Admin::UsersController < ApplicationController + # end + # + # will try to check if Admin::User or +User+ model exists, and use it to + # determine the wrapper key respectively. If both models don't exist, + # it will then fallback to use +user+ as the key. + module ParamsWrapper + extend ActiveSupport::Concern + + EXCLUDE_PARAMETERS = %w(authenticity_token _method utf8) + + require 'mutex_m' + + class Options < Struct.new(:name, :format, :include, :exclude, :klass, :model) # :nodoc: + include Mutex_m + + def self.from_hash(hash) + name = hash[:name] + format = Array(hash[:format]) + include = hash[:include] && Array(hash[:include]).collect(&:to_s) + exclude = hash[:exclude] && Array(hash[:exclude]).collect(&:to_s) + new name, format, include, exclude, nil, nil + end + + def initialize(name, format, include, exclude, klass, model) # nodoc + super + @include_set = include + @name_set = name + end + + def model + super || synchronize { super || self.model = _default_wrap_model } + end + + def include + return super if @include_set + + m = model + synchronize do + return super if @include_set + + @include_set = true + + unless super || exclude + if m.respond_to?(:attribute_names) && m.attribute_names.any? + self.include = m.attribute_names + end + end + end + end + + def name + return super if @name_set + + m = model + synchronize do + return super if @name_set + + @name_set = true + + unless super || klass.anonymous? + self.name = m ? m.to_s.demodulize.underscore : + klass.controller_name.singularize + end + end + end + + private + # Determine the wrapper model from the controller's name. By convention, + # this could be done by trying to find the defined model that has the + # same singularize name as the controller. For example, +UsersController+ + # will try to find if the +User+ model exists. + # + # This method also does namespace lookup. Foo::Bar::UsersController will + # try to find Foo::Bar::User, Foo::User and finally User. + def _default_wrap_model #:nodoc: + return nil if klass.anonymous? + model_name = klass.name.sub(/Controller$/, '').classify + + begin + if model_klass = model_name.safe_constantize + model_klass + else + namespaces = model_name.split("::") + namespaces.delete_at(-2) + break if namespaces.last == model_name + model_name = namespaces.join("::") + end + end until model_klass + + model_klass + end + end + + included do + class_attribute :_wrapper_options + self._wrapper_options = Options.from_hash(format: []) + end + + module ClassMethods + def _set_wrapper_options(options) + self._wrapper_options = Options.from_hash(options) + end + + # Sets the name of the wrapper key, or the model which +ParamsWrapper+ + # would use to determine the attribute names from. + # + # ==== Examples + # wrap_parameters format: :xml + # # enables the parameter wrapper for XML format + # + # wrap_parameters :person + # # wraps parameters into +params[:person]+ hash + # + # wrap_parameters Person + # # wraps parameters by determining the wrapper key from Person class + # (+person+, in this case) and the list of attribute names + # + # wrap_parameters include: [:username, :title] + # # wraps only +:username+ and +:title+ attributes from parameters. + # + # wrap_parameters false + # # disables parameters wrapping for this controller altogether. + # + # ==== Options + # * :format - The list of formats in which the parameters wrapper + # will be enabled. + # * :include - The list of attribute names which parameters wrapper + # will wrap into a nested hash. + # * :exclude - The list of attribute names which parameters wrapper + # will exclude from a nested hash. + def wrap_parameters(name_or_model_or_options, options = {}) + model = nil + + case name_or_model_or_options + when Hash + options = name_or_model_or_options + when false + options = options.merge(:format => []) + when Symbol, String + options = options.merge(:name => name_or_model_or_options) + else + model = name_or_model_or_options + end + + opts = Options.from_hash _wrapper_options.to_h.slice(:format).merge(options) + opts.model = model + opts.klass = self + + self._wrapper_options = opts + end + + # Sets the default wrapper key or model which will be used to determine + # wrapper key and attribute names. Will be called automatically when the + # module is inherited. + def inherited(klass) + if klass._wrapper_options.format.any? + params = klass._wrapper_options.dup + params.klass = klass + klass._wrapper_options = params + end + super + end + end + + # Performs parameters wrapping upon the request. Will be called automatically + # by the metal call stack. + def process_action(*args) + if _wrapper_enabled? + if request.parameters[_wrapper_key].present? + wrapped_hash = _extract_parameters(request.parameters) + else + wrapped_hash = _wrap_parameters request.request_parameters + end + + wrapped_keys = request.request_parameters.keys + wrapped_filtered_hash = _wrap_parameters request.filtered_parameters.slice(*wrapped_keys) + + # This will make the wrapped hash accessible from controller and view + request.parameters.merge! wrapped_hash + request.request_parameters.merge! wrapped_hash + + # This will display the wrapped hash in the log file + request.filtered_parameters.merge! wrapped_filtered_hash + end + super + end + + private + + # Returns the wrapper key which will be used to stored wrapped parameters. + def _wrapper_key + _wrapper_options.name + end + + # Returns the list of enabled formats. + def _wrapper_formats + _wrapper_options.format + end + + # Returns the list of parameters which will be selected for wrapped. + def _wrap_parameters(parameters) + { _wrapper_key => _extract_parameters(parameters) } + end + + def _extract_parameters(parameters) + if include_only = _wrapper_options.include + parameters.slice(*include_only) + else + exclude = _wrapper_options.exclude || [] + parameters.except(*(exclude + EXCLUDE_PARAMETERS)) + end + end + + # Checks if we should perform parameters wrapping. + def _wrapper_enabled? + ref = request.content_mime_type.try(:ref) + _wrapper_formats.include?(ref) && _wrapper_key && !request.request_parameters[_wrapper_key] + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/rack_delegation.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/rack_delegation.rb new file mode 100644 index 0000000..545d4a7 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/rack_delegation.rb @@ -0,0 +1,32 @@ +require 'action_dispatch/http/request' +require 'action_dispatch/http/response' + +module ActionController + module RackDelegation + extend ActiveSupport::Concern + + delegate :headers, :status=, :location=, :content_type=, + :status, :location, :content_type, :response_code, :to => "@_response" + + def dispatch(action, request) + set_response!(request) + super(action, request) + end + + def response_body=(body) + response.body = body if response + super + end + + def reset_session + @_request.reset_session + end + + private + + def set_response!(request) + @_response = ActionDispatch::Response.new + @_response.request = request + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/redirecting.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/redirecting.rb new file mode 100644 index 0000000..acaa822 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/redirecting.rb @@ -0,0 +1,112 @@ +module ActionController + class RedirectBackError < AbstractController::Error #:nodoc: + DEFAULT_MESSAGE = 'No HTTP_REFERER was set in the request to this action, so redirect_to :back could not be called successfully. If this is a test, make sure to specify request.env["HTTP_REFERER"].' + + def initialize(message = nil) + super(message || DEFAULT_MESSAGE) + end + end + + module Redirecting + extend ActiveSupport::Concern + + include AbstractController::Logger + include ActionController::RackDelegation + include ActionController::UrlFor + + # Redirects the browser to the target specified in +options+. This parameter can be any one of: + # + # * Hash - The URL will be generated by calling url_for with the +options+. + # * Record - The URL will be generated by calling url_for with the +options+, which will reference a named URL for that record. + # * String starting with protocol:// (like http://) or a protocol relative reference (like //) - Is passed straight through as the target for redirection. + # * String not containing a protocol - The current protocol and host is prepended to the string. + # * Proc - A block that will be executed in the controller's context. Should return any option accepted by +redirect_to+. + # * :back - Back to the page that issued the request. Useful for forms that are triggered from multiple places. + # Short-hand for redirect_to(request.env["HTTP_REFERER"]) + # + # === Examples: + # + # redirect_to action: "show", id: 5 + # redirect_to post + # redirect_to "http://www.rubyonrails.org" + # redirect_to "/images/screenshot.jpg" + # redirect_to articles_url + # redirect_to :back + # redirect_to proc { edit_post_url(@post) } + # + # The redirection happens as a "302 Found" header unless otherwise specified using the :status option: + # + # redirect_to post_url(@post), status: :found + # redirect_to action: 'atom', status: :moved_permanently + # redirect_to post_url(@post), status: 301 + # redirect_to action: 'atom', status: 302 + # + # The status code can either be a standard {HTTP Status code}[http://www.iana.org/assignments/http-status-codes] as an + # integer, or a symbol representing the downcased, underscored and symbolized description. + # Note that the status code must be a 3xx HTTP code, or redirection will not occur. + # + # If you are using XHR requests other than GET or POST and redirecting after the + # request then some browsers will follow the redirect using the original request + # method. This may lead to undesirable behavior such as a double DELETE. To work + # around this you can return a 303 See Other status code which will be + # followed using a GET request. + # + # redirect_to posts_url, status: :see_other + # redirect_to action: 'index', status: 303 + # + # It is also possible to assign a flash message as part of the redirection. There are two special accessors for the commonly used flash names + # +alert+ and +notice+ as well as a general purpose +flash+ bucket. + # + # redirect_to post_url(@post), alert: "Watch it, mister!" + # redirect_to post_url(@post), status: :found, notice: "Pay attention to the road" + # redirect_to post_url(@post), status: 301, flash: { updated_post_id: @post.id } + # redirect_to({ action: 'atom' }, alert: "Something serious happened") + # + # When using redirect_to :back, if there is no referrer, + # ActionController::RedirectBackError will be raised. You + # may specify some fallback behavior for this case by rescuing + # ActionController::RedirectBackError. + def redirect_to(options = {}, response_status = {}) #:doc: + raise ActionControllerError.new("Cannot redirect to nil!") unless options + raise ActionControllerError.new("Cannot redirect to a parameter hash!") if options.is_a?(ActionController::Parameters) + raise AbstractController::DoubleRenderError if response_body + + self.status = _extract_redirect_to_status(options, response_status) + self.location = _compute_redirect_to_location(request, options) + self.response_body = "You are being redirected." + end + + def _compute_redirect_to_location(request, options) #:nodoc: + case options + # The scheme name consist of a letter followed by any combination of + # letters, digits, and the plus ("+"), period ("."), or hyphen ("-") + # characters; and is terminated by a colon (":"). + # See http://tools.ietf.org/html/rfc3986#section-3.1 + # The protocol relative scheme starts with a double slash "//". + when /\A([a-z][a-z\d\-+\.]*:|\/\/).*/i + options + when String + request.protocol + request.host_with_port + options + when :back + request.headers["Referer"] or raise RedirectBackError + when Proc + _compute_redirect_to_location request, options.call + else + url_for(options) + end.delete("\0\r\n") + end + module_function :_compute_redirect_to_location + public :_compute_redirect_to_location + + private + def _extract_redirect_to_status(options, response_status) + if options.is_a?(Hash) && options.key?(:status) + Rack::Utils.status_code(options.delete(:status)) + elsif response_status.key?(:status) + Rack::Utils.status_code(response_status[:status]) + else + 302 + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/renderers.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/renderers.rb new file mode 100644 index 0000000..45d3962 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/renderers.rb @@ -0,0 +1,140 @@ +require 'set' + +module ActionController + # See Renderers.add + def self.add_renderer(key, &block) + Renderers.add(key, &block) + end + + # See Renderers.remove + def self.remove_renderer(key) + Renderers.remove(key) + end + + class MissingRenderer < LoadError + def initialize(format) + super "No renderer defined for format: #{format}" + end + end + + module Renderers + extend ActiveSupport::Concern + + included do + class_attribute :_renderers + self._renderers = Set.new.freeze + end + + module ClassMethods + def use_renderers(*args) + renderers = _renderers + args + self._renderers = renderers.freeze + end + alias use_renderer use_renderers + end + + def render_to_body(options) + _render_to_body_with_renderer(options) || super + end + + def _render_to_body_with_renderer(options) + _renderers.each do |name| + if options.key?(name) + _process_options(options) + method_name = Renderers._render_with_renderer_method_name(name) + return send(method_name, options.delete(name), options) + end + end + nil + end + + # A Set containing renderer names that correspond to available renderer procs. + # Default values are :json, :js, :xml. + RENDERERS = Set.new + + def self._render_with_renderer_method_name(key) + "_render_with_renderer_#{key}" + end + + # Adds a new renderer to call within controller actions. + # A renderer is invoked by passing its name as an option to + # AbstractController::Rendering#render. To create a renderer + # pass it a name and a block. The block takes two arguments, the first + # is the value paired with its key and the second is the remaining + # hash of options passed to +render+. + # + # Create a csv renderer: + # + # ActionController::Renderers.add :csv do |obj, options| + # filename = options[:filename] || 'data' + # str = obj.respond_to?(:to_csv) ? obj.to_csv : obj.to_s + # send_data str, type: Mime::CSV, + # disposition: "attachment; filename=#{filename}.csv" + # end + # + # Note that we used Mime::CSV for the csv mime type as it comes with Rails. + # For a custom renderer, you'll need to register a mime type with + # Mime::Type.register. + # + # To use the csv renderer in a controller action: + # + # def show + # @csvable = Csvable.find(params[:id]) + # respond_to do |format| + # format.html + # format.csv { render csv: @csvable, filename: @csvable.name } + # end + # end + # To use renderers and their mime types in more concise ways, see + # ActionController::MimeResponds::ClassMethods.respond_to + def self.add(key, &block) + define_method(_render_with_renderer_method_name(key), &block) + RENDERERS << key.to_sym + end + + # This method is the opposite of add method. + # + # Usage: + # + # ActionController::Renderers.remove(:csv) + def self.remove(key) + RENDERERS.delete(key.to_sym) + method_name = _render_with_renderer_method_name(key) + remove_method(method_name) if method_defined?(method_name) + end + + module All + extend ActiveSupport::Concern + include Renderers + + included do + self._renderers = RENDERERS + end + end + + add :json do |json, options| + json = json.to_json(options) unless json.kind_of?(String) + + if options[:callback].present? + if content_type.nil? || content_type == Mime::JSON + self.content_type = Mime::JS + end + + "/**/#{options[:callback]}(#{json})" + else + self.content_type ||= Mime::JSON + json + end + end + + add :js do |js, options| + self.content_type ||= Mime::JS + js.respond_to?(:to_js) ? js.to_js(options) : js + end + + add :xml do |xml, options| + self.content_type ||= Mime::XML + xml.respond_to?(:to_xml) ? xml.to_xml(options) : xml + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/rendering.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/rendering.rb new file mode 100644 index 0000000..7bbff04 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/rendering.rb @@ -0,0 +1,100 @@ +module ActionController + module Rendering + extend ActiveSupport::Concern + + RENDER_FORMATS_IN_PRIORITY = [:body, :text, :plain, :html] + + # Before processing, set the request formats in current controller formats. + def process_action(*) #:nodoc: + self.formats = request.formats.map(&:ref).compact + super + end + + # Check for double render errors and set the content_type after rendering. + def render(*args) #:nodoc: + raise ::AbstractController::DoubleRenderError if self.response_body + super + end + + # Overwrite render_to_string because body can now be set to a rack body. + def render_to_string(*) + result = super + if result.respond_to?(:each) + string = "" + result.each { |r| string << r } + string + else + result + end + end + + def render_to_body(options = {}) + super || _render_in_priorities(options) || ' ' + end + + private + + def _render_in_priorities(options) + RENDER_FORMATS_IN_PRIORITY.each do |format| + return options[format] if options.key?(format) + end + + nil + end + + def _process_format(format, options = {}) + super + + if options[:plain] + self.content_type = Mime::TEXT + else + self.content_type ||= format.to_s + end + end + + # Normalize arguments by catching blocks and setting them on :update. + def _normalize_args(action=nil, options={}, &blk) #:nodoc: + options = super + options[:update] = blk if block_given? + options + end + + # Normalize both text and status options. + def _normalize_options(options) #:nodoc: + _normalize_text(options) + + if options[:html] + options[:html] = ERB::Util.html_escape(options[:html]) + end + + if options.delete(:nothing) + options[:body] = nil + end + + if options[:status] + options[:status] = Rack::Utils.status_code(options[:status]) + end + + super + end + + def _normalize_text(options) + RENDER_FORMATS_IN_PRIORITY.each do |format| + if options.key?(format) && options[format].respond_to?(:to_text) + options[format] = options[format].to_text + end + end + end + + # Process controller specific options, as status, content-type and location. + def _process_options(options) #:nodoc: + status, content_type, location = options.values_at(:status, :content_type, :location) + + self.status = status if status + self.content_type = content_type if content_type + self.headers["Location"] = url_for(location) if location + + super + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/request_forgery_protection.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/request_forgery_protection.rb new file mode 100644 index 0000000..abd936f --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/request_forgery_protection.rb @@ -0,0 +1,334 @@ +require 'rack/session/abstract/id' +require 'action_controller/metal/exceptions' +require 'active_support/security_utils' + +module ActionController #:nodoc: + class InvalidAuthenticityToken < ActionControllerError #:nodoc: + end + + class InvalidCrossOriginRequest < ActionControllerError #:nodoc: + end + + # Controller actions are protected from Cross-Site Request Forgery (CSRF) attacks + # by including a token in the rendered HTML for your application. This token is + # stored as a random string in the session, to which an attacker does not have + # access. When a request reaches your application, \Rails verifies the received + # token with the token in the session. Only HTML and JavaScript requests are checked, + # so this will not protect your XML API (presumably you'll have a different + # authentication scheme there anyway). + # + # GET requests are not protected since they don't have side effects like writing + # to the database and don't leak sensitive information. JavaScript requests are + # an exception: a third-party site can use a + # + # The first two characters (">) are required in case the exception happens + # while rendering attributes for a given tag. You can check the real cause + # for the exception in your logger. + # + # == Web server support + # + # Not all web servers support streaming out-of-the-box. You need to check + # the instructions for each of them. + # + # ==== Unicorn + # + # Unicorn supports streaming but it needs to be configured. For this, you + # need to create a config file as follow: + # + # # unicorn.config.rb + # listen 3000, tcp_nopush: false + # + # And use it on initialization: + # + # unicorn_rails --config-file unicorn.config.rb + # + # You may also want to configure other parameters like :tcp_nodelay. + # Please check its documentation for more information: http://unicorn.bogomips.org/Unicorn/Configurator.html#method-i-listen + # + # If you are using Unicorn with NGINX, you may need to tweak NGINX. + # Streaming should work out of the box on Rainbows. + # + # ==== Passenger + # + # To be described. + # + module Streaming + extend ActiveSupport::Concern + + protected + + # Set proper cache control and transfer encoding when streaming + def _process_options(options) #:nodoc: + super + if options[:stream] + if env["HTTP_VERSION"] == "HTTP/1.0" + options.delete(:stream) + else + headers["Cache-Control"] ||= "no-cache" + headers["Transfer-Encoding"] = "chunked" + headers.delete("Content-Length") + end + end + end + + # Call render_body if we are streaming instead of usual +render+. + def _render_template(options) #:nodoc: + if options.delete(:stream) + Rack::Chunked::Body.new view_renderer.render_body(view_context, options) + else + super + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/strong_parameters.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/strong_parameters.rb new file mode 100644 index 0000000..ec2a7e0 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/strong_parameters.rb @@ -0,0 +1,669 @@ +require 'active_support/core_ext/hash/indifferent_access' +require 'active_support/core_ext/array/wrap' +require 'active_support/core_ext/string/filters' +require 'active_support/deprecation' +require 'active_support/rescuable' +require 'action_dispatch/http/upload' +require 'stringio' +require 'set' + +module ActionController + # Raised when a required parameter is missing. + # + # params = ActionController::Parameters.new(a: {}) + # params.fetch(:b) + # # => ActionController::ParameterMissing: param not found: b + # params.require(:a) + # # => ActionController::ParameterMissing: param not found: a + class ParameterMissing < KeyError + attr_reader :param # :nodoc: + + def initialize(param) # :nodoc: + @param = param + super("param is missing or the value is empty: #{param}") + end + end + + # Raised when a supplied parameter is not expected and + # ActionController::Parameters.action_on_unpermitted_parameters + # is set to :raise. + # + # params = ActionController::Parameters.new(a: "123", b: "456") + # params.permit(:c) + # # => ActionController::UnpermittedParameters: found unpermitted parameters: a, b + class UnpermittedParameters < IndexError + attr_reader :params # :nodoc: + + def initialize(params) # :nodoc: + @params = params + super("found unpermitted parameter#{'s' if params.size > 1 }: #{params.join(", ")}") + end + end + + # == Action Controller \Parameters + # + # Allows to choose which attributes should be whitelisted for mass updating + # and thus prevent accidentally exposing that which shouldn't be exposed. + # Provides two methods for this purpose: #require and #permit. The former is + # used to mark parameters as required. The latter is used to set the parameter + # as permitted and limit which attributes should be allowed for mass updating. + # + # params = ActionController::Parameters.new({ + # person: { + # name: 'Francesco', + # age: 22, + # role: 'admin' + # } + # }) + # + # permitted = params.require(:person).permit(:name, :age) + # permitted # => {"name"=>"Francesco", "age"=>22} + # permitted.class # => ActionController::Parameters + # permitted.permitted? # => true + # + # Person.first.update!(permitted) + # # => # + # + # It provides two options that controls the top-level behavior of new instances: + # + # * +permit_all_parameters+ - If it's +true+, all the parameters will be + # permitted by default. The default is +false+. + # * +action_on_unpermitted_parameters+ - Allow to control the behavior when parameters + # that are not explicitly permitted are found. The values can be :log to + # write a message on the logger or :raise to raise + # ActionController::UnpermittedParameters exception. The default value is :log + # in test and development environments, +false+ otherwise. + # + # Examples: + # + # params = ActionController::Parameters.new + # params.permitted? # => false + # + # ActionController::Parameters.permit_all_parameters = true + # + # params = ActionController::Parameters.new + # params.permitted? # => true + # + # params = ActionController::Parameters.new(a: "123", b: "456") + # params.permit(:c) + # # => {} + # + # ActionController::Parameters.action_on_unpermitted_parameters = :raise + # + # params = ActionController::Parameters.new(a: "123", b: "456") + # params.permit(:c) + # # => ActionController::UnpermittedParameters: found unpermitted keys: a, b + # + # Please note that these options *are not thread-safe*. In a multi-threaded + # environment they should only be set once at boot-time and never mutated at + # runtime. + # + # ActionController::Parameters inherits from + # ActiveSupport::HashWithIndifferentAccess, this means + # that you can fetch values using either :key or "key". + # + # params = ActionController::Parameters.new(key: 'value') + # params[:key] # => "value" + # params["key"] # => "value" + class Parameters < ActiveSupport::HashWithIndifferentAccess + cattr_accessor :permit_all_parameters, instance_accessor: false + cattr_accessor :action_on_unpermitted_parameters, instance_accessor: false + + # By default, never raise an UnpermittedParameters exception if these + # params are present. The default includes both 'controller' and 'action' + # because they are added by Rails and should be of no concern. One way + # to change these is to specify `always_permitted_parameters` in your + # config. For instance: + # + # config.always_permitted_parameters = %w( controller action format ) + cattr_accessor :always_permitted_parameters + self.always_permitted_parameters = %w( controller action ) + + def self.const_missing(const_name) + super unless const_name == :NEVER_UNPERMITTED_PARAMS + ActiveSupport::Deprecation.warn(<<-MSG.squish) + `ActionController::Parameters::NEVER_UNPERMITTED_PARAMS` has been deprecated. + Use `ActionController::Parameters.always_permitted_parameters` instead. + MSG + + always_permitted_parameters + end + + # Returns a new instance of ActionController::Parameters. + # Also, sets the +permitted+ attribute to the default value of + # ActionController::Parameters.permit_all_parameters. + # + # class Person < ActiveRecord::Base + # end + # + # params = ActionController::Parameters.new(name: 'Francesco') + # params.permitted? # => false + # Person.new(params) # => ActiveModel::ForbiddenAttributesError + # + # ActionController::Parameters.permit_all_parameters = true + # + # params = ActionController::Parameters.new(name: 'Francesco') + # params.permitted? # => true + # Person.new(params) # => # + def initialize(attributes = nil) + super(attributes) + @permitted = self.class.permit_all_parameters + end + + # Returns a safe +Hash+ representation of this parameter with all + # unpermitted keys removed. + # + # params = ActionController::Parameters.new({ + # name: 'Senjougahara Hitagi', + # oddity: 'Heavy stone crab' + # }) + # params.to_h # => {} + # + # safe_params = params.permit(:name) + # safe_params.to_h # => {"name"=>"Senjougahara Hitagi"} + def to_h + if permitted? + to_hash + else + slice(*self.class.always_permitted_parameters).permit!.to_h + end + end + + # Returns an unsafe, unfiltered +Hash+ representation of this parameter. + def to_unsafe_h + to_hash + end + alias_method :to_unsafe_hash, :to_unsafe_h + + # Convert all hashes in values into parameters, then yield each pair like + # the same way as Hash#each_pair + def each_pair(&block) + super do |key, value| + convert_hashes_to_parameters(key, value) + end + + super + end + + alias_method :each, :each_pair + + # Attribute that keeps track of converted arrays, if any, to avoid double + # looping in the common use case permit + mass-assignment. Defined in a + # method to instantiate it only if needed. + # + # Testing membership still loops, but it's going to be faster than our own + # loop that converts values. Also, we are not going to build a new array + # object per fetch. + def converted_arrays + @converted_arrays ||= Set.new + end + + # Returns +true+ if the parameter is permitted, +false+ otherwise. + # + # params = ActionController::Parameters.new + # params.permitted? # => false + # params.permit! + # params.permitted? # => true + def permitted? + @permitted + end + + # Sets the +permitted+ attribute to +true+. This can be used to pass + # mass assignment. Returns +self+. + # + # class Person < ActiveRecord::Base + # end + # + # params = ActionController::Parameters.new(name: 'Francesco') + # params.permitted? # => false + # Person.new(params) # => ActiveModel::ForbiddenAttributesError + # params.permit! + # params.permitted? # => true + # Person.new(params) # => # + def permit! + each_pair do |key, value| + Array.wrap(value).each do |v| + v.permit! if v.respond_to? :permit! + end + end + + @permitted = true + self + end + + # Ensures that a parameter is present. If it's present, returns + # the parameter at the given +key+, otherwise raises an + # ActionController::ParameterMissing error. + # + # ActionController::Parameters.new(person: { name: 'Francesco' }).require(:person) + # # => {"name"=>"Francesco"} + # + # ActionController::Parameters.new(person: nil).require(:person) + # # => ActionController::ParameterMissing: param not found: person + # + # ActionController::Parameters.new(person: {}).require(:person) + # # => ActionController::ParameterMissing: param not found: person + def require(key) + value = self[key] + if value.present? || value == false + value + else + raise ParameterMissing.new(key) + end + end + + # Alias of #require. + alias :required :require + + # Returns a new ActionController::Parameters instance that + # includes only the given +filters+ and sets the +permitted+ attribute + # for the object to +true+. This is useful for limiting which attributes + # should be allowed for mass updating. + # + # params = ActionController::Parameters.new(user: { name: 'Francesco', age: 22, role: 'admin' }) + # permitted = params.require(:user).permit(:name, :age) + # permitted.permitted? # => true + # permitted.has_key?(:name) # => true + # permitted.has_key?(:age) # => true + # permitted.has_key?(:role) # => false + # + # Only permitted scalars pass the filter. For example, given + # + # params.permit(:name) + # + # +:name+ passes it is a key of +params+ whose associated value is of type + # +String+, +Symbol+, +NilClass+, +Numeric+, +TrueClass+, +FalseClass+, + # +Date+, +Time+, +DateTime+, +StringIO+, +IO+, + # +ActionDispatch::Http::UploadedFile+ or +Rack::Test::UploadedFile+. + # Otherwise, the key +:name+ is filtered out. + # + # You may declare that the parameter should be an array of permitted scalars + # by mapping it to an empty array: + # + # params = ActionController::Parameters.new(tags: ['rails', 'parameters']) + # params.permit(tags: []) + # + # You can also use +permit+ on nested parameters, like: + # + # params = ActionController::Parameters.new({ + # person: { + # name: 'Francesco', + # age: 22, + # pets: [{ + # name: 'Purplish', + # category: 'dogs' + # }] + # } + # }) + # + # permitted = params.permit(person: [ :name, { pets: :name } ]) + # permitted.permitted? # => true + # permitted[:person][:name] # => "Francesco" + # permitted[:person][:age] # => nil + # permitted[:person][:pets][0][:name] # => "Purplish" + # permitted[:person][:pets][0][:category] # => nil + # + # Note that if you use +permit+ in a key that points to a hash, + # it won't allow all the hash. You also need to specify which + # attributes inside the hash should be whitelisted. + # + # params = ActionController::Parameters.new({ + # person: { + # contact: { + # email: 'none@test.com', + # phone: '555-1234' + # } + # } + # }) + # + # params.require(:person).permit(:contact) + # # => {} + # + # params.require(:person).permit(contact: :phone) + # # => {"contact"=>{"phone"=>"555-1234"}} + # + # params.require(:person).permit(contact: [ :email, :phone ]) + # # => {"contact"=>{"email"=>"none@test.com", "phone"=>"555-1234"}} + def permit(*filters) + params = self.class.new + + filters.flatten.each do |filter| + case filter + when Symbol, String + permitted_scalar_filter(params, filter) + when Hash then + hash_filter(params, filter) + end + end + + unpermitted_parameters!(params) if self.class.action_on_unpermitted_parameters + + params.permit! + end + + # Returns a parameter for the given +key+. If not found, + # returns +nil+. + # + # params = ActionController::Parameters.new(person: { name: 'Francesco' }) + # params[:person] # => {"name"=>"Francesco"} + # params[:none] # => nil + def [](key) + convert_hashes_to_parameters(key, super) + end + + # Returns a parameter for the given +key+. If the +key+ + # can't be found, there are several options: With no other arguments, + # it will raise an ActionController::ParameterMissing error; + # if more arguments are given, then that will be returned; if a block + # is given, then that will be run and its result returned. + # + # params = ActionController::Parameters.new(person: { name: 'Francesco' }) + # params.fetch(:person) # => {"name"=>"Francesco"} + # params.fetch(:none) # => ActionController::ParameterMissing: param not found: none + # params.fetch(:none, 'Francesco') # => "Francesco" + # params.fetch(:none) { 'Francesco' } # => "Francesco" + def fetch(key, *args) + convert_hashes_to_parameters(key, super, false) + rescue KeyError + raise ActionController::ParameterMissing.new(key) + end + + # Returns a new ActionController::Parameters instance that + # includes only the given +keys+. If the given +keys+ + # don't exist, returns an empty hash. + # + # params = ActionController::Parameters.new(a: 1, b: 2, c: 3) + # params.slice(:a, :b) # => {"a"=>1, "b"=>2} + # params.slice(:d) # => {} + def slice(*keys) + new_instance_with_inherited_permitted_status(super) + end + + # Removes and returns the key/value pairs matching the given keys. + # + # params = ActionController::Parameters.new(a: 1, b: 2, c: 3) + # params.extract!(:a, :b) # => {"a"=>1, "b"=>2} + # params # => {"c"=>3} + def extract!(*keys) + new_instance_with_inherited_permitted_status(super) + end + + # Returns a new ActionController::Parameters with the results of + # running +block+ once for every value. The keys are unchanged. + # + # params = ActionController::Parameters.new(a: 1, b: 2, c: 3) + # params.transform_values { |x| x * 2 } + # # => {"a"=>2, "b"=>4, "c"=>6} + def transform_values + if block_given? + new_instance_with_inherited_permitted_status(super) + else + super + end + end + + # This method is here only to make sure that the returned object has the + # correct +permitted+ status. It should not matter since the parent of + # this object is +HashWithIndifferentAccess+ + def transform_keys # :nodoc: + if block_given? + new_instance_with_inherited_permitted_status(super) + else + super + end + end + + # Deletes and returns a key-value pair from +Parameters+ whose key is equal + # to key. If the key is not found, returns the default value. If the + # optional code block is given and the key is not found, pass in the key + # and return the result of block. + def delete(key, &block) + convert_hashes_to_parameters(key, super, false) + end + + # Equivalent to Hash#keep_if, but returns nil if no changes were made. + def select!(&block) + convert_value_to_parameters(super) + end + + # Returns an exact copy of the ActionController::Parameters + # instance. +permitted+ state is kept on the duped object. + # + # params = ActionController::Parameters.new(a: 1) + # params.permit! + # params.permitted? # => true + # copy_params = params.dup # => {"a"=>1} + # copy_params.permitted? # => true + def dup + super.tap do |duplicate| + duplicate.permitted = @permitted + end + end + + protected + def permitted=(new_permitted) + @permitted = new_permitted + end + + private + def new_instance_with_inherited_permitted_status(hash) + self.class.new(hash).tap do |new_instance| + new_instance.permitted = @permitted + end + end + + def convert_hashes_to_parameters(key, value, assign_if_converted=true) + converted = convert_value_to_parameters(value) + self[key] = converted if assign_if_converted && !converted.equal?(value) + converted + end + + def convert_value_to_parameters(value) + if value.is_a?(Array) && !converted_arrays.member?(value) + converted = value.map { |_| convert_value_to_parameters(_) } + converted_arrays << converted + converted + elsif value.is_a?(Parameters) || !value.is_a?(Hash) + value + else + self.class.new(value) + end + end + + def each_element(object) + if object.is_a?(Array) + object.map { |el| yield el }.compact + elsif fields_for_style?(object) + hash = object.class.new + object.each { |k,v| hash[k] = yield v } + hash + else + yield object + end + end + + def fields_for_style?(object) + object.is_a?(Hash) && object.all? { |k, v| k =~ /\A-?\d+\z/ && v.is_a?(Hash) } + end + + def unpermitted_parameters!(params) + unpermitted_keys = unpermitted_keys(params) + if unpermitted_keys.any? + case self.class.action_on_unpermitted_parameters + when :log + name = "unpermitted_parameters.action_controller" + ActiveSupport::Notifications.instrument(name, keys: unpermitted_keys) + when :raise + raise ActionController::UnpermittedParameters.new(unpermitted_keys) + end + end + end + + def unpermitted_keys(params) + self.keys - params.keys - self.always_permitted_parameters + end + + # + # --- Filtering ---------------------------------------------------------- + # + + # This is a white list of permitted scalar types that includes the ones + # supported in XML and JSON requests. + # + # This list is in particular used to filter ordinary requests, String goes + # as first element to quickly short-circuit the common case. + # + # If you modify this collection please update the API of +permit+ above. + PERMITTED_SCALAR_TYPES = [ + String, + Symbol, + NilClass, + Numeric, + TrueClass, + FalseClass, + Date, + Time, + # DateTimes are Dates, we document the type but avoid the redundant check. + StringIO, + IO, + ActionDispatch::Http::UploadedFile, + Rack::Test::UploadedFile, + ] + + def permitted_scalar?(value) + PERMITTED_SCALAR_TYPES.any? {|type| value.is_a?(type)} + end + + def permitted_scalar_filter(params, key) + if has_key?(key) && permitted_scalar?(self[key]) + params[key] = self[key] + end + + keys.grep(/\A#{Regexp.escape(key)}\(\d+[if]?\)\z/) do |k| + if permitted_scalar?(self[k]) + params[k] = self[k] + end + end + end + + def array_of_permitted_scalars?(value) + if value.is_a?(Array) + value.all? {|element| permitted_scalar?(element)} + end + end + + def array_of_permitted_scalars_filter(params, key) + if has_key?(key) && array_of_permitted_scalars?(self[key]) + params[key] = self[key] + end + end + + EMPTY_ARRAY = [] + def hash_filter(params, filter) + filter = filter.with_indifferent_access + + # Slicing filters out non-declared keys. + slice(*filter.keys).each do |key, value| + next unless value + + if filter[key] == EMPTY_ARRAY + # Declaration { comment_ids: [] }. + array_of_permitted_scalars_filter(params, key) + else + # Declaration { user: :name } or { user: [:name, :age, { address: ... }] }. + params[key] = each_element(value) do |element| + if element.is_a?(Hash) + element = self.class.new(element) unless element.respond_to?(:permit) + element.permit(*Array.wrap(filter[key])) + end + end + end + end + end + end + + # == Strong \Parameters + # + # It provides an interface for protecting attributes from end-user + # assignment. This makes Action Controller parameters forbidden + # to be used in Active Model mass assignment until they have been + # whitelisted. + # + # In addition, parameters can be marked as required and flow through a + # predefined raise/rescue flow to end up as a 400 Bad Request with no + # effort. + # + # class PeopleController < ActionController::Base + # # Using "Person.create(params[:person])" would raise an + # # ActiveModel::ForbiddenAttributes exception because it'd + # # be using mass assignment without an explicit permit step. + # # This is the recommended form: + # def create + # Person.create(person_params) + # end + # + # # This will pass with flying colors as long as there's a person key in the + # # parameters, otherwise it'll raise an ActionController::MissingParameter + # # exception, which will get caught by ActionController::Base and turned + # # into a 400 Bad Request reply. + # def update + # redirect_to current_account.people.find(params[:id]).tap { |person| + # person.update!(person_params) + # } + # end + # + # private + # # Using a private method to encapsulate the permissible parameters is + # # just a good pattern since you'll be able to reuse the same permit + # # list between create and update. Also, you can specialize this method + # # with per-user checking of permissible attributes. + # def person_params + # params.require(:person).permit(:name, :age) + # end + # end + # + # In order to use accepts_nested_attributes_for with Strong \Parameters, you + # will need to specify which nested attributes should be whitelisted. + # + # class Person + # has_many :pets + # accepts_nested_attributes_for :pets + # end + # + # class PeopleController < ActionController::Base + # def create + # Person.create(person_params) + # end + # + # ... + # + # private + # + # def person_params + # # It's mandatory to specify the nested attributes that should be whitelisted. + # # If you use `permit` with just the key that points to the nested attributes hash, + # # it will return an empty hash. + # params.require(:person).permit(:name, :age, pets_attributes: [ :name, :category ]) + # end + # end + # + # See ActionController::Parameters.require and ActionController::Parameters.permit + # for more information. + module StrongParameters + extend ActiveSupport::Concern + include ActiveSupport::Rescuable + + # Returns a new ActionController::Parameters object that + # has been instantiated with the request.parameters. + def params + @_params ||= Parameters.new(request.parameters) + end + + # Assigns the given +value+ to the +params+ hash. If +value+ + # is a Hash, this will create an ActionController::Parameters + # object that has been instantiated with the given +value+ hash. + def params=(value) + @_params = value.is_a?(Hash) ? Parameters.new(value) : value + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/testing.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/testing.rb new file mode 100644 index 0000000..dd8da4b --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/testing.rb @@ -0,0 +1,31 @@ +module ActionController + module Testing + extend ActiveSupport::Concern + + include RackDelegation + + # TODO : Rewrite tests using controller.headers= to use Rack env + def headers=(new_headers) + @_response ||= ActionDispatch::Response.new + @_response.headers.replace(new_headers) + end + + # Behavior specific to functional tests + module Functional # :nodoc: + def set_response!(request) + end + + def recycle! + @_url_options = nil + self.formats = nil + self.params = nil + end + end + + module ClassMethods + def before_filters + _process_action_callbacks.find_all{|x| x.kind == :before}.map{|x| x.name} + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/url_for.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/url_for.rb new file mode 100644 index 0000000..0f2fa5f --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/metal/url_for.rb @@ -0,0 +1,49 @@ +module ActionController + # Includes +url_for+ into the host class. The class has to provide a +RouteSet+ by implementing + # the _routes method. Otherwise, an exception will be raised. + # + # In addition to AbstractController::UrlFor, this module accesses the HTTP layer to define + # url options like the +host+. In order to do so, this module requires the host class + # to implement +env+ and +request+, which need to be a Rack-compatible. + # + # class RootUrl + # include ActionController::UrlFor + # include Rails.application.routes.url_helpers + # + # delegate :env, :request, to: :controller + # + # def initialize(controller) + # @controller = controller + # @url = root_path # named route from the application. + # end + # end + module UrlFor + extend ActiveSupport::Concern + + include AbstractController::UrlFor + + def url_options + @_url_options ||= { + :host => request.host, + :port => request.optional_port, + :protocol => request.protocol, + :_recall => request.path_parameters + }.merge!(super).freeze + + if (same_origin = _routes.equal?(env["action_dispatch.routes".freeze])) || + (script_name = env["ROUTES_#{_routes.object_id}_SCRIPT_NAME"]) || + (original_script_name = env['ORIGINAL_SCRIPT_NAME'.freeze]) + + options = @_url_options.dup + if original_script_name + options[:original_script_name] = original_script_name + else + options[:script_name] = same_origin ? request.script_name.dup : script_name + end + options.freeze + else + @_url_options + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/middleware.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/middleware.rb new file mode 100644 index 0000000..437fec3 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/middleware.rb @@ -0,0 +1,39 @@ +module ActionController + class Middleware < Metal + class ActionMiddleware + def initialize(controller, app) + @controller, @app = controller, app + end + + def call(env) + request = ActionDispatch::Request.new(env) + @controller.build(@app).dispatch(:index, request) + end + end + + class << self + alias build new + + def new(app) + ActionMiddleware.new(self, app) + end + end + + attr_internal :app + + def process(action) + response = super + self.status, self.headers, self.response_body = response if response.is_a?(Array) + response + end + + def initialize(app) + super() + @_app = app + end + + def index + call(env) + end + end +end \ No newline at end of file diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/model_naming.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/model_naming.rb new file mode 100644 index 0000000..2b33f67 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/model_naming.rb @@ -0,0 +1,12 @@ +module ActionController + module ModelNaming + # Converts the given object to an ActiveModel compliant one. + def convert_to_model(object) + object.respond_to?(:to_model) ? object.to_model : object + end + + def model_name_from_record_or_class(record_or_class) + convert_to_model(record_or_class).model_name + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/railtie.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/railtie.rb new file mode 100644 index 0000000..28b2005 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/railtie.rb @@ -0,0 +1,71 @@ +require "rails" +require "action_controller" +require "action_dispatch/railtie" +require "abstract_controller/railties/routes_helpers" +require "action_controller/railties/helpers" +require "action_view/railtie" + +module ActionController + class Railtie < Rails::Railtie #:nodoc: + config.action_controller = ActiveSupport::OrderedOptions.new + + config.eager_load_namespaces << ActionController + + initializer "action_controller.assets_config", :group => :all do |app| + app.config.action_controller.assets_dir ||= app.config.paths["public"].first + end + + initializer "action_controller.set_helpers_path" do |app| + ActionController::Helpers.helpers_path = app.helpers_paths + end + + initializer "action_controller.parameters_config" do |app| + options = app.config.action_controller + + ActionController::Parameters.permit_all_parameters = options.delete(:permit_all_parameters) { false } + if app.config.action_controller[:always_permitted_parameters] + ActionController::Parameters.always_permitted_parameters = + app.config.action_controller.delete(:always_permitted_parameters) + end + ActionController::Parameters.action_on_unpermitted_parameters = options.delete(:action_on_unpermitted_parameters) do + (Rails.env.test? || Rails.env.development?) ? :log : false + end + end + + initializer "action_controller.set_configs" do |app| + paths = app.config.paths + options = app.config.action_controller + + options.logger ||= Rails.logger + options.cache_store ||= Rails.cache + + options.javascripts_dir ||= paths["public/javascripts"].first + options.stylesheets_dir ||= paths["public/stylesheets"].first + + # Ensure readers methods get compiled + options.asset_host ||= app.config.asset_host + options.relative_url_root ||= app.config.relative_url_root + + ActiveSupport.on_load(:action_controller) do + include app.routes.mounted_helpers + extend ::AbstractController::Railties::RoutesHelpers.with(app.routes) + extend ::ActionController::Railties::Helpers + + options.each do |k,v| + k = "#{k}=" + if respond_to?(k) + send(k, v) + elsif !Base.respond_to?(k) + raise "Invalid option key: #{k}" + end + end + end + end + + initializer "action_controller.compile_config_methods" do + ActiveSupport.on_load(:action_controller) do + config.compile_methods! if config.respond_to?(:compile_methods!) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/railties/helpers.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/railties/helpers.rb new file mode 100644 index 0000000..3985c6b --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/railties/helpers.rb @@ -0,0 +1,22 @@ +module ActionController + module Railties + module Helpers + def inherited(klass) + super + return unless klass.respond_to?(:helpers_path=) + + if namespace = klass.parents.detect { |m| m.respond_to?(:railtie_helpers_paths) } + paths = namespace.railtie_helpers_paths + else + paths = ActionController::Helpers.helpers_path + end + + klass.helpers_path = paths + + if klass.superclass == ActionController::Base && ActionController::Base.include_all_helpers + klass.helper :all + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/test_case.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/test_case.rb new file mode 100644 index 0000000..c2d8d2a --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_controller/test_case.rb @@ -0,0 +1,761 @@ +require 'rack/session/abstract/id' +require 'active_support/core_ext/object/to_query' +require 'active_support/core_ext/module/anonymous' +require 'active_support/core_ext/hash/keys' +require 'active_support/deprecation' + +require 'rails-dom-testing' + +module ActionController + module TemplateAssertions + extend ActiveSupport::Concern + + included do + setup :setup_subscriptions + teardown :teardown_subscriptions + end + + RENDER_TEMPLATE_INSTANCE_VARIABLES = %w{partials templates layouts files}.freeze + + def setup_subscriptions + RENDER_TEMPLATE_INSTANCE_VARIABLES.each do |instance_variable| + instance_variable_set("@_#{instance_variable}", Hash.new(0)) + end + + @_subscribers = [] + + @_subscribers << ActiveSupport::Notifications.subscribe("render_template.action_view") do |_name, _start, _finish, _id, payload| + path = payload[:layout] + if path + @_layouts[path] += 1 + if path =~ /^layouts\/(.*)/ + @_layouts[$1] += 1 + end + end + end + + @_subscribers << ActiveSupport::Notifications.subscribe("!render_template.action_view") do |_name, _start, _finish, _id, payload| + if virtual_path = payload[:virtual_path] + partial = virtual_path =~ /^.*\/_[^\/]*$/ + + if partial + @_partials[virtual_path] += 1 + @_partials[virtual_path.split("/").last] += 1 + end + + @_templates[virtual_path] += 1 + else + path = payload[:identifier] + if path + @_files[path] += 1 + @_files[path.split("/").last] += 1 + end + end + end + end + + def teardown_subscriptions + return unless defined?(@_subscribers) + + @_subscribers.each do |subscriber| + ActiveSupport::Notifications.unsubscribe(subscriber) + end + end + + def process(*args) + reset_template_assertion + super + end + + def reset_template_assertion + RENDER_TEMPLATE_INSTANCE_VARIABLES.each do |instance_variable| + ivar_name = "@_#{instance_variable}" + if instance_variable_defined?(ivar_name) + instance_variable_get(ivar_name).clear + end + end + end + + # Asserts that the request was rendered with the appropriate template file or partials. + # + # # assert that the "new" view template was rendered + # assert_template "new" + # + # # assert that the exact template "admin/posts/new" was rendered + # assert_template %r{\Aadmin/posts/new\Z} + # + # # assert that the layout 'admin' was rendered + # assert_template layout: 'admin' + # assert_template layout: 'layouts/admin' + # assert_template layout: :admin + # + # # assert that no layout was rendered + # assert_template layout: nil + # assert_template layout: false + # + # # assert that the "_customer" partial was rendered twice + # assert_template partial: '_customer', count: 2 + # + # # assert that no partials were rendered + # assert_template partial: false + # + # # assert that a file was rendered + # assert_template file: "README.rdoc" + # + # # assert that no file was rendered + # assert_template file: nil + # assert_template file: false + # + # In a view test case, you can also assert that specific locals are passed + # to partials: + # + # # assert that the "_customer" partial was rendered with a specific object + # assert_template partial: '_customer', locals: { customer: @customer } + def assert_template(options = {}, message = nil) + # Force body to be read in case the template is being streamed. + response.body + + case options + when NilClass, Regexp, String, Symbol + options = options.to_s if Symbol === options + rendered = @_templates + msg = message || sprintf("expecting <%s> but rendering with <%s>", + options.inspect, rendered.keys) + matches_template = + case options + when String + !options.empty? && rendered.any? do |t, num| + options_splited = options.split(File::SEPARATOR) + t_splited = t.split(File::SEPARATOR) + t_splited.last(options_splited.size) == options_splited + end + when Regexp + rendered.any? { |t,num| t.match(options) } + when NilClass + rendered.blank? + end + assert matches_template, msg + when Hash + options.assert_valid_keys(:layout, :partial, :locals, :count, :file) + + if options.key?(:layout) + expected_layout = options[:layout] + msg = message || sprintf("expecting layout <%s> but action rendered <%s>", + expected_layout, @_layouts.keys) + + case expected_layout + when String, Symbol + assert_includes @_layouts.keys, expected_layout.to_s, msg + when Regexp + assert(@_layouts.keys.any? {|l| l =~ expected_layout }, msg) + when nil, false + assert(@_layouts.empty?, msg) + end + end + + if options[:file] + assert_includes @_files.keys, options[:file] + elsif options.key?(:file) + assert @_files.blank?, "expected no files but #{@_files.keys} was rendered" + end + + if expected_partial = options[:partial] + if expected_locals = options[:locals] + if defined?(@_rendered_views) + view = expected_partial.to_s.sub(/^_/, '').sub(/\/_(?=[^\/]+\z)/, '/') + + partial_was_not_rendered_msg = "expected %s to be rendered but it was not." % view + assert_includes @_rendered_views.rendered_views, view, partial_was_not_rendered_msg + + msg = 'expecting %s to be rendered with %s but was with %s' % [expected_partial, + expected_locals, + @_rendered_views.locals_for(view)] + assert(@_rendered_views.view_rendered?(view, options[:locals]), msg) + else + warn "the :locals option to #assert_template is only supported in a ActionView::TestCase" + end + elsif expected_count = options[:count] + actual_count = @_partials[expected_partial] + msg = message || sprintf("expecting %s to be rendered %s time(s) but rendered %s time(s)", + expected_partial, expected_count, actual_count) + assert(actual_count == expected_count.to_i, msg) + else + msg = message || sprintf("expecting partial <%s> but action rendered <%s>", + options[:partial], @_partials.keys) + assert_includes @_partials, expected_partial, msg + end + elsif options.key?(:partial) + assert @_partials.empty?, + "Expected no partials to be rendered" + end + else + raise ArgumentError, "assert_template only accepts a String, Symbol, Hash, Regexp, or nil" + end + end + end + + class TestRequest < ActionDispatch::TestRequest #:nodoc: + DEFAULT_ENV = ActionDispatch::TestRequest::DEFAULT_ENV.dup + DEFAULT_ENV.delete 'PATH_INFO' + + def initialize(env = {}) + super + + self.session = TestSession.new + self.session_options = TestSession::DEFAULT_OPTIONS.merge(:id => SecureRandom.hex(16)) + end + + def assign_parameters(routes, controller_path, action, parameters = {}) + parameters = parameters.symbolize_keys.merge(:controller => controller_path, :action => action) + extra_keys = routes.extra_keys(parameters) + non_path_parameters = get? ? query_parameters : request_parameters + parameters.each do |key, value| + if value.is_a?(Array) && (value.frozen? || value.any?(&:frozen?)) + value = value.map{ |v| v.duplicable? ? v.dup : v } + elsif value.is_a?(Hash) && (value.frozen? || value.any?{ |k,v| v.frozen? }) + value = Hash[value.map{ |k,v| [k, v.duplicable? ? v.dup : v] }] + elsif value.frozen? && value.duplicable? + value = value.dup + end + + if extra_keys.include?(key) + non_path_parameters[key] = value + else + if value.is_a?(Array) + value = value.map(&:to_param) + else + value = value.to_param + end + + path_parameters[key] = value + end + end + + # Clear the combined params hash in case it was already referenced. + @env.delete("action_dispatch.request.parameters") + + # Clear the filter cache variables so they're not stale + @filtered_parameters = @filtered_env = @filtered_path = nil + + params = self.request_parameters.dup + %w(controller action only_path).each do |k| + params.delete(k) + params.delete(k.to_sym) + end + data = params.to_query + + @env['CONTENT_LENGTH'] = data.length.to_s + @env['rack.input'] = StringIO.new(data) + end + + def recycle! + @formats = nil + @env.delete_if { |k, v| k =~ /^(action_dispatch|rack)\.request/ } + @env.delete_if { |k, v| k =~ /^action_dispatch\.rescue/ } + @method = @request_method = nil + @fullpath = @ip = @remote_ip = @protocol = nil + @env['action_dispatch.request.query_parameters'] = {} + @set_cookies ||= {} + @set_cookies.update(Hash[cookie_jar.instance_variable_get("@set_cookies").map{ |k,o| [k,o[:value]] }]) + deleted_cookies = cookie_jar.instance_variable_get("@delete_cookies") + @set_cookies.reject!{ |k,v| deleted_cookies.include?(k) } + cookie_jar.update(rack_cookies) + cookie_jar.update(cookies) + cookie_jar.update(@set_cookies) + cookie_jar.recycle! + end + + private + + def default_env + DEFAULT_ENV + end + end + + class TestResponse < ActionDispatch::TestResponse + def recycle! + initialize + end + end + + class LiveTestResponse < Live::Response + def recycle! + @body = nil + initialize + end + + def body + @body ||= super + end + + # Was the response successful? + alias_method :success?, :successful? + + # Was the URL not found? + alias_method :missing?, :not_found? + + # Were we redirected? + alias_method :redirect?, :redirection? + + # Was there a server-side error? + alias_method :error?, :server_error? + end + + # Methods #destroy and #load! are overridden to avoid calling methods on the + # @store object, which does not exist for the TestSession class. + class TestSession < Rack::Session::Abstract::SessionHash #:nodoc: + DEFAULT_OPTIONS = Rack::Session::Abstract::ID::DEFAULT_OPTIONS + + def initialize(session = {}) + super(nil, nil) + @id = SecureRandom.hex(16) + @data = stringify_keys(session) + @loaded = true + end + + def exists? + true + end + + def keys + @data.keys + end + + def values + @data.values + end + + def destroy + clear + end + + def fetch(key, *args, &block) + @data.fetch(key.to_s, *args, &block) + end + + private + + def load! + @id + end + end + + # Superclass for ActionController functional tests. Functional tests allow you to + # test a single controller action per test method. This should not be confused with + # integration tests (see ActionDispatch::IntegrationTest), which are more like + # "stories" that can involve multiple controllers and multiple actions (i.e. multiple + # different HTTP requests). + # + # == Basic example + # + # Functional tests are written as follows: + # 1. First, one uses the +get+, +post+, +patch+, +put+, +delete+ or +head+ method to simulate + # an HTTP request. + # 2. Then, one asserts whether the current state is as expected. "State" can be anything: + # the controller's HTTP response, the database contents, etc. + # + # For example: + # + # class BooksControllerTest < ActionController::TestCase + # def test_create + # # Simulate a POST response with the given HTTP parameters. + # post(:create, book: { title: "Love Hina" }) + # + # # Assert that the controller tried to redirect us to + # # the created book's URI. + # assert_response :found + # + # # Assert that the controller really put the book in the database. + # assert_not_nil Book.find_by(title: "Love Hina") + # end + # end + # + # You can also send a real document in the simulated HTTP request. + # + # def test_create + # json = {book: { title: "Love Hina" }}.to_json + # post :create, json + # end + # + # == Special instance variables + # + # ActionController::TestCase will also automatically provide the following instance + # variables for use in the tests: + # + # @controller:: + # The controller instance that will be tested. + # @request:: + # An ActionController::TestRequest, representing the current HTTP + # request. You can modify this object before sending the HTTP request. For example, + # you might want to set some session properties before sending a GET request. + # @response:: + # An ActionController::TestResponse object, representing the response + # of the last HTTP response. In the above example, @response becomes valid + # after calling +post+. If the various assert methods are not sufficient, then you + # may use this object to inspect the HTTP response in detail. + # + # (Earlier versions of \Rails required each functional test to subclass + # Test::Unit::TestCase and define @controller, @request, @response in +setup+.) + # + # == Controller is automatically inferred + # + # ActionController::TestCase will automatically infer the controller under test + # from the test class name. If the controller cannot be inferred from the test + # class name, you can explicitly set it with +tests+. + # + # class SpecialEdgeCaseWidgetsControllerTest < ActionController::TestCase + # tests WidgetController + # end + # + # == \Testing controller internals + # + # In addition to these specific assertions, you also have easy access to various collections that the regular test/unit assertions + # can be used against. These collections are: + # + # * assigns: Instance variables assigned in the action that are available for the view. + # * session: Objects being saved in the session. + # * flash: The flash objects currently in the session. + # * cookies: \Cookies being sent to the user on this request. + # + # These collections can be used just like any other hash: + # + # assert_not_nil assigns(:person) # makes sure that a @person instance variable was set + # assert_equal "Dave", cookies[:name] # makes sure that a cookie called :name was set as "Dave" + # assert flash.empty? # makes sure that there's nothing in the flash + # + # For historic reasons, the assigns hash uses string-based keys. So assigns[:person] won't work, but assigns["person"] will. To + # appease our yearning for symbols, though, an alternative accessor has been devised using a method call instead of index referencing. + # So assigns(:person) will work just like assigns["person"], but again, assigns[:person] will not work. + # + # On top of the collections, you have the complete url that a given action redirected to available in redirect_to_url. + # + # For redirects within the same controller, you can even call follow_redirect and the redirect will be followed, triggering another + # action call which can then be asserted against. + # + # == Manipulating session and cookie variables + # + # Sometimes you need to set up the session and cookie variables for a test. + # To do this just assign a value to the session or cookie collection: + # + # session[:key] = "value" + # cookies[:key] = "value" + # + # To clear the cookies for a test just clear the cookie collection: + # + # cookies.clear + # + # == \Testing named routes + # + # If you're using named routes, they can be easily tested using the original named routes' methods straight in the test case. + # + # assert_redirected_to page_url(title: 'foo') + class TestCase < ActiveSupport::TestCase + module Behavior + extend ActiveSupport::Concern + include ActionDispatch::TestProcess + include ActiveSupport::Testing::ConstantLookup + include Rails::Dom::Testing::Assertions + + attr_reader :response, :request + + module ClassMethods + + # Sets the controller class name. Useful if the name can't be inferred from test class. + # Normalizes +controller_class+ before using. + # + # tests WidgetController + # tests :widget + # tests 'widget' + def tests(controller_class) + case controller_class + when String, Symbol + self.controller_class = "#{controller_class.to_s.camelize}Controller".constantize + when Class + self.controller_class = controller_class + else + raise ArgumentError, "controller class must be a String, Symbol, or Class" + end + end + + def controller_class=(new_class) + self._controller_class = new_class + end + + def controller_class + if current_controller_class = self._controller_class + current_controller_class + else + self.controller_class = determine_default_controller_class(name) + end + end + + def determine_default_controller_class(name) + determine_constant_from_test_name(name) do |constant| + Class === constant && constant < ActionController::Metal + end + end + end + + # Simulate a GET request with the given parameters. + # + # - +action+: The controller action to call. + # - +parameters+: The HTTP parameters that you want to pass. This may + # be +nil+, a hash, or a string that is appropriately encoded + # (application/x-www-form-urlencoded or multipart/form-data). + # - +session+: A hash of parameters to store in the session. This may be +nil+. + # - +flash+: A hash of parameters to store in the flash. This may be +nil+. + # + # You can also simulate POST, PATCH, PUT, DELETE, and HEAD requests with + # +post+, +patch+, +put+, +delete+, and +head+. + # + # Note that the request method is not verified. The different methods are + # available to make the tests more expressive. + def get(action, *args) + process(action, "GET", *args) + end + + # Simulate a POST request with the given parameters and set/volley the response. + # See +get+ for more details. + def post(action, *args) + process(action, "POST", *args) + end + + # Simulate a PATCH request with the given parameters and set/volley the response. + # See +get+ for more details. + def patch(action, *args) + process(action, "PATCH", *args) + end + + # Simulate a PUT request with the given parameters and set/volley the response. + # See +get+ for more details. + def put(action, *args) + process(action, "PUT", *args) + end + + # Simulate a DELETE request with the given parameters and set/volley the response. + # See +get+ for more details. + def delete(action, *args) + process(action, "DELETE", *args) + end + + # Simulate a HEAD request with the given parameters and set/volley the response. + # See +get+ for more details. + def head(action, *args) + process(action, "HEAD", *args) + end + + def xml_http_request(request_method, action, parameters = nil, session = nil, flash = nil) + @request.env['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest' + @request.env['HTTP_ACCEPT'] ||= [Mime::JS, Mime::HTML, Mime::XML, 'text/xml', Mime::ALL].join(', ') + __send__(request_method, action, parameters, session, flash).tap do + @request.env.delete 'HTTP_X_REQUESTED_WITH' + @request.env.delete 'HTTP_ACCEPT' + end + end + alias xhr :xml_http_request + + def paramify_values(hash_or_array_or_value) + case hash_or_array_or_value + when Hash + Hash[hash_or_array_or_value.map{|key, value| [key, paramify_values(value)] }] + when Array + hash_or_array_or_value.map {|i| paramify_values(i)} + when Rack::Test::UploadedFile, ActionDispatch::Http::UploadedFile + hash_or_array_or_value + else + hash_or_array_or_value.to_param + end + end + + # Simulate a HTTP request to +action+ by specifying request method, + # parameters and set/volley the response. + # + # - +action+: The controller action to call. + # - +http_method+: Request method used to send the http request. Possible values + # are +GET+, +POST+, +PATCH+, +PUT+, +DELETE+, +HEAD+. Defaults to +GET+. + # - +parameters+: The HTTP parameters. This may be +nil+, a hash, or a + # string that is appropriately encoded (+application/x-www-form-urlencoded+ + # or +multipart/form-data+). + # - +session+: A hash of parameters to store in the session. This may be +nil+. + # - +flash+: A hash of parameters to store in the flash. This may be +nil+. + # + # Example calling +create+ action and sending two params: + # + # process :create, 'POST', user: { name: 'Gaurish Sharma', email: 'user@example.com' } + # + # Example sending parameters, +nil+ session and setting a flash message: + # + # process :view, 'GET', { id: 7 }, nil, { notice: 'This is flash message' } + # + # To simulate +GET+, +POST+, +PATCH+, +PUT+, +DELETE+ and +HEAD+ requests + # prefer using #get, #post, #patch, #put, #delete and #head methods + # respectively which will make tests more expressive. + # + # Note that the request method is not verified. + def process(action, http_method = 'GET', *args) + check_required_ivars + + if args.first.is_a?(String) && http_method != 'HEAD' + @request.env['RAW_POST_DATA'] = args.shift + end + + parameters, session, flash = args + parameters ||= {} + + # Ensure that numbers and symbols passed as params are converted to + # proper params, as is the case when engaging rack. + parameters = paramify_values(parameters) if html_format?(parameters) + + @html_document = nil + @html_scanner_document = nil + + unless @controller.respond_to?(:recycle!) + @controller.extend(Testing::Functional) + end + + @request.recycle! + @response.recycle! + @controller.recycle! + + @request.env['REQUEST_METHOD'] = http_method + + controller_class_name = @controller.class.anonymous? ? + "anonymous" : + @controller.class.controller_path + + @request.assign_parameters(@routes, controller_class_name, action.to_s, parameters) + + @request.session.update(session) if session + @request.flash.update(flash || {}) + + @controller.request = @request + @controller.response = @response + + build_request_uri(action, parameters) + + name = @request.parameters[:action] + + @controller.recycle! + @controller.process(name) + + if cookies = @request.env['action_dispatch.cookies'] + unless @response.committed? + cookies.write(@response) + end + end + @response.prepare! + + @assigns = @controller.respond_to?(:view_assigns) ? @controller.view_assigns : {} + + if flash_value = @request.flash.to_session_value + @request.session['flash'] = flash_value + end + + @response + end + + def setup_controller_request_and_response + @controller = nil unless defined? @controller + + response_klass = TestResponse + + if klass = self.class.controller_class + if klass < ActionController::Live + response_klass = LiveTestResponse + end + unless @controller + begin + @controller = klass.new + rescue + warn "could not construct controller #{klass}" if $VERBOSE + end + end + end + + @request = build_request + @response = build_response response_klass + @response.request = @request + + if @controller + @controller.request = @request + @controller.params = {} + end + end + + def build_request + TestRequest.new + end + + def build_response(klass) + klass.new + end + + included do + include ActionController::TemplateAssertions + include ActionDispatch::Assertions + class_attribute :_controller_class + setup :setup_controller_request_and_response + end + + private + + def document_root_element + html_document.root + end + + def check_required_ivars + # Sanity check for required instance variables so we can give an + # understandable error message. + [:@routes, :@controller, :@request, :@response].each do |iv_name| + if !instance_variable_defined?(iv_name) || instance_variable_get(iv_name).nil? + raise "#{iv_name} is nil: make sure you set it in your test's setup method." + end + end + end + + def build_request_uri(action, parameters) + unless @request.env["PATH_INFO"] + options = @controller.respond_to?(:url_options) ? @controller.__send__(:url_options).merge(parameters) : parameters + options.update( + :action => action, + :relative_url_root => nil, + :_recall => @request.path_parameters) + + if route_name = options.delete(:use_route) + ActiveSupport::Deprecation.warn <<-MSG.squish + Passing the `use_route` option in functional tests are deprecated. + Support for this option in the `process` method (and the related + `get`, `head`, `post`, `patch`, `put` and `delete` helpers) will + be removed in the next version without replacement. + + Functional tests are essentially unit tests for controllers and + they should not require knowledge to how the application's routes + are configured. Instead, you should explicitly pass the appropiate + params to the `process` method. + + Previously the engines guide also contained an incorrect example + that recommended using this option to test an engine's controllers + within the dummy application. That recommendation was incorrect + and has since been corrected. Instead, you should override the + `@routes` variable in the test case with `Foo::Engine.routes`. See + the updated engines guide for details. + MSG + end + + url, query_string = @routes.path_for(options, route_name).split("?", 2) + + @request.env["SCRIPT_NAME"] = @controller.config.relative_url_root + @request.env["PATH_INFO"] = url + @request.env["QUERY_STRING"] = query_string || "" + end + end + + def html_format?(parameters) + return true unless parameters.key?(:format) + Mime.fetch(parameters[:format]) { Mime['html'] }.html? + end + end + + include Behavior + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch.rb new file mode 100644 index 0000000..11b5e6b --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch.rb @@ -0,0 +1,105 @@ +#-- +# Copyright (c) 2004-2014 David Heinemeier Hansson +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +#++ + +require 'active_support' +require 'active_support/rails' +require 'active_support/core_ext/module/attribute_accessors' + +require 'action_pack' +require 'rack' + +module Rack + autoload :Test, 'rack/test' +end + +module ActionDispatch + extend ActiveSupport::Autoload + + class IllegalStateError < StandardError + end + + eager_autoload do + autoload_under 'http' do + autoload :Request + autoload :Response + end + end + + autoload_under 'middleware' do + autoload :RequestId + autoload :Callbacks + autoload :Cookies + autoload :DebugExceptions + autoload :ExceptionWrapper + autoload :Flash + autoload :ParamsParser + autoload :PublicExceptions + autoload :Reloader + autoload :RemoteIp + autoload :ShowExceptions + autoload :SSL + autoload :Static + end + + autoload :Journey + autoload :MiddlewareStack, 'action_dispatch/middleware/stack' + autoload :Routing + + module Http + extend ActiveSupport::Autoload + + autoload :Cache + autoload :Headers + autoload :MimeNegotiation + autoload :Parameters + autoload :ParameterFilter + autoload :Upload + autoload :UploadedFile, 'action_dispatch/http/upload' + autoload :URL + end + + module Session + autoload :AbstractStore, 'action_dispatch/middleware/session/abstract_store' + autoload :CookieStore, 'action_dispatch/middleware/session/cookie_store' + autoload :MemCacheStore, 'action_dispatch/middleware/session/mem_cache_store' + autoload :CacheStore, 'action_dispatch/middleware/session/cache_store' + end + + mattr_accessor :test_app + + autoload_under 'testing' do + autoload :Assertions + autoload :Integration + autoload :IntegrationTest, 'action_dispatch/testing/integration' + autoload :TestProcess + autoload :TestRequest + autoload :TestResponse + end +end + +autoload :Mime, 'action_dispatch/http/mime_type' + +ActiveSupport.on_load(:action_view) do + ActionView::Base.default_formats ||= Mime::SET.symbols + ActionView::Template::Types.delegate_to Mime +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/http/cache.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/http/cache.rb new file mode 100644 index 0000000..747d295 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/http/cache.rb @@ -0,0 +1,176 @@ + +module ActionDispatch + module Http + module Cache + module Request + + HTTP_IF_MODIFIED_SINCE = 'HTTP_IF_MODIFIED_SINCE'.freeze + HTTP_IF_NONE_MATCH = 'HTTP_IF_NONE_MATCH'.freeze + + def if_modified_since + if since = env[HTTP_IF_MODIFIED_SINCE] + Time.rfc2822(since) rescue nil + end + end + + def if_none_match + env[HTTP_IF_NONE_MATCH] + end + + def if_none_match_etags + (if_none_match ? if_none_match.split(/\s*,\s*/) : []).collect do |etag| + etag.gsub(/^\"|\"$/, "") + end + end + + def not_modified?(modified_at) + if_modified_since && modified_at && if_modified_since >= modified_at + end + + def etag_matches?(etag) + if etag + etag = etag.gsub(/^\"|\"$/, "") + if_none_match_etags.include?(etag) + end + end + + # Check response freshness (Last-Modified and ETag) against request + # If-Modified-Since and If-None-Match conditions. If both headers are + # supplied, both must match, or the request is not considered fresh. + def fresh?(response) + last_modified = if_modified_since + etag = if_none_match + + return false unless last_modified || etag + + success = true + success &&= not_modified?(response.last_modified) if last_modified + success &&= etag_matches?(response.etag) if etag + success + end + end + + module Response + attr_reader :cache_control, :etag + alias :etag? :etag + + def last_modified + if last = headers[LAST_MODIFIED] + Time.httpdate(last) + end + end + + def last_modified? + headers.include?(LAST_MODIFIED) + end + + def last_modified=(utc_time) + headers[LAST_MODIFIED] = utc_time.httpdate + end + + def date + if date_header = headers[DATE] + Time.httpdate(date_header) + end + end + + def date? + headers.include?(DATE) + end + + def date=(utc_time) + headers[DATE] = utc_time.httpdate + end + + def etag=(etag) + key = ActiveSupport::Cache.expand_cache_key(etag) + @etag = self[ETAG] = %("#{Digest::MD5.hexdigest(key)}") + end + + private + + DATE = 'Date'.freeze + LAST_MODIFIED = "Last-Modified".freeze + ETAG = "ETag".freeze + CACHE_CONTROL = "Cache-Control".freeze + SPECIAL_KEYS = Set.new(%w[extras no-cache max-age public must-revalidate]) + + def cache_control_segments + if cache_control = self[CACHE_CONTROL] + cache_control.delete(' ').split(',') + else + [] + end + end + + def cache_control_headers + cache_control = {} + + cache_control_segments.each do |segment| + directive, argument = segment.split('=', 2) + + if SPECIAL_KEYS.include? directive + key = directive.tr('-', '_') + cache_control[key.to_sym] = argument || true + else + cache_control[:extras] ||= [] + cache_control[:extras] << segment + end + end + + cache_control + end + + def prepare_cache_control! + @cache_control = cache_control_headers + @etag = self[ETAG] + end + + def handle_conditional_get! + if etag? || last_modified? || !@cache_control.empty? + set_conditional_cache_control! + end + end + + DEFAULT_CACHE_CONTROL = "max-age=0, private, must-revalidate".freeze + NO_CACHE = "no-cache".freeze + PUBLIC = "public".freeze + PRIVATE = "private".freeze + MUST_REVALIDATE = "must-revalidate".freeze + + def set_conditional_cache_control! + control = {} + cc_headers = cache_control_headers + if extras = cc_headers.delete(:extras) + @cache_control[:extras] ||= [] + @cache_control[:extras] += extras + @cache_control[:extras].uniq! + end + + control.merge! cc_headers + control.merge! @cache_control + + if control.empty? + headers[CACHE_CONTROL] = DEFAULT_CACHE_CONTROL + elsif control[:no_cache] + headers[CACHE_CONTROL] = NO_CACHE + if control[:extras] + headers[CACHE_CONTROL] += ", #{control[:extras].join(', ')}" + end + else + extras = control[:extras] + max_age = control[:max_age] + + options = [] + options << "max-age=#{max_age.to_i}" if max_age + options << (control[:public] ? PUBLIC : PRIVATE) + options << MUST_REVALIDATE if control[:must_revalidate] + options.concat(extras) if extras + + headers[CACHE_CONTROL] = options.join(", ") + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/http/filter_parameters.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/http/filter_parameters.rb new file mode 100644 index 0000000..2b851cc --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/http/filter_parameters.rb @@ -0,0 +1,78 @@ +require 'active_support/core_ext/hash/keys' +require 'active_support/core_ext/object/duplicable' +require 'action_dispatch/http/parameter_filter' + +module ActionDispatch + module Http + # Allows you to specify sensitive parameters which will be replaced from + # the request log by looking in the query string of the request and all + # sub-hashes of the params hash to filter. If a block is given, each key and + # value of the params hash and all sub-hashes is passed to it, the value + # or key can be replaced using String#replace or similar method. + # + # env["action_dispatch.parameter_filter"] = [:password] + # => replaces the value to all keys matching /password/i with "[FILTERED]" + # + # env["action_dispatch.parameter_filter"] = [:foo, "bar"] + # => replaces the value to all keys matching /foo|bar/i with "[FILTERED]" + # + # env["action_dispatch.parameter_filter"] = lambda do |k,v| + # v.reverse! if k =~ /secret/i + # end + # => reverses the value to all keys matching /secret/i + module FilterParameters + ENV_MATCH = [/RAW_POST_DATA/, "rack.request.form_vars"] # :nodoc: + NULL_PARAM_FILTER = ParameterFilter.new # :nodoc: + NULL_ENV_FILTER = ParameterFilter.new ENV_MATCH # :nodoc: + + def initialize(env) + super + @filtered_parameters = nil + @filtered_env = nil + @filtered_path = nil + end + + # Return a hash of parameters with all sensitive data replaced. + def filtered_parameters + @filtered_parameters ||= parameter_filter.filter(parameters) + end + + # Return a hash of request.env with all sensitive data replaced. + def filtered_env + @filtered_env ||= env_filter.filter(@env) + end + + # Reconstructed a path with all sensitive GET parameters replaced. + def filtered_path + @filtered_path ||= query_string.empty? ? path : "#{path}?#{filtered_query_string}" + end + + protected + + def parameter_filter + parameter_filter_for @env.fetch("action_dispatch.parameter_filter") { + return NULL_PARAM_FILTER + } + end + + def env_filter + user_key = @env.fetch("action_dispatch.parameter_filter") { + return NULL_ENV_FILTER + } + parameter_filter_for(Array(user_key) + ENV_MATCH) + end + + def parameter_filter_for(filters) + ParameterFilter.new(filters) + end + + KV_RE = '[^&;=]+' + PAIR_RE = %r{(#{KV_RE})=(#{KV_RE})} + def filtered_query_string + query_string.gsub(PAIR_RE) do |_| + parameter_filter.filter([[$1, $2]]).first.join("=") + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/http/filter_redirect.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/http/filter_redirect.rb new file mode 100644 index 0000000..cd60364 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/http/filter_redirect.rb @@ -0,0 +1,38 @@ +module ActionDispatch + module Http + module FilterRedirect + + FILTERED = '[FILTERED]'.freeze # :nodoc: + + def filtered_location + filters = location_filter + if !filters.empty? && location_filter_match?(filters) + FILTERED + else + location + end + end + + private + + def location_filter + if request + request.env['action_dispatch.redirect_filter'] || [] + else + [] + end + end + + def location_filter_match?(filters) + filters.any? do |filter| + if String === filter + location.include?(filter) + elsif Regexp === filter + location.match(filter) + end + end + end + + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/http/headers.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/http/headers.rb new file mode 100644 index 0000000..bc5410d --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/http/headers.rb @@ -0,0 +1,99 @@ +module ActionDispatch + module Http + # Provides access to the request's HTTP headers from the environment. + # + # env = { "CONTENT_TYPE" => "text/plain" } + # headers = ActionDispatch::Http::Headers.new(env) + # headers["Content-Type"] # => "text/plain" + class Headers + CGI_VARIABLES = Set.new(%W[ + AUTH_TYPE + CONTENT_LENGTH + CONTENT_TYPE + GATEWAY_INTERFACE + HTTPS + PATH_INFO + PATH_TRANSLATED + QUERY_STRING + REMOTE_ADDR + REMOTE_HOST + REMOTE_IDENT + REMOTE_USER + REQUEST_METHOD + SCRIPT_NAME + SERVER_NAME + SERVER_PORT + SERVER_PROTOCOL + SERVER_SOFTWARE + ]).freeze + + HTTP_HEADER = /\A[A-Za-z0-9-]+\z/ + + include Enumerable + attr_reader :env + + def initialize(env = {}) # :nodoc: + @env = env + end + + # Returns the value for the given key mapped to @env. + def [](key) + @env[env_name(key)] + end + + # Sets the given value for the key mapped to @env. + def []=(key, value) + @env[env_name(key)] = value + end + + def key?(key) + @env.key? env_name(key) + end + alias :include? :key? + + # Returns the value for the given key mapped to @env. + # + # If the key is not found and an optional code block is not provided, + # raises a KeyError exception. + # + # If the code block is provided, then it will be run and + # its result returned. + def fetch(key, *args, &block) + @env.fetch env_name(key), *args, &block + end + + def each(&block) + @env.each(&block) + end + + # Returns a new Http::Headers instance containing the contents of + # headers_or_env and the original instance. + def merge(headers_or_env) + headers = Http::Headers.new(env.dup) + headers.merge!(headers_or_env) + headers + end + + # Adds the contents of headers_or_env to original instance + # entries; duplicate keys are overwritten with the values from + # headers_or_env. + def merge!(headers_or_env) + headers_or_env.each do |key, value| + self[env_name(key)] = value + end + end + + private + # Converts a HTTP header name to an environment variable name if it is + # not contained within the headers hash. + def env_name(key) + key = key.to_s + if key =~ HTTP_HEADER + key = key.upcase.tr('-', '_') + key = "HTTP_" + key unless CGI_VARIABLES.include?(key) + end + key + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/http/mime_negotiation.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/http/mime_negotiation.rb new file mode 100644 index 0000000..53a98c5 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/http/mime_negotiation.rb @@ -0,0 +1,156 @@ +require 'active_support/core_ext/module/attribute_accessors' + +module ActionDispatch + module Http + module MimeNegotiation + extend ActiveSupport::Concern + + included do + mattr_accessor :ignore_accept_header + self.ignore_accept_header = false + end + + attr_reader :variant + + # The MIME type of the HTTP request, such as Mime::XML. + # + # For backward compatibility, the post \format is extracted from the + # X-Post-Data-Format HTTP header if present. + def content_mime_type + @env["action_dispatch.request.content_type"] ||= begin + if @env['CONTENT_TYPE'] =~ /^([^,\;]*)/ + Mime::Type.lookup($1.strip.downcase) + else + nil + end + end + end + + def content_type + content_mime_type && content_mime_type.to_s + end + + # Returns the accepted MIME type for the request. + def accepts + @env["action_dispatch.request.accepts"] ||= begin + header = @env['HTTP_ACCEPT'].to_s.strip + + if header.empty? + [content_mime_type] + else + Mime::Type.parse(header) + end + end + end + + # Returns the MIME type for the \format used in the request. + # + # GET /posts/5.xml | request.format => Mime::XML + # GET /posts/5.xhtml | request.format => Mime::HTML + # GET /posts/5 | request.format => Mime::HTML or MIME::JS, or request.accepts.first + # + def format(view_path = []) + formats.first || Mime::NullType.instance + end + + def formats + @env["action_dispatch.request.formats"] ||= begin + params_readable = begin + parameters[:format] + rescue ActionController::BadRequest + false + end + + if params_readable + Array(Mime[parameters[:format]]) + elsif use_accept_header && valid_accept_header + accepts + elsif xhr? + [Mime::JS] + else + [Mime::HTML] + end + end + end + + # Sets the \variant for template. + def variant=(variant) + if variant.is_a?(Symbol) + @variant = [variant] + elsif variant.nil? || variant.is_a?(Array) && variant.any? && variant.all?{ |v| v.is_a?(Symbol) } + @variant = variant + else + raise ArgumentError, "request.variant must be set to a Symbol or an Array of Symbols, not a #{variant.class}. " \ + "For security reasons, never directly set the variant to a user-provided value, " \ + "like params[:variant].to_sym. Check user-provided value against a whitelist first, " \ + "then set the variant: request.variant = :tablet if params[:variant] == 'tablet'" + end + end + + # Sets the \format by string extension, which can be used to force custom formats + # that are not controlled by the extension. + # + # class ApplicationController < ActionController::Base + # before_action :adjust_format_for_iphone + # + # private + # def adjust_format_for_iphone + # request.format = :iphone if request.env["HTTP_USER_AGENT"][/iPhone/] + # end + # end + def format=(extension) + parameters[:format] = extension.to_s + @env["action_dispatch.request.formats"] = [Mime::Type.lookup_by_extension(parameters[:format])] + end + + # Sets the \formats by string extensions. This differs from #format= by allowing you + # to set multiple, ordered formats, which is useful when you want to have a fallback. + # + # In this example, the :iphone format will be used if it's available, otherwise it'll fallback + # to the :html format. + # + # class ApplicationController < ActionController::Base + # before_action :adjust_format_for_iphone_with_html_fallback + # + # private + # def adjust_format_for_iphone_with_html_fallback + # request.formats = [ :iphone, :html ] if request.env["HTTP_USER_AGENT"][/iPhone/] + # end + # end + def formats=(extensions) + parameters[:format] = extensions.first.to_s + @env["action_dispatch.request.formats"] = extensions.collect do |extension| + Mime::Type.lookup_by_extension(extension) + end + end + + # Receives an array of mimes and return the first user sent mime that + # matches the order array. + # + def negotiate_mime(order) + formats.each do |priority| + if priority == Mime::ALL + return order.first + elsif order.include?(priority) + return priority + end + end + + order.include?(Mime::ALL) ? format : nil + end + + protected + + BROWSER_LIKE_ACCEPTS = /,\s*\*\/\*|\*\/\*\s*,/ + + def valid_accept_header + (xhr? && (accept.present? || content_mime_type)) || + (accept.present? && accept !~ BROWSER_LIKE_ACCEPTS) + end + + def use_accept_header + !self.class.ignore_accept_header + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/http/mime_type.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/http/mime_type.rb new file mode 100644 index 0000000..3257e21 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/http/mime_type.rb @@ -0,0 +1,329 @@ +require 'set' +require 'singleton' +require 'active_support/core_ext/module/attribute_accessors' +require 'active_support/core_ext/string/starts_ends_with' + +module Mime + class Mimes < Array + def symbols + @symbols ||= map { |m| m.to_sym } + end + + %w(<< concat shift unshift push pop []= clear compact! collect! + delete delete_at delete_if flatten! map! insert reject! reverse! + replace slice! sort! uniq!).each do |method| + module_eval <<-CODE, __FILE__, __LINE__ + 1 + def #{method}(*) + @symbols = nil + super + end + CODE + end + end + + SET = Mimes.new + EXTENSION_LOOKUP = {} + LOOKUP = {} + + class << self + def [](type) + return type if type.is_a?(Type) + Type.lookup_by_extension(type) + end + + def fetch(type) + return type if type.is_a?(Type) + EXTENSION_LOOKUP.fetch(type.to_s) { |k| yield k } + end + end + + # Encapsulates the notion of a mime type. Can be used at render time, for example, with: + # + # class PostsController < ActionController::Base + # def show + # @post = Post.find(params[:id]) + # + # respond_to do |format| + # format.html + # format.ics { render text: @post.to_ics, mime_type: Mime::Type["text/calendar"] } + # format.xml { render xml: @post } + # end + # end + # end + class Type + @@html_types = Set.new [:html, :all] + cattr_reader :html_types + + attr_reader :symbol + + @register_callbacks = [] + + # A simple helper class used in parsing the accept header + class AcceptItem #:nodoc: + attr_accessor :index, :name, :q + alias :to_s :name + + def initialize(index, name, q = nil) + @index = index + @name = name + q ||= 0.0 if @name == Mime::ALL.to_s # default wildcard match to end of list + @q = ((q || 1.0).to_f * 100).to_i + end + + def <=>(item) + result = item.q <=> @q + result = @index <=> item.index if result == 0 + result + end + + def ==(item) + @name == item.to_s + end + end + + class AcceptList < Array #:nodoc: + def assort! + sort! + + # Take care of the broken text/xml entry by renaming or deleting it + if text_xml_idx && app_xml_idx + app_xml.q = [text_xml.q, app_xml.q].max # set the q value to the max of the two + exchange_xml_items if app_xml_idx > text_xml_idx # make sure app_xml is ahead of text_xml in the list + delete_at(text_xml_idx) # delete text_xml from the list + elsif text_xml_idx + text_xml.name = Mime::XML.to_s + end + + # Look for more specific XML-based types and sort them ahead of app/xml + if app_xml_idx + idx = app_xml_idx + + while idx < length + type = self[idx] + break if type.q < app_xml.q + + if type.name.ends_with? '+xml' + self[app_xml_idx], self[idx] = self[idx], app_xml + @app_xml_idx = idx + end + idx += 1 + end + end + + map! { |i| Mime::Type.lookup(i.name) }.uniq! + to_a + end + + private + def text_xml_idx + @text_xml_idx ||= index('text/xml') + end + + def app_xml_idx + @app_xml_idx ||= index(Mime::XML.to_s) + end + + def text_xml + self[text_xml_idx] + end + + def app_xml + self[app_xml_idx] + end + + def exchange_xml_items + self[app_xml_idx], self[text_xml_idx] = text_xml, app_xml + @app_xml_idx, @text_xml_idx = text_xml_idx, app_xml_idx + end + end + + class << self + TRAILING_STAR_REGEXP = /(text|application)\/\*/ + PARAMETER_SEPARATOR_REGEXP = /;\s*\w+="?\w+"?/ + + def register_callback(&block) + @register_callbacks << block + end + + def lookup(string) + LOOKUP[string] || Type.new(string) + end + + def lookup_by_extension(extension) + EXTENSION_LOOKUP[extension.to_s] + end + + # Registers an alias that's not used on mime type lookup, but can be referenced directly. Especially useful for + # rendering different HTML versions depending on the user agent, like an iPhone. + def register_alias(string, symbol, extension_synonyms = []) + register(string, symbol, [], extension_synonyms, true) + end + + def register(string, symbol, mime_type_synonyms = [], extension_synonyms = [], skip_lookup = false) + Mime.const_set(symbol.upcase, Type.new(string, symbol, mime_type_synonyms)) + + new_mime = Mime.const_get(symbol.upcase) + SET << new_mime + + ([string] + mime_type_synonyms).each { |str| LOOKUP[str] = SET.last } unless skip_lookup + ([symbol] + extension_synonyms).each { |ext| EXTENSION_LOOKUP[ext.to_s] = SET.last } + + @register_callbacks.each do |callback| + callback.call(new_mime) + end + end + + def parse(accept_header) + if !accept_header.include?(',') + accept_header = accept_header.split(PARAMETER_SEPARATOR_REGEXP).first + parse_trailing_star(accept_header) || [Mime::Type.lookup(accept_header)].compact + else + list, index = AcceptList.new, 0 + accept_header.split(',').each do |header| + params, q = header.split(PARAMETER_SEPARATOR_REGEXP) + if params.present? + params.strip! + + params = parse_trailing_star(params) || [params] + + params.each do |m| + list << AcceptItem.new(index, m.to_s, q) + index += 1 + end + end + end + list.assort! + end + end + + def parse_trailing_star(accept_header) + parse_data_with_trailing_star($1) if accept_header =~ TRAILING_STAR_REGEXP + end + + # For an input of 'text', returns [Mime::JSON, Mime::XML, Mime::ICS, + # Mime::HTML, Mime::CSS, Mime::CSV, Mime::JS, Mime::YAML, Mime::TEXT]. + # + # For an input of 'application', returns [Mime::HTML, Mime::JS, + # Mime::XML, Mime::YAML, Mime::ATOM, Mime::JSON, Mime::RSS, Mime::URL_ENCODED_FORM]. + def parse_data_with_trailing_star(input) + Mime::SET.select { |m| m =~ input } + end + + # This method is opposite of register method. + # + # Usage: + # + # Mime::Type.unregister(:mobile) + def unregister(symbol) + symbol = symbol.upcase + mime = Mime.const_get(symbol) + Mime.instance_eval { remove_const(symbol) } + + SET.delete_if { |v| v.eql?(mime) } + LOOKUP.delete_if { |_,v| v.eql?(mime) } + EXTENSION_LOOKUP.delete_if { |_,v| v.eql?(mime) } + end + end + + attr_reader :hash + + def initialize(string, symbol = nil, synonyms = []) + @symbol, @synonyms = symbol, synonyms + @string = string + @hash = [@string, @synonyms, @symbol].hash + end + + def to_s + @string + end + + def to_str + to_s + end + + def to_sym + @symbol + end + + def ref + to_sym || to_s + end + + def ===(list) + if list.is_a?(Array) + (@synonyms + [ self ]).any? { |synonym| list.include?(synonym) } + else + super + end + end + + def ==(mime_type) + return false if mime_type.blank? + (@synonyms + [ self ]).any? do |synonym| + synonym.to_s == mime_type.to_s || synonym.to_sym == mime_type.to_sym + end + end + + def eql?(other) + super || (self.class == other.class && + @string == other.string && + @synonyms == other.synonyms && + @symbol == other.symbol) + end + + def =~(mime_type) + return false if mime_type.blank? + regexp = Regexp.new(Regexp.quote(mime_type.to_s)) + (@synonyms + [ self ]).any? do |synonym| + synonym.to_s =~ regexp + end + end + + def html? + @@html_types.include?(to_sym) || @string =~ /html/ + end + + + protected + + attr_reader :string, :synonyms + + private + + def to_ary; end + def to_a; end + + def method_missing(method, *args) + if method.to_s.ends_with? '?' + method[0..-2].downcase.to_sym == to_sym + else + super + end + end + + def respond_to_missing?(method, include_private = false) #:nodoc: + method.to_s.ends_with? '?' + end + end + + class NullType + include Singleton + + def nil? + true + end + + def ref; end + + def respond_to_missing?(method, include_private = false) + method.to_s.ends_with? '?' + end + + private + def method_missing(method, *args) + false if method.to_s.ends_with? '?' + end + end +end + +require 'action_dispatch/http/mime_types' diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/http/mime_types.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/http/mime_types.rb new file mode 100644 index 0000000..0e4da36 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/http/mime_types.rb @@ -0,0 +1,36 @@ +# Build list of Mime types for HTTP responses +# http://www.iana.org/assignments/media-types/ + +Mime::Type.register "text/html", :html, %w( application/xhtml+xml ), %w( xhtml ) +Mime::Type.register "text/plain", :text, [], %w(txt) +Mime::Type.register "text/javascript", :js, %w( application/javascript application/x-javascript ) +Mime::Type.register "text/css", :css +Mime::Type.register "text/calendar", :ics +Mime::Type.register "text/csv", :csv +Mime::Type.register "text/vcard", :vcf + +Mime::Type.register "image/png", :png, [], %w(png) +Mime::Type.register "image/jpeg", :jpeg, [], %w(jpg jpeg jpe pjpeg) +Mime::Type.register "image/gif", :gif, [], %w(gif) +Mime::Type.register "image/bmp", :bmp, [], %w(bmp) +Mime::Type.register "image/tiff", :tiff, [], %w(tif tiff) + +Mime::Type.register "video/mpeg", :mpeg, [], %w(mpg mpeg mpe) + +Mime::Type.register "application/xml", :xml, %w( text/xml application/x-xml ) +Mime::Type.register "application/rss+xml", :rss +Mime::Type.register "application/atom+xml", :atom +Mime::Type.register "application/x-yaml", :yaml, %w( text/yaml ) + +Mime::Type.register "multipart/form-data", :multipart_form +Mime::Type.register "application/x-www-form-urlencoded", :url_encoded_form + +# http://www.ietf.org/rfc/rfc4627.txt +# http://www.json.org/JSONRequest.html +Mime::Type.register "application/json", :json, %w( text/x-json application/jsonrequest ) + +Mime::Type.register "application/pdf", :pdf, [], %w(pdf) +Mime::Type.register "application/zip", :zip, [], %w(zip) + +# Create Mime::ALL but do not add it to the SET. +Mime::ALL = Mime::Type.new("*/*", :all, []) diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/http/parameter_filter.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/http/parameter_filter.rb new file mode 100644 index 0000000..df4b073 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/http/parameter_filter.rb @@ -0,0 +1,72 @@ +module ActionDispatch + module Http + class ParameterFilter + FILTERED = '[FILTERED]'.freeze # :nodoc: + + def initialize(filters = []) + @filters = filters + end + + def filter(params) + compiled_filter.call(params) + end + + private + + def compiled_filter + @compiled_filter ||= CompiledFilter.compile(@filters) + end + + class CompiledFilter # :nodoc: + def self.compile(filters) + return lambda { |params| params.dup } if filters.empty? + + strings, regexps, blocks = [], [], [] + + filters.each do |item| + case item + when Proc + blocks << item + when Regexp + regexps << item + else + strings << item.to_s + end + end + + regexps << Regexp.new(strings.join('|'), true) unless strings.empty? + new regexps, blocks + end + + attr_reader :regexps, :blocks + + def initialize(regexps, blocks) + @regexps = regexps + @blocks = blocks + end + + def call(original_params) + filtered_params = {} + + original_params.each do |key, value| + if regexps.any? { |r| key =~ r } + value = FILTERED + elsif value.is_a?(Hash) + value = call(value) + elsif value.is_a?(Array) + value = value.map { |v| v.is_a?(Hash) ? call(v) : v } + elsif blocks.any? + key = key.dup if key.duplicable? + value = value.dup if value.duplicable? + blocks.each { |b| b.call(key, value) } + end + + filtered_params[key] = value + end + + filtered_params + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/http/parameters.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/http/parameters.rb new file mode 100644 index 0000000..a5cd26a --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/http/parameters.rb @@ -0,0 +1,67 @@ +require 'active_support/core_ext/hash/keys' +require 'active_support/core_ext/hash/indifferent_access' +require 'active_support/deprecation' + +module ActionDispatch + module Http + module Parameters + PARAMETERS_KEY = 'action_dispatch.request.path_parameters' + + # Returns both GET and POST \parameters in a single hash. + def parameters + @env["action_dispatch.request.parameters"] ||= begin + params = begin + request_parameters.merge(query_parameters) + rescue EOFError + query_parameters.dup + end + params.merge!(path_parameters) + end + end + alias :params :parameters + + def path_parameters=(parameters) #:nodoc: + @env.delete('action_dispatch.request.parameters') + @env[PARAMETERS_KEY] = parameters + end + + def symbolized_path_parameters + ActiveSupport::Deprecation.warn( + '`symbolized_path_parameters` is deprecated. Please use `path_parameters`.' + ) + path_parameters + end + + # Returns a hash with the \parameters used to form the \path of the request. + # Returned hash keys are strings: + # + # {'action' => 'my_action', 'controller' => 'my_controller'} + def path_parameters + @env[PARAMETERS_KEY] ||= {} + end + + private + + # Convert nested Hash to HashWithIndifferentAccess. + # + def normalize_encode_params(params) + case params + when Hash + if params.has_key?(:tempfile) + UploadedFile.new(params) + else + params.each_with_object({}) do |(key, val), new_hash| + new_hash[key] = if val.is_a?(Array) + val.map! { |el| normalize_encode_params(el) } + else + normalize_encode_params(val) + end + end.with_indifferent_access + end + else + params + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/http/rack_cache.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/http/rack_cache.rb new file mode 100644 index 0000000..003ae40 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/http/rack_cache.rb @@ -0,0 +1,61 @@ +require "rack/cache" +require "rack/cache/context" +require "active_support/cache" + +module ActionDispatch + class RailsMetaStore < Rack::Cache::MetaStore + def self.resolve(uri) + new + end + + def initialize(store = Rails.cache) + @store = store + end + + def read(key) + if data = @store.read(key) + Marshal.load(data) + else + [] + end + end + + def write(key, value) + @store.write(key, Marshal.dump(value)) + end + + ::Rack::Cache::MetaStore::RAILS = self + end + + class RailsEntityStore < Rack::Cache::EntityStore + def self.resolve(uri) + new + end + + def initialize(store = Rails.cache) + @store = store + end + + def exist?(key) + @store.exist?(key) + end + + def open(key) + @store.read(key) + end + + def read(key) + body = open(key) + body.join if body + end + + def write(body) + buf = [] + key, size = slurp(body) { |part| buf << part } + @store.write(key, buf) + [key, size] + end + + ::Rack::Cache::EntityStore::RAILS = self + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/http/request.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/http/request.rb new file mode 100644 index 0000000..2a7bb37 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/http/request.rb @@ -0,0 +1,348 @@ +require 'stringio' + +require 'active_support/inflector' +require 'action_dispatch/http/headers' +require 'action_controller/metal/exceptions' +require 'rack/request' +require 'action_dispatch/http/cache' +require 'action_dispatch/http/mime_negotiation' +require 'action_dispatch/http/parameters' +require 'action_dispatch/http/filter_parameters' +require 'action_dispatch/http/upload' +require 'action_dispatch/http/url' +require 'active_support/core_ext/array/conversions' + +module ActionDispatch + class Request < Rack::Request + include ActionDispatch::Http::Cache::Request + include ActionDispatch::Http::MimeNegotiation + include ActionDispatch::Http::Parameters + include ActionDispatch::Http::FilterParameters + include ActionDispatch::Http::URL + + autoload :Session, 'action_dispatch/request/session' + autoload :Utils, 'action_dispatch/request/utils' + + LOCALHOST = Regexp.union [/^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/, /^::1$/, /^0:0:0:0:0:0:0:1(%.*)?$/] + + ENV_METHODS = %w[ AUTH_TYPE GATEWAY_INTERFACE + PATH_TRANSLATED REMOTE_HOST + REMOTE_IDENT REMOTE_USER REMOTE_ADDR + SERVER_NAME SERVER_PROTOCOL + + HTTP_ACCEPT HTTP_ACCEPT_CHARSET HTTP_ACCEPT_ENCODING + HTTP_ACCEPT_LANGUAGE HTTP_CACHE_CONTROL HTTP_FROM + HTTP_NEGOTIATE HTTP_PRAGMA ].freeze + + ENV_METHODS.each do |env| + class_eval <<-METHOD, __FILE__, __LINE__ + 1 + def #{env.sub(/^HTTP_/n, '').downcase} # def accept_charset + @env["#{env}"] # @env["HTTP_ACCEPT_CHARSET"] + end # end + METHOD + end + + def initialize(env) + super + @method = nil + @request_method = nil + @remote_ip = nil + @original_fullpath = nil + @fullpath = nil + @ip = nil + @uuid = nil + end + + def check_path_parameters! + # If any of the path parameters has an invalid encoding then + # raise since it's likely to trigger errors further on. + path_parameters.each do |key, value| + next unless value.respond_to?(:valid_encoding?) + unless value.valid_encoding? + raise ActionController::BadRequest, "Invalid parameter: #{key} => #{value}" + end + end + end + + def key?(key) + @env.key?(key) + end + + # List of HTTP request methods from the following RFCs: + # Hypertext Transfer Protocol -- HTTP/1.1 (http://www.ietf.org/rfc/rfc2616.txt) + # HTTP Extensions for Distributed Authoring -- WEBDAV (http://www.ietf.org/rfc/rfc2518.txt) + # Versioning Extensions to WebDAV (http://www.ietf.org/rfc/rfc3253.txt) + # Ordered Collections Protocol (WebDAV) (http://www.ietf.org/rfc/rfc3648.txt) + # Web Distributed Authoring and Versioning (WebDAV) Access Control Protocol (http://www.ietf.org/rfc/rfc3744.txt) + # Web Distributed Authoring and Versioning (WebDAV) SEARCH (http://www.ietf.org/rfc/rfc5323.txt) + # Calendar Extensions to WebDAV (http://www.ietf.org/rfc/rfc4791.txt) + # PATCH Method for HTTP (http://www.ietf.org/rfc/rfc5789.txt) + RFC2616 = %w(OPTIONS GET HEAD POST PUT DELETE TRACE CONNECT) + RFC2518 = %w(PROPFIND PROPPATCH MKCOL COPY MOVE LOCK UNLOCK) + RFC3253 = %w(VERSION-CONTROL REPORT CHECKOUT CHECKIN UNCHECKOUT MKWORKSPACE UPDATE LABEL MERGE BASELINE-CONTROL MKACTIVITY) + RFC3648 = %w(ORDERPATCH) + RFC3744 = %w(ACL) + RFC5323 = %w(SEARCH) + RFC4791 = %w(MKCALENDAR) + RFC5789 = %w(PATCH) + + HTTP_METHODS = RFC2616 + RFC2518 + RFC3253 + RFC3648 + RFC3744 + RFC5323 + RFC4791 + RFC5789 + + HTTP_METHOD_LOOKUP = {} + + # Populate the HTTP method lookup cache + HTTP_METHODS.each { |method| + HTTP_METHOD_LOOKUP[method] = method.underscore.to_sym + } + + # Returns the HTTP \method that the application should see. + # In the case where the \method was overridden by a middleware + # (for instance, if a HEAD request was converted to a GET, + # or if a _method parameter was used to determine the \method + # the application should use), this \method returns the overridden + # value, not the original. + def request_method + @request_method ||= check_method(env["REQUEST_METHOD"]) + end + + def request_method=(request_method) #:nodoc: + if check_method(request_method) + @request_method = env["REQUEST_METHOD"] = request_method + end + end + + # Returns a symbol form of the #request_method + def request_method_symbol + HTTP_METHOD_LOOKUP[request_method] + end + + # Returns the original value of the environment's REQUEST_METHOD, + # even if it was overridden by middleware. See #request_method for + # more information. + def method + @method ||= check_method(env["rack.methodoverride.original_method"] || env['REQUEST_METHOD']) + end + + # Returns a symbol form of the #method + def method_symbol + HTTP_METHOD_LOOKUP[method] + end + + # Is this a GET (or HEAD) request? + # Equivalent to request.request_method_symbol == :get. + def get? + HTTP_METHOD_LOOKUP[request_method] == :get + end + + # Is this a POST request? + # Equivalent to request.request_method_symbol == :post. + def post? + HTTP_METHOD_LOOKUP[request_method] == :post + end + + # Is this a PATCH request? + # Equivalent to request.request_method == :patch. + def patch? + HTTP_METHOD_LOOKUP[request_method] == :patch + end + + # Is this a PUT request? + # Equivalent to request.request_method_symbol == :put. + def put? + HTTP_METHOD_LOOKUP[request_method] == :put + end + + # Is this a DELETE request? + # Equivalent to request.request_method_symbol == :delete. + def delete? + HTTP_METHOD_LOOKUP[request_method] == :delete + end + + # Is this a HEAD request? + # Equivalent to request.request_method_symbol == :head. + def head? + HTTP_METHOD_LOOKUP[request_method] == :head + end + + # Provides access to the request's HTTP headers, for example: + # + # request.headers["Content-Type"] # => "text/plain" + def headers + Http::Headers.new(@env) + end + + # Returns a +String+ with the last requested path including their params. + # + # # get '/foo' + # request.original_fullpath # => '/foo' + # + # # get '/foo?bar' + # request.original_fullpath # => '/foo?bar' + def original_fullpath + @original_fullpath ||= (env["ORIGINAL_FULLPATH"] || fullpath) + end + + # Returns the +String+ full path including params of the last URL requested. + # + # # get "/articles" + # request.fullpath # => "/articles" + # + # # get "/articles?page=2" + # request.fullpath # => "/articles?page=2" + def fullpath + @fullpath ||= super + end + + # Returns the original request URL as a +String+. + # + # # get "/articles?page=2" + # request.original_url # => "http://www.example.com/articles?page=2" + def original_url + base_url + original_fullpath + end + + # The +String+ MIME type of the request. + # + # # get "/articles" + # request.media_type # => "application/x-www-form-urlencoded" + def media_type + content_mime_type.to_s + end + + # Returns the content length of the request as an integer. + def content_length + super.to_i + end + + # Returns true if the "X-Requested-With" header contains "XMLHttpRequest" + # (case-insensitive), which may need to be manually added depending on the + # choice of JavaScript libraries and frameworks. + def xml_http_request? + @env['HTTP_X_REQUESTED_WITH'] =~ /XMLHttpRequest/i + end + alias :xhr? :xml_http_request? + + def ip + @ip ||= super + end + + # Originating IP address, usually set by the RemoteIp middleware. + def remote_ip + @remote_ip ||= (@env["action_dispatch.remote_ip"] || ip).to_s + end + + # Returns the unique request id, which is based on either the X-Request-Id header that can + # be generated by a firewall, load balancer, or web server or by the RequestId middleware + # (which sets the action_dispatch.request_id environment variable). + # + # This unique ID is useful for tracing a request from end-to-end as part of logging or debugging. + # This relies on the rack variable set by the ActionDispatch::RequestId middleware. + def uuid + @uuid ||= env["action_dispatch.request_id"] + end + + # Returns the lowercase name of the HTTP server software. + def server_software + (@env['SERVER_SOFTWARE'] && /^([a-zA-Z]+)/ =~ @env['SERVER_SOFTWARE']) ? $1.downcase : nil + end + + # Read the request \body. This is useful for web services that need to + # work with raw requests directly. + def raw_post + unless @env.include? 'RAW_POST_DATA' + raw_post_body = body + @env['RAW_POST_DATA'] = raw_post_body.read(content_length) + raw_post_body.rewind if raw_post_body.respond_to?(:rewind) + end + @env['RAW_POST_DATA'] + end + + # The request body is an IO input stream. If the RAW_POST_DATA environment + # variable is already set, wrap it in a StringIO. + def body + if raw_post = @env['RAW_POST_DATA'] + raw_post.force_encoding(Encoding::BINARY) + StringIO.new(raw_post) + else + @env['rack.input'] + end + end + + def form_data? + FORM_DATA_MEDIA_TYPES.include?(content_mime_type.to_s) + end + + def body_stream #:nodoc: + @env['rack.input'] + end + + # TODO This should be broken apart into AD::Request::Session and probably + # be included by the session middleware. + def reset_session + if session && session.respond_to?(:destroy) + session.destroy + else + self.session = {} + end + @env['action_dispatch.request.flash_hash'] = nil + end + + def session=(session) #:nodoc: + Session.set @env, session + end + + def session_options=(options) + Session::Options.set @env, options + end + + # Override Rack's GET method to support indifferent access + def GET + @env["action_dispatch.request.query_parameters"] ||= Utils.deep_munge(normalize_encode_params(super || {})) + rescue Rack::Utils::ParameterTypeError, Rack::Utils::InvalidParameterError => e + raise ActionController::BadRequest.new(:query, e) + end + alias :query_parameters :GET + + # Override Rack's POST method to support indifferent access + def POST + @env["action_dispatch.request.request_parameters"] ||= Utils.deep_munge(normalize_encode_params(super || {})) + rescue Rack::Utils::ParameterTypeError, Rack::Utils::InvalidParameterError => e + raise ActionController::BadRequest.new(:request, e) + end + alias :request_parameters :POST + + # Returns the authorization header regardless of whether it was specified directly or through one of the + # proxy alternatives. + def authorization + @env['HTTP_AUTHORIZATION'] || + @env['X-HTTP_AUTHORIZATION'] || + @env['X_HTTP_AUTHORIZATION'] || + @env['REDIRECT_X_HTTP_AUTHORIZATION'] + end + + # True if the request came from localhost, 127.0.0.1. + def local? + LOCALHOST =~ remote_addr && LOCALHOST =~ remote_ip + end + + # Extracted into ActionDispatch::Request::Utils.deep_munge, but kept here for backwards compatibility. + def deep_munge(hash) + ActiveSupport::Deprecation.warn( + 'This method has been extracted into `ActionDispatch::Request::Utils.deep_munge`. Please start using that instead.' + ) + + Utils.deep_munge(hash) + end + + protected + def parse_query(qs) + Utils.deep_munge(super) + end + + private + def check_method(name) + HTTP_METHOD_LOOKUP[name] || raise(ActionController::UnknownHttpMethod, "#{name}, accepted HTTP methods are #{HTTP_METHODS[0...-1].join(', ')}, and #{HTTP_METHODS[-1]}") + name + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/http/response.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/http/response.rb new file mode 100644 index 0000000..f80a8bf --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/http/response.rb @@ -0,0 +1,405 @@ +require 'active_support/core_ext/module/attribute_accessors' +require 'active_support/core_ext/string/filters' +require 'active_support/deprecation' +require 'action_dispatch/http/filter_redirect' +require 'monitor' + +module ActionDispatch # :nodoc: + # Represents an HTTP response generated by a controller action. Use it to + # retrieve the current state of the response, or customize the response. It can + # either represent a real HTTP response (i.e. one that is meant to be sent + # back to the web browser) or a TestResponse (i.e. one that is generated + # from integration tests). + # + # \Response is mostly a Ruby on \Rails framework implementation detail, and + # should never be used directly in controllers. Controllers should use the + # methods defined in ActionController::Base instead. For example, if you want + # to set the HTTP response's content MIME type, then use + # ActionControllerBase#headers instead of Response#headers. + # + # Nevertheless, integration tests may want to inspect controller responses in + # more detail, and that's when \Response can be useful for application + # developers. Integration test methods such as + # ActionDispatch::Integration::Session#get and + # ActionDispatch::Integration::Session#post return objects of type + # TestResponse (which are of course also of type \Response). + # + # For example, the following demo integration test prints the body of the + # controller response to the console: + # + # class DemoControllerTest < ActionDispatch::IntegrationTest + # def test_print_root_path_to_console + # get('/') + # puts response.body + # end + # end + class Response + # The request that the response is responding to. + attr_accessor :request + + # The HTTP status code. + attr_reader :status + + attr_writer :sending_file + + # Get and set headers for this response. + attr_accessor :header + + alias_method :headers=, :header= + alias_method :headers, :header + + delegate :[], :[]=, :to => :@header + delegate :each, :to => :@stream + + # Sets the HTTP response's content MIME type. For example, in the controller + # you could write this: + # + # response.content_type = "text/plain" + # + # If a character set has been defined for this response (see charset=) then + # the character set information will also be included in the content type + # information. + attr_reader :content_type + + # The charset of the response. HTML wants to know the encoding of the + # content you're giving them, so we need to send that along. + attr_accessor :charset + + CONTENT_TYPE = "Content-Type".freeze + SET_COOKIE = "Set-Cookie".freeze + LOCATION = "Location".freeze + NO_CONTENT_CODES = [204, 304] + + cattr_accessor(:default_charset) { "utf-8" } + cattr_accessor(:default_headers) + + include Rack::Response::Helpers + include ActionDispatch::Http::FilterRedirect + include ActionDispatch::Http::Cache::Response + include MonitorMixin + + class Buffer # :nodoc: + def initialize(response, buf) + @response = response + @buf = buf + @closed = false + end + + def write(string) + raise IOError, "closed stream" if closed? + + @response.commit! + @buf.push string + end + + def each(&block) + @response.sending! + x = @buf.each(&block) + @response.sent! + x + end + + def abort + end + + def close + @response.commit! + @closed = true + end + + def closed? + @closed + end + end + + # The underlying body, as a streamable object. + attr_reader :stream + + def initialize(status = 200, header = {}, body = [], options = {}) + super() + + default_headers = options.fetch(:default_headers, self.class.default_headers) + header = merge_default_headers(header, default_headers) + + self.body, self.header, self.status = body, header, status + + @sending_file = false + @blank = false + @cv = new_cond + @committed = false + @sending = false + @sent = false + @content_type = nil + @charset = nil + + if content_type = self[CONTENT_TYPE] + type, charset = content_type.split(/;\s*charset=/) + @content_type = Mime::Type.lookup(type) + @charset = charset || self.class.default_charset + end + + prepare_cache_control! + + yield self if block_given? + end + + def await_commit + synchronize do + @cv.wait_until { @committed } + end + end + + def await_sent + synchronize { @cv.wait_until { @sent } } + end + + def commit! + synchronize do + before_committed + @committed = true + @cv.broadcast + end + end + + def sending! + synchronize do + before_sending + @sending = true + @cv.broadcast + end + end + + def sent! + synchronize do + @sent = true + @cv.broadcast + end + end + + def sending?; synchronize { @sending }; end + def committed?; synchronize { @committed }; end + def sent?; synchronize { @sent }; end + + # Sets the HTTP status code. + def status=(status) + @status = Rack::Utils.status_code(status) + end + + # Sets the HTTP content type. + def content_type=(content_type) + @content_type = content_type.to_s + end + + # The response code of the request. + def response_code + @status + end + + # Returns a string to ensure compatibility with Net::HTTPResponse. + def code + @status.to_s + end + + # Returns the corresponding message for the current HTTP status code: + # + # response.status = 200 + # response.message # => "OK" + # + # response.status = 404 + # response.message # => "Not Found" + # + def message + Rack::Utils::HTTP_STATUS_CODES[@status] + end + alias_method :status_message, :message + + # Returns the content of the response as a string. This contains the contents + # of any calls to render. + def body + strings = [] + each { |part| strings << part.to_s } + strings.join + end + + EMPTY = " " + + # Allows you to manually set or override the response body. + def body=(body) + @blank = true if body == EMPTY + + if body.respond_to?(:to_path) + @stream = body + else + synchronize do + @stream = build_buffer self, munge_body_object(body) + end + end + end + + def body_parts + parts = [] + @stream.each { |x| parts << x } + parts + end + + def set_cookie(key, value) + ::Rack::Utils.set_cookie_header!(header, key, value) + end + + def delete_cookie(key, value={}) + ::Rack::Utils.delete_cookie_header!(header, key, value) + end + + # The location header we'll be responding with. + def location + headers[LOCATION] + end + alias_method :redirect_url, :location + + # Sets the location header we'll be responding with. + def location=(url) + headers[LOCATION] = url + end + + def close + stream.close if stream.respond_to?(:close) + end + + def abort + if stream.respond_to?(:abort) + stream.abort + elsif stream.respond_to?(:close) + # `stream.close` should really be reserved for a close from the + # other direction, but we must fall back to it for + # compatibility. + stream.close + end + end + + # Turns the Response into a Rack-compatible array of the status, headers, + # and body. Allows explict splatting: + # + # status, headers, body = *response + def to_a + rack_response @status, @header.to_hash + end + alias prepare! to_a + + # Be super clear that a response object is not an Array. Defining this + # would make implicit splatting work, but it also makes adding responses + # as arrays work, and "flattening" responses, cascading to the rack body! + # Not sensible behavior. + def to_ary + ActiveSupport::Deprecation.warn(<<-MSG.squish) + `ActionDispatch::Response#to_ary` no longer performs implicit conversion + to an array. Please use `response.to_a` instead, or a splat like `status, + headers, body = *response`. + MSG + + to_a + end + + # Returns the response cookies, converted to a Hash of (name => value) pairs + # + # assert_equal 'AuthorOfNewPage', r.cookies['author'] + def cookies + cookies = {} + if header = self[SET_COOKIE] + header = header.split("\n") if header.respond_to?(:to_str) + header.each do |cookie| + if pair = cookie.split(';').first + key, value = pair.split("=").map { |v| Rack::Utils.unescape(v) } + cookies[key] = value + end + end + end + cookies + end + + private + + def before_committed + end + + def before_sending + end + + def merge_default_headers(original, default) + default.respond_to?(:merge) ? default.merge(original) : original + end + + def build_buffer(response, body) + Buffer.new response, body + end + + def munge_body_object(body) + body.respond_to?(:each) ? body : [body] + end + + def assign_default_content_type_and_charset!(headers) + return if headers[CONTENT_TYPE].present? + + @content_type ||= Mime::HTML + @charset ||= self.class.default_charset unless @charset == false + + type = @content_type.to_s.dup + type << "; charset=#{@charset}" if append_charset? + + headers[CONTENT_TYPE] = type + end + + def append_charset? + !@sending_file && @charset != false + end + + class RackBody + def initialize(response) + @response = response + end + + def each(*args, &block) + @response.each(*args, &block) + end + + def close + # Rack "close" maps to Response#abort, and *not* Response#close + # (which is used when the controller's finished writing) + @response.abort + end + + def body + @response.body + end + + def respond_to?(method, include_private = false) + if method.to_s == 'to_path' + @response.stream.respond_to?(method) + else + super + end + end + + def to_path + @response.stream.to_path + end + + def to_ary + nil + end + end + + def rack_response(status, header) + assign_default_content_type_and_charset!(header) + handle_conditional_get! + + header[SET_COOKIE] = header[SET_COOKIE].join("\n") if header[SET_COOKIE].respond_to?(:join) + + if NO_CONTENT_CODES.include?(@status) + header.delete CONTENT_TYPE + [status, header, []] + else + [status, header, RackBody.new(self)] + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/http/upload.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/http/upload.rb new file mode 100644 index 0000000..a221f4c --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/http/upload.rb @@ -0,0 +1,78 @@ +module ActionDispatch + module Http + # Models uploaded files. + # + # The actual file is accessible via the +tempfile+ accessor, though some + # of its interface is available directly for convenience. + # + # Uploaded files are temporary files whose lifespan is one request. When + # the object is finalized Ruby unlinks the file, so there is no need to + # clean them with a separate maintenance task. + class UploadedFile + # The basename of the file in the client. + attr_accessor :original_filename + + # A string with the MIME type of the file. + attr_accessor :content_type + + # A +Tempfile+ object with the actual uploaded file. Note that some of + # its interface is available directly. + attr_accessor :tempfile + alias :to_io :tempfile + + # A string with the headers of the multipart request. + attr_accessor :headers + + def initialize(hash) # :nodoc: + @tempfile = hash[:tempfile] + raise(ArgumentError, ':tempfile is required') unless @tempfile + + @original_filename = hash[:filename] + if @original_filename + begin + @original_filename.encode!(Encoding::UTF_8) + rescue EncodingError + @original_filename.force_encoding(Encoding::UTF_8) + end + end + @content_type = hash[:type] + @headers = hash[:head] + end + + # Shortcut for +tempfile.read+. + def read(length=nil, buffer=nil) + @tempfile.read(length, buffer) + end + + # Shortcut for +tempfile.open+. + def open + @tempfile.open + end + + # Shortcut for +tempfile.close+. + def close(unlink_now=false) + @tempfile.close(unlink_now) + end + + # Shortcut for +tempfile.path+. + def path + @tempfile.path + end + + # Shortcut for +tempfile.rewind+. + def rewind + @tempfile.rewind + end + + # Shortcut for +tempfile.size+. + def size + @tempfile.size + end + + # Shortcut for +tempfile.eof?+. + def eof? + @tempfile.eof? + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/http/url.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/http/url.rb new file mode 100644 index 0000000..3f41300 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/http/url.rb @@ -0,0 +1,268 @@ +require 'active_support/core_ext/module/attribute_accessors' +require 'active_support/core_ext/hash/slice' + +module ActionDispatch + module Http + module URL + IP_HOST_REGEXP = /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/ + HOST_REGEXP = /(^[^:]+:\/\/)?(\[[^\]]+\]|[^:]+)(?::(\d+$))?/ + PROTOCOL_REGEXP = /^([^:]+)(:)?(\/\/)?$/ + + mattr_accessor :tld_length + self.tld_length = 1 + + class << self + def extract_domain(host, tld_length) + extract_domain_from(host, tld_length) if named_host?(host) + end + + def extract_subdomains(host, tld_length) + if named_host?(host) + extract_subdomains_from(host, tld_length) + else + [] + end + end + + def extract_subdomain(host, tld_length) + extract_subdomains(host, tld_length).join('.') + end + + def url_for(options) + if options[:only_path] + path_for options + else + full_url_for options + end + end + + def full_url_for(options) + host = options[:host] + protocol = options[:protocol] + port = options[:port] + + unless host + raise ArgumentError, 'Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true' + end + + build_host_url(host, port, protocol, options, path_for(options)) + end + + def path_for(options) + path = options[:script_name].to_s.chomp("/") + path << options[:path] if options.key?(:path) + + add_trailing_slash(path) if options[:trailing_slash] + add_params(path, options[:params]) if options.key?(:params) + add_anchor(path, options[:anchor]) if options.key?(:anchor) + + path + end + + private + + def add_params(path, params) + params = { params: params } unless params.is_a?(Hash) + params.reject! { |_,v| v.to_param.nil? } + path << "?#{params.to_query}" unless params.empty? + end + + def add_anchor(path, anchor) + if anchor + path << "##{Journey::Router::Utils.escape_fragment(anchor.to_param)}" + end + end + + def extract_domain_from(host, tld_length) + host.split('.').last(1 + tld_length).join('.') + end + + def extract_subdomains_from(host, tld_length) + parts = host.split('.') + parts[0..-(tld_length + 2)] + end + + def add_trailing_slash(path) + # includes querysting + if path.include?('?') + path.sub!(/\?/, '/\&') + # does not have a .format + elsif !path.include?(".") + path.sub!(/[^\/]\z|\A\z/, '\&/') + end + end + + def build_host_url(host, port, protocol, options, path) + if match = host.match(HOST_REGEXP) + protocol ||= match[1] unless protocol == false + host = match[2] + port = match[3] unless options.key? :port + end + + protocol = normalize_protocol protocol + host = normalize_host(host, options) + + result = protocol.dup + + if options[:user] && options[:password] + result << "#{Rack::Utils.escape(options[:user])}:#{Rack::Utils.escape(options[:password])}@" + end + + result << host + normalize_port(port, protocol) { |normalized_port| + result << ":#{normalized_port}" + } + + result.concat path + end + + def named_host?(host) + IP_HOST_REGEXP !~ host + end + + def normalize_protocol(protocol) + case protocol + when nil + "http://" + when false, "//" + "//" + when PROTOCOL_REGEXP + "#{$1}://" + else + raise ArgumentError, "Invalid :protocol option: #{protocol.inspect}" + end + end + + def normalize_host(_host, options) + return _host unless named_host?(_host) + + tld_length = options[:tld_length] || @@tld_length + subdomain = options.fetch :subdomain, true + domain = options[:domain] + + host = "" + if subdomain == true + return _host if domain.nil? + + host << extract_subdomains_from(_host, tld_length).join('.') + elsif subdomain + host << subdomain.to_param + end + host << "." unless host.empty? + host << (domain || extract_domain_from(_host, tld_length)) + host + end + + def normalize_port(port, protocol) + return unless port + + case protocol + when "//" then yield port + when "https://" + yield port unless port.to_i == 443 + else + yield port unless port.to_i == 80 + end + end + end + + def initialize(env) + super + @protocol = nil + @port = nil + end + + # Returns the complete URL used for this request. + def url + protocol + host_with_port + fullpath + end + + # Returns 'https://' if this is an SSL request and 'http://' otherwise. + def protocol + @protocol ||= ssl? ? 'https://' : 'http://' + end + + # Returns the \host for this request, such as "example.com". + def raw_host_with_port + if forwarded = env["HTTP_X_FORWARDED_HOST"].presence + forwarded.split(/,\s?/).last + else + env['HTTP_HOST'] || "#{env['SERVER_NAME'] || env['SERVER_ADDR']}:#{env['SERVER_PORT']}" + end + end + + # Returns the host for this request, such as example.com. + def host + raw_host_with_port.sub(/:\d+$/, '') + end + + # Returns a \host:\port string for this request, such as "example.com" or + # "example.com:8080". + def host_with_port + "#{host}#{port_string}" + end + + # Returns the port number of this request as an integer. + def port + @port ||= begin + if raw_host_with_port =~ /:(\d+)$/ + $1.to_i + else + standard_port + end + end + end + + # Returns the standard \port number for this request's protocol. + def standard_port + case protocol + when 'https://' then 443 + else 80 + end + end + + # Returns whether this request is using the standard port + def standard_port? + port == standard_port + end + + # Returns a number \port suffix like 8080 if the \port number of this request + # is not the default HTTP \port 80 or HTTPS \port 443. + def optional_port + standard_port? ? nil : port + end + + # Returns a string \port suffix, including colon, like ":8080" if the \port + # number of this request is not the default HTTP \port 80 or HTTPS \port 443. + def port_string + standard_port? ? '' : ":#{port}" + end + + def server_port + @env['SERVER_PORT'].to_i + end + + # Returns the \domain part of a \host, such as "rubyonrails.org" in "www.rubyonrails.org". You can specify + # a different tld_length, such as 2 to catch rubyonrails.co.uk in "www.rubyonrails.co.uk". + def domain(tld_length = @@tld_length) + ActionDispatch::Http::URL.extract_domain(host, tld_length) + end + + # Returns all the \subdomains as an array, so ["dev", "www"] would be + # returned for "dev.www.rubyonrails.org". You can specify a different tld_length, + # such as 2 to catch ["www"] instead of ["www", "rubyonrails"] + # in "www.rubyonrails.co.uk". + def subdomains(tld_length = @@tld_length) + ActionDispatch::Http::URL.extract_subdomains(host, tld_length) + end + + # Returns all the \subdomains as a string, so "dev.www" would be + # returned for "dev.www.rubyonrails.org". You can specify a different tld_length, + # such as 2 to catch "www" instead of "www.rubyonrails" + # in "www.rubyonrails.co.uk". + def subdomain(tld_length = @@tld_length) + ActionDispatch::Http::URL.extract_subdomain(host, tld_length) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey.rb new file mode 100644 index 0000000..ad42713 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey.rb @@ -0,0 +1,5 @@ +require 'action_dispatch/journey/router' +require 'action_dispatch/journey/gtg/builder' +require 'action_dispatch/journey/gtg/simulator' +require 'action_dispatch/journey/nfa/builder' +require 'action_dispatch/journey/nfa/simulator' diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/backwards.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/backwards.rb new file mode 100644 index 0000000..3bd20fd --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/backwards.rb @@ -0,0 +1,5 @@ +module Rack # :nodoc: + Mount = ActionDispatch::Journey::Router + Mount::RouteSet = ActionDispatch::Journey::Router + Mount::RegexpWithNamedGroups = ActionDispatch::Journey::Path::Pattern +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/formatter.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/formatter.rb new file mode 100644 index 0000000..99251b0 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/formatter.rb @@ -0,0 +1,166 @@ +require 'action_controller/metal/exceptions' +require 'active_support/deprecation' + +module ActionDispatch + module Journey + # The Formatter class is used for formatting URLs. For example, parameters + # passed to +url_for+ in Rails will eventually call Formatter#generate. + class Formatter # :nodoc: + attr_reader :routes + + def initialize(routes) + @routes = routes + @cache = nil + end + + def generate(name, options, path_parameters, parameterize = nil) + constraints = path_parameters.merge(options) + missing_keys = [] + + match_route(name, constraints) do |route| + parameterized_parts = extract_parameterized_parts(route, options, path_parameters, parameterize) + + # Skip this route unless a name has been provided or it is a + # standard Rails route since we can't determine whether an options + # hash passed to url_for matches a Rack application or a redirect. + next unless name || route.dispatcher? + + missing_keys = missing_keys(route, parameterized_parts) + next unless missing_keys.empty? + params = options.dup.delete_if do |key, _| + parameterized_parts.key?(key) || route.defaults.key?(key) + end + + defaults = route.defaults + required_parts = route.required_parts + parameterized_parts.delete_if do |key, value| + value.to_s == defaults[key].to_s && !required_parts.include?(key) + end + + return [route.format(parameterized_parts), params] + end + + message = "No route matches #{Hash[constraints.sort_by{|k,v| k.to_s}].inspect}" + message << " missing required keys: #{missing_keys.sort.inspect}" unless missing_keys.empty? + + raise ActionController::UrlGenerationError, message + end + + def clear + @cache = nil + end + + private + + def extract_parameterized_parts(route, options, recall, parameterize = nil) + parameterized_parts = recall.merge(options) + + keys_to_keep = route.parts.reverse.drop_while { |part| + !options.key?(part) || (options[part] || recall[part]).nil? + } | route.required_parts + + (parameterized_parts.keys - keys_to_keep).each do |bad_key| + parameterized_parts.delete(bad_key) + end + + if parameterize + parameterized_parts.each do |k, v| + parameterized_parts[k] = parameterize.call(k, v) + end + end + + parameterized_parts.keep_if { |_, v| v } + parameterized_parts + end + + def named_routes + routes.named_routes + end + + def match_route(name, options) + if named_routes.key?(name) + yield named_routes[name] + else + # Make sure we don't show the deprecation warning more than once + warned = false + + routes = non_recursive(cache, options) + + hash = routes.group_by { |_, r| r.score(options) } + + hash.keys.sort.reverse_each do |score| + break if score < 0 + + hash[score].sort_by { |i, _| i }.each do |_, route| + if name && !warned + ActiveSupport::Deprecation.warn <<-MSG.squish + You are trying to generate the URL for a named route called + #{name.inspect} but no such route was found. In the future, + this will result in an `ActionController::UrlGenerationError` + exception. + MSG + + warned = true + end + + yield route + end + end + end + end + + def non_recursive(cache, options) + routes = [] + queue = [cache] + + while queue.any? + c = queue.shift + routes.concat(c[:___routes]) if c.key?(:___routes) + + options.each do |pair| + queue << c[pair] if c.key?(pair) + end + end + + routes + end + + # Returns an array populated with missing keys if any are present. + def missing_keys(route, parts) + missing_keys = [] + tests = route.path.requirements + route.required_parts.each { |key| + if tests.key?(key) + missing_keys << key unless /\A#{tests[key]}\Z/ === parts[key] + else + missing_keys << key unless parts[key] + end + } + missing_keys + end + + def possibles(cache, options, depth = 0) + cache.fetch(:___routes) { [] } + options.find_all { |pair| + cache.key?(pair) + }.flat_map { |pair| + possibles(cache[pair], options, depth + 1) + } + end + + def build_cache + root = { ___routes: [] } + routes.each_with_index do |route, i| + leaf = route.required_defaults.inject(root) do |h, tuple| + h[tuple] ||= {} + end + (leaf[:___routes] ||= []) << [i, route] + end + root + end + + def cache + @cache ||= build_cache + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/gtg/builder.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/gtg/builder.rb new file mode 100644 index 0000000..450588c --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/gtg/builder.rb @@ -0,0 +1,162 @@ +require 'action_dispatch/journey/gtg/transition_table' + +module ActionDispatch + module Journey # :nodoc: + module GTG # :nodoc: + class Builder # :nodoc: + DUMMY = Nodes::Dummy.new + + attr_reader :root, :ast, :endpoints + + def initialize(root) + @root = root + @ast = Nodes::Cat.new root, DUMMY + @followpos = nil + end + + def transition_table + dtrans = TransitionTable.new + marked = {} + state_id = Hash.new { |h,k| h[k] = h.length } + + start = firstpos(root) + dstates = [start] + until dstates.empty? + s = dstates.shift + next if marked[s] + marked[s] = true # mark s + + s.group_by { |state| symbol(state) }.each do |sym, ps| + u = ps.flat_map { |l| followpos(l) } + next if u.empty? + + if u.uniq == [DUMMY] + from = state_id[s] + to = state_id[Object.new] + dtrans[from, to] = sym + + dtrans.add_accepting(to) + ps.each { |state| dtrans.add_memo(to, state.memo) } + else + dtrans[state_id[s], state_id[u]] = sym + + if u.include?(DUMMY) + to = state_id[u] + + accepting = ps.find_all { |l| followpos(l).include?(DUMMY) } + + accepting.each { |accepting_state| + dtrans.add_memo(to, accepting_state.memo) + } + + dtrans.add_accepting(state_id[u]) + end + end + + dstates << u + end + end + + dtrans + end + + def nullable?(node) + case node + when Nodes::Group + true + when Nodes::Star + true + when Nodes::Or + node.children.any? { |c| nullable?(c) } + when Nodes::Cat + nullable?(node.left) && nullable?(node.right) + when Nodes::Terminal + !node.left + when Nodes::Unary + nullable?(node.left) + else + raise ArgumentError, 'unknown nullable: %s' % node.class.name + end + end + + def firstpos(node) + case node + when Nodes::Star + firstpos(node.left) + when Nodes::Cat + if nullable?(node.left) + firstpos(node.left) | firstpos(node.right) + else + firstpos(node.left) + end + when Nodes::Or + node.children.flat_map { |c| firstpos(c) }.uniq + when Nodes::Unary + firstpos(node.left) + when Nodes::Terminal + nullable?(node) ? [] : [node] + else + raise ArgumentError, 'unknown firstpos: %s' % node.class.name + end + end + + def lastpos(node) + case node + when Nodes::Star + firstpos(node.left) + when Nodes::Or + node.children.flat_map { |c| lastpos(c) }.uniq + when Nodes::Cat + if nullable?(node.right) + lastpos(node.left) | lastpos(node.right) + else + lastpos(node.right) + end + when Nodes::Terminal + nullable?(node) ? [] : [node] + when Nodes::Unary + lastpos(node.left) + else + raise ArgumentError, 'unknown lastpos: %s' % node.class.name + end + end + + def followpos(node) + followpos_table[node] + end + + private + + def followpos_table + @followpos ||= build_followpos + end + + def build_followpos + table = Hash.new { |h, k| h[k] = [] } + @ast.each do |n| + case n + when Nodes::Cat + lastpos(n.left).each do |i| + table[i] += firstpos(n.right) + end + when Nodes::Star + lastpos(n).each do |i| + table[i] += firstpos(n) + end + end + end + table + end + + def symbol(edge) + case edge + when Journey::Nodes::Symbol + edge.regexp + else + edge.left + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/gtg/simulator.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/gtg/simulator.rb new file mode 100644 index 0000000..94b0a24 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/gtg/simulator.rb @@ -0,0 +1,47 @@ +require 'strscan' + +module ActionDispatch + module Journey # :nodoc: + module GTG # :nodoc: + class MatchData # :nodoc: + attr_reader :memos + + def initialize(memos) + @memos = memos + end + end + + class Simulator # :nodoc: + attr_reader :tt + + def initialize(transition_table) + @tt = transition_table + end + + def simulate(string) + ms = memos(string) { return } + MatchData.new(ms) + end + + alias :=~ :simulate + alias :match :simulate + + def memos(string) + input = StringScanner.new(string) + state = [0] + while sym = input.scan(%r([/.?]|[^/.?]+)) + state = tt.move(state, sym) + end + + acceptance_states = state.find_all { |s| + tt.accepting? s + } + + return yield if acceptance_states.empty? + + acceptance_states.flat_map { |x| tt.memo(x) }.compact + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/gtg/transition_table.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/gtg/transition_table.rb new file mode 100644 index 0000000..1b914f0 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/gtg/transition_table.rb @@ -0,0 +1,157 @@ +require 'action_dispatch/journey/nfa/dot' + +module ActionDispatch + module Journey # :nodoc: + module GTG # :nodoc: + class TransitionTable # :nodoc: + include Journey::NFA::Dot + + attr_reader :memos + + def initialize + @regexp_states = {} + @string_states = {} + @accepting = {} + @memos = Hash.new { |h,k| h[k] = [] } + end + + def add_accepting(state) + @accepting[state] = true + end + + def accepting_states + @accepting.keys + end + + def accepting?(state) + @accepting[state] + end + + def add_memo(idx, memo) + @memos[idx] << memo + end + + def memo(idx) + @memos[idx] + end + + def eclosure(t) + Array(t) + end + + def move(t, a) + return [] if t.empty? + + regexps = [] + + t.map { |s| + if states = @regexp_states[s] + regexps.concat states.map { |re, v| re === a ? v : nil } + end + + if states = @string_states[s] + states[a] + end + }.compact.concat regexps + end + + def as_json(options = nil) + simple_regexp = Hash.new { |h,k| h[k] = {} } + + @regexp_states.each do |from, hash| + hash.each do |re, to| + simple_regexp[from][re.source] = to + end + end + + { + regexp_states: simple_regexp, + string_states: @string_states, + accepting: @accepting + } + end + + def to_svg + svg = IO.popen('dot -Tsvg', 'w+') { |f| + f.write(to_dot) + f.close_write + f.readlines + } + 3.times { svg.shift } + svg.join.sub(/width="[^"]*"/, '').sub(/height="[^"]*"/, '') + end + + def visualizer(paths, title = 'FSM') + viz_dir = File.join File.dirname(__FILE__), '..', 'visualizer' + fsm_js = File.read File.join(viz_dir, 'fsm.js') + fsm_css = File.read File.join(viz_dir, 'fsm.css') + erb = File.read File.join(viz_dir, 'index.html.erb') + states = "function tt() { return #{to_json}; }" + + fun_routes = paths.sample(3).map do |ast| + ast.map { |n| + case n + when Nodes::Symbol + case n.left + when ':id' then rand(100).to_s + when ':format' then %w{ xml json }.sample + else + 'omg' + end + when Nodes::Terminal then n.symbol + else + nil + end + }.compact.join + end + + stylesheets = [fsm_css] + svg = to_svg + javascripts = [states, fsm_js] + + # Annoying hack for 1.9 warnings + fun_routes = fun_routes + stylesheets = stylesheets + svg = svg + javascripts = javascripts + + require 'erb' + template = ERB.new erb + template.result(binding) + end + + def []=(from, to, sym) + to_mappings = states_hash_for(sym)[from] ||= {} + to_mappings[sym] = to + end + + def states + ss = @string_states.keys + @string_states.values.flat_map(&:values) + rs = @regexp_states.keys + @regexp_states.values.flat_map(&:values) + (ss + rs).uniq + end + + def transitions + @string_states.flat_map { |from, hash| + hash.map { |s, to| [from, s, to] } + } + @regexp_states.flat_map { |from, hash| + hash.map { |s, to| [from, s, to] } + } + end + + private + + def states_hash_for(sym) + case sym + when String + @string_states + when Regexp + @regexp_states + else + raise ArgumentError, 'unknown symbol: %s' % sym.class + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/nfa/builder.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/nfa/builder.rb new file mode 100644 index 0000000..ee6494c --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/nfa/builder.rb @@ -0,0 +1,76 @@ +require 'action_dispatch/journey/nfa/transition_table' +require 'action_dispatch/journey/gtg/transition_table' + +module ActionDispatch + module Journey # :nodoc: + module NFA # :nodoc: + class Visitor < Visitors::Visitor # :nodoc: + def initialize(tt) + @tt = tt + @i = -1 + end + + def visit_CAT(node) + left = visit(node.left) + right = visit(node.right) + + @tt.merge(left.last, right.first) + + [left.first, right.last] + end + + def visit_GROUP(node) + from = @i += 1 + left = visit(node.left) + to = @i += 1 + + @tt.accepting = to + + @tt[from, left.first] = nil + @tt[left.last, to] = nil + @tt[from, to] = nil + + [from, to] + end + + def visit_OR(node) + from = @i += 1 + children = node.children.map { |c| visit(c) } + to = @i += 1 + + children.each do |child| + @tt[from, child.first] = nil + @tt[child.last, to] = nil + end + + @tt.accepting = to + + [from, to] + end + + def terminal(node) + from_i = @i += 1 # new state + to_i = @i += 1 # new state + + @tt[from_i, to_i] = node + @tt.accepting = to_i + @tt.add_memo(to_i, node.memo) + + [from_i, to_i] + end + end + + class Builder # :nodoc: + def initialize(ast) + @ast = ast + end + + def transition_table + tt = TransitionTable.new + Visitor.new(tt).accept(@ast) + tt + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/nfa/dot.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/nfa/dot.rb new file mode 100644 index 0000000..47bf76b --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/nfa/dot.rb @@ -0,0 +1,36 @@ +# encoding: utf-8 + +module ActionDispatch + module Journey # :nodoc: + module NFA # :nodoc: + module Dot # :nodoc: + def to_dot + edges = transitions.map { |from, sym, to| + " #{from} -> #{to} [label=\"#{sym || 'ε'}\"];" + } + + #memo_nodes = memos.values.flatten.map { |n| + # label = n + # if Journey::Route === n + # label = "#{n.verb.source} #{n.path.spec}" + # end + # " #{n.object_id} [label=\"#{label}\", shape=box];" + #} + #memo_edges = memos.flat_map { |k, memos| + # (memos || []).map { |v| " #{k} -> #{v.object_id};" } + #}.uniq + + <<-eodot +digraph nfa { + rankdir=LR; + node [shape = doublecircle]; + #{accepting_states.join ' '}; + node [shape = circle]; +#{edges.join "\n"} +} + eodot + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/nfa/simulator.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/nfa/simulator.rb new file mode 100644 index 0000000..b23270d --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/nfa/simulator.rb @@ -0,0 +1,47 @@ +require 'strscan' + +module ActionDispatch + module Journey # :nodoc: + module NFA # :nodoc: + class MatchData # :nodoc: + attr_reader :memos + + def initialize(memos) + @memos = memos + end + end + + class Simulator # :nodoc: + attr_reader :tt + + def initialize(transition_table) + @tt = transition_table + end + + def simulate(string) + input = StringScanner.new(string) + state = tt.eclosure(0) + until input.eos? + sym = input.scan(%r([/.?]|[^/.?]+)) + + # FIXME: tt.eclosure is not needed for the GTG + state = tt.eclosure(tt.move(state, sym)) + end + + acceptance_states = state.find_all { |s| + tt.accepting?(tt.eclosure(s).sort.last) + } + + return if acceptance_states.empty? + + memos = acceptance_states.flat_map { |x| tt.memo(x) }.compact + + MatchData.new(memos) + end + + alias :=~ :simulate + alias :match :simulate + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/nfa/transition_table.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/nfa/transition_table.rb new file mode 100644 index 0000000..66e4142 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/nfa/transition_table.rb @@ -0,0 +1,163 @@ +require 'action_dispatch/journey/nfa/dot' + +module ActionDispatch + module Journey # :nodoc: + module NFA # :nodoc: + class TransitionTable # :nodoc: + include Journey::NFA::Dot + + attr_accessor :accepting + attr_reader :memos + + def initialize + @table = Hash.new { |h,f| h[f] = {} } + @memos = {} + @accepting = nil + @inverted = nil + end + + def accepting?(state) + accepting == state + end + + def accepting_states + [accepting] + end + + def add_memo(idx, memo) + @memos[idx] = memo + end + + def memo(idx) + @memos[idx] + end + + def []=(i, f, s) + @table[f][i] = s + end + + def merge(left, right) + @memos[right] = @memos.delete(left) + @table[right] = @table.delete(left) + end + + def states + (@table.keys + @table.values.flat_map(&:keys)).uniq + end + + # Returns a generalized transition graph with reduced states. The states + # are reduced like a DFA, but the table must be simulated like an NFA. + # + # Edges of the GTG are regular expressions. + def generalized_table + gt = GTG::TransitionTable.new + marked = {} + state_id = Hash.new { |h,k| h[k] = h.length } + alphabet = self.alphabet + + stack = [eclosure(0)] + + until stack.empty? + state = stack.pop + next if marked[state] || state.empty? + + marked[state] = true + + alphabet.each do |alpha| + next_state = eclosure(following_states(state, alpha)) + next if next_state.empty? + + gt[state_id[state], state_id[next_state]] = alpha + stack << next_state + end + end + + final_groups = state_id.keys.find_all { |s| + s.sort.last == accepting + } + + final_groups.each do |states| + id = state_id[states] + + gt.add_accepting(id) + save = states.find { |s| + @memos.key?(s) && eclosure(s).sort.last == accepting + } + + gt.add_memo(id, memo(save)) + end + + gt + end + + # Returns set of NFA states to which there is a transition on ast symbol + # +a+ from some state +s+ in +t+. + def following_states(t, a) + Array(t).flat_map { |s| inverted[s][a] }.uniq + end + + # Returns set of NFA states to which there is a transition on ast symbol + # +a+ from some state +s+ in +t+. + def move(t, a) + Array(t).map { |s| + inverted[s].keys.compact.find_all { |sym| + sym === a + }.map { |sym| inverted[s][sym] } + }.flatten.uniq + end + + def alphabet + inverted.values.flat_map(&:keys).compact.uniq.sort_by { |x| x.to_s } + end + + # Returns a set of NFA states reachable from some NFA state +s+ in set + # +t+ on nil-transitions alone. + def eclosure(t) + stack = Array(t) + seen = {} + children = [] + + until stack.empty? + s = stack.pop + next if seen[s] + + seen[s] = true + children << s + + stack.concat(inverted[s][nil]) + end + + children.uniq + end + + def transitions + @table.flat_map { |to, hash| + hash.map { |from, sym| [from, sym, to] } + } + end + + private + + def inverted + return @inverted if @inverted + + @inverted = Hash.new { |h, from| + h[from] = Hash.new { |j, s| j[s] = [] } + } + + @table.each { |to, hash| + hash.each { |from, sym| + if sym + sym = Nodes::Symbol === sym ? sym.regexp : sym.left + end + + @inverted[from][sym] << to + } + } + + @inverted + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/nodes/node.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/nodes/node.rb new file mode 100644 index 0000000..bb01c08 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/nodes/node.rb @@ -0,0 +1,128 @@ +require 'action_dispatch/journey/visitors' + +module ActionDispatch + module Journey # :nodoc: + module Nodes # :nodoc: + class Node # :nodoc: + include Enumerable + + attr_accessor :left, :memo + + def initialize(left) + @left = left + @memo = nil + end + + def each(&block) + Visitors::Each.new(block).accept(self) + end + + def to_s + Visitors::String.new.accept(self) + end + + def to_dot + Visitors::Dot.new.accept(self) + end + + def to_sym + name.to_sym + end + + def name + left.tr '*:', '' + end + + def type + raise NotImplementedError + end + + def symbol?; false; end + def literal?; false; end + end + + class Terminal < Node # :nodoc: + alias :symbol :left + end + + class Literal < Terminal # :nodoc: + def literal?; true; end + def type; :LITERAL; end + end + + class Dummy < Literal # :nodoc: + def initialize(x = Object.new) + super + end + + def literal?; false; end + end + + %w{ Symbol Slash Dot }.each do |t| + class_eval <<-eoruby, __FILE__, __LINE__ + 1 + class #{t} < Terminal; + def type; :#{t.upcase}; end + end + eoruby + end + + class Symbol < Terminal # :nodoc: + attr_accessor :regexp + alias :symbol :regexp + + DEFAULT_EXP = /[^\.\/\?]+/ + def initialize(left) + super + @regexp = DEFAULT_EXP + end + + def default_regexp? + regexp == DEFAULT_EXP + end + + def symbol?; true; end + end + + class Unary < Node # :nodoc: + def children; [left] end + end + + class Group < Unary # :nodoc: + def type; :GROUP; end + end + + class Star < Unary # :nodoc: + def type; :STAR; end + + def name + left.name.tr '*:', '' + end + end + + class Binary < Node # :nodoc: + attr_accessor :right + + def initialize(left, right) + super(left) + @right = right + end + + def children; [left, right] end + end + + class Cat < Binary # :nodoc: + def type; :CAT; end + end + + class Or < Node # :nodoc: + attr_reader :children + + def initialize(children) + @children = children + end + + def type; :OR; end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/parser.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/parser.rb new file mode 100644 index 0000000..9012297 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/parser.rb @@ -0,0 +1,198 @@ +# +# DO NOT MODIFY!!!! +# This file is automatically generated by Racc 1.4.11 +# from Racc grammer file "". +# + +require 'racc/parser.rb' + + +require 'action_dispatch/journey/parser_extras' +module ActionDispatch + module Journey + class Parser < Racc::Parser +##### State transition tables begin ### + +racc_action_table = [ + 13, 15, 14, 7, 21, 16, 8, 19, 13, 15, + 14, 7, 17, 16, 8, 13, 15, 14, 7, 24, + 16, 8, 13, 15, 14, 7, 19, 16, 8 ] + +racc_action_check = [ + 2, 2, 2, 2, 17, 2, 2, 2, 0, 0, + 0, 0, 1, 0, 0, 19, 19, 19, 19, 20, + 19, 19, 7, 7, 7, 7, 22, 7, 7 ] + +racc_action_pointer = [ + 6, 12, -2, nil, nil, nil, nil, 20, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 4, nil, 13, + 13, nil, 17, nil, nil ] + +racc_action_default = [ + -19, -19, -2, -3, -4, -5, -6, -19, -10, -11, + -12, -13, -14, -15, -16, -17, -18, -19, -1, -19, + -19, 25, -8, -9, -7 ] + +racc_goto_table = [ + 1, 22, 18, 23, nil, nil, nil, 20 ] + +racc_goto_check = [ + 1, 2, 1, 3, nil, nil, nil, 1 ] + +racc_goto_pointer = [ + nil, 0, -18, -16, nil, nil, nil, nil, nil, nil, + nil ] + +racc_goto_default = [ + nil, nil, 2, 3, 4, 5, 6, 9, 10, 11, + 12 ] + +racc_reduce_table = [ + 0, 0, :racc_error, + 2, 11, :_reduce_1, + 1, 11, :_reduce_2, + 1, 11, :_reduce_none, + 1, 12, :_reduce_none, + 1, 12, :_reduce_none, + 1, 12, :_reduce_none, + 3, 15, :_reduce_7, + 3, 13, :_reduce_8, + 3, 13, :_reduce_9, + 1, 16, :_reduce_10, + 1, 14, :_reduce_none, + 1, 14, :_reduce_none, + 1, 14, :_reduce_none, + 1, 14, :_reduce_none, + 1, 19, :_reduce_15, + 1, 17, :_reduce_16, + 1, 18, :_reduce_17, + 1, 20, :_reduce_18 ] + +racc_reduce_n = 19 + +racc_shift_n = 25 + +racc_token_table = { + false => 0, + :error => 1, + :SLASH => 2, + :LITERAL => 3, + :SYMBOL => 4, + :LPAREN => 5, + :RPAREN => 6, + :DOT => 7, + :STAR => 8, + :OR => 9 } + +racc_nt_base = 10 + +racc_use_result_var = false + +Racc_arg = [ + racc_action_table, + racc_action_check, + racc_action_default, + racc_action_pointer, + racc_goto_table, + racc_goto_check, + racc_goto_default, + racc_goto_pointer, + racc_nt_base, + racc_reduce_table, + racc_token_table, + racc_shift_n, + racc_reduce_n, + racc_use_result_var ] + +Racc_token_to_s_table = [ + "$end", + "error", + "SLASH", + "LITERAL", + "SYMBOL", + "LPAREN", + "RPAREN", + "DOT", + "STAR", + "OR", + "$start", + "expressions", + "expression", + "or", + "terminal", + "group", + "star", + "symbol", + "literal", + "slash", + "dot" ] + +Racc_debug_parser = false + +##### State transition tables end ##### + +# reduce 0 omitted + +def _reduce_1(val, _values) + Cat.new(val.first, val.last) +end + +def _reduce_2(val, _values) + val.first +end + +# reduce 3 omitted + +# reduce 4 omitted + +# reduce 5 omitted + +# reduce 6 omitted + +def _reduce_7(val, _values) + Group.new(val[1]) +end + +def _reduce_8(val, _values) + Or.new([val.first, val.last]) +end + +def _reduce_9(val, _values) + Or.new([val.first, val.last]) +end + +def _reduce_10(val, _values) + Star.new(Symbol.new(val.last)) +end + +# reduce 11 omitted + +# reduce 12 omitted + +# reduce 13 omitted + +# reduce 14 omitted + +def _reduce_15(val, _values) + Slash.new('/') +end + +def _reduce_16(val, _values) + Symbol.new(val.first) +end + +def _reduce_17(val, _values) + Literal.new(val.first) +end + +def _reduce_18(val, _values) + Dot.new(val.first) +end + +def _reduce_none(val, _values) + val[0] +end + + end # class Parser + end # module Journey + end # module ActionDispatch diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/parser.y b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/parser.y new file mode 100644 index 0000000..d3f7c4d --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/parser.y @@ -0,0 +1,49 @@ +class ActionDispatch::Journey::Parser + options no_result_var +token SLASH LITERAL SYMBOL LPAREN RPAREN DOT STAR OR + +rule + expressions + : expression expressions { Cat.new(val.first, val.last) } + | expression { val.first } + | or + ; + expression + : terminal + | group + | star + ; + group + : LPAREN expressions RPAREN { Group.new(val[1]) } + ; + or + : expression OR expression { Or.new([val.first, val.last]) } + | expression OR or { Or.new([val.first, val.last]) } + ; + star + : STAR { Star.new(Symbol.new(val.last)) } + ; + terminal + : symbol + | literal + | slash + | dot + ; + slash + : SLASH { Slash.new('/') } + ; + symbol + : SYMBOL { Symbol.new(val.first) } + ; + literal + : LITERAL { Literal.new(val.first) } + ; + dot + : DOT { Dot.new(val.first) } + ; + +end + +---- header + +require 'action_dispatch/journey/parser_extras' diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/parser_extras.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/parser_extras.rb new file mode 100644 index 0000000..14892f4 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/parser_extras.rb @@ -0,0 +1,23 @@ +require 'action_dispatch/journey/scanner' +require 'action_dispatch/journey/nodes/node' + +module ActionDispatch + module Journey # :nodoc: + class Parser < Racc::Parser # :nodoc: + include Journey::Nodes + + def initialize + @scanner = Scanner.new + end + + def parse(string) + @scanner.scan_setup(string) + do_parse + end + + def next_token + @scanner.next_token + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/path/pattern.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/path/pattern.rb new file mode 100644 index 0000000..3af940a --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/path/pattern.rb @@ -0,0 +1,193 @@ +require 'action_dispatch/journey/router/strexp' + +module ActionDispatch + module Journey # :nodoc: + module Path # :nodoc: + class Pattern # :nodoc: + attr_reader :spec, :requirements, :anchored + + def self.from_string string + new Journey::Router::Strexp.build(string, {}, ["/.?"], true) + end + + def initialize(strexp) + @spec = strexp.ast + @requirements = strexp.requirements + @separators = strexp.separators.join + @anchored = strexp.anchor + + @names = nil + @optional_names = nil + @required_names = nil + @re = nil + @offsets = nil + end + + def build_formatter + Visitors::FormatBuilder.new.accept(spec) + end + + def ast + @spec.grep(Nodes::Symbol).each do |node| + re = @requirements[node.to_sym] + node.regexp = re if re + end + + @spec.grep(Nodes::Star).each do |node| + node = node.left + node.regexp = @requirements[node.to_sym] || /(.+)/ + end + + @spec + end + + def names + @names ||= spec.grep(Nodes::Symbol).map { |n| n.name } + end + + def required_names + @required_names ||= names - optional_names + end + + def optional_names + @optional_names ||= spec.grep(Nodes::Group).flat_map { |group| + group.grep(Nodes::Symbol) + }.map { |n| n.name }.uniq + end + + class RegexpOffsets < Journey::Visitors::Visitor # :nodoc: + attr_reader :offsets + + def initialize(matchers) + @matchers = matchers + @capture_count = [0] + end + + def visit(node) + super + @capture_count + end + + def visit_SYMBOL(node) + node = node.to_sym + + if @matchers.key?(node) + re = /#{@matchers[node]}|/ + @capture_count.push((re.match('').length - 1) + (@capture_count.last || 0)) + else + @capture_count << (@capture_count.last || 0) + end + end + end + + class AnchoredRegexp < Journey::Visitors::Visitor # :nodoc: + def initialize(separator, matchers) + @separator = separator + @matchers = matchers + @separator_re = "([^#{separator}]+)" + super() + end + + def accept(node) + %r{\A#{visit node}\Z} + end + + def visit_CAT(node) + [visit(node.left), visit(node.right)].join + end + + def visit_SYMBOL(node) + node = node.to_sym + + return @separator_re unless @matchers.key?(node) + + re = @matchers[node] + "(#{re})" + end + + def visit_GROUP(node) + "(?:#{visit node.left})?" + end + + def visit_LITERAL(node) + Regexp.escape(node.left) + end + alias :visit_DOT :visit_LITERAL + + def visit_SLASH(node) + node.left + end + + def visit_STAR(node) + re = @matchers[node.left.to_sym] || '.+' + "(#{re})" + end + end + + class UnanchoredRegexp < AnchoredRegexp # :nodoc: + def accept(node) + %r{\A#{visit node}} + end + end + + class MatchData # :nodoc: + attr_reader :names + + def initialize(names, offsets, match) + @names = names + @offsets = offsets + @match = match + end + + def captures + (length - 1).times.map { |i| self[i + 1] } + end + + def [](x) + idx = @offsets[x - 1] + x + @match[idx] + end + + def length + @offsets.length + end + + def post_match + @match.post_match + end + + def to_s + @match.to_s + end + end + + def match(other) + return unless match = to_regexp.match(other) + MatchData.new(names, offsets, match) + end + alias :=~ :match + + def source + to_regexp.source + end + + def to_regexp + @re ||= regexp_visitor.new(@separators, @requirements).accept spec + end + + private + + def regexp_visitor + @anchored ? AnchoredRegexp : UnanchoredRegexp + end + + def offsets + return @offsets if @offsets + + viz = RegexpOffsets.new(@requirements) + @offsets = viz.accept(spec) + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/route.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/route.rb new file mode 100644 index 0000000..4cdf273 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/route.rb @@ -0,0 +1,125 @@ +module ActionDispatch + module Journey # :nodoc: + class Route # :nodoc: + attr_reader :app, :path, :defaults, :name + + attr_reader :constraints + alias :conditions :constraints + + attr_accessor :precedence + + ## + # +path+ is a path constraint. + # +constraints+ is a hash of constraints to be applied to this route. + def initialize(name, app, path, constraints, defaults = {}) + @name = name + @app = app + @path = path + + @constraints = constraints + @defaults = defaults + @required_defaults = nil + @required_parts = nil + @parts = nil + @decorated_ast = nil + @precedence = 0 + @path_formatter = @path.build_formatter + end + + def ast + @decorated_ast ||= begin + decorated_ast = path.ast + decorated_ast.grep(Nodes::Terminal).each { |n| n.memo = self } + decorated_ast + end + end + + def requirements # :nodoc: + # needed for rails `rake routes` + @defaults.merge(path.requirements).delete_if { |_,v| + /.+?/ == v + } + end + + def segments + path.names + end + + def required_keys + required_parts + required_defaults.keys + end + + def score(constraints) + required_keys = path.required_names + supplied_keys = constraints.map { |k,v| v && k.to_s }.compact + + return -1 unless (required_keys - supplied_keys).empty? + + score = (supplied_keys & path.names).length + score + (required_defaults.length * 2) + end + + def parts + @parts ||= segments.map { |n| n.to_sym } + end + alias :segment_keys :parts + + def format(path_options) + @path_formatter.evaluate path_options + end + + def optional_parts + path.optional_names.map { |n| n.to_sym } + end + + def required_parts + @required_parts ||= path.required_names.map { |n| n.to_sym } + end + + def required_default?(key) + (constraints[:required_defaults] || []).include?(key) + end + + def required_defaults + @required_defaults ||= @defaults.dup.delete_if do |k,_| + parts.include?(k) || !required_default?(k) + end + end + + def glob? + !path.spec.grep(Nodes::Star).empty? + end + + def dispatcher? + @app.dispatcher? + end + + def matches?(request) + constraints.all? do |method, value| + next true unless request.respond_to?(method) + + case value + when Regexp, String + value === request.send(method).to_s + when Array + value.include?(request.send(method)) + when TrueClass + request.send(method).present? + when FalseClass + request.send(method).blank? + else + value === request.send(method) + end + end + end + + def ip + constraints[:ip] || // + end + + def verb + constraints[:request_method] || // + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/router.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/router.rb new file mode 100644 index 0000000..8c36ebc --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/router.rb @@ -0,0 +1,144 @@ +require 'action_dispatch/journey/router/utils' +require 'action_dispatch/journey/router/strexp' +require 'action_dispatch/journey/routes' +require 'action_dispatch/journey/formatter' + +before = $-w +$-w = false +require 'action_dispatch/journey/parser' +$-w = before + +require 'action_dispatch/journey/route' +require 'action_dispatch/journey/path/pattern' + +module ActionDispatch + module Journey # :nodoc: + class Router # :nodoc: + class RoutingError < ::StandardError # :nodoc: + end + + # :nodoc: + VERSION = '2.0.0' + + attr_accessor :routes + + def initialize(routes) + @routes = routes + end + + def serve(req) + find_routes(req).each do |match, parameters, route| + set_params = req.path_parameters + path_info = req.path_info + script_name = req.script_name + + unless route.path.anchored + req.script_name = (script_name.to_s + match.to_s).chomp('/') + req.path_info = match.post_match + req.path_info = "/" + req.path_info unless req.path_info.start_with? "/" + end + + req.path_parameters = set_params.merge parameters + + status, headers, body = route.app.serve(req) + + if 'pass' == headers['X-Cascade'] + req.script_name = script_name + req.path_info = path_info + req.path_parameters = set_params + next + end + + return [status, headers, body] + end + + return [404, {'X-Cascade' => 'pass'}, ['Not Found']] + end + + def recognize(rails_req) + find_routes(rails_req).each do |match, parameters, route| + unless route.path.anchored + rails_req.script_name = match.to_s + rails_req.path_info = match.post_match.sub(/^([^\/])/, '/\1') + end + + yield(route, parameters) + end + end + + def visualizer + tt = GTG::Builder.new(ast).transition_table + groups = partitioned_routes.first.map(&:ast).group_by { |a| a.to_s } + asts = groups.values.map { |v| v.first } + tt.visualizer(asts) + end + + private + + def partitioned_routes + routes.partitioned_routes + end + + def ast + routes.ast + end + + def simulator + routes.simulator + end + + def custom_routes + partitioned_routes.last + end + + def filter_routes(path) + return [] unless ast + simulator.memos(path) { [] } + end + + def find_routes req + routes = filter_routes(req.path_info).concat custom_routes.find_all { |r| + r.path.match(req.path_info) + } + + routes = + if req.request_method == "HEAD" + match_head_routes(routes, req) + else + match_routes(routes, req) + end + + routes.sort_by!(&:precedence) + + routes.map! { |r| + match_data = r.path.match(req.path_info) + path_parameters = r.defaults.dup + match_data.names.zip(match_data.captures) { |name,val| + path_parameters[name.to_sym] = Utils.unescape_uri(val) if val + } + [match_data, path_parameters, r] + } + end + + def match_head_routes(routes, req) + verb_specific_routes = routes.reject { |route| route.verb == // } + head_routes = match_routes(verb_specific_routes, req) + + if head_routes.empty? + begin + req.request_method = "GET" + match_routes(routes, req) + ensure + req.request_method = "HEAD" + end + else + head_routes + end + end + + def match_routes(routes, req) + routes.select { |r| r.matches?(req) } + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/router/strexp.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/router/strexp.rb new file mode 100644 index 0000000..4b7738f --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/router/strexp.rb @@ -0,0 +1,27 @@ +module ActionDispatch + module Journey # :nodoc: + class Router # :nodoc: + class Strexp # :nodoc: + class << self + alias :compile :new + end + + attr_reader :path, :requirements, :separators, :anchor, :ast + + def self.build(path, requirements, separators, anchor = true) + parser = Journey::Parser.new + ast = parser.parse path + new ast, path, requirements, separators, anchor + end + + def initialize(ast, path, requirements, separators, anchor = true) + @ast = ast + @path = path + @requirements = requirements + @separators = separators + @anchor = anchor + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/router/utils.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/router/utils.rb new file mode 100644 index 0000000..2b0a657 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/router/utils.rb @@ -0,0 +1,93 @@ +module ActionDispatch + module Journey # :nodoc: + class Router # :nodoc: + class Utils # :nodoc: + # Normalizes URI path. + # + # Strips off trailing slash and ensures there is a leading slash. + # Also converts downcase url encoded string to uppercase. + # + # normalize_path("/foo") # => "/foo" + # normalize_path("/foo/") # => "/foo" + # normalize_path("foo") # => "/foo" + # normalize_path("") # => "/" + # normalize_path("/%ab") # => "/%AB" + def self.normalize_path(path) + path = "/#{path}" + path.squeeze!('/') + path.sub!(%r{/+\Z}, '') + path.gsub!(/(%[a-f0-9]{2})/) { $1.upcase } + path = '/' if path == '' + path + end + + # URI path and fragment escaping + # http://tools.ietf.org/html/rfc3986 + class UriEncoder # :nodoc: + ENCODE = "%%%02X".freeze + US_ASCII = Encoding::US_ASCII + UTF_8 = Encoding::UTF_8 + EMPTY = "".force_encoding(US_ASCII).freeze + DEC2HEX = (0..255).to_a.map{ |i| ENCODE % i }.map{ |s| s.force_encoding(US_ASCII) } + + ALPHA = "a-zA-Z".freeze + DIGIT = "0-9".freeze + UNRESERVED = "#{ALPHA}#{DIGIT}\\-\\._~".freeze + SUB_DELIMS = "!\\$&'\\(\\)\\*\\+,;=".freeze + + ESCAPED = /%[a-zA-Z0-9]{2}/.freeze + + FRAGMENT = /[^#{UNRESERVED}#{SUB_DELIMS}:@\/\?]/.freeze + SEGMENT = /[^#{UNRESERVED}#{SUB_DELIMS}:@]/.freeze + PATH = /[^#{UNRESERVED}#{SUB_DELIMS}:@\/]/.freeze + + def escape_fragment(fragment) + escape(fragment, FRAGMENT) + end + + def escape_path(path) + escape(path, PATH) + end + + def escape_segment(segment) + escape(segment, SEGMENT) + end + + def unescape_uri(uri) + encoding = uri.encoding == US_ASCII ? UTF_8 : uri.encoding + uri.gsub(ESCAPED) { [$&[1, 2].hex].pack('C') }.force_encoding(encoding) + end + + protected + def escape(component, pattern) + component.gsub(pattern){ |unsafe| percent_encode(unsafe) }.force_encoding(US_ASCII) + end + + def percent_encode(unsafe) + safe = EMPTY.dup + unsafe.each_byte { |b| safe << DEC2HEX[b] } + safe + end + end + + ENCODER = UriEncoder.new + + def self.escape_path(path) + ENCODER.escape_path(path.to_s) + end + + def self.escape_segment(segment) + ENCODER.escape_segment(segment.to_s) + end + + def self.escape_fragment(fragment) + ENCODER.escape_fragment(fragment.to_s) + end + + def self.unescape_uri(uri) + ENCODER.unescape_uri(uri) + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/routes.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/routes.rb new file mode 100644 index 0000000..dd773b5 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/routes.rb @@ -0,0 +1,80 @@ +module ActionDispatch + module Journey # :nodoc: + # The Routing table. Contains all routes for a system. Routes can be + # added to the table by calling Routes#add_route. + class Routes # :nodoc: + include Enumerable + + attr_reader :routes, :named_routes + + def initialize + @routes = [] + @named_routes = {} + @ast = nil + @partitioned_routes = nil + @simulator = nil + end + + def empty? + routes.empty? + end + + def length + routes.length + end + alias :size :length + + def last + routes.last + end + + def each(&block) + routes.each(&block) + end + + def clear + routes.clear + named_routes.clear + end + + def partitioned_routes + @partitioned_routes ||= routes.partition do |r| + r.path.anchored && r.ast.grep(Nodes::Symbol).all?(&:default_regexp?) + end + end + + def ast + @ast ||= begin + asts = partitioned_routes.first.map(&:ast) + Nodes::Or.new(asts) unless asts.empty? + end + end + + def simulator + @simulator ||= begin + gtg = GTG::Builder.new(ast).transition_table + GTG::Simulator.new(gtg) + end + end + + # Add a route to the routing table. + def add_route(app, path, conditions, defaults, name = nil) + route = Route.new(name, app, path, conditions, defaults) + + route.precedence = routes.length + routes << route + named_routes[name] = route if name && !named_routes[name] + clear_cache! + route + end + + private + + def clear_cache! + @ast = nil + @partitioned_routes = nil + @simulator = nil + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/scanner.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/scanner.rb new file mode 100644 index 0000000..19e0bc0 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/scanner.rb @@ -0,0 +1,61 @@ +require 'strscan' + +module ActionDispatch + module Journey # :nodoc: + class Scanner # :nodoc: + def initialize + @ss = nil + end + + def scan_setup(str) + @ss = StringScanner.new(str) + end + + def eos? + @ss.eos? + end + + def pos + @ss.pos + end + + def pre_match + @ss.pre_match + end + + def next_token + return if @ss.eos? + + until token = scan || @ss.eos?; end + token + end + + private + + def scan + case + # / + when text = @ss.scan(/\//) + [:SLASH, text] + when text = @ss.scan(/\*\w+/) + [:STAR, text] + when text = @ss.scan(/(?(value) { Router::Utils.escape_path(value) } + ESCAPE_SEGMENT = ->(value) { Router::Utils.escape_segment(value) } + + class Parameter < Struct.new(:name, :escaper) + def escape(value); escaper.call value; end + end + + def self.required_path(symbol) + Parameter.new symbol, ESCAPE_PATH + end + + def self.required_segment(symbol) + Parameter.new symbol, ESCAPE_SEGMENT + end + + def initialize(parts) + @parts = parts + @children = [] + @parameters = [] + + parts.each_with_index do |object,i| + case object + when Journey::Format + @children << i + when Parameter + @parameters << i + end + end + end + + def evaluate(hash) + parts = @parts.dup + + @parameters.each do |index| + param = parts[index] + value = hash[param.name] + return ''.freeze unless value + parts[index] = param.escape value + end + + @children.each { |index| parts[index] = parts[index].evaluate(hash) } + + parts.join + end + end + + module Visitors # :nodoc: + class Visitor # :nodoc: + DISPATCH_CACHE = {} + + def accept(node) + visit(node) + end + + private + + def visit node + send(DISPATCH_CACHE[node.type], node) + end + + def binary(node) + visit(node.left) + visit(node.right) + end + def visit_CAT(n); binary(n); end + + def nary(node) + node.children.each { |c| visit(c) } + end + def visit_OR(n); nary(n); end + + def unary(node) + visit(node.left) + end + def visit_GROUP(n); unary(n); end + def visit_STAR(n); unary(n); end + + def terminal(node); end + def visit_LITERAL(n); terminal(n); end + def visit_SYMBOL(n); terminal(n); end + def visit_SLASH(n); terminal(n); end + def visit_DOT(n); terminal(n); end + + private_instance_methods(false).each do |pim| + next unless pim =~ /^visit_(.*)$/ + DISPATCH_CACHE[$1.to_sym] = pim + end + end + + class FormatBuilder < Visitor # :nodoc: + def accept(node); Journey::Format.new(super); end + def terminal(node); [node.left]; end + + def binary(node) + visit(node.left) + visit(node.right) + end + + def visit_GROUP(n); [Journey::Format.new(unary(n))]; end + + def visit_STAR(n) + [Journey::Format.required_path(n.left.to_sym)] + end + + def visit_SYMBOL(n) + symbol = n.to_sym + if symbol == :controller + [Journey::Format.required_path(symbol)] + else + [Journey::Format.required_segment(symbol)] + end + end + end + + # Loop through the requirements AST + class Each < Visitor # :nodoc: + attr_reader :block + + def initialize(block) + @block = block + end + + def visit(node) + block.call(node) + super + end + end + + class String < Visitor # :nodoc: + private + + def binary(node) + [visit(node.left), visit(node.right)].join + end + + def nary(node) + node.children.map { |c| visit(c) }.join '|' + end + + def terminal(node) + node.left + end + + def visit_GROUP(node) + "(#{visit(node.left)})" + end + end + + class Dot < Visitor # :nodoc: + def initialize + @nodes = [] + @edges = [] + end + + def accept(node) + super + <<-eodot + digraph parse_tree { + size="8,5" + node [shape = none]; + edge [dir = none]; + #{@nodes.join "\n"} + #{@edges.join("\n")} + } + eodot + end + + private + + def binary(node) + node.children.each do |c| + @edges << "#{node.object_id} -> #{c.object_id};" + end + super + end + + def nary(node) + node.children.each do |c| + @edges << "#{node.object_id} -> #{c.object_id};" + end + super + end + + def unary(node) + @edges << "#{node.object_id} -> #{node.left.object_id};" + super + end + + def visit_GROUP(node) + @nodes << "#{node.object_id} [label=\"()\"];" + super + end + + def visit_CAT(node) + @nodes << "#{node.object_id} [label=\"○\"];" + super + end + + def visit_STAR(node) + @nodes << "#{node.object_id} [label=\"*\"];" + super + end + + def visit_OR(node) + @nodes << "#{node.object_id} [label=\"|\"];" + super + end + + def terminal(node) + value = node.left + + @nodes << "#{node.object_id} [label=\"#{value}\"];" + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/visualizer/fsm.css b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/visualizer/fsm.css new file mode 100644 index 0000000..403e16a --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/visualizer/fsm.css @@ -0,0 +1,30 @@ +body { + font-family: "Helvetica Neue", Helvetica, Arial, Sans-Serif; + margin: 0; +} + +h1 { + font-size: 2.0em; font-weight: bold; text-align: center; + color: white; background-color: black; + padding: 5px 0; + margin: 0 0 20px; +} + +h2 { + text-align: center; + display: none; + font-size: 0.5em; +} + +.clearfix {display: inline-block; } +.input { overflow: show;} +.instruction { color: #666; padding: 0 30px 20px; font-size: 0.9em} +.instruction p { padding: 0 0 5px; } +.instruction li { padding: 0 10px 5px; } + +.form { background: #EEE; padding: 20px 30px; border-radius: 5px; margin-left: auto; margin-right: auto; width: 500px; margin-bottom: 20px} +.form p, .form form { text-align: center } +.form form {padding: 0 10px 5px; } +.form .fun_routes { font-size: 0.9em;} +.form .fun_routes a { margin: 0 5px 0 0; } + diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/visualizer/fsm.js b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/visualizer/fsm.js new file mode 100644 index 0000000..d9bcaef --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/visualizer/fsm.js @@ -0,0 +1,134 @@ +function tokenize(input, callback) { + while(input.length > 0) { + callback(input.match(/^[\/\.\?]|[^\/\.\?]+/)[0]); + input = input.replace(/^[\/\.\?]|[^\/\.\?]+/, ''); + } +} + +var graph = d3.select("#chart-2 svg"); +var svg_edges = {}; +var svg_nodes = {}; + +graph.selectAll("g.edge").each(function() { + var node = d3.select(this); + var index = node.select("title").text().split("->"); + var left = parseInt(index[0]); + var right = parseInt(index[1]); + + if(!svg_edges[left]) { svg_edges[left] = {} } + svg_edges[left][right] = node; +}); + +graph.selectAll("g.node").each(function() { + var node = d3.select(this); + var index = parseInt(node.select("title").text()); + svg_nodes[index] = node; +}); + +function reset_graph() { + for(var key in svg_edges) { + for(var mkey in svg_edges[key]) { + var node = svg_edges[key][mkey]; + var path = node.select("path"); + var arrow = node.select("polygon"); + path.style("stroke", "black"); + arrow.style("stroke", "black").style("fill", "black"); + } + } + + for(var key in svg_nodes) { + var node = svg_nodes[key]; + node.select('ellipse').style("fill", "white"); + node.select('polygon').style("fill", "white"); + } + return false; +} + +function highlight_edge(from, to) { + var node = svg_edges[from][to]; + var path = node.select("path"); + var arrow = node.select("polygon"); + + path + .transition().duration(500) + .style("stroke", "green"); + + arrow + .transition().duration(500) + .style("stroke", "green").style("fill", "green"); +} + +function highlight_state(index, color) { + if(!color) { color = "green"; } + + svg_nodes[index].select('ellipse') + .style("fill", "white") + .transition().duration(500) + .style("fill", color); +} + +function highlight_finish(index) { + svg_nodes[index].select('polygon') + .style("fill", "while") + .transition().duration(500) + .style("fill", "blue"); +} + +function match(input) { + reset_graph(); + var table = tt(); + var states = [0]; + var regexp_states = table['regexp_states']; + var string_states = table['string_states']; + var accepting = table['accepting']; + + highlight_state(0); + + tokenize(input, function(token) { + var new_states = []; + for(var key in states) { + var state = states[key]; + + if(string_states[state] && string_states[state][token]) { + var new_state = string_states[state][token]; + highlight_edge(state, new_state); + highlight_state(new_state); + new_states.push(new_state); + } + + if(regexp_states[state]) { + for(var key in regexp_states[state]) { + var re = new RegExp("^" + key + "$"); + if(re.test(token)) { + var new_state = regexp_states[state][key]; + highlight_edge(state, new_state); + highlight_state(new_state); + new_states.push(new_state); + } + } + } + } + + if(new_states.length == 0) { + return; + } + states = new_states; + }); + + for(var key in states) { + var state = states[key]; + if(accepting[state]) { + for(var mkey in svg_edges[state]) { + if(!regexp_states[mkey] && !string_states[mkey]) { + highlight_edge(state, mkey); + highlight_finish(mkey); + } + } + } else { + highlight_state(state, "red"); + } + } + + return false; +} + diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/visualizer/index.html.erb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/visualizer/index.html.erb new file mode 100644 index 0000000..9b28a65 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/journey/visualizer/index.html.erb @@ -0,0 +1,52 @@ + + + + <%= title %> + + + + + +
+

Routes FSM with NFA simulation

+
+

+ Type a route in to the box and click "simulate". +

+
+ + + +
+

+ Some fun routes to try: + <% fun_routes.each do |path| %> + + <%= path %> + + <% end %> +

+
+
+ <%= svg %> +
+
+

+ This is a FSM for a system that has the following routes: +

+
    + <% paths.each do |route| %> +
  • <%= route %>
  • + <% end %> +
+
+
+ <% javascripts.each do |js| %> + + <% end %> + + diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/callbacks.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/callbacks.rb new file mode 100644 index 0000000..f80df78 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/callbacks.rb @@ -0,0 +1,37 @@ + +module ActionDispatch + # Provides callbacks to be executed before and after dispatching the request. + class Callbacks + include ActiveSupport::Callbacks + + define_callbacks :call + + class << self + delegate :to_prepare, :to_cleanup, :to => "ActionDispatch::Reloader" + + def before(*args, &block) + set_callback(:call, :before, *args, &block) + end + + def after(*args, &block) + set_callback(:call, :after, *args, &block) + end + end + + def initialize(app) + @app = app + end + + def call(env) + error = nil + result = run_callbacks :call do + begin + @app.call(env) + rescue => error + end + end + raise error if error + result + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/cookies.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/cookies.rb new file mode 100644 index 0000000..393b422 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/cookies.rb @@ -0,0 +1,574 @@ +require 'active_support/core_ext/hash/keys' +require 'active_support/core_ext/module/attribute_accessors' +require 'active_support/core_ext/object/blank' +require 'active_support/key_generator' +require 'active_support/message_verifier' +require 'active_support/json' + +module ActionDispatch + class Request < Rack::Request + def cookie_jar + env['action_dispatch.cookies'] ||= Cookies::CookieJar.build(self) + end + end + + # \Cookies are read and written through ActionController#cookies. + # + # The cookies being read are the ones received along with the request, the cookies + # being written will be sent out with the response. Reading a cookie does not get + # the cookie object itself back, just the value it holds. + # + # Examples of writing: + # + # # Sets a simple session cookie. + # # This cookie will be deleted when the user's browser is closed. + # cookies[:user_name] = "david" + # + # # Cookie values are String based. Other data types need to be serialized. + # cookies[:lat_lon] = JSON.generate([47.68, -122.37]) + # + # # Sets a cookie that expires in 1 hour. + # cookies[:login] = { value: "XJ-122", expires: 1.hour.from_now } + # + # # Sets a signed cookie, which prevents users from tampering with its value. + # # The cookie is signed by your app's `secrets.secret_key_base` value. + # # It can be read using the signed method `cookies.signed[:name]` + # cookies.signed[:user_id] = current_user.id + # + # # Sets a "permanent" cookie (which expires in 20 years from now). + # cookies.permanent[:login] = "XJ-122" + # + # # You can also chain these methods: + # cookies.permanent.signed[:login] = "XJ-122" + # + # Examples of reading: + # + # cookies[:user_name] # => "david" + # cookies.size # => 2 + # JSON.parse(cookies[:lat_lon]) # => [47.68, -122.37] + # cookies.signed[:login] # => "XJ-122" + # + # Example for deleting: + # + # cookies.delete :user_name + # + # Please note that if you specify a :domain when setting a cookie, you must also specify the domain when deleting the cookie: + # + # cookies[:name] = { + # value: 'a yummy cookie', + # expires: 1.year.from_now, + # domain: 'domain.com' + # } + # + # cookies.delete(:name, domain: 'domain.com') + # + # The option symbols for setting cookies are: + # + # * :value - The cookie's value. + # * :path - The path for which this cookie applies. Defaults to the root + # of the application. + # * :domain - The domain for which this cookie applies so you can + # restrict to the domain level. If you use a schema like www.example.com + # and want to share session with user.example.com set :domain + # to :all. Make sure to specify the :domain option with + # :all or Array again when deleting cookies. + # + # domain: nil # Does not sets cookie domain. (default) + # domain: :all # Allow the cookie for the top most level + # # domain and subdomains. + # domain: %w(.example.com .example.org) # Allow the cookie + # # for concrete domain names. + # + # * :expires - The time at which this cookie expires, as a \Time object. + # * :secure - Whether this cookie is only transmitted to HTTPS servers. + # Default is +false+. + # * :httponly - Whether this cookie is accessible via scripting or + # only HTTP. Defaults to +false+. + class Cookies + HTTP_HEADER = "Set-Cookie".freeze + GENERATOR_KEY = "action_dispatch.key_generator".freeze + SIGNED_COOKIE_SALT = "action_dispatch.signed_cookie_salt".freeze + ENCRYPTED_COOKIE_SALT = "action_dispatch.encrypted_cookie_salt".freeze + ENCRYPTED_SIGNED_COOKIE_SALT = "action_dispatch.encrypted_signed_cookie_salt".freeze + SECRET_TOKEN = "action_dispatch.secret_token".freeze + SECRET_KEY_BASE = "action_dispatch.secret_key_base".freeze + COOKIES_SERIALIZER = "action_dispatch.cookies_serializer".freeze + COOKIES_DIGEST = "action_dispatch.cookies_digest".freeze + + # Cookies can typically store 4096 bytes. + MAX_COOKIE_SIZE = 4096 + + # Raised when storing more than 4K of session data. + CookieOverflow = Class.new StandardError + + # Include in a cookie jar to allow chaining, e.g. cookies.permanent.signed + module ChainedCookieJars + # Returns a jar that'll automatically set the assigned cookies to have an expiration date 20 years from now. Example: + # + # cookies.permanent[:prefers_open_id] = true + # # => Set-Cookie: prefers_open_id=true; path=/; expires=Sun, 16-Dec-2029 03:24:16 GMT + # + # This jar is only meant for writing. You'll read permanent cookies through the regular accessor. + # + # This jar allows chaining with the signed jar as well, so you can set permanent, signed cookies. Examples: + # + # cookies.permanent.signed[:remember_me] = current_user.id + # # => Set-Cookie: remember_me=BAhU--848956038e692d7046deab32b7131856ab20e14e; path=/; expires=Sun, 16-Dec-2029 03:24:16 GMT + def permanent + @permanent ||= PermanentCookieJar.new(self, @key_generator, @options) + end + + # Returns a jar that'll automatically generate a signed representation of cookie value and verify it when reading from + # the cookie again. This is useful for creating cookies with values that the user is not supposed to change. If a signed + # cookie was tampered with by the user (or a 3rd party), nil will be returned. + # + # If +secrets.secret_key_base+ and +secrets.secret_token+ (deprecated) are both set, + # legacy cookies signed with the old key generator will be transparently upgraded. + # + # This jar requires that you set a suitable secret for the verification on your app's +secrets.secret_key_base+. + # + # Example: + # + # cookies.signed[:discount] = 45 + # # => Set-Cookie: discount=BAhpMg==--2c1c6906c90a3bc4fd54a51ffb41dffa4bf6b5f7; path=/ + # + # cookies.signed[:discount] # => 45 + def signed + @signed ||= + if @options[:upgrade_legacy_signed_cookies] + UpgradeLegacySignedCookieJar.new(self, @key_generator, @options) + else + SignedCookieJar.new(self, @key_generator, @options) + end + end + + # Returns a jar that'll automatically encrypt cookie values before sending them to the client and will decrypt them for read. + # If the cookie was tampered with by the user (or a 3rd party), nil will be returned. + # + # If +secrets.secret_key_base+ and +secrets.secret_token+ (deprecated) are both set, + # legacy cookies signed with the old key generator will be transparently upgraded. + # + # This jar requires that you set a suitable secret for the verification on your app's +secrets.secret_key_base+. + # + # Example: + # + # cookies.encrypted[:discount] = 45 + # # => Set-Cookie: discount=ZS9ZZ1R4cG1pcUJ1bm80anhQang3dz09LS1mbDZDSU5scGdOT3ltQ2dTdlhSdWpRPT0%3D--ab54663c9f4e3bc340c790d6d2b71e92f5b60315; path=/ + # + # cookies.encrypted[:discount] # => 45 + def encrypted + @encrypted ||= + if @options[:upgrade_legacy_signed_cookies] + UpgradeLegacyEncryptedCookieJar.new(self, @key_generator, @options) + else + EncryptedCookieJar.new(self, @key_generator, @options) + end + end + + # Returns the +signed+ or +encrypted+ jar, preferring +encrypted+ if +secret_key_base+ is set. + # Used by ActionDispatch::Session::CookieStore to avoid the need to introduce new cookie stores. + def signed_or_encrypted + @signed_or_encrypted ||= + if @options[:secret_key_base].present? + encrypted + else + signed + end + end + end + + # Passing the ActiveSupport::MessageEncryptor::NullSerializer downstream + # to the Message{Encryptor,Verifier} allows us to handle the + # (de)serialization step within the cookie jar, which gives us the + # opportunity to detect and migrate legacy cookies. + module VerifyAndUpgradeLegacySignedMessage # :nodoc: + def initialize(*args) + super + @legacy_verifier = ActiveSupport::MessageVerifier.new(@options[:secret_token], serializer: ActiveSupport::MessageEncryptor::NullSerializer) + end + + def verify_and_upgrade_legacy_signed_message(name, signed_message) + deserialize(name, @legacy_verifier.verify(signed_message)).tap do |value| + self[name] = { value: value } + end + rescue ActiveSupport::MessageVerifier::InvalidSignature + nil + end + end + + class CookieJar #:nodoc: + include Enumerable, ChainedCookieJars + + # This regular expression is used to split the levels of a domain. + # The top level domain can be any string without a period or + # **.**, ***.** style TLDs like co.uk or com.au + # + # www.example.co.uk gives: + # $& => example.co.uk + # + # example.com gives: + # $& => example.com + # + # lots.of.subdomains.example.local gives: + # $& => example.local + DOMAIN_REGEXP = /[^.]*\.([^.]*|..\...|...\...)$/ + + def self.options_for_env(env) #:nodoc: + { signed_cookie_salt: env[SIGNED_COOKIE_SALT] || '', + encrypted_cookie_salt: env[ENCRYPTED_COOKIE_SALT] || '', + encrypted_signed_cookie_salt: env[ENCRYPTED_SIGNED_COOKIE_SALT] || '', + secret_token: env[SECRET_TOKEN], + secret_key_base: env[SECRET_KEY_BASE], + upgrade_legacy_signed_cookies: env[SECRET_TOKEN].present? && env[SECRET_KEY_BASE].present?, + serializer: env[COOKIES_SERIALIZER], + digest: env[COOKIES_DIGEST] + } + end + + def self.build(request) + env = request.env + key_generator = env[GENERATOR_KEY] + options = options_for_env env + + host = request.host + secure = request.ssl? + + new(key_generator, host, secure, options).tap do |hash| + hash.update(request.cookies) + end + end + + def initialize(key_generator, host = nil, secure = false, options = {}) + @key_generator = key_generator + @set_cookies = {} + @delete_cookies = {} + @host = host + @secure = secure + @options = options + @cookies = {} + @committed = false + end + + def committed?; @committed; end + + def commit! + @committed = true + @set_cookies.freeze + @delete_cookies.freeze + end + + def each(&block) + @cookies.each(&block) + end + + # Returns the value of the cookie by +name+, or +nil+ if no such cookie exists. + def [](name) + @cookies[name.to_s] + end + + def fetch(name, *args, &block) + @cookies.fetch(name.to_s, *args, &block) + end + + def key?(name) + @cookies.key?(name.to_s) + end + alias :has_key? :key? + + def update(other_hash) + @cookies.update other_hash.stringify_keys + self + end + + def handle_options(options) #:nodoc: + options[:path] ||= "/" + + if options[:domain] == :all + # if there is a provided tld length then we use it otherwise default domain regexp + domain_regexp = options[:tld_length] ? /([^.]+\.?){#{options[:tld_length]}}$/ : DOMAIN_REGEXP + + # if host is not ip and matches domain regexp + # (ip confirms to domain regexp so we explicitly check for ip) + options[:domain] = if (@host !~ /^[\d.]+$/) && (@host =~ domain_regexp) + ".#{$&}" + end + elsif options[:domain].is_a? Array + # if host matches one of the supplied domains without a dot in front of it + options[:domain] = options[:domain].find {|domain| @host.include? domain.sub(/^\./, '') } + end + end + + # Sets the cookie named +name+. The second argument may be the cookie's + # value or a hash of options as documented above. + def []=(name, options) + if options.is_a?(Hash) + options.symbolize_keys! + value = options[:value] + else + value = options + options = { :value => value } + end + + handle_options(options) + + if @cookies[name.to_s] != value or options[:expires] + @cookies[name.to_s] = value + @set_cookies[name.to_s] = options + @delete_cookies.delete(name.to_s) + end + + value + end + + # Removes the cookie on the client machine by setting the value to an empty string + # and the expiration date in the past. Like []=, you can pass in + # an options hash to delete cookies with extra data such as a :path. + def delete(name, options = {}) + return unless @cookies.has_key? name.to_s + + options.symbolize_keys! + handle_options(options) + + value = @cookies.delete(name.to_s) + @delete_cookies[name.to_s] = options + value + end + + # Whether the given cookie is to be deleted by this CookieJar. + # Like []=, you can pass in an options hash to test if a + # deletion applies to a specific :path, :domain etc. + def deleted?(name, options = {}) + options.symbolize_keys! + handle_options(options) + @delete_cookies[name.to_s] == options + end + + # Removes all cookies on the client machine by calling delete for each cookie + def clear(options = {}) + @cookies.each_key{ |k| delete(k, options) } + end + + def write(headers) + @set_cookies.each { |k, v| ::Rack::Utils.set_cookie_header!(headers, k, v) if write_cookie?(v) } + @delete_cookies.each { |k, v| ::Rack::Utils.delete_cookie_header!(headers, k, v) } + end + + def recycle! #:nodoc: + @set_cookies = {} + @delete_cookies = {} + end + + mattr_accessor :always_write_cookie + self.always_write_cookie = false + + private + def write_cookie?(cookie) + @secure || !cookie[:secure] || always_write_cookie + end + end + + class PermanentCookieJar #:nodoc: + include ChainedCookieJars + + def initialize(parent_jar, key_generator, options = {}) + @parent_jar = parent_jar + @key_generator = key_generator + @options = options + end + + def [](name) + @parent_jar[name.to_s] + end + + def []=(name, options) + if options.is_a?(Hash) + options.symbolize_keys! + else + options = { :value => options } + end + + options[:expires] = 20.years.from_now + @parent_jar[name] = options + end + end + + class JsonSerializer # :nodoc: + def self.load(value) + ActiveSupport::JSON.decode(value) + end + + def self.dump(value) + ActiveSupport::JSON.encode(value) + end + end + + module SerializedCookieJars # :nodoc: + MARSHAL_SIGNATURE = "\x04\x08".freeze + + protected + def needs_migration?(value) + @options[:serializer] == :hybrid && value.start_with?(MARSHAL_SIGNATURE) + end + + def serialize(name, value) + serializer.dump(value) + end + + def deserialize(name, value) + if value + if needs_migration?(value) + Marshal.load(value).tap do |v| + self[name] = { value: v } + end + else + serializer.load(value) + end + end + end + + def serializer + serializer = @options[:serializer] || :marshal + case serializer + when :marshal + Marshal + when :json, :hybrid + JsonSerializer + else + serializer + end + end + + def digest + @options[:digest] || 'SHA1' + end + end + + class SignedCookieJar #:nodoc: + include ChainedCookieJars + include SerializedCookieJars + + def initialize(parent_jar, key_generator, options = {}) + @parent_jar = parent_jar + @options = options + secret = key_generator.generate_key(@options[:signed_cookie_salt]) + @verifier = ActiveSupport::MessageVerifier.new(secret, digest: digest, serializer: ActiveSupport::MessageEncryptor::NullSerializer) + end + + def [](name) + if signed_message = @parent_jar[name] + deserialize name, verify(signed_message) + end + end + + def []=(name, options) + if options.is_a?(Hash) + options.symbolize_keys! + options[:value] = @verifier.generate(serialize(name, options[:value])) + else + options = { :value => @verifier.generate(serialize(name, options)) } + end + + raise CookieOverflow if options[:value].bytesize > MAX_COOKIE_SIZE + @parent_jar[name] = options + end + + private + def verify(signed_message) + @verifier.verify(signed_message) + rescue ActiveSupport::MessageVerifier::InvalidSignature + nil + end + end + + # UpgradeLegacySignedCookieJar is used instead of SignedCookieJar if + # secrets.secret_token and secrets.secret_key_base are both set. It reads + # legacy cookies signed with the old dummy key generator and re-saves + # them using the new key generator to provide a smooth upgrade path. + class UpgradeLegacySignedCookieJar < SignedCookieJar #:nodoc: + include VerifyAndUpgradeLegacySignedMessage + + def [](name) + if signed_message = @parent_jar[name] + deserialize(name, verify(signed_message)) || verify_and_upgrade_legacy_signed_message(name, signed_message) + end + end + end + + class EncryptedCookieJar #:nodoc: + include ChainedCookieJars + include SerializedCookieJars + + def initialize(parent_jar, key_generator, options = {}) + if ActiveSupport::LegacyKeyGenerator === key_generator + raise "You didn't set secrets.secret_key_base, which is required for this cookie jar. " + + "Read the upgrade documentation to learn more about this new config option." + end + + @parent_jar = parent_jar + @options = options + secret = key_generator.generate_key(@options[:encrypted_cookie_salt]) + sign_secret = key_generator.generate_key(@options[:encrypted_signed_cookie_salt]) + @encryptor = ActiveSupport::MessageEncryptor.new(secret, sign_secret, digest: digest, serializer: ActiveSupport::MessageEncryptor::NullSerializer) + end + + def [](name) + if encrypted_message = @parent_jar[name] + deserialize name, decrypt_and_verify(encrypted_message) + end + end + + def []=(name, options) + if options.is_a?(Hash) + options.symbolize_keys! + else + options = { :value => options } + end + + options[:value] = @encryptor.encrypt_and_sign(serialize(name, options[:value])) + + raise CookieOverflow if options[:value].bytesize > MAX_COOKIE_SIZE + @parent_jar[name] = options + end + + private + def decrypt_and_verify(encrypted_message) + @encryptor.decrypt_and_verify(encrypted_message) + rescue ActiveSupport::MessageVerifier::InvalidSignature, ActiveSupport::MessageEncryptor::InvalidMessage + nil + end + end + + # UpgradeLegacyEncryptedCookieJar is used by ActionDispatch::Session::CookieStore + # instead of EncryptedCookieJar if secrets.secret_token and secrets.secret_key_base + # are both set. It reads legacy cookies signed with the old dummy key generator and + # encrypts and re-saves them using the new key generator to provide a smooth upgrade path. + class UpgradeLegacyEncryptedCookieJar < EncryptedCookieJar #:nodoc: + include VerifyAndUpgradeLegacySignedMessage + + def [](name) + if encrypted_or_signed_message = @parent_jar[name] + deserialize(name, decrypt_and_verify(encrypted_or_signed_message)) || verify_and_upgrade_legacy_signed_message(name, encrypted_or_signed_message) + end + end + end + + def initialize(app) + @app = app + end + + def call(env) + status, headers, body = @app.call(env) + + if cookie_jar = env['action_dispatch.cookies'] + unless cookie_jar.committed? + cookie_jar.write(headers) + if headers[HTTP_HEADER].respond_to?(:join) + headers[HTTP_HEADER] = headers[HTTP_HEADER].join("\n") + end + end + end + + [status, headers, body] + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/debug_exceptions.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/debug_exceptions.rb new file mode 100644 index 0000000..c1562fc --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/debug_exceptions.rb @@ -0,0 +1,110 @@ +require 'action_dispatch/http/request' +require 'action_dispatch/middleware/exception_wrapper' +require 'action_dispatch/routing/inspector' + +module ActionDispatch + # This middleware is responsible for logging exceptions and + # showing a debugging page in case the request is local. + class DebugExceptions + RESCUES_TEMPLATE_PATH = File.expand_path('../templates', __FILE__) + + def initialize(app, routes_app = nil) + @app = app + @routes_app = routes_app + end + + def call(env) + _, headers, body = response = @app.call(env) + + if headers['X-Cascade'] == 'pass' + body.close if body.respond_to?(:close) + raise ActionController::RoutingError, "No route matches [#{env['REQUEST_METHOD']}] #{env['PATH_INFO'].inspect}" + end + + response + rescue Exception => exception + raise exception if env['action_dispatch.show_exceptions'] == false + render_exception(env, exception) + end + + private + + def render_exception(env, exception) + wrapper = ExceptionWrapper.new(env, exception) + log_error(env, wrapper) + + if env['action_dispatch.show_detailed_exceptions'] + request = Request.new(env) + traces = wrapper.traces + + trace_to_show = 'Application Trace' + if traces[trace_to_show].empty? && wrapper.rescue_template != 'routing_error' + trace_to_show = 'Full Trace' + end + + if source_to_show = traces[trace_to_show].first + source_to_show_id = source_to_show[:id] + end + + template = ActionView::Base.new([RESCUES_TEMPLATE_PATH], + request: request, + exception: wrapper.exception, + traces: traces, + show_source_idx: source_to_show_id, + trace_to_show: trace_to_show, + routes_inspector: routes_inspector(exception), + source_extracts: wrapper.source_extracts, + line_number: wrapper.line_number, + file: wrapper.file + ) + file = "rescues/#{wrapper.rescue_template}" + + if request.xhr? + body = template.render(template: file, layout: false, formats: [:text]) + format = "text/plain" + else + body = template.render(template: file, layout: 'rescues/layout') + format = "text/html" + end + render(wrapper.status_code, body, format) + else + raise exception + end + end + + def render(status, body, format) + [status, {'Content-Type' => "#{format}; charset=#{Response.default_charset}", 'Content-Length' => body.bytesize.to_s}, [body]] + end + + def log_error(env, wrapper) + logger = logger(env) + return unless logger + + exception = wrapper.exception + + trace = wrapper.application_trace + trace = wrapper.framework_trace if trace.empty? + + ActiveSupport::Deprecation.silence do + message = "\n#{exception.class} (#{exception.message}):\n" + message << exception.annoted_source_code.to_s if exception.respond_to?(:annoted_source_code) + message << " " << trace.join("\n ") + logger.fatal("#{message}\n\n") + end + end + + def logger(env) + env['action_dispatch.logger'] || stderr_logger + end + + def stderr_logger + @stderr_logger ||= ActiveSupport::Logger.new($stderr) + end + + def routes_inspector(exception) + if @routes_app.respond_to?(:routes) && (exception.is_a?(ActionController::RoutingError) || exception.is_a?(ActionView::Template::Error)) + ActionDispatch::Routing::RoutesInspector.new(@routes_app.routes.routes) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/exception_wrapper.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/exception_wrapper.rb new file mode 100644 index 0000000..a4862e3 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/exception_wrapper.rb @@ -0,0 +1,148 @@ +require 'action_controller/metal/exceptions' +require 'active_support/core_ext/module/attribute_accessors' + +module ActionDispatch + class ExceptionWrapper + cattr_accessor :rescue_responses + @@rescue_responses = Hash.new(:internal_server_error) + @@rescue_responses.merge!( + 'ActionController::RoutingError' => :not_found, + 'AbstractController::ActionNotFound' => :not_found, + 'ActionController::MethodNotAllowed' => :method_not_allowed, + 'ActionController::UnknownHttpMethod' => :method_not_allowed, + 'ActionController::NotImplemented' => :not_implemented, + 'ActionController::UnknownFormat' => :not_acceptable, + 'ActionController::InvalidAuthenticityToken' => :unprocessable_entity, + 'ActionController::InvalidCrossOriginRequest' => :unprocessable_entity, + 'ActionDispatch::ParamsParser::ParseError' => :bad_request, + 'ActionController::BadRequest' => :bad_request, + 'ActionController::ParameterMissing' => :bad_request + ) + + cattr_accessor :rescue_templates + @@rescue_templates = Hash.new('diagnostics') + @@rescue_templates.merge!( + 'ActionView::MissingTemplate' => 'missing_template', + 'ActionController::RoutingError' => 'routing_error', + 'AbstractController::ActionNotFound' => 'unknown_action', + 'ActionView::Template::Error' => 'template_error' + ) + + attr_reader :env, :exception, :line_number, :file + + def initialize(env, exception) + @env = env + @exception = original_exception(exception) + + expand_backtrace if exception.is_a?(SyntaxError) || exception.try(:original_exception).try(:is_a?, SyntaxError) + end + + def rescue_template + @@rescue_templates[@exception.class.name] + end + + def status_code + self.class.status_code_for_exception(@exception.class.name) + end + + def application_trace + clean_backtrace(:silent) + end + + def framework_trace + clean_backtrace(:noise) + end + + def full_trace + clean_backtrace(:all) + end + + def traces + appplication_trace_with_ids = [] + framework_trace_with_ids = [] + full_trace_with_ids = [] + + full_trace.each_with_index do |trace, idx| + trace_with_id = { id: idx, trace: trace } + + if application_trace.include?(trace) + appplication_trace_with_ids << trace_with_id + else + framework_trace_with_ids << trace_with_id + end + + full_trace_with_ids << trace_with_id + end + + { + "Application Trace" => appplication_trace_with_ids, + "Framework Trace" => framework_trace_with_ids, + "Full Trace" => full_trace_with_ids + } + end + + def self.status_code_for_exception(class_name) + Rack::Utils.status_code(@@rescue_responses[class_name]) + end + + def source_extracts + backtrace.map do |trace| + file, line = trace.split(":") + line_number = line.to_i + + { + code: source_fragment(file, line_number), + line_number: line_number + } + end + end + + private + + def backtrace + Array(@exception.backtrace) + end + + def original_exception(exception) + if registered_original_exception?(exception) + exception.original_exception + else + exception + end + end + + def registered_original_exception?(exception) + exception.respond_to?(:original_exception) && @@rescue_responses.has_key?(exception.original_exception.class.name) + end + + def clean_backtrace(*args) + if backtrace_cleaner + backtrace_cleaner.clean(backtrace, *args) + else + backtrace + end + end + + def backtrace_cleaner + @backtrace_cleaner ||= @env['action_dispatch.backtrace_cleaner'] + end + + def source_fragment(path, line) + return unless Rails.respond_to?(:root) && Rails.root + full_path = Rails.root.join(path) + if File.exist?(full_path) + File.open(full_path, "r") do |file| + start = [line - 3, 0].max + lines = file.each_line.drop(start).take(6) + Hash[*(start+1..(lines.count+start)).zip(lines).flatten] + end + end + end + + def expand_backtrace + @exception.backtrace.unshift( + @exception.to_s.split("\n") + ).flatten! + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/flash.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/flash.rb new file mode 100644 index 0000000..a7f9515 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/flash.rb @@ -0,0 +1,276 @@ +require 'active_support/core_ext/hash/keys' + +module ActionDispatch + class Request < Rack::Request + # Access the contents of the flash. Use flash["notice"] to + # read a notice you put there or flash["notice"] = "hello" + # to put a new one. + def flash + @env[Flash::KEY] ||= Flash::FlashHash.from_session_value(session["flash"]) + end + end + + # The flash provides a way to pass temporary primitive-types (String, Array, Hash) between actions. Anything you place in the flash will be exposed + # to the very next action and then cleared out. This is a great way of doing notices and alerts, such as a create + # action that sets flash[:notice] = "Post successfully created" before redirecting to a display action that can + # then expose the flash to its template. Actually, that exposure is automatically done. + # + # class PostsController < ActionController::Base + # def create + # # save post + # flash[:notice] = "Post successfully created" + # redirect_to @post + # end + # + # def show + # # doesn't need to assign the flash notice to the template, that's done automatically + # end + # end + # + # show.html.erb + # <% if flash[:notice] %> + #
<%= flash[:notice] %>
+ # <% end %> + # + # Since the +notice+ and +alert+ keys are a common idiom, convenience accessors are available: + # + # flash.alert = "You must be logged in" + # flash.notice = "Post successfully created" + # + # This example places a string in the flash. And of course, you can put as many as you like at a time too. If you want to pass + # non-primitive types, you will have to handle that in your application. Example: To show messages with links, you will have to + # use sanitize helper. + # + # Just remember: They'll be gone by the time the next action has been performed. + # + # See docs on the FlashHash class for more details about the flash. + class Flash + KEY = 'action_dispatch.request.flash_hash'.freeze + + class FlashNow #:nodoc: + attr_accessor :flash + + def initialize(flash) + @flash = flash + end + + def []=(k, v) + k = k.to_s + @flash[k] = v + @flash.discard(k) + v + end + + def [](k) + @flash[k.to_s] + end + + # Convenience accessor for flash.now[:alert]=. + def alert=(message) + self[:alert] = message + end + + # Convenience accessor for flash.now[:notice]=. + def notice=(message) + self[:notice] = message + end + end + + class FlashHash + include Enumerable + + def self.from_session_value(value) #:nodoc: + flash = case value + when FlashHash # Rails 3.1, 3.2 + new(value.instance_variable_get(:@flashes), value.instance_variable_get(:@used)) + when Hash # Rails 4.0 + new(value['flashes'], value['discard']) + else + new + end + + flash.tap(&:sweep) + end + + # Builds a hash containing the discarded values and the hashes + # representing the flashes. + # If there are no values in @flashes, returns nil. + def to_session_value #:nodoc: + return nil if empty? + {'discard' => @discard.to_a, 'flashes' => @flashes} + end + + def initialize(flashes = {}, discard = []) #:nodoc: + @discard = Set.new(stringify_array(discard)) + @flashes = flashes.stringify_keys + @now = nil + end + + def initialize_copy(other) + if other.now_is_loaded? + @now = other.now.dup + @now.flash = self + end + super + end + + def []=(k, v) + k = k.to_s + @discard.delete k + @flashes[k] = v + end + + def [](k) + @flashes[k.to_s] + end + + def update(h) #:nodoc: + @discard.subtract stringify_array(h.keys) + @flashes.update h.stringify_keys + self + end + + def keys + @flashes.keys + end + + def key?(name) + @flashes.key? name.to_s + end + + def delete(key) + key = key.to_s + @discard.delete key + @flashes.delete key + self + end + + def to_hash + @flashes.dup + end + + def empty? + @flashes.empty? + end + + def clear + @discard.clear + @flashes.clear + end + + def each(&block) + @flashes.each(&block) + end + + alias :merge! :update + + def replace(h) #:nodoc: + @discard.clear + @flashes.replace h.stringify_keys + self + end + + # Sets a flash that will not be available to the next action, only to the current. + # + # flash.now[:message] = "Hello current action" + # + # This method enables you to use the flash as a central messaging system in your app. + # When you need to pass an object to the next action, you use the standard flash assign ([]=). + # When you need to pass an object to the current action, you use now, and your object will + # vanish when the current action is done. + # + # Entries set via now are accessed the same way as standard entries: flash['my-key']. + # + # Also, brings two convenience accessors: + # + # flash.now.alert = "Beware now!" + # # Equivalent to flash.now[:alert] = "Beware now!" + # + # flash.now.notice = "Good luck now!" + # # Equivalent to flash.now[:notice] = "Good luck now!" + def now + @now ||= FlashNow.new(self) + end + + # Keeps either the entire current flash or a specific flash entry available for the next action: + # + # flash.keep # keeps the entire flash + # flash.keep(:notice) # keeps only the "notice" entry, the rest of the flash is discarded + def keep(k = nil) + k = k.to_s if k + @discard.subtract Array(k || keys) + k ? self[k] : self + end + + # Marks the entire flash or a single flash entry to be discarded by the end of the current action: + # + # flash.discard # discard the entire flash at the end of the current action + # flash.discard(:warning) # discard only the "warning" entry at the end of the current action + def discard(k = nil) + k = k.to_s if k + @discard.merge Array(k || keys) + k ? self[k] : self + end + + # Mark for removal entries that were kept, and delete unkept ones. + # + # This method is called automatically by filters, so you generally don't need to care about it. + def sweep #:nodoc: + @discard.each { |k| @flashes.delete k } + @discard.replace @flashes.keys + end + + # Convenience accessor for flash[:alert]. + def alert + self[:alert] + end + + # Convenience accessor for flash[:alert]=. + def alert=(message) + self[:alert] = message + end + + # Convenience accessor for flash[:notice]. + def notice + self[:notice] + end + + # Convenience accessor for flash[:notice]=. + def notice=(message) + self[:notice] = message + end + + protected + def now_is_loaded? + @now + end + + def stringify_array(array) + array.map do |item| + item.kind_of?(Symbol) ? item.to_s : item + end + end + end + + def initialize(app) + @app = app + end + + def call(env) + @app.call(env) + ensure + session = Request::Session.find(env) || {} + flash_hash = env[KEY] + + if flash_hash && (flash_hash.present? || session.key?('flash')) + session["flash"] = flash_hash.to_session_value + env[KEY] = flash_hash.dup + end + + if (!session.respond_to?(:loaded?) || session.loaded?) && # (reset_session uses {}, which doesn't implement #loaded?) + session.key?('flash') && session['flash'].nil? + session.delete('flash') + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/params_parser.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/params_parser.rb new file mode 100644 index 0000000..29d43fa --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/params_parser.rb @@ -0,0 +1,60 @@ +require 'active_support/core_ext/hash/conversions' +require 'action_dispatch/http/request' +require 'active_support/core_ext/hash/indifferent_access' + +module ActionDispatch + class ParamsParser + class ParseError < StandardError + attr_reader :original_exception + + def initialize(message, original_exception) + super(message) + @original_exception = original_exception + end + end + + DEFAULT_PARSERS = { Mime::JSON => :json } + + def initialize(app, parsers = {}) + @app, @parsers = app, DEFAULT_PARSERS.merge(parsers) + end + + def call(env) + if params = parse_formatted_parameters(env) + env["action_dispatch.request.request_parameters"] = params + end + + @app.call(env) + end + + private + def parse_formatted_parameters(env) + request = Request.new(env) + + return false if request.content_length.zero? + + strategy = @parsers[request.content_mime_type] + + return false unless strategy + + case strategy + when Proc + strategy.call(request.raw_post) + when :json + data = ActiveSupport::JSON.decode(request.raw_post) + data = {:_json => data} unless data.is_a?(Hash) + Request::Utils.deep_munge(data).with_indifferent_access + else + false + end + rescue => e # JSON or Ruby code block errors + logger(env).debug "Error occurred while parsing request parameters.\nContents:\n\n#{request.raw_post}" + + raise ParseError.new(e.message, e) + end + + def logger(env) + env['action_dispatch.logger'] || ActiveSupport::Logger.new($stderr) + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/public_exceptions.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/public_exceptions.rb new file mode 100644 index 0000000..040cb21 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/public_exceptions.rb @@ -0,0 +1,55 @@ +module ActionDispatch + # When called, this middleware renders an error page. By default if an HTML + # response is expected it will render static error pages from the `/public` + # directory. For example when this middleware receives a 500 response it will + # render the template found in `/public/500.html`. + # If an internationalized locale is set, this middleware will attempt to render + # the template in `/public/500..html`. If an internationalized template + # is not found it will fall back on `/public/500.html`. + # + # When a request with a content type other than HTML is made, this middleware + # will attempt to convert error information into the appropriate response type. + class PublicExceptions + attr_accessor :public_path + + def initialize(public_path) + @public_path = public_path + end + + def call(env) + status = env["PATH_INFO"][1..-1] + request = ActionDispatch::Request.new(env) + content_type = request.formats.first + body = { :status => status, :error => Rack::Utils::HTTP_STATUS_CODES.fetch(status.to_i, Rack::Utils::HTTP_STATUS_CODES[500]) } + + render(status, content_type, body) + end + + private + + def render(status, content_type, body) + format = "to_#{content_type.to_sym}" if content_type + if format && body.respond_to?(format) + render_format(status, content_type, body.public_send(format)) + else + render_html(status) + end + end + + def render_format(status, content_type, body) + [status, {'Content-Type' => "#{content_type}; charset=#{ActionDispatch::Response.default_charset}", + 'Content-Length' => body.bytesize.to_s}, [body]] + end + + def render_html(status) + path = "#{public_path}/#{status}.#{I18n.locale}.html" + path = "#{public_path}/#{status}.html" unless (found = File.exist?(path)) + + if found || File.exist?(path) + render_format(status, 'text/html', File.read(path)) + else + [404, { "X-Cascade" => "pass" }, []] + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/reloader.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/reloader.rb new file mode 100644 index 0000000..15b5a48 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/reloader.rb @@ -0,0 +1,98 @@ +require 'active_support/deprecation/reporting' + +module ActionDispatch + # ActionDispatch::Reloader provides prepare and cleanup callbacks, + # intended to assist with code reloading during development. + # + # Prepare callbacks are run before each request, and cleanup callbacks + # after each request. In this respect they are analogs of ActionDispatch::Callback's + # before and after callbacks. However, cleanup callbacks are not called until the + # request is fully complete -- that is, after #close has been called on + # the response body. This is important for streaming responses such as the + # following: + # + # self.response_body = lambda { |response, output| + # # code here which refers to application models + # } + # + # Cleanup callbacks will not be called until after the response_body lambda + # is evaluated, ensuring that it can refer to application models and other + # classes before they are unloaded. + # + # By default, ActionDispatch::Reloader is included in the middleware stack + # only in the development environment; specifically, when +config.cache_classes+ + # is false. Callbacks may be registered even when it is not included in the + # middleware stack, but are executed only when ActionDispatch::Reloader.prepare! + # or ActionDispatch::Reloader.cleanup! are called manually. + # + class Reloader + include ActiveSupport::Callbacks + include ActiveSupport::Deprecation::Reporting + + define_callbacks :prepare + define_callbacks :cleanup + + # Add a prepare callback. Prepare callbacks are run before each request, prior + # to ActionDispatch::Callback's before callbacks. + def self.to_prepare(*args, &block) + unless block_given? + warn "to_prepare without a block is deprecated. Please use a block" + end + set_callback(:prepare, *args, &block) + end + + # Add a cleanup callback. Cleanup callbacks are run after each request is + # complete (after #close is called on the response body). + def self.to_cleanup(*args, &block) + unless block_given? + warn "to_cleanup without a block is deprecated. Please use a block" + end + set_callback(:cleanup, *args, &block) + end + + # Execute all prepare callbacks. + def self.prepare! + new(nil).prepare! + end + + # Execute all cleanup callbacks. + def self.cleanup! + new(nil).cleanup! + end + + def initialize(app, condition=nil) + @app = app + @condition = condition || lambda { true } + @validated = true + end + + def call(env) + @validated = @condition.call + prepare! + + response = @app.call(env) + response[2] = ::Rack::BodyProxy.new(response[2]) { cleanup! } + + response + rescue Exception + cleanup! + raise + end + + def prepare! #:nodoc: + run_callbacks :prepare if validated? + end + + def cleanup! #:nodoc: + run_callbacks :cleanup if validated? + ensure + @validated = true + end + + private + + def validated? #:nodoc: + @validated + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/remote_ip.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/remote_ip.rb new file mode 100644 index 0000000..7c42365 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/remote_ip.rb @@ -0,0 +1,173 @@ +require 'ipaddr' + +module ActionDispatch + # This middleware calculates the IP address of the remote client that is + # making the request. It does this by checking various headers that could + # contain the address, and then picking the last-set address that is not + # on the list of trusted IPs. This follows the precedent set by e.g. + # {the Tomcat server}[https://issues.apache.org/bugzilla/show_bug.cgi?id=50453], + # with {reasoning explained at length}[http://blog.gingerlime.com/2012/rails-ip-spoofing-vulnerabilities-and-protection] + # by @gingerlime. A more detailed explanation of the algorithm is given + # at GetIp#calculate_ip. + # + # Some Rack servers concatenate repeated headers, like {HTTP RFC 2616}[http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2] + # requires. Some Rack servers simply drop preceding headers, and only report + # the value that was {given in the last header}[http://andre.arko.net/2011/12/26/repeated-headers-and-ruby-web-servers]. + # If you are behind multiple proxy servers (like NGINX to HAProxy to Unicorn) + # then you should test your Rack server to make sure your data is good. + # + # IF YOU DON'T USE A PROXY, THIS MAKES YOU VULNERABLE TO IP SPOOFING. + # This middleware assumes that there is at least one proxy sitting around + # and setting headers with the client's remote IP address. If you don't use + # a proxy, because you are hosted on e.g. Heroku without SSL, any client can + # claim to have any IP address by setting the X-Forwarded-For header. If you + # care about that, then you need to explicitly drop or ignore those headers + # sometime before this middleware runs. + class RemoteIp + class IpSpoofAttackError < StandardError; end + + # The default trusted IPs list simply includes IP addresses that are + # guaranteed by the IP specification to be private addresses. Those will + # not be the ultimate client IP in production, and so are discarded. See + # http://en.wikipedia.org/wiki/Private_network for details. + TRUSTED_PROXIES = [ + "127.0.0.1", # localhost IPv4 + "::1", # localhost IPv6 + "fc00::/7", # private IPv6 range fc00::/7 + "10.0.0.0/8", # private IPv4 range 10.x.x.x + "172.16.0.0/12", # private IPv4 range 172.16.0.0 .. 172.31.255.255 + "192.168.0.0/16", # private IPv4 range 192.168.x.x + ].map { |proxy| IPAddr.new(proxy) } + + attr_reader :check_ip, :proxies + + # Create a new +RemoteIp+ middleware instance. + # + # The +check_ip_spoofing+ option is on by default. When on, an exception + # is raised if it looks like the client is trying to lie about its own IP + # address. It makes sense to turn off this check on sites aimed at non-IP + # clients (like WAP devices), or behind proxies that set headers in an + # incorrect or confusing way (like AWS ELB). + # + # The +custom_proxies+ argument can take an Array of string, IPAddr, or + # Regexp objects which will be used instead of +TRUSTED_PROXIES+. If a + # single string, IPAddr, or Regexp object is provided, it will be used in + # addition to +TRUSTED_PROXIES+. Any proxy setup will put the value you + # want in the middle (or at the beginning) of the X-Forwarded-For list, + # with your proxy servers after it. If your proxies aren't removed, pass + # them in via the +custom_proxies+ parameter. That way, the middleware will + # ignore those IP addresses, and return the one that you want. + def initialize(app, check_ip_spoofing = true, custom_proxies = nil) + @app = app + @check_ip = check_ip_spoofing + @proxies = if custom_proxies.blank? + TRUSTED_PROXIES + elsif custom_proxies.respond_to?(:any?) + custom_proxies + else + Array(custom_proxies) + TRUSTED_PROXIES + end + end + + # Since the IP address may not be needed, we store the object here + # without calculating the IP to keep from slowing down the majority of + # requests. For those requests that do need to know the IP, the + # GetIp#calculate_ip method will calculate the memoized client IP address. + def call(env) + env["action_dispatch.remote_ip"] = GetIp.new(env, self) + @app.call(env) + end + + # The GetIp class exists as a way to defer processing of the request data + # into an actual IP address. If the ActionDispatch::Request#remote_ip method + # is called, this class will calculate the value and then memoize it. + class GetIp + def initialize(env, middleware) + @env = env + @check_ip = middleware.check_ip + @proxies = middleware.proxies + end + + # Sort through the various IP address headers, looking for the IP most + # likely to be the address of the actual remote client making this + # request. + # + # REMOTE_ADDR will be correct if the request is made directly against the + # Ruby process, on e.g. Heroku. When the request is proxied by another + # server like HAProxy or NGINX, the IP address that made the original + # request will be put in an X-Forwarded-For header. If there are multiple + # proxies, that header may contain a list of IPs. Other proxy services + # set the Client-Ip header instead, so we check that too. + # + # As discussed in {this post about Rails IP Spoofing}[http://blog.gingerlime.com/2012/rails-ip-spoofing-vulnerabilities-and-protection/], + # while the first IP in the list is likely to be the "originating" IP, + # it could also have been set by the client maliciously. + # + # In order to find the first address that is (probably) accurate, we + # take the list of IPs, remove known and trusted proxies, and then take + # the last address left, which was presumably set by one of those proxies. + def calculate_ip + # Set by the Rack web server, this is a single value. + remote_addr = ips_from('REMOTE_ADDR').last + + # Could be a CSV list and/or repeated headers that were concatenated. + client_ips = ips_from('HTTP_CLIENT_IP').reverse + forwarded_ips = ips_from('HTTP_X_FORWARDED_FOR').reverse + + # +Client-Ip+ and +X-Forwarded-For+ should not, generally, both be set. + # If they are both set, it means that this request passed through two + # proxies with incompatible IP header conventions, and there is no way + # for us to determine which header is the right one after the fact. + # Since we have no idea, we give up and explode. + should_check_ip = @check_ip && client_ips.last && forwarded_ips.last + if should_check_ip && !forwarded_ips.include?(client_ips.last) + # We don't know which came from the proxy, and which from the user + raise IpSpoofAttackError, "IP spoofing attack?! " + + "HTTP_CLIENT_IP=#{@env['HTTP_CLIENT_IP'].inspect} " + + "HTTP_X_FORWARDED_FOR=#{@env['HTTP_X_FORWARDED_FOR'].inspect}" + end + + # We assume these things about the IP headers: + # + # - X-Forwarded-For will be a list of IPs, one per proxy, or blank + # - Client-Ip is propagated from the outermost proxy, or is blank + # - REMOTE_ADDR will be the IP that made the request to Rack + ips = [forwarded_ips, client_ips, remote_addr].flatten.compact + + # If every single IP option is in the trusted list, just return REMOTE_ADDR + filter_proxies(ips).first || remote_addr + end + + # Memoizes the value returned by #calculate_ip and returns it for + # ActionDispatch::Request to use. + def to_s + @ip ||= calculate_ip + end + + protected + + def ips_from(header) + # Split the comma-separated list into an array of strings + ips = @env[header] ? @env[header].strip.split(/[,\s]+/) : [] + ips.select do |ip| + begin + # Only return IPs that are valid according to the IPAddr#new method + range = IPAddr.new(ip).to_range + # we want to make sure nobody is sneaking a netmask in + range.begin == range.end + rescue ArgumentError + nil + end + end + end + + def filter_proxies(ips) + ips.reject do |ip| + @proxies.any? { |proxy| proxy === ip } + end + end + + end + + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/request_id.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/request_id.rb new file mode 100644 index 0000000..25658ba --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/request_id.rb @@ -0,0 +1,35 @@ +require 'securerandom' +require 'active_support/core_ext/string/access' + +module ActionDispatch + # Makes a unique request id available to the action_dispatch.request_id env variable (which is then accessible through + # ActionDispatch::Request#uuid) and sends the same id to the client via the X-Request-Id header. + # + # The unique request id is either based on the X-Request-Id header in the request, which would typically be generated + # by a firewall, load balancer, or the web server, or, if this header is not available, a random uuid. If the + # header is accepted from the outside world, we sanitize it to a max of 255 chars and alphanumeric and dashes only. + # + # The unique request id can be used to trace a request end-to-end and would typically end up being part of log files + # from multiple pieces of the stack. + class RequestId + def initialize(app) + @app = app + end + + def call(env) + env["action_dispatch.request_id"] = external_request_id(env) || internal_request_id + @app.call(env).tap { |_status, headers, _body| headers["X-Request-Id"] = env["action_dispatch.request_id"] } + end + + private + def external_request_id(env) + if request_id = env["HTTP_X_REQUEST_ID"].presence + request_id.gsub(/[^\w\-]/, "").first(255) + end + end + + def internal_request_id + SecureRandom.uuid + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/session/abstract_store.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/session/abstract_store.rb new file mode 100644 index 0000000..84df55f --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/session/abstract_store.rb @@ -0,0 +1,90 @@ +require 'rack/utils' +require 'rack/request' +require 'rack/session/abstract/id' +require 'action_dispatch/middleware/cookies' +require 'action_dispatch/request/session' + +module ActionDispatch + module Session + class SessionRestoreError < StandardError #:nodoc: + attr_reader :original_exception + + def initialize(const_error) + @original_exception = const_error + + super("Session contains objects whose class definition isn't available.\n" + + "Remember to require the classes for all objects kept in the session.\n" + + "(Original exception: #{const_error.message} [#{const_error.class}])\n") + end + end + + module Compatibility + def initialize(app, options = {}) + options[:key] ||= '_session_id' + super + end + + def generate_sid + sid = SecureRandom.hex(16) + sid.encode!(Encoding::UTF_8) + sid + end + + protected + + def initialize_sid + @default_options.delete(:sidbits) + @default_options.delete(:secure_random) + end + end + + module StaleSessionCheck + def load_session(env) + stale_session_check! { super } + end + + def extract_session_id(env) + stale_session_check! { super } + end + + def stale_session_check! + yield + rescue ArgumentError => argument_error + if argument_error.message =~ %r{undefined class/module ([\w:]*\w)} + begin + # Note that the regexp does not allow $1 to end with a ':' + $1.constantize + rescue LoadError, NameError => e + raise ActionDispatch::Session::SessionRestoreError, e, e.backtrace + end + retry + else + raise + end + end + end + + module SessionObject # :nodoc: + def prepare_session(env) + Request::Session.create(self, env, @default_options) + end + + def loaded_session?(session) + !session.is_a?(Request::Session) || session.loaded? + end + end + + class AbstractStore < Rack::Session::Abstract::ID + include Compatibility + include StaleSessionCheck + include SessionObject + + private + + def set_cookie(env, session_id, cookie) + request = ActionDispatch::Request.new(env) + request.cookie_jar[key] = cookie + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/session/cache_store.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/session/cache_store.rb new file mode 100644 index 0000000..625050d --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/session/cache_store.rb @@ -0,0 +1,49 @@ +require 'action_dispatch/middleware/session/abstract_store' + +module ActionDispatch + module Session + # Session store that uses an ActiveSupport::Cache::Store to store the sessions. This store is most useful + # if you don't store critical data in your sessions and you don't need them to live for extended periods + # of time. + class CacheStore < AbstractStore + # Create a new store. The cache to use can be passed in the :cache option. If it is + # not specified, Rails.cache will be used. + def initialize(app, options = {}) + @cache = options[:cache] || Rails.cache + options[:expire_after] ||= @cache.options[:expires_in] + super + end + + # Get a session from the cache. + def get_session(env, sid) + unless sid and session = @cache.read(cache_key(sid)) + sid, session = generate_sid, {} + end + [sid, session] + end + + # Set a session in the cache. + def set_session(env, sid, session, options) + key = cache_key(sid) + if session + @cache.write(key, session, :expires_in => options[:expire_after]) + else + @cache.delete(key) + end + sid + end + + # Remove a session from the cache. + def destroy_session(env, sid, options) + @cache.delete(cache_key(sid)) + generate_sid + end + + private + # Turn the session id into a cache key. + def cache_key(sid) + "_session_id:#{sid}" + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/session/cookie_store.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/session/cookie_store.rb new file mode 100644 index 0000000..ed25c67 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/session/cookie_store.rb @@ -0,0 +1,123 @@ +require 'active_support/core_ext/hash/keys' +require 'action_dispatch/middleware/session/abstract_store' +require 'rack/session/cookie' + +module ActionDispatch + module Session + # This cookie-based session store is the Rails default. It is + # dramatically faster than the alternatives. + # + # Sessions typically contain at most a user_id and flash message; both fit + # within the 4K cookie size limit. A CookieOverflow exception is raised if + # you attempt to store more than 4K of data. + # + # The cookie jar used for storage is automatically configured to be the + # best possible option given your application's configuration. + # + # If you only have secret_token set, your cookies will be signed, but + # not encrypted. This means a user cannot alter their +user_id+ without + # knowing your app's secret key, but can easily read their +user_id+. This + # was the default for Rails 3 apps. + # + # If you have secret_key_base set, your cookies will be encrypted. This + # goes a step further than signed cookies in that encrypted cookies cannot + # be altered or read by users. This is the default starting in Rails 4. + # + # If you have both secret_token and secret_key base set, your cookies will + # be encrypted, and signed cookies generated by Rails 3 will be + # transparently read and encrypted to provide a smooth upgrade path. + # + # Configure your session store in config/initializers/session_store.rb: + # + # Rails.application.config.session_store :cookie_store, key: '_your_app_session' + # + # Configure your secret key in config/secrets.yml: + # + # development: + # secret_key_base: 'secret key' + # + # To generate a secret key for an existing application, run `rake secret`. + # + # If you are upgrading an existing Rails 3 app, you should leave your + # existing secret_token in place and simply add the new secret_key_base. + # Note that you should wait to set secret_key_base until you have 100% of + # your userbase on Rails 4 and are reasonably sure you will not need to + # rollback to Rails 3. This is because cookies signed based on the new + # secret_key_base in Rails 4 are not backwards compatible with Rails 3. + # You are free to leave your existing secret_token in place, not set the + # new secret_key_base, and ignore the deprecation warnings until you are + # reasonably sure that your upgrade is otherwise complete. Additionally, + # you should take care to make sure you are not relying on the ability to + # decode signed cookies generated by your app in external applications or + # JavaScript before upgrading. + # + # Note that changing the secret key will invalidate all existing sessions! + class CookieStore < Rack::Session::Abstract::ID + include Compatibility + include StaleSessionCheck + include SessionObject + + def initialize(app, options={}) + super(app, options.merge!(:cookie_only => true)) + end + + def destroy_session(env, session_id, options) + new_sid = generate_sid unless options[:drop] + # Reset hash and Assign the new session id + env["action_dispatch.request.unsigned_session_cookie"] = new_sid ? { "session_id" => new_sid } : {} + new_sid + end + + def load_session(env) + stale_session_check! do + data = unpacked_cookie_data(env) + data = persistent_session_id!(data) + [data["session_id"], data] + end + end + + private + + def extract_session_id(env) + stale_session_check! do + unpacked_cookie_data(env)["session_id"] + end + end + + def unpacked_cookie_data(env) + env["action_dispatch.request.unsigned_session_cookie"] ||= begin + stale_session_check! do + if data = get_cookie(env) + data.stringify_keys! + end + data || {} + end + end + end + + def persistent_session_id!(data, sid=nil) + data ||= {} + data["session_id"] ||= sid || generate_sid + data + end + + def set_session(env, sid, session_data, options) + session_data["session_id"] = sid + session_data + end + + def set_cookie(env, session_id, cookie) + cookie_jar(env)[@key] = cookie + end + + def get_cookie(env) + cookie_jar(env)[@key] + end + + def cookie_jar(env) + request = ActionDispatch::Request.new(env) + request.cookie_jar.signed_or_encrypted + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/session/mem_cache_store.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/session/mem_cache_store.rb new file mode 100644 index 0000000..b4d6629 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/session/mem_cache_store.rb @@ -0,0 +1,22 @@ +require 'action_dispatch/middleware/session/abstract_store' +begin + require 'rack/session/dalli' +rescue LoadError => e + $stderr.puts "You don't have dalli installed in your application. Please add it to your Gemfile and run bundle install" + raise e +end + +module ActionDispatch + module Session + class MemCacheStore < Rack::Session::Dalli + include Compatibility + include StaleSessionCheck + include SessionObject + + def initialize(app, options = {}) + options[:expire_after] ||= options[:expires] + super + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/show_exceptions.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/show_exceptions.rb new file mode 100644 index 0000000..f077927 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/show_exceptions.rb @@ -0,0 +1,58 @@ +require 'action_dispatch/http/request' +require 'action_dispatch/middleware/exception_wrapper' + +module ActionDispatch + # This middleware rescues any exception returned by the application + # and calls an exceptions app that will wrap it in a format for the end user. + # + # The exceptions app should be passed as parameter on initialization + # of ShowExceptions. Every time there is an exception, ShowExceptions will + # store the exception in env["action_dispatch.exception"], rewrite the + # PATH_INFO to the exception status code and call the rack app. + # + # If the application returns a "X-Cascade" pass response, this middleware + # will send an empty response as result with the correct status code. + # If any exception happens inside the exceptions app, this middleware + # catches the exceptions and returns a FAILSAFE_RESPONSE. + class ShowExceptions + FAILSAFE_RESPONSE = [500, { 'Content-Type' => 'text/plain' }, + ["500 Internal Server Error\n" \ + "If you are the administrator of this website, then please read this web " \ + "application's log file and/or the web server's log file to find out what " \ + "went wrong."]] + + def initialize(app, exceptions_app) + @app = app + @exceptions_app = exceptions_app + end + + def call(env) + @app.call(env) + rescue Exception => exception + if env['action_dispatch.show_exceptions'] == false + raise exception + else + render_exception(env, exception) + end + end + + private + + def render_exception(env, exception) + wrapper = ExceptionWrapper.new(env, exception) + status = wrapper.status_code + env["action_dispatch.exception"] = wrapper.exception + env["action_dispatch.original_path"] = env["PATH_INFO"] + env["PATH_INFO"] = "/#{status}" + response = @exceptions_app.call(env) + response[1]['X-Cascade'] == 'pass' ? pass_response(status) : response + rescue Exception => failsafe_error + $stderr.puts "Error during failsafe response: #{failsafe_error}\n #{failsafe_error.backtrace * "\n "}" + FAILSAFE_RESPONSE + end + + def pass_response(status) + [status, {"Content-Type" => "text/html; charset=#{Response.default_charset}", "Content-Length" => "0"}, []] + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/ssl.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/ssl.rb new file mode 100644 index 0000000..7b3d8bc --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/ssl.rb @@ -0,0 +1,72 @@ +module ActionDispatch + class SSL + YEAR = 31536000 + + def self.default_hsts_options + { :expires => YEAR, :subdomains => false } + end + + def initialize(app, options = {}) + @app = app + + @hsts = options.fetch(:hsts, {}) + @hsts = {} if @hsts == true + @hsts = self.class.default_hsts_options.merge(@hsts) if @hsts + + @host = options[:host] + @port = options[:port] + end + + def call(env) + request = Request.new(env) + + if request.ssl? + status, headers, body = @app.call(env) + headers.reverse_merge!(hsts_headers) + flag_cookies_as_secure!(headers) + [status, headers, body] + else + redirect_to_https(request) + end + end + + private + def redirect_to_https(request) + host = @host || request.host + port = @port || request.port + + location = "https://#{host}" + location << ":#{port}" if port != 80 + location << request.fullpath + + headers = { 'Content-Type' => 'text/html', 'Location' => location } + + [301, headers, []] + end + + # http://tools.ietf.org/html/draft-hodges-strict-transport-sec-02 + def hsts_headers + if @hsts + value = "max-age=#{@hsts[:expires].to_i}" + value += "; includeSubDomains" if @hsts[:subdomains] + { 'Strict-Transport-Security' => value } + else + {} + end + end + + def flag_cookies_as_secure!(headers) + if cookies = headers['Set-Cookie'] + cookies = cookies.split("\n") + + headers['Set-Cookie'] = cookies.map { |cookie| + if cookie !~ /;\s*secure\s*(;|$)/i + "#{cookie}; secure" + else + cookie + end + }.join("\n") + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/stack.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/stack.rb new file mode 100644 index 0000000..bbf734f --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/stack.rb @@ -0,0 +1,129 @@ +require "active_support/inflector/methods" +require "active_support/dependencies" + +module ActionDispatch + class MiddlewareStack + class Middleware + attr_reader :args, :block, :name, :classcache + + def initialize(klass_or_name, *args, &block) + @klass = nil + + if klass_or_name.respond_to?(:name) + @klass = klass_or_name + @name = @klass.name + else + @name = klass_or_name.to_s + end + + @classcache = ActiveSupport::Dependencies::Reference + @args, @block = args, block + end + + def klass + @klass || classcache[@name] + end + + def ==(middleware) + case middleware + when Middleware + klass == middleware.klass + when Class + klass == middleware + else + normalize(@name) == normalize(middleware) + end + end + + def inspect + klass.to_s + end + + def build(app) + klass.new(app, *args, &block) + end + + private + + def normalize(object) + object.to_s.strip.sub(/^::/, '') + end + end + + include Enumerable + + attr_accessor :middlewares + + def initialize(*args) + @middlewares = [] + yield(self) if block_given? + end + + def each + @middlewares.each { |x| yield x } + end + + def size + middlewares.size + end + + def last + middlewares.last + end + + def [](i) + middlewares[i] + end + + def unshift(*args, &block) + middleware = self.class::Middleware.new(*args, &block) + middlewares.unshift(middleware) + end + + def initialize_copy(other) + self.middlewares = other.middlewares.dup + end + + def insert(index, *args, &block) + index = assert_index(index, :before) + middleware = self.class::Middleware.new(*args, &block) + middlewares.insert(index, middleware) + end + + alias_method :insert_before, :insert + + def insert_after(index, *args, &block) + index = assert_index(index, :after) + insert(index + 1, *args, &block) + end + + def swap(target, *args, &block) + index = assert_index(target, :before) + insert(index, *args, &block) + middlewares.delete_at(index + 1) + end + + def delete(target) + middlewares.delete target + end + + def use(*args, &block) + middleware = self.class::Middleware.new(*args, &block) + middlewares.push(middleware) + end + + def build(app = nil, &block) + app ||= block + raise "MiddlewareStack#build requires an app" unless app + middlewares.freeze.reverse.inject(app) { |a, e| e.build(a) } + end + + protected + + def assert_index(index, where) + i = index.is_a?(Integer) ? index : middlewares.index(index) + raise "No such middleware to insert #{where}: #{index.inspect}" unless i + i + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/static.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/static.rb new file mode 100644 index 0000000..fcfbac5 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/static.rb @@ -0,0 +1,123 @@ +require 'rack/utils' +require 'active_support/core_ext/uri' + +module ActionDispatch + # This middleware returns a file's contents from disk in the body response. + # When initialized it can accept an optional 'Cache-Control' header which + # will be set when a response containing a file's contents is delivered. + # + # This middleware will render the file specified in `env["PATH_INFO"]` + # where the base path is in the +root+ directory. For example if the +root+ + # is set to `public/` then a request with `env["PATH_INFO"]` of + # `assets/application.js` will return a response with contents of a file + # located at `public/assets/application.js` if the file exists. If the file + # does not exist a 404 "File not Found" response will be returned. + class FileHandler + def initialize(root, cache_control) + @root = root.chomp('/') + @compiled_root = /^#{Regexp.escape(root)}/ + headers = cache_control && { 'Cache-Control' => cache_control } + @file_server = ::Rack::File.new(@root, headers) + end + + def match?(path) + path = URI.parser.unescape(path) + return false unless valid_path?(path) + + paths = [path, "#{path}#{ext}", "#{path}/index#{ext}"].map { |v| + Rack::Utils.clean_path_info v + } + + if match = paths.detect { |p| + path = File.join(@root, p.force_encoding('UTF-8')) + begin + File.file?(path) && File.readable?(path) + rescue SystemCallError + false + end + + } + return ::Rack::Utils.escape(match) + end + end + + def call(env) + path = env['PATH_INFO'] + gzip_path = gzip_file_path(path) + + if gzip_path && gzip_encoding_accepted?(env) + env['PATH_INFO'] = gzip_path + status, headers, body = @file_server.call(env) + if status == 304 + return [status, headers, body] + end + headers['Content-Encoding'] = 'gzip' + headers['Content-Type'] = content_type(path) + else + status, headers, body = @file_server.call(env) + end + + headers['Vary'] = 'Accept-Encoding' if gzip_path + + return [status, headers, body] + ensure + env['PATH_INFO'] = path + end + + private + def ext + ::ActionController::Base.default_static_extension + end + + def content_type(path) + ::Rack::Mime.mime_type(::File.extname(path), 'text/plain') + end + + def gzip_encoding_accepted?(env) + env['HTTP_ACCEPT_ENCODING'] =~ /\bgzip\b/i + end + + def gzip_file_path(path) + can_gzip_mime = content_type(path) =~ /\A(?:text\/|application\/javascript)/ + gzip_path = "#{path}.gz" + if can_gzip_mime && File.exist?(File.join(@root, ::Rack::Utils.unescape(gzip_path))) + gzip_path + else + false + end + end + + def valid_path?(path) + path.valid_encoding? && !path.include?("\0") + end + end + + # This middleware will attempt to return the contents of a file's body from + # disk in the response. If a file is not found on disk, the request will be + # delegated to the application stack. This middleware is commonly initialized + # to serve assets from a server's `public/` directory. + # + # This middleware verifies the path to ensure that only files + # living in the root directory can be rendered. A request cannot + # produce a directory traversal using this middleware. Only 'GET' and 'HEAD' + # requests will result in a file being returned. + class Static + def initialize(app, path, cache_control=nil) + @app = app + @file_handler = FileHandler.new(path, cache_control) + end + + def call(env) + case env['REQUEST_METHOD'] + when 'GET', 'HEAD' + path = env['PATH_INFO'].chomp('/') + if match = @file_handler.match?(path) + env["PATH_INFO"] = match + return @file_handler.call(env) + end + end + + @app.call(env) + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb new file mode 100644 index 0000000..db219c8 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb @@ -0,0 +1,34 @@ +<% unless @exception.blamed_files.blank? %> + <% if (hide = @exception.blamed_files.length > 8) %> + Toggle blamed files + <% end %> +
><%= @exception.describe_blame %>
+<% end %> + +<% + clean_params = @request.filtered_parameters.clone + clean_params.delete("action") + clean_params.delete("controller") + + request_dump = clean_params.empty? ? 'None' : clean_params.inspect.gsub(',', ",\n") + + def debug_hash(object) + object.to_hash.sort_by { |k, _| k.to_s }.map { |k, v| "#{k}: #{v.inspect rescue $!.message}" }.join("\n") + end unless self.class.method_defined?(:debug_hash) +%> + +

Request

+

Parameters:

<%= request_dump %>
+ +
+ + +
+ +
+ + +
+ +

Response

+

Headers:

<%= defined?(@response) ? @response.headers.inspect.gsub(',', ",\n") : 'None' %>
diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb new file mode 100644 index 0000000..396768e --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb @@ -0,0 +1,23 @@ +<% + clean_params = @request.filtered_parameters.clone + clean_params.delete("action") + clean_params.delete("controller") + + request_dump = clean_params.empty? ? 'None' : clean_params.inspect.gsub(',', ",\n") + + def debug_hash(object) + object.to_hash.sort_by { |k, _| k.to_s }.map { |k, v| "#{k}: #{v.inspect rescue $!.message}" }.join("\n") + end unless self.class.method_defined?(:debug_hash) +%> + +Request parameters +<%= request_dump %> + +Session dump +<%= debug_hash @request.session %> + +Env dump +<%= debug_hash @request.env.slice(*@request.class::ENV_METHODS) %> + +Response headers +<%= defined?(@response) ? @response.headers.inspect.gsub(',', ",\n") : 'None' %> diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/_source.erb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/_source.erb new file mode 100644 index 0000000..e7b913b --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/_source.erb @@ -0,0 +1,27 @@ +<% @source_extracts.each_with_index do |source_extract, index| %> + <% if source_extract[:code] %> +
" id="frame-source-<%=index%>"> +
+ Extracted source (around line #<%= source_extract[:line_number] %>): +
+
+ + + + + +
+
+                <% source_extract[:code].each_key do |line_number| %>
+<%= line_number -%>
+                <% end %>
+              
+
+
+<% source_extract[:code].each do |line, source| -%>
"><%= source -%>
<% end -%> +
+
+
+
+ <% end %> +<% end %> diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb new file mode 100644 index 0000000..ab57b11 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb @@ -0,0 +1,52 @@ +<% names = @traces.keys %> + +

Rails.root: <%= defined?(Rails) && Rails.respond_to?(:root) ? Rails.root : "unset" %>

+ +
+ <% names.each do |name| %> + <% + show = "show('#{name.gsub(/\s/, '-')}');" + hide = (names - [name]).collect {|hide_name| "hide('#{hide_name.gsub(/\s/, '-')}');"} + %> + <%= name %> <%= '|' unless names.last == name %> + <% end %> + + <% @traces.each do |name, trace| %> +
+
<% trace.each do |frame| %><%= frame[:trace] %>
<% end %>
+
+ <% end %> + + +
diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb new file mode 100644 index 0000000..c0b5306 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb @@ -0,0 +1,9 @@ +Rails.root: <%= defined?(Rails) && Rails.respond_to?(:root) ? Rails.root : "unset" %> + +<% @traces.each do |name, trace| %> +<% if trace.any? %> +<%= name %> +<%= trace.map { |t| t[:trace] }.join("\n") %> + +<% end %> +<% end %> diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb new file mode 100644 index 0000000..f154021 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb @@ -0,0 +1,16 @@ +
+

+ <%= @exception.class.to_s %> + <% if @request.parameters['controller'] %> + in <%= @request.parameters['controller'].camelize %>Controller<% if @request.parameters['action'] %>#<%= @request.parameters['action'] %><% end %> + <% end %> +

+
+ +
+

<%= h @exception.message %>

+ + <%= render template: "rescues/_source" %> + <%= render template: "rescues/_trace" %> + <%= render template: "rescues/_request_and_response" %> +
diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb new file mode 100644 index 0000000..603de54 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb @@ -0,0 +1,9 @@ +<%= @exception.class.to_s %><% + if @request.parameters['controller'] +%> in <%= @request.parameters['controller'].camelize %>Controller<% if @request.parameters['action'] %>#<%= @request.parameters['action'] %><% end %> +<% end %> + +<%= @exception.message %> +<%= render template: "rescues/_source" %> +<%= render template: "rescues/_trace" %> +<%= render template: "rescues/_request_and_response" %> diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/layout.erb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/layout.erb new file mode 100644 index 0000000..e0509f5 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/layout.erb @@ -0,0 +1,160 @@ + + + + + Action Controller: Exception caught + + + + + + +<%= yield %> + + + diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb new file mode 100644 index 0000000..2a65fd0 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb @@ -0,0 +1,11 @@ +
+

Template is missing

+
+ +
+

<%= h @exception.message %>

+ + <%= render template: "rescues/_source" %> + <%= render template: "rescues/_trace" %> + <%= render template: "rescues/_request_and_response" %> +
diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/missing_template.text.erb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/missing_template.text.erb new file mode 100644 index 0000000..ae62d9e --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/missing_template.text.erb @@ -0,0 +1,3 @@ +Template is missing + +<%= @exception.message %> diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb new file mode 100644 index 0000000..55dd5dd --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb @@ -0,0 +1,32 @@ +
+

Routing Error

+
+
+

<%= h @exception.message %>

+ <% unless @exception.failures.empty? %> +

+

Failure reasons:

+
    + <% @exception.failures.each do |route, reason| %> +
  1. <%= route.inspect.delete('\\') %> failed because <%= reason.downcase %>
  2. + <% end %> +
+

+ <% end %> + + <%= render template: "rescues/_trace" %> + + <% if @routes_inspector %> +

+ Routes +

+ +

+ Routes match in priority from top to bottom +

+ + <%= @routes_inspector.format(ActionDispatch::Routing::HtmlTableFormatter.new(self)) %> + <% end %> + + <%= render template: "rescues/_request_and_response" %> +
diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/routing_error.text.erb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/routing_error.text.erb new file mode 100644 index 0000000..f6e4dac --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/routing_error.text.erb @@ -0,0 +1,11 @@ +Routing Error + +<%= @exception.message %> +<% unless @exception.failures.empty? %> +Failure reasons: +<% @exception.failures.each do |route, reason| %> + - <%= route.inspect.delete('\\') %> failed because <%= reason.downcase %> +<% end %> +<% end %> + +<%= render template: "rescues/_trace", format: :text %> diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb new file mode 100644 index 0000000..c1e8b6c --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb @@ -0,0 +1,20 @@ +
+

+ <%= @exception.original_exception.class.to_s %> in + <%= @request.parameters["controller"].camelize if @request.parameters["controller"] %>#<%= @request.parameters["action"] %> +

+
+ +
+

+ Showing <%= @exception.file_name %> where line #<%= @exception.line_number %> raised: +

+
<%= h @exception.message %>
+ + <%= render template: "rescues/_source" %> + +

<%= @exception.sub_template_message %>

+ + <%= render template: "rescues/_trace" %> + <%= render template: "rescues/_request_and_response" %> +
diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb new file mode 100644 index 0000000..77bcd26 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb @@ -0,0 +1,7 @@ +<%= @exception.original_exception.class.to_s %> in <%= @request.parameters["controller"].camelize if @request.parameters["controller"] %>#<%= @request.parameters["action"] %> + +Showing <%= @exception.file_name %> where line #<%= @exception.line_number %> raised: +<%= @exception.message %> +<%= @exception.sub_template_message %> +<%= render template: "rescues/_trace", format: :text %> +<%= render template: "rescues/_request_and_response", format: :text %> diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb new file mode 100644 index 0000000..259fb2b --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb @@ -0,0 +1,6 @@ +
+

Unknown action

+
+
+

<%= h @exception.message %>

+
diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb new file mode 100644 index 0000000..83973ad --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb @@ -0,0 +1,3 @@ +Unknown action + +<%= @exception.message %> diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/routes/_route.html.erb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/routes/_route.html.erb new file mode 100644 index 0000000..24e44f3 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/routes/_route.html.erb @@ -0,0 +1,16 @@ + + + <% if route[:name].present? %> + <%= route[:name] %>_path + <% end %> + + + <%= route[:verb] %> + + + <%= route[:path] %> + + + <%= route[:reqs] %> + + diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/routes/_table.html.erb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/routes/_table.html.erb new file mode 100644 index 0000000..5cee0b5 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/routes/_table.html.erb @@ -0,0 +1,200 @@ +<% content_for :style do %> + #route_table { + margin: 0; + border-collapse: collapse; + } + + #route_table thead tr { + border-bottom: 2px solid #ddd; + } + + #route_table thead tr.bottom { + border-bottom: none; + } + + #route_table thead tr.bottom th { + padding: 10px 0; + line-height: 15px; + } + + #route_table tbody tr { + border-bottom: 1px solid #ddd; + } + + #route_table tbody tr:nth-child(odd) { + background: #f2f2f2; + } + + #route_table tbody.exact_matches, + #route_table tbody.fuzzy_matches { + background-color: LightGoldenRodYellow; + border-bottom: solid 2px SlateGrey; + } + + #route_table tbody.exact_matches tr, + #route_table tbody.fuzzy_matches tr { + background: none; + border-bottom: none; + } + + #route_table td { + padding: 4px 30px; + } + + #path_search { + width: 80%; + font-size: inherit; + } +<% end %> + + + + + + + + + + + + + + + + + + + + + + <%= yield %> + +
HelperHTTP VerbPathController#Action
<%# Helper %> + <%= link_to "Path", "#", 'data-route-helper' => '_path', + title: "Returns a relative path (without the http or domain)" %> / + <%= link_to "Url", "#", 'data-route-helper' => '_url', + title: "Returns an absolute url (with the http and domain)" %> + <%# HTTP Verb %> + <%# Path %> + <%= search_field(:path, nil, id: 'search', placeholder: "Path Match") %> + <%# Controller#action %> +
+ + diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/railtie.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/railtie.rb new file mode 100644 index 0000000..8cde5eb --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/railtie.rb @@ -0,0 +1,47 @@ +require "action_dispatch" + +module ActionDispatch + class Railtie < Rails::Railtie # :nodoc: + config.action_dispatch = ActiveSupport::OrderedOptions.new + config.action_dispatch.x_sendfile_header = nil + config.action_dispatch.ip_spoofing_check = true + config.action_dispatch.show_exceptions = true + config.action_dispatch.tld_length = 1 + config.action_dispatch.ignore_accept_header = false + config.action_dispatch.rescue_templates = { } + config.action_dispatch.rescue_responses = { } + config.action_dispatch.default_charset = nil + config.action_dispatch.rack_cache = false + config.action_dispatch.http_auth_salt = 'http authentication' + config.action_dispatch.signed_cookie_salt = 'signed cookie' + config.action_dispatch.encrypted_cookie_salt = 'encrypted cookie' + config.action_dispatch.encrypted_signed_cookie_salt = 'signed encrypted cookie' + config.action_dispatch.perform_deep_munge = true + + config.action_dispatch.default_headers = { + 'X-Frame-Options' => 'SAMEORIGIN', + 'X-XSS-Protection' => '1; mode=block', + 'X-Content-Type-Options' => 'nosniff' + } + + config.eager_load_namespaces << ActionDispatch + + initializer "action_dispatch.configure" do |app| + ActionDispatch::Http::URL.tld_length = app.config.action_dispatch.tld_length + ActionDispatch::Request.ignore_accept_header = app.config.action_dispatch.ignore_accept_header + ActionDispatch::Request::Utils.perform_deep_munge = app.config.action_dispatch.perform_deep_munge + ActionDispatch::Response.default_charset = app.config.action_dispatch.default_charset || app.config.encoding + ActionDispatch::Response.default_headers = app.config.action_dispatch.default_headers + + ActionDispatch::ExceptionWrapper.rescue_responses.merge!(config.action_dispatch.rescue_responses) + ActionDispatch::ExceptionWrapper.rescue_templates.merge!(config.action_dispatch.rescue_templates) + + config.action_dispatch.always_write_cookie = Rails.env.development? if config.action_dispatch.always_write_cookie.nil? + ActionDispatch::Cookies::CookieJar.always_write_cookie = config.action_dispatch.always_write_cookie + + ActionDispatch.test_app = app + + ActionDispatch::Routing::RouteSet.relative_url_root = app.config.relative_url_root + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/request/session.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/request/session.rb new file mode 100644 index 0000000..973627f --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/request/session.rb @@ -0,0 +1,193 @@ +require 'rack/session/abstract/id' + +module ActionDispatch + class Request < Rack::Request + # Session is responsible for lazily loading the session from store. + class Session # :nodoc: + ENV_SESSION_KEY = Rack::Session::Abstract::ENV_SESSION_KEY # :nodoc: + ENV_SESSION_OPTIONS_KEY = Rack::Session::Abstract::ENV_SESSION_OPTIONS_KEY # :nodoc: + + # Singleton object used to determine if an optional param wasn't specified + Unspecified = Object.new + + def self.create(store, env, default_options) + session_was = find env + session = Request::Session.new(store, env) + session.merge! session_was if session_was + + set(env, session) + Options.set(env, Request::Session::Options.new(store, env, default_options)) + session + end + + def self.find(env) + env[ENV_SESSION_KEY] + end + + def self.set(env, session) + env[ENV_SESSION_KEY] = session + end + + class Options #:nodoc: + def self.set(env, options) + env[ENV_SESSION_OPTIONS_KEY] = options + end + + def self.find(env) + env[ENV_SESSION_OPTIONS_KEY] + end + + def initialize(by, env, default_options) + @by = by + @env = env + @delegate = default_options.dup + end + + def [](key) + if key == :id + @delegate.fetch(key) { + @delegate[:id] = @by.send(:extract_session_id, @env) + } + else + @delegate[key] + end + end + + def []=(k,v); @delegate[k] = v; end + def to_hash; @delegate.dup; end + def values_at(*args); @delegate.values_at(*args); end + end + + def initialize(by, env) + @by = by + @env = env + @delegate = {} + @loaded = false + @exists = nil # we haven't checked yet + end + + def id + options[:id] + end + + def options + Options.find @env + end + + def destroy + clear + options = self.options || {} + new_sid = @by.send(:destroy_session, @env, options[:id], options) + options[:id] = new_sid # Reset session id with a new value or nil + + # Load the new sid to be written with the response + @loaded = false + load_for_write! + end + + def [](key) + load_for_read! + @delegate[key.to_s] + end + + def has_key?(key) + load_for_read! + @delegate.key?(key.to_s) + end + alias :key? :has_key? + alias :include? :has_key? + + def keys + @delegate.keys + end + + def values + @delegate.values + end + + def []=(key, value) + load_for_write! + @delegate[key.to_s] = value + end + + def clear + load_for_write! + @delegate.clear + end + + def to_hash + load_for_read! + @delegate.dup.delete_if { |_,v| v.nil? } + end + + def update(hash) + load_for_write! + @delegate.update stringify_keys(hash) + end + + def delete(key) + load_for_write! + @delegate.delete key.to_s + end + + def fetch(key, default=Unspecified, &block) + load_for_read! + if default == Unspecified + @delegate.fetch(key.to_s, &block) + else + @delegate.fetch(key.to_s, default, &block) + end + end + + def inspect + if loaded? + super + else + "#<#{self.class}:0x#{(object_id << 1).to_s(16)} not yet loaded>" + end + end + + def exists? + return @exists unless @exists.nil? + @exists = @by.send(:session_exists?, @env) + end + + def loaded? + @loaded + end + + def empty? + load_for_read! + @delegate.empty? + end + + def merge!(other) + load_for_write! + @delegate.merge!(other) + end + + private + + def load_for_read! + load! if !loaded? && exists? + end + + def load_for_write! + load! unless loaded? + end + + def load! + id, session = @by.load_session @env + options[:id] = id + @delegate.replace(stringify_keys(session)) + @loaded = true + end + + def stringify_keys(other) + other.each_with_object({}) { |(key, value), hash| + hash[key.to_s] = value + } + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/request/utils.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/request/utils.rb new file mode 100644 index 0000000..9d4f1aa --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/request/utils.rb @@ -0,0 +1,35 @@ +module ActionDispatch + class Request < Rack::Request + class Utils # :nodoc: + + mattr_accessor :perform_deep_munge + self.perform_deep_munge = true + + class << self + # Remove nils from the params hash + def deep_munge(hash, keys = []) + return hash unless perform_deep_munge + + hash.each do |k, v| + keys << k + case v + when Array + v.grep(Hash) { |x| deep_munge(x, keys) } + v.compact! + if v.empty? + hash[k] = nil + ActiveSupport::Notifications.instrument("deep_munge.action_controller", keys: keys) + end + when Hash + deep_munge(v, keys) + end + keys.pop + end + + hash + end + end + end + end +end + diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/routing.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/routing.rb new file mode 100644 index 0000000..ce03164 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/routing.rb @@ -0,0 +1,261 @@ +# encoding: UTF-8 +require 'active_support/core_ext/object/to_param' +require 'active_support/core_ext/regexp' +require 'active_support/dependencies/autoload' + +module ActionDispatch + # The routing module provides URL rewriting in native Ruby. It's a way to + # redirect incoming requests to controllers and actions. This replaces + # mod_rewrite rules. Best of all, Rails' \Routing works with any web server. + # Routes are defined in config/routes.rb. + # + # Think of creating routes as drawing a map for your requests. The map tells + # them where to go based on some predefined pattern: + # + # Rails.application.routes.draw do + # Pattern 1 tells some request to go to one place + # Pattern 2 tell them to go to another + # ... + # end + # + # The following symbols are special: + # + # :controller maps to your controller name + # :action maps to an action with your controllers + # + # Other names simply map to a parameter as in the case of :id. + # + # == Resources + # + # Resource routing allows you to quickly declare all of the common routes + # for a given resourceful controller. Instead of declaring separate routes + # for your +index+, +show+, +new+, +edit+, +create+, +update+ and +destroy+ + # actions, a resourceful route declares them in a single line of code: + # + # resources :photos + # + # Sometimes, you have a resource that clients always look up without + # referencing an ID. A common example, /profile always shows the profile of + # the currently logged in user. In this case, you can use a singular resource + # to map /profile (rather than /profile/:id) to the show action. + # + # resource :profile + # + # It's common to have resources that are logically children of other + # resources: + # + # resources :magazines do + # resources :ads + # end + # + # You may wish to organize groups of controllers under a namespace. Most + # commonly, you might group a number of administrative controllers under + # an +admin+ namespace. You would place these controllers under the + # app/controllers/admin directory, and you can group them together + # in your router: + # + # namespace "admin" do + # resources :posts, :comments + # end + # + # Alternately, you can add prefixes to your path without using a separate + # directory by using +scope+. +scope+ takes additional options which + # apply to all enclosed routes. + # + # scope path: "/cpanel", as: 'admin' do + # resources :posts, :comments + # end + # + # For more, see Routing::Mapper::Resources#resources, + # Routing::Mapper::Scoping#namespace, and + # Routing::Mapper::Scoping#scope. + # + # == Non-resourceful routes + # + # For routes that don't fit the resources mold, you can use the HTTP helper + # methods get, post, patch, put and delete. + # + # get 'post/:id' => 'posts#show' + # post 'post/:id' => 'posts#create_comment' + # + # If your route needs to respond to more than one HTTP method (or all methods) then using the + # :via option on match is preferable. + # + # match 'post/:id' => 'posts#show', via: [:get, :post] + # + # Now, if you POST to /posts/:id, it will route to the create_comment action. A GET on the same + # URL will route to the show action. + # + # == Named routes + # + # Routes can be named by passing an :as option, + # allowing for easy reference within your source as +name_of_route_url+ + # for the full URL and +name_of_route_path+ for the URI path. + # + # Example: + # + # # In routes.rb + # get '/login' => 'accounts#login', as: 'login' + # + # # With render, redirect_to, tests, etc. + # redirect_to login_url + # + # Arguments can be passed as well. + # + # redirect_to show_item_path(id: 25) + # + # Use root as a shorthand to name a route for the root path "/". + # + # # In routes.rb + # root to: 'blogs#index' + # + # # would recognize http://www.example.com/ as + # params = { controller: 'blogs', action: 'index' } + # + # # and provide these named routes + # root_url # => 'http://www.example.com/' + # root_path # => '/' + # + # Note: when using +controller+, the route is simply named after the + # method you call on the block parameter rather than map. + # + # # In routes.rb + # controller :blog do + # get 'blog/show' => :list + # get 'blog/delete' => :delete + # get 'blog/edit/:id' => :edit + # end + # + # # provides named routes for show, delete, and edit + # link_to @article.title, show_path(id: @article.id) + # + # == Pretty URLs + # + # Routes can generate pretty URLs. For example: + # + # get '/articles/:year/:month/:day' => 'articles#find_by_id', constraints: { + # year: /\d{4}/, + # month: /\d{1,2}/, + # day: /\d{1,2}/ + # } + # + # Using the route above, the URL "http://localhost:3000/articles/2005/11/06" + # maps to + # + # params = {year: '2005', month: '11', day: '06'} + # + # == Regular Expressions and parameters + # You can specify a regular expression to define a format for a parameter. + # + # controller 'geocode' do + # get 'geocode/:postalcode' => :show, constraints: { + # postalcode: /\d{5}(-\d{4})?/ + # } + # + # Constraints can include the 'ignorecase' and 'extended syntax' regular + # expression modifiers: + # + # controller 'geocode' do + # get 'geocode/:postalcode' => :show, constraints: { + # postalcode: /hx\d\d\s\d[a-z]{2}/i + # } + # end + # + # controller 'geocode' do + # get 'geocode/:postalcode' => :show, constraints: { + # postalcode: /# Postcode format + # \d{5} #Prefix + # (-\d{4})? #Suffix + # /x + # } + # end + # + # Using the multiline modifier will raise an +ArgumentError+. + # Encoding regular expression modifiers are silently ignored. The + # match will always use the default encoding or ASCII. + # + # == External redirects + # + # You can redirect any path to another path using the redirect helper in your router: + # + # get "/stories" => redirect("/posts") + # + # == Unicode character routes + # + # You can specify unicode character routes in your router: + # + # get "ã“ã‚“ã«ã¡ã¯" => "welcome#index" + # + # == Routing to Rack Applications + # + # Instead of a String, like posts#index, which corresponds to the + # index action in the PostsController, you can specify any Rack application + # as the endpoint for a matcher: + # + # get "/application.js" => Sprockets + # + # == Reloading routes + # + # You can reload routes if you feel you must: + # + # Rails.application.reload_routes! + # + # This will clear all named routes and reload routes.rb if the file has been modified from + # last load. To absolutely force reloading, use reload!. + # + # == Testing Routes + # + # The two main methods for testing your routes: + # + # === +assert_routing+ + # + # def test_movie_route_properly_splits + # opts = {controller: "plugin", action: "checkout", id: "2"} + # assert_routing "plugin/checkout/2", opts + # end + # + # +assert_routing+ lets you test whether or not the route properly resolves into options. + # + # === +assert_recognizes+ + # + # def test_route_has_options + # opts = {controller: "plugin", action: "show", id: "12"} + # assert_recognizes opts, "/plugins/show/12" + # end + # + # Note the subtle difference between the two: +assert_routing+ tests that + # a URL fits options while +assert_recognizes+ tests that a URL + # breaks into parameters properly. + # + # In tests you can simply pass the URL or named route to +get+ or +post+. + # + # def send_to_jail + # get '/jail' + # assert_response :success + # assert_template "jail/front" + # end + # + # def goes_to_login + # get login_url + # #... + # end + # + # == View a list of all your routes + # + # rake routes + # + # Target specific controllers by prefixing the command with CONTROLLER=x. + # + module Routing + extend ActiveSupport::Autoload + + autoload :Mapper + autoload :RouteSet + autoload :RoutesProxy + autoload :UrlFor + autoload :PolymorphicRoutes + + SEPARATORS = %w( / . ? ) #:nodoc: + HTTP_METHODS = [:get, :head, :post, :patch, :put, :delete, :options] #:nodoc: + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/routing/endpoint.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/routing/endpoint.rb new file mode 100644 index 0000000..88aa13c --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/routing/endpoint.rb @@ -0,0 +1,10 @@ +module ActionDispatch + module Routing + class Endpoint # :nodoc: + def dispatcher?; false; end + def redirect?; false; end + def matches?(req); true; end + def app; self; end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/routing/inspector.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/routing/inspector.rb new file mode 100644 index 0000000..cfe2237 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/routing/inspector.rb @@ -0,0 +1,234 @@ +require 'delegate' +require 'active_support/core_ext/string/strip' + +module ActionDispatch + module Routing + class RouteWrapper < SimpleDelegator + def endpoint + app.dispatcher? ? "#{controller}##{action}" : rack_app.inspect + end + + def constraints + requirements.except(:controller, :action) + end + + def rack_app + app.app + end + + def verb + super.source.gsub(/[$^]/, '') + end + + def path + super.spec.to_s + end + + def name + super.to_s + end + + def regexp + __getobj__.path.to_regexp + end + + def json_regexp + str = regexp.inspect. + sub('\\A' , '^'). + sub('\\Z' , '$'). + sub('\\z' , '$'). + sub(/^\// , ''). + sub(/\/[a-z]*$/ , ''). + gsub(/\(\?#.+\)/ , ''). + gsub(/\(\?-\w+:/ , '('). + gsub(/\s/ , '') + Regexp.new(str).source + end + + def reqs + @reqs ||= begin + reqs = endpoint + reqs += " #{constraints}" unless constraints.empty? + reqs + end + end + + def controller + requirements[:controller] || ':controller' + end + + def action + requirements[:action] || ':action' + end + + def internal? + controller.to_s =~ %r{\Arails/(info|mailers|welcome)} || path =~ %r{\A#{Rails.application.config.assets.prefix}\z} + end + + def engine? + rack_app.respond_to?(:routes) + end + end + + ## + # This class is just used for displaying route information when someone + # executes `rake routes` or looks at the RoutingError page. + # People should not use this class. + class RoutesInspector # :nodoc: + def initialize(routes) + @engines = {} + @routes = routes + end + + def format(formatter, filter = nil) + routes_to_display = filter_routes(filter) + + routes = collect_routes(routes_to_display) + + if routes.none? + formatter.no_routes + return formatter.result + end + + formatter.header routes + formatter.section routes + + @engines.each do |name, engine_routes| + formatter.section_title "Routes for #{name}" + formatter.section engine_routes + end + + formatter.result + end + + private + + def filter_routes(filter) + if filter + @routes.select { |route| route.defaults[:controller] == filter } + else + @routes + end + end + + def collect_routes(routes) + routes.collect do |route| + RouteWrapper.new(route) + end.reject do |route| + route.internal? + end.collect do |route| + collect_engine_routes(route) + + { name: route.name, + verb: route.verb, + path: route.path, + reqs: route.reqs, + regexp: route.json_regexp } + end + end + + def collect_engine_routes(route) + name = route.endpoint + return unless route.engine? + return if @engines[name] + + routes = route.rack_app.routes + if routes.is_a?(ActionDispatch::Routing::RouteSet) + @engines[name] = collect_routes(routes.routes) + end + end + end + + class ConsoleFormatter + def initialize + @buffer = [] + end + + def result + @buffer.join("\n") + end + + def section_title(title) + @buffer << "\n#{title}:" + end + + def section(routes) + @buffer << draw_section(routes) + end + + def header(routes) + @buffer << draw_header(routes) + end + + def no_routes + @buffer << <<-MESSAGE.strip_heredoc + You don't have any routes defined! + + Please add some routes in config/routes.rb. + + For more information about routes, see the Rails guide: http://guides.rubyonrails.org/routing.html. + MESSAGE + end + + private + def draw_section(routes) + header_lengths = ['Prefix', 'Verb', 'URI Pattern'].map(&:length) + name_width, verb_width, path_width = widths(routes).zip(header_lengths).map(&:max) + + routes.map do |r| + "#{r[:name].rjust(name_width)} #{r[:verb].ljust(verb_width)} #{r[:path].ljust(path_width)} #{r[:reqs]}" + end + end + + def draw_header(routes) + name_width, verb_width, path_width = widths(routes) + + "#{"Prefix".rjust(name_width)} #{"Verb".ljust(verb_width)} #{"URI Pattern".ljust(path_width)} Controller#Action" + end + + def widths(routes) + [routes.map { |r| r[:name].length }.max || 0, + routes.map { |r| r[:verb].length }.max || 0, + routes.map { |r| r[:path].length }.max || 0] + end + end + + class HtmlTableFormatter + def initialize(view) + @view = view + @buffer = [] + end + + def section_title(title) + @buffer << %(#{title}) + end + + def section(routes) + @buffer << @view.render(partial: "routes/route", collection: routes) + end + + # the header is part of the HTML page, so we don't construct it here. + def header(routes) + end + + def no_routes + @buffer << <<-MESSAGE.strip_heredoc +

You don't have any routes defined!

+ + MESSAGE + end + + def result + @view.raw @view.render(layout: "routes/table") { + @view.raw @buffer.join("\n") + } + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/routing/mapper.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/routing/mapper.rb new file mode 100644 index 0000000..2df4b9e --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/routing/mapper.rb @@ -0,0 +1,1980 @@ +require 'active_support/core_ext/hash/except' +require 'active_support/core_ext/hash/reverse_merge' +require 'active_support/core_ext/hash/slice' +require 'active_support/core_ext/enumerable' +require 'active_support/core_ext/array/extract_options' +require 'active_support/core_ext/module/remove_method' +require 'active_support/core_ext/string/filters' +require 'active_support/inflector' +require 'action_dispatch/routing/redirection' +require 'action_dispatch/routing/endpoint' +require 'active_support/deprecation' + +module ActionDispatch + module Routing + class Mapper + URL_OPTIONS = [:protocol, :subdomain, :domain, :host, :port] + + class Constraints < Endpoint #:nodoc: + attr_reader :app, :constraints + + def initialize(app, constraints, dispatcher_p) + # Unwrap Constraints objects. I don't actually think it's possible + # to pass a Constraints object to this constructor, but there were + # multiple places that kept testing children of this object. I + # *think* they were just being defensive, but I have no idea. + if app.is_a?(self.class) + constraints += app.constraints + app = app.app + end + + @dispatcher = dispatcher_p + + @app, @constraints, = app, constraints + end + + def dispatcher?; @dispatcher; end + + def matches?(req) + @constraints.all? do |constraint| + (constraint.respond_to?(:matches?) && constraint.matches?(req)) || + (constraint.respond_to?(:call) && constraint.call(*constraint_args(constraint, req))) + end + end + + def serve(req) + return [ 404, {'X-Cascade' => 'pass'}, [] ] unless matches?(req) + + if dispatcher? + @app.serve req + else + @app.call req.env + end + end + + private + def constraint_args(constraint, request) + constraint.arity == 1 ? [request] : [request.path_parameters, request] + end + end + + class Mapping #:nodoc: + ANCHOR_CHARACTERS_REGEX = %r{\A(\\A|\^)|(\\Z|\\z|\$)\Z} + + attr_reader :requirements, :conditions, :defaults + attr_reader :to, :default_controller, :default_action, :as, :anchor + + def self.build(scope, set, path, as, options) + options = scope[:options].merge(options) if scope[:options] + + options.delete :only + options.delete :except + options.delete :shallow_path + options.delete :shallow_prefix + options.delete :shallow + + defaults = (scope[:defaults] || {}).merge options.delete(:defaults) || {} + + new scope, set, path, defaults, as, options + end + + def initialize(scope, set, path, defaults, as, options) + @requirements, @conditions = {}, {} + @defaults = defaults + @set = set + + @to = options.delete :to + @default_controller = options.delete(:controller) || scope[:controller] + @default_action = options.delete(:action) || scope[:action] + @as = as + @anchor = options.delete :anchor + + formatted = options.delete :format + via = Array(options.delete(:via) { [] }) + options_constraints = options.delete :constraints + + path = normalize_path! path, formatted + ast = path_ast path + path_params = path_params ast + + options = normalize_options!(options, formatted, path_params, ast, scope[:module]) + + + split_constraints(path_params, scope[:constraints]) if scope[:constraints] + constraints = constraints(options, path_params) + + split_constraints path_params, constraints + + @blocks = blocks(options_constraints, scope[:blocks]) + + if options_constraints.is_a?(Hash) + split_constraints path_params, options_constraints + options_constraints.each do |key, default| + if URL_OPTIONS.include?(key) && (String === default || Fixnum === default) + @defaults[key] ||= default + end + end + end + + normalize_format!(formatted) + + @conditions[:path_info] = path + @conditions[:parsed_path_info] = ast + + add_request_method(via, @conditions) + normalize_defaults!(options) + end + + def to_route + [ app(@blocks), conditions, requirements, defaults, as, anchor ] + end + + private + + def normalize_path!(path, format) + path = Mapper.normalize_path(path) + + if format == true + "#{path}.:format" + elsif optional_format?(path, format) + "#{path}(.:format)" + else + path + end + end + + def optional_format?(path, format) + format != false && !path.include?(':format') && !path.end_with?('/') + end + + def normalize_options!(options, formatted, path_params, path_ast, modyoule) + # Add a constraint for wildcard route to make it non-greedy and match the + # optional format part of the route by default + if formatted != false + path_ast.grep(Journey::Nodes::Star) do |node| + options[node.name.to_sym] ||= /.+?/ + end + end + + if path_params.include?(:controller) + raise ArgumentError, ":controller segment is not allowed within a namespace block" if modyoule + + # Add a default constraint for :controller path segments that matches namespaced + # controllers with default routes like :controller/:action/:id(.:format), e.g: + # GET /admin/products/show/1 + # => { controller: 'admin/products', action: 'show', id: '1' } + options[:controller] ||= /.+?/ + end + + if to.respond_to? :call + options + else + to_endpoint = split_to to + controller = to_endpoint[0] || default_controller + action = to_endpoint[1] || default_action + + controller = add_controller_module(controller, modyoule) + + options.merge! check_controller_and_action(path_params, controller, action) + end + end + + def split_constraints(path_params, constraints) + constraints.each_pair do |key, requirement| + if path_params.include?(key) || key == :controller + verify_regexp_requirement(requirement) if requirement.is_a?(Regexp) + @requirements[key] = requirement + else + @conditions[key] = requirement + end + end + end + + def normalize_format!(formatted) + if formatted == true + @requirements[:format] ||= /.+/ + elsif Regexp === formatted + @requirements[:format] = formatted + @defaults[:format] = nil + elsif String === formatted + @requirements[:format] = Regexp.compile(formatted) + @defaults[:format] = formatted + end + end + + def verify_regexp_requirement(requirement) + if requirement.source =~ ANCHOR_CHARACTERS_REGEX + raise ArgumentError, "Regexp anchor characters are not allowed in routing requirements: #{requirement.inspect}" + end + + if requirement.multiline? + raise ArgumentError, "Regexp multiline option is not allowed in routing requirements: #{requirement.inspect}" + end + end + + def normalize_defaults!(options) + options.each_pair do |key, default| + unless Regexp === default + @defaults[key] = default + end + end + end + + def verify_callable_constraint(callable_constraint) + unless callable_constraint.respond_to?(:call) || callable_constraint.respond_to?(:matches?) + raise ArgumentError, "Invalid constraint: #{callable_constraint.inspect} must respond to :call or :matches?" + end + end + + def add_request_method(via, conditions) + return if via == [:all] + + if via.empty? + msg = "You should not use the `match` method in your router without specifying an HTTP method.\n" \ + "If you want to expose your action to both GET and POST, add `via: [:get, :post]` option.\n" \ + "If you want to expose your action to GET, use `get` in the router:\n" \ + " Instead of: match \"controller#action\"\n" \ + " Do: get \"controller#action\"" + raise ArgumentError, msg + end + + conditions[:request_method] = via.map { |m| m.to_s.dasherize.upcase } + end + + def app(blocks) + if to.respond_to?(:call) + Constraints.new(to, blocks, false) + elsif blocks.any? + Constraints.new(dispatcher(defaults), blocks, true) + else + dispatcher(defaults) + end + end + + def check_controller_and_action(path_params, controller, action) + hash = check_part(:controller, controller, path_params, {}) do |part| + translate_controller(part) { + message = "'#{part}' is not a supported controller name. This can lead to potential routing problems." + message << " See http://guides.rubyonrails.org/routing.html#specifying-a-controller-to-use" + + raise ArgumentError, message + } + end + + check_part(:action, action, path_params, hash) { |part| + part.is_a?(Regexp) ? part : part.to_s + } + end + + def check_part(name, part, path_params, hash) + if part + hash[name] = yield(part) + else + unless path_params.include?(name) + message = "Missing :#{name} key on routes definition, please check your routes." + raise ArgumentError, message + end + end + hash + end + + def split_to(to) + case to + when Symbol + ActiveSupport::Deprecation.warn(<<-MSG.squish) + Defining a route where `to` is a symbol is deprecated. + Please change `to: :#{to}` to `action: :#{to}`. + MSG + + [nil, to.to_s] + when /#/ then to.split('#') + when String + ActiveSupport::Deprecation.warn(<<-MSG.squish) + Defining a route where `to` is a controller without an action is deprecated. + Please change `to: '#{to}'` to `controller: '#{to}'`. + MSG + + [to, nil] + else + [] + end + end + + def add_controller_module(controller, modyoule) + if modyoule && !controller.is_a?(Regexp) + if controller =~ %r{\A/} + controller[1..-1] + else + [modyoule, controller].compact.join("/") + end + else + controller + end + end + + def translate_controller(controller) + return controller if Regexp === controller + return controller.to_s if controller =~ /\A[a-z_0-9][a-z_0-9\/]*\z/ + + yield + end + + def blocks(options_constraints, scope_blocks) + if options_constraints && !options_constraints.is_a?(Hash) + verify_callable_constraint(options_constraints) + [options_constraints] + else + scope_blocks || [] + end + end + + def constraints(options, path_params) + constraints = {} + required_defaults = [] + options.each_pair do |key, option| + if Regexp === option + constraints[key] = option + else + required_defaults << key unless path_params.include?(key) + end + end + @conditions[:required_defaults] = required_defaults + constraints + end + + def path_params(ast) + ast.grep(Journey::Nodes::Symbol).map { |n| n.name.to_sym } + end + + def path_ast(path) + parser = Journey::Parser.new + parser.parse path + end + + def dispatcher(defaults) + @set.dispatcher defaults + end + end + + # Invokes Journey::Router::Utils.normalize_path and ensure that + # (:locale) becomes (/:locale) instead of /(:locale). Except + # for root cases, where the latter is the correct one. + def self.normalize_path(path) + path = Journey::Router::Utils.normalize_path(path) + path.gsub!(%r{/(\(+)/?}, '\1/') unless path =~ %r{^/\(+[^)]+\)$} + path + end + + def self.normalize_name(name) + normalize_path(name)[1..-1].tr("/", "_") + end + + module Base + # You can specify what Rails should route "/" to with the root method: + # + # root to: 'pages#main' + # + # For options, see +match+, as +root+ uses it internally. + # + # You can also pass a string which will expand + # + # root 'pages#main' + # + # You should put the root route at the top of config/routes.rb, + # because this means it will be matched first. As this is the most popular route + # of most Rails applications, this is beneficial. + def root(options = {}) + match '/', { :as => :root, :via => :get }.merge!(options) + end + + # Matches a url pattern to one or more routes. + # + # You should not use the +match+ method in your router + # without specifying an HTTP method. + # + # If you want to expose your action to both GET and POST, use: + # + # # sets :controller, :action and :id in params + # match ':controller/:action/:id', via: [:get, :post] + # + # Note that +:controller+, +:action+ and +:id+ are interpreted as url + # query parameters and thus available through +params+ in an action. + # + # If you want to expose your action to GET, use +get+ in the router: + # + # Instead of: + # + # match ":controller/:action/:id" + # + # Do: + # + # get ":controller/:action/:id" + # + # Two of these symbols are special, +:controller+ maps to the controller + # and +:action+ to the controller's action. A pattern can also map + # wildcard segments (globs) to params: + # + # get 'songs/*category/:title', to: 'songs#show' + # + # # 'songs/rock/classic/stairway-to-heaven' sets + # # params[:category] = 'rock/classic' + # # params[:title] = 'stairway-to-heaven' + # + # To match a wildcard parameter, it must have a name assigned to it. + # Without a variable name to attach the glob parameter to, the route + # can't be parsed. + # + # When a pattern points to an internal route, the route's +:action+ and + # +:controller+ should be set in options or hash shorthand. Examples: + # + # match 'photos/:id' => 'photos#show', via: :get + # match 'photos/:id', to: 'photos#show', via: :get + # match 'photos/:id', controller: 'photos', action: 'show', via: :get + # + # A pattern can also point to a +Rack+ endpoint i.e. anything that + # responds to +call+: + # + # match 'photos/:id', to: lambda {|hash| [200, {}, ["Coming soon"]] }, via: :get + # match 'photos/:id', to: PhotoRackApp, via: :get + # # Yes, controller actions are just rack endpoints + # match 'photos/:id', to: PhotosController.action(:show), via: :get + # + # Because requesting various HTTP verbs with a single action has security + # implications, you must either specify the actions in + # the via options or use one of the HttpHelpers[rdoc-ref:HttpHelpers] + # instead +match+ + # + # === Options + # + # Any options not seen here are passed on as params with the url. + # + # [:controller] + # The route's controller. + # + # [:action] + # The route's action. + # + # [:param] + # Overrides the default resource identifier +:id+ (name of the + # dynamic segment used to generate the routes). + # You can access that segment from your controller using + # params[<:param>]. + # + # [:path] + # The path prefix for the routes. + # + # [:module] + # The namespace for :controller. + # + # match 'path', to: 'c#a', module: 'sekret', controller: 'posts', via: :get + # # => Sekret::PostsController + # + # See Scoping#namespace for its scope equivalent. + # + # [:as] + # The name used to generate routing helpers. + # + # [:via] + # Allowed HTTP verb(s) for route. + # + # match 'path', to: 'c#a', via: :get + # match 'path', to: 'c#a', via: [:get, :post] + # match 'path', to: 'c#a', via: :all + # + # [:to] + # Points to a +Rack+ endpoint. Can be an object that responds to + # +call+ or a string representing a controller's action. + # + # match 'path', to: 'controller#action', via: :get + # match 'path', to: lambda { |env| [200, {}, ["Success!"]] }, via: :get + # match 'path', to: RackApp, via: :get + # + # [:on] + # Shorthand for wrapping routes in a specific RESTful context. Valid + # values are +:member+, +:collection+, and +:new+. Only use within + # resource(s) block. For example: + # + # resource :bar do + # match 'foo', to: 'c#a', on: :member, via: [:get, :post] + # end + # + # Is equivalent to: + # + # resource :bar do + # member do + # match 'foo', to: 'c#a', via: [:get, :post] + # end + # end + # + # [:constraints] + # Constrains parameters with a hash of regular expressions + # or an object that responds to matches?. In addition, constraints + # other than path can also be specified with any object + # that responds to === (eg. String, Array, Range, etc.). + # + # match 'path/:id', constraints: { id: /[A-Z]\d{5}/ }, via: :get + # + # match 'json_only', constraints: { format: 'json' }, via: :get + # + # class Whitelist + # def matches?(request) request.remote_ip == '1.2.3.4' end + # end + # match 'path', to: 'c#a', constraints: Whitelist.new, via: :get + # + # See Scoping#constraints for more examples with its scope + # equivalent. + # + # [:defaults] + # Sets defaults for parameters + # + # # Sets params[:format] to 'jpg' by default + # match 'path', to: 'c#a', defaults: { format: 'jpg' }, via: :get + # + # See Scoping#defaults for its scope equivalent. + # + # [:anchor] + # Boolean to anchor a match pattern. Default is true. When set to + # false, the pattern matches any request prefixed with the given path. + # + # # Matches any request starting with 'path' + # match 'path', to: 'c#a', anchor: false, via: :get + # + # [:format] + # Allows you to specify the default value for optional +format+ + # segment or disable it by supplying +false+. + def match(path, options=nil) + end + + # Mount a Rack-based application to be used within the application. + # + # mount SomeRackApp, at: "some_route" + # + # Alternatively: + # + # mount(SomeRackApp => "some_route") + # + # For options, see +match+, as +mount+ uses it internally. + # + # All mounted applications come with routing helpers to access them. + # These are named after the class specified, so for the above example + # the helper is either +some_rack_app_path+ or +some_rack_app_url+. + # To customize this helper's name, use the +:as+ option: + # + # mount(SomeRackApp => "some_route", as: "exciting") + # + # This will generate the +exciting_path+ and +exciting_url+ helpers + # which can be used to navigate to this mounted app. + def mount(app, options = nil) + if options + path = options.delete(:at) + else + unless Hash === app + raise ArgumentError, "must be called with mount point" + end + + options = app + app, path = options.find { |k, _| k.respond_to?(:call) } + options.delete(app) if app + end + + raise "A rack application must be specified" unless path + + rails_app = rails_app? app + options[:as] ||= app_name(app, rails_app) + + target_as = name_for_action(options[:as], path) + options[:via] ||= :all + + match(path, options.merge(:to => app, :anchor => false, :format => false)) + + define_generate_prefix(app, target_as) if rails_app + self + end + + def default_url_options=(options) + @set.default_url_options = options + end + alias_method :default_url_options, :default_url_options= + + def with_default_scope(scope, &block) + scope(scope) do + instance_exec(&block) + end + end + + # Query if the following named route was already defined. + def has_named_route?(name) + @set.named_routes.routes[name.to_sym] + end + + private + def rails_app?(app) + app.is_a?(Class) && app < Rails::Railtie + end + + def app_name(app, rails_app) + if rails_app + app.railtie_name + elsif app.is_a?(Class) + class_name = app.name + ActiveSupport::Inflector.underscore(class_name).tr("/", "_") + end + end + + def define_generate_prefix(app, name) + _route = @set.named_routes.get name + _routes = @set + app.routes.define_mounted_helper(name) + app.routes.extend Module.new { + def optimize_routes_generation?; false; end + define_method :find_script_name do |options| + if options.key? :script_name + super(options) + else + prefix_options = options.slice(*_route.segment_keys) + prefix_options[:relative_url_root] = ''.freeze + # we must actually delete prefix segment keys to avoid passing them to next url_for + _route.segment_keys.each { |k| options.delete(k) } + _routes.url_helpers.send("#{name}_path", prefix_options) + end + end + } + end + end + + module HttpHelpers + # Define a route that only recognizes HTTP GET. + # For supported arguments, see match[rdoc-ref:Base#match] + # + # get 'bacon', to: 'food#bacon' + def get(*args, &block) + map_method(:get, args, &block) + end + + # Define a route that only recognizes HTTP POST. + # For supported arguments, see match[rdoc-ref:Base#match] + # + # post 'bacon', to: 'food#bacon' + def post(*args, &block) + map_method(:post, args, &block) + end + + # Define a route that only recognizes HTTP PATCH. + # For supported arguments, see match[rdoc-ref:Base#match] + # + # patch 'bacon', to: 'food#bacon' + def patch(*args, &block) + map_method(:patch, args, &block) + end + + # Define a route that only recognizes HTTP PUT. + # For supported arguments, see match[rdoc-ref:Base#match] + # + # put 'bacon', to: 'food#bacon' + def put(*args, &block) + map_method(:put, args, &block) + end + + # Define a route that only recognizes HTTP DELETE. + # For supported arguments, see match[rdoc-ref:Base#match] + # + # delete 'broccoli', to: 'food#broccoli' + def delete(*args, &block) + map_method(:delete, args, &block) + end + + private + def map_method(method, args, &block) + options = args.extract_options! + options[:via] = method + match(*args, options, &block) + self + end + end + + # You may wish to organize groups of controllers under a namespace. + # Most commonly, you might group a number of administrative controllers + # under an +admin+ namespace. You would place these controllers under + # the app/controllers/admin directory, and you can group them + # together in your router: + # + # namespace "admin" do + # resources :posts, :comments + # end + # + # This will create a number of routes for each of the posts and comments + # controller. For Admin::PostsController, Rails will create: + # + # GET /admin/posts + # GET /admin/posts/new + # POST /admin/posts + # GET /admin/posts/1 + # GET /admin/posts/1/edit + # PATCH/PUT /admin/posts/1 + # DELETE /admin/posts/1 + # + # If you want to route /posts (without the prefix /admin) to + # Admin::PostsController, you could use + # + # scope module: "admin" do + # resources :posts + # end + # + # or, for a single case + # + # resources :posts, module: "admin" + # + # If you want to route /admin/posts to +PostsController+ + # (without the Admin:: module prefix), you could use + # + # scope "/admin" do + # resources :posts + # end + # + # or, for a single case + # + # resources :posts, path: "/admin/posts" + # + # In each of these cases, the named routes remain the same as if you did + # not use scope. In the last case, the following paths map to + # +PostsController+: + # + # GET /admin/posts + # GET /admin/posts/new + # POST /admin/posts + # GET /admin/posts/1 + # GET /admin/posts/1/edit + # PATCH/PUT /admin/posts/1 + # DELETE /admin/posts/1 + module Scoping + # Scopes a set of routes to the given default options. + # + # Take the following route definition as an example: + # + # scope path: ":account_id", as: "account" do + # resources :projects + # end + # + # This generates helpers such as +account_projects_path+, just like +resources+ does. + # The difference here being that the routes generated are like /:account_id/projects, + # rather than /accounts/:account_id/projects. + # + # === Options + # + # Takes same options as Base#match and Resources#resources. + # + # # route /posts (without the prefix /admin) to Admin::PostsController + # scope module: "admin" do + # resources :posts + # end + # + # # prefix the posts resource's requests with '/admin' + # scope path: "/admin" do + # resources :posts + # end + # + # # prefix the routing helper name: +sekret_posts_path+ instead of +posts_path+ + # scope as: "sekret" do + # resources :posts + # end + def scope(*args) + options = args.extract_options!.dup + scope = {} + + options[:path] = args.flatten.join('/') if args.any? + options[:constraints] ||= {} + + unless nested_scope? + options[:shallow_path] ||= options[:path] if options.key?(:path) + options[:shallow_prefix] ||= options[:as] if options.key?(:as) + end + + if options[:constraints].is_a?(Hash) + defaults = options[:constraints].select do + |k, v| URL_OPTIONS.include?(k) && (v.is_a?(String) || v.is_a?(Fixnum)) + end + + (options[:defaults] ||= {}).reverse_merge!(defaults) + else + block, options[:constraints] = options[:constraints], {} + end + + @scope.options.each do |option| + if option == :blocks + value = block + elsif option == :options + value = options + else + value = options.delete(option) + end + + if value + scope[option] = send("merge_#{option}_scope", @scope[option], value) + end + end + + @scope = @scope.new scope + yield + self + ensure + @scope = @scope.parent + end + + # Scopes routes to a specific controller + # + # controller "food" do + # match "bacon", action: "bacon" + # end + def controller(controller, options={}) + options[:controller] = controller + scope(options) { yield } + end + + # Scopes routes to a specific namespace. For example: + # + # namespace :admin do + # resources :posts + # end + # + # This generates the following routes: + # + # admin_posts GET /admin/posts(.:format) admin/posts#index + # admin_posts POST /admin/posts(.:format) admin/posts#create + # new_admin_post GET /admin/posts/new(.:format) admin/posts#new + # edit_admin_post GET /admin/posts/:id/edit(.:format) admin/posts#edit + # admin_post GET /admin/posts/:id(.:format) admin/posts#show + # admin_post PATCH/PUT /admin/posts/:id(.:format) admin/posts#update + # admin_post DELETE /admin/posts/:id(.:format) admin/posts#destroy + # + # === Options + # + # The +:path+, +:as+, +:module+, +:shallow_path+ and +:shallow_prefix+ + # options all default to the name of the namespace. + # + # For options, see Base#match. For +:shallow_path+ option, see + # Resources#resources. + # + # # accessible through /sekret/posts rather than /admin/posts + # namespace :admin, path: "sekret" do + # resources :posts + # end + # + # # maps to Sekret::PostsController rather than Admin::PostsController + # namespace :admin, module: "sekret" do + # resources :posts + # end + # + # # generates +sekret_posts_path+ rather than +admin_posts_path+ + # namespace :admin, as: "sekret" do + # resources :posts + # end + def namespace(path, options = {}) + path = path.to_s + + defaults = { + module: path, + path: options.fetch(:path, path), + as: options.fetch(:as, path), + shallow_path: options.fetch(:path, path), + shallow_prefix: options.fetch(:as, path) + } + + scope(defaults.merge!(options)) { yield } + end + + # === Parameter Restriction + # Allows you to constrain the nested routes based on a set of rules. + # For instance, in order to change the routes to allow for a dot character in the +id+ parameter: + # + # constraints(id: /\d+\.\d+/) do + # resources :posts + # end + # + # Now routes such as +/posts/1+ will no longer be valid, but +/posts/1.1+ will be. + # The +id+ parameter must match the constraint passed in for this example. + # + # You may use this to also restrict other parameters: + # + # resources :posts do + # constraints(post_id: /\d+\.\d+/) do + # resources :comments + # end + # end + # + # === Restricting based on IP + # + # Routes can also be constrained to an IP or a certain range of IP addresses: + # + # constraints(ip: /192\.168\.\d+\.\d+/) do + # resources :posts + # end + # + # Any user connecting from the 192.168.* range will be able to see this resource, + # where as any user connecting outside of this range will be told there is no such route. + # + # === Dynamic request matching + # + # Requests to routes can be constrained based on specific criteria: + # + # constraints(lambda { |req| req.env["HTTP_USER_AGENT"] =~ /iPhone/ }) do + # resources :iphones + # end + # + # You are able to move this logic out into a class if it is too complex for routes. + # This class must have a +matches?+ method defined on it which either returns +true+ + # if the user should be given access to that route, or +false+ if the user should not. + # + # class Iphone + # def self.matches?(request) + # request.env["HTTP_USER_AGENT"] =~ /iPhone/ + # end + # end + # + # An expected place for this code would be +lib/constraints+. + # + # This class is then used like this: + # + # constraints(Iphone) do + # resources :iphones + # end + def constraints(constraints = {}) + scope(:constraints => constraints) { yield } + end + + # Allows you to set default parameters for a route, such as this: + # defaults id: 'home' do + # match 'scoped_pages/(:id)', to: 'pages#show' + # end + # Using this, the +:id+ parameter here will default to 'home'. + def defaults(defaults = {}) + scope(:defaults => defaults) { yield } + end + + private + def merge_path_scope(parent, child) #:nodoc: + Mapper.normalize_path("#{parent}/#{child}") + end + + def merge_shallow_path_scope(parent, child) #:nodoc: + Mapper.normalize_path("#{parent}/#{child}") + end + + def merge_as_scope(parent, child) #:nodoc: + parent ? "#{parent}_#{child}" : child + end + + def merge_shallow_prefix_scope(parent, child) #:nodoc: + parent ? "#{parent}_#{child}" : child + end + + def merge_module_scope(parent, child) #:nodoc: + parent ? "#{parent}/#{child}" : child + end + + def merge_controller_scope(parent, child) #:nodoc: + child + end + + def merge_action_scope(parent, child) #:nodoc: + child + end + + def merge_path_names_scope(parent, child) #:nodoc: + merge_options_scope(parent, child) + end + + def merge_constraints_scope(parent, child) #:nodoc: + merge_options_scope(parent, child) + end + + def merge_defaults_scope(parent, child) #:nodoc: + merge_options_scope(parent, child) + end + + def merge_blocks_scope(parent, child) #:nodoc: + merged = parent ? parent.dup : [] + merged << child if child + merged + end + + def merge_options_scope(parent, child) #:nodoc: + (parent || {}).except(*override_keys(child)).merge!(child) + end + + def merge_shallow_scope(parent, child) #:nodoc: + child ? true : false + end + + def override_keys(child) #:nodoc: + child.key?(:only) || child.key?(:except) ? [:only, :except] : [] + end + end + + # Resource routing allows you to quickly declare all of the common routes + # for a given resourceful controller. Instead of declaring separate routes + # for your +index+, +show+, +new+, +edit+, +create+, +update+ and +destroy+ + # actions, a resourceful route declares them in a single line of code: + # + # resources :photos + # + # Sometimes, you have a resource that clients always look up without + # referencing an ID. A common example, /profile always shows the profile of + # the currently logged in user. In this case, you can use a singular resource + # to map /profile (rather than /profile/:id) to the show action. + # + # resource :profile + # + # It's common to have resources that are logically children of other + # resources: + # + # resources :magazines do + # resources :ads + # end + # + # You may wish to organize groups of controllers under a namespace. Most + # commonly, you might group a number of administrative controllers under + # an +admin+ namespace. You would place these controllers under the + # app/controllers/admin directory, and you can group them together + # in your router: + # + # namespace "admin" do + # resources :posts, :comments + # end + # + # By default the +:id+ parameter doesn't accept dots. If you need to + # use dots as part of the +:id+ parameter add a constraint which + # overrides this restriction, e.g: + # + # resources :articles, id: /[^\/]+/ + # + # This allows any character other than a slash as part of your +:id+. + # + module Resources + # CANONICAL_ACTIONS holds all actions that does not need a prefix or + # a path appended since they fit properly in their scope level. + VALID_ON_OPTIONS = [:new, :collection, :member] + RESOURCE_OPTIONS = [:as, :controller, :path, :only, :except, :param, :concerns] + CANONICAL_ACTIONS = %w(index create new show update destroy) + + class Resource #:nodoc: + attr_reader :controller, :path, :options, :param + + def initialize(entities, options = {}) + @name = entities.to_s + @path = (options[:path] || @name).to_s + @controller = (options[:controller] || @name).to_s + @as = options[:as] + @param = (options[:param] || :id).to_sym + @options = options + @shallow = false + end + + def default_actions + [:index, :create, :new, :show, :update, :destroy, :edit] + end + + def actions + if only = @options[:only] + Array(only).map(&:to_sym) + elsif except = @options[:except] + default_actions - Array(except).map(&:to_sym) + else + default_actions + end + end + + def name + @as || @name + end + + def plural + @plural ||= name.to_s + end + + def singular + @singular ||= name.to_s.singularize + end + + alias :member_name :singular + + # Checks for uncountable plurals, and appends "_index" if the plural + # and singular form are the same. + def collection_name + singular == plural ? "#{plural}_index" : plural + end + + def resource_scope + { :controller => controller } + end + + alias :collection_scope :path + + def member_scope + "#{path}/:#{param}" + end + + alias :shallow_scope :member_scope + + def new_scope(new_path) + "#{path}/#{new_path}" + end + + def nested_param + :"#{singular}_#{param}" + end + + def nested_scope + "#{path}/:#{nested_param}" + end + + def shallow=(value) + @shallow = value + end + + def shallow? + @shallow + end + end + + class SingletonResource < Resource #:nodoc: + def initialize(entities, options) + super + @as = nil + @controller = (options[:controller] || plural).to_s + @as = options[:as] + end + + def default_actions + [:show, :create, :update, :destroy, :new, :edit] + end + + def plural + @plural ||= name.to_s.pluralize + end + + def singular + @singular ||= name.to_s + end + + alias :member_name :singular + alias :collection_name :singular + + alias :member_scope :path + alias :nested_scope :path + end + + def resources_path_names(options) + @scope[:path_names].merge!(options) + end + + # Sometimes, you have a resource that clients always look up without + # referencing an ID. A common example, /profile always shows the + # profile of the currently logged in user. In this case, you can use + # a singular resource to map /profile (rather than /profile/:id) to + # the show action: + # + # resource :profile + # + # creates six different routes in your application, all mapping to + # the +Profiles+ controller (note that the controller is named after + # the plural): + # + # GET /profile/new + # POST /profile + # GET /profile + # GET /profile/edit + # PATCH/PUT /profile + # DELETE /profile + # + # === Options + # Takes same options as +resources+. + def resource(*resources, &block) + options = resources.extract_options!.dup + + if apply_common_behavior_for(:resource, resources, options, &block) + return self + end + + resource_scope(:resource, SingletonResource.new(resources.pop, options)) do + yield if block_given? + + concerns(options[:concerns]) if options[:concerns] + + collection do + post :create + end if parent_resource.actions.include?(:create) + + new do + get :new + end if parent_resource.actions.include?(:new) + + set_member_mappings_for_resource + end + + self + end + + # In Rails, a resourceful route provides a mapping between HTTP verbs + # and URLs and controller actions. By convention, each action also maps + # to particular CRUD operations in a database. A single entry in the + # routing file, such as + # + # resources :photos + # + # creates seven different routes in your application, all mapping to + # the +Photos+ controller: + # + # GET /photos + # GET /photos/new + # POST /photos + # GET /photos/:id + # GET /photos/:id/edit + # PATCH/PUT /photos/:id + # DELETE /photos/:id + # + # Resources can also be nested infinitely by using this block syntax: + # + # resources :photos do + # resources :comments + # end + # + # This generates the following comments routes: + # + # GET /photos/:photo_id/comments + # GET /photos/:photo_id/comments/new + # POST /photos/:photo_id/comments + # GET /photos/:photo_id/comments/:id + # GET /photos/:photo_id/comments/:id/edit + # PATCH/PUT /photos/:photo_id/comments/:id + # DELETE /photos/:photo_id/comments/:id + # + # === Options + # Takes same options as Base#match as well as: + # + # [:path_names] + # Allows you to change the segment component of the +edit+ and +new+ actions. + # Actions not specified are not changed. + # + # resources :posts, path_names: { new: "brand_new" } + # + # The above example will now change /posts/new to /posts/brand_new + # + # [:path] + # Allows you to change the path prefix for the resource. + # + # resources :posts, path: 'postings' + # + # The resource and all segments will now route to /postings instead of /posts + # + # [:only] + # Only generate routes for the given actions. + # + # resources :cows, only: :show + # resources :cows, only: [:show, :index] + # + # [:except] + # Generate all routes except for the given actions. + # + # resources :cows, except: :show + # resources :cows, except: [:show, :index] + # + # [:shallow] + # Generates shallow routes for nested resource(s). When placed on a parent resource, + # generates shallow routes for all nested resources. + # + # resources :posts, shallow: true do + # resources :comments + # end + # + # Is the same as: + # + # resources :posts do + # resources :comments, except: [:show, :edit, :update, :destroy] + # end + # resources :comments, only: [:show, :edit, :update, :destroy] + # + # This allows URLs for resources that otherwise would be deeply nested such + # as a comment on a blog post like /posts/a-long-permalink/comments/1234 + # to be shortened to just /comments/1234. + # + # [:shallow_path] + # Prefixes nested shallow routes with the specified path. + # + # scope shallow_path: "sekret" do + # resources :posts do + # resources :comments, shallow: true + # end + # end + # + # The +comments+ resource here will have the following routes generated for it: + # + # post_comments GET /posts/:post_id/comments(.:format) + # post_comments POST /posts/:post_id/comments(.:format) + # new_post_comment GET /posts/:post_id/comments/new(.:format) + # edit_comment GET /sekret/comments/:id/edit(.:format) + # comment GET /sekret/comments/:id(.:format) + # comment PATCH/PUT /sekret/comments/:id(.:format) + # comment DELETE /sekret/comments/:id(.:format) + # + # [:shallow_prefix] + # Prefixes nested shallow route names with specified prefix. + # + # scope shallow_prefix: "sekret" do + # resources :posts do + # resources :comments, shallow: true + # end + # end + # + # The +comments+ resource here will have the following routes generated for it: + # + # post_comments GET /posts/:post_id/comments(.:format) + # post_comments POST /posts/:post_id/comments(.:format) + # new_post_comment GET /posts/:post_id/comments/new(.:format) + # edit_sekret_comment GET /comments/:id/edit(.:format) + # sekret_comment GET /comments/:id(.:format) + # sekret_comment PATCH/PUT /comments/:id(.:format) + # sekret_comment DELETE /comments/:id(.:format) + # + # [:format] + # Allows you to specify the default value for optional +format+ + # segment or disable it by supplying +false+. + # + # === Examples + # + # # routes call Admin::PostsController + # resources :posts, module: "admin" + # + # # resource actions are at /admin/posts. + # resources :posts, path: "admin/posts" + def resources(*resources, &block) + options = resources.extract_options!.dup + + if apply_common_behavior_for(:resources, resources, options, &block) + return self + end + + resource_scope(:resources, Resource.new(resources.pop, options)) do + yield if block_given? + + concerns(options[:concerns]) if options[:concerns] + + collection do + get :index if parent_resource.actions.include?(:index) + post :create if parent_resource.actions.include?(:create) + end + + new do + get :new + end if parent_resource.actions.include?(:new) + + set_member_mappings_for_resource + end + + self + end + + # To add a route to the collection: + # + # resources :photos do + # collection do + # get 'search' + # end + # end + # + # This will enable Rails to recognize paths such as /photos/search + # with GET, and route to the search action of +PhotosController+. It will also + # create the search_photos_url and search_photos_path + # route helpers. + def collection + unless resource_scope? + raise ArgumentError, "can't use collection outside resource(s) scope" + end + + with_scope_level(:collection) do + scope(parent_resource.collection_scope) do + yield + end + end + end + + # To add a member route, add a member block into the resource block: + # + # resources :photos do + # member do + # get 'preview' + # end + # end + # + # This will recognize /photos/1/preview with GET, and route to the + # preview action of +PhotosController+. It will also create the + # preview_photo_url and preview_photo_path helpers. + def member + unless resource_scope? + raise ArgumentError, "can't use member outside resource(s) scope" + end + + with_scope_level(:member) do + if shallow? + shallow_scope(parent_resource.member_scope) { yield } + else + scope(parent_resource.member_scope) { yield } + end + end + end + + def new + unless resource_scope? + raise ArgumentError, "can't use new outside resource(s) scope" + end + + with_scope_level(:new) do + scope(parent_resource.new_scope(action_path(:new))) do + yield + end + end + end + + def nested + unless resource_scope? + raise ArgumentError, "can't use nested outside resource(s) scope" + end + + with_scope_level(:nested) do + if shallow? && shallow_nesting_depth >= 1 + shallow_scope(parent_resource.nested_scope, nested_options) { yield } + else + scope(parent_resource.nested_scope, nested_options) { yield } + end + end + end + + # See ActionDispatch::Routing::Mapper::Scoping#namespace + def namespace(path, options = {}) + if resource_scope? + nested { super } + else + super + end + end + + def shallow + scope(:shallow => true) do + yield + end + end + + def shallow? + parent_resource.instance_of?(Resource) && @scope[:shallow] + end + + # match 'path' => 'controller#action' + # match 'path', to: 'controller#action' + # match 'path', 'otherpath', on: :member, via: :get + def match(path, *rest) + if rest.empty? && Hash === path + options = path + path, to = options.find { |name, _value| name.is_a?(String) } + + case to + when Symbol + options[:action] = to + when String + if to =~ /#/ + options[:to] = to + else + options[:controller] = to + end + else + options[:to] = to + end + + options.delete(path) + paths = [path] + else + options = rest.pop || {} + paths = [path] + rest + end + + options[:anchor] = true unless options.key?(:anchor) + + if options[:on] && !VALID_ON_OPTIONS.include?(options[:on]) + raise ArgumentError, "Unknown scope #{on.inspect} given to :on" + end + + if @scope[:controller] && @scope[:action] + options[:to] ||= "#{@scope[:controller]}##{@scope[:action]}" + end + + paths.each do |_path| + route_options = options.dup + route_options[:path] ||= _path if _path.is_a?(String) + + path_without_format = _path.to_s.sub(/\(\.:format\)$/, '') + if using_match_shorthand?(path_without_format, route_options) + route_options[:to] ||= path_without_format.gsub(%r{^/}, "").sub(%r{/([^/]*)$}, '#\1') + route_options[:to].tr!("-", "_") + end + + decomposed_match(_path, route_options) + end + self + end + + def using_match_shorthand?(path, options) + path && (options[:to] || options[:action]).nil? && path =~ %r{^/?[-\w]+/[-\w/]+$} + end + + def decomposed_match(path, options) # :nodoc: + if on = options.delete(:on) + send(on) { decomposed_match(path, options) } + else + case @scope.scope_level + when :resources + nested { decomposed_match(path, options) } + when :resource + member { decomposed_match(path, options) } + else + add_route(path, options) + end + end + end + + def add_route(action, options) # :nodoc: + path = path_for_action(action, options.delete(:path)) + raise ArgumentError, "path is required" if path.blank? + + action = action.to_s.dup + + if action =~ /^[\w\-\/]+$/ + options[:action] ||= action.tr('-', '_') unless action.include?("/") + else + action = nil + end + + as = if !options.fetch(:as, true) # if it's set to nil or false + options.delete(:as) + else + name_for_action(options.delete(:as), action) + end + + mapping = Mapping.build(@scope, @set, URI.parser.escape(path), as, options) + app, conditions, requirements, defaults, as, anchor = mapping.to_route + @set.add_route(app, conditions, requirements, defaults, as, anchor) + end + + def root(path, options={}) + if path.is_a?(String) + options[:to] = path + elsif path.is_a?(Hash) and options.empty? + options = path + else + raise ArgumentError, "must be called with a path and/or options" + end + + if @scope.resources? + with_scope_level(:root) do + scope(parent_resource.path) do + super(options) + end + end + else + super(options) + end + end + + protected + + def parent_resource #:nodoc: + @scope[:scope_level_resource] + end + + def apply_common_behavior_for(method, resources, options, &block) #:nodoc: + if resources.length > 1 + resources.each { |r| send(method, r, options, &block) } + return true + end + + if options.delete(:shallow) + shallow do + send(method, resources.pop, options, &block) + end + return true + end + + if resource_scope? + nested { send(method, resources.pop, options, &block) } + return true + end + + options.keys.each do |k| + (options[:constraints] ||= {})[k] = options.delete(k) if options[k].is_a?(Regexp) + end + + scope_options = options.slice!(*RESOURCE_OPTIONS) + unless scope_options.empty? + scope(scope_options) do + send(method, resources.pop, options, &block) + end + return true + end + + unless action_options?(options) + options.merge!(scope_action_options) if scope_action_options? + end + + false + end + + def action_options?(options) #:nodoc: + options[:only] || options[:except] + end + + def scope_action_options? #:nodoc: + @scope[:options] && (@scope[:options][:only] || @scope[:options][:except]) + end + + def scope_action_options #:nodoc: + @scope[:options].slice(:only, :except) + end + + def resource_scope? #:nodoc: + @scope.resource_scope? + end + + def resource_method_scope? #:nodoc: + @scope.resource_method_scope? + end + + def nested_scope? #:nodoc: + @scope.nested? + end + + def with_exclusive_scope + begin + @scope = @scope.new(:as => nil, :path => nil) + + with_scope_level(:exclusive) do + yield + end + ensure + @scope = @scope.parent + end + end + + def with_scope_level(kind) + @scope = @scope.new_level(kind) + yield + ensure + @scope = @scope.parent + end + + def resource_scope(kind, resource) #:nodoc: + resource.shallow = @scope[:shallow] + @scope = @scope.new(:scope_level_resource => resource) + @nesting.push(resource) + + with_scope_level(kind) do + scope(parent_resource.resource_scope) { yield } + end + ensure + @nesting.pop + @scope = @scope.parent + end + + def nested_options #:nodoc: + options = { :as => parent_resource.member_name } + options[:constraints] = { + parent_resource.nested_param => param_constraint + } if param_constraint? + + options + end + + def nesting_depth #:nodoc: + @nesting.size + end + + def shallow_nesting_depth #:nodoc: + @nesting.select(&:shallow?).size + end + + def param_constraint? #:nodoc: + @scope[:constraints] && @scope[:constraints][parent_resource.param].is_a?(Regexp) + end + + def param_constraint #:nodoc: + @scope[:constraints][parent_resource.param] + end + + def canonical_action?(action) #:nodoc: + resource_method_scope? && CANONICAL_ACTIONS.include?(action.to_s) + end + + def shallow_scope(path, options = {}) #:nodoc: + scope = { :as => @scope[:shallow_prefix], + :path => @scope[:shallow_path] } + @scope = @scope.new scope + + scope(path, options) { yield } + ensure + @scope = @scope.parent + end + + def path_for_action(action, path) #:nodoc: + if path.blank? && canonical_action?(action) + @scope[:path].to_s + else + "#{@scope[:path]}/#{action_path(action, path)}" + end + end + + def action_path(name, path = nil) #:nodoc: + name = name.to_sym if name.is_a?(String) + path || @scope[:path_names][name] || name.to_s + end + + def prefix_name_for_action(as, action) #:nodoc: + if as + prefix = as + elsif !canonical_action?(action) + prefix = action + end + + if prefix && prefix != '/' && !prefix.empty? + Mapper.normalize_name prefix.to_s.tr('-', '_') + end + end + + def name_for_action(as, action) #:nodoc: + prefix = prefix_name_for_action(as, action) + name_prefix = @scope[:as] + + if parent_resource + return nil unless as || action + + collection_name = parent_resource.collection_name + member_name = parent_resource.member_name + end + + name = @scope.action_name(name_prefix, prefix, collection_name, member_name) + + if candidate = name.compact.join("_").presence + # If a name was not explicitly given, we check if it is valid + # and return nil in case it isn't. Otherwise, we pass the invalid name + # forward so the underlying router engine treats it and raises an exception. + if as.nil? + candidate unless candidate !~ /\A[_a-z]/i || @set.named_routes.key?(candidate) + else + candidate + end + end + end + + def set_member_mappings_for_resource + member do + get :edit if parent_resource.actions.include?(:edit) + get :show if parent_resource.actions.include?(:show) + if parent_resource.actions.include?(:update) + patch :update + put :update + end + delete :destroy if parent_resource.actions.include?(:destroy) + end + end + end + + # Routing Concerns allow you to declare common routes that can be reused + # inside others resources and routes. + # + # concern :commentable do + # resources :comments + # end + # + # concern :image_attachable do + # resources :images, only: :index + # end + # + # These concerns are used in Resources routing: + # + # resources :messages, concerns: [:commentable, :image_attachable] + # + # or in a scope or namespace: + # + # namespace :posts do + # concerns :commentable + # end + module Concerns + # Define a routing concern using a name. + # + # Concerns may be defined inline, using a block, or handled by + # another object, by passing that object as the second parameter. + # + # The concern object, if supplied, should respond to call, + # which will receive two parameters: + # + # * The current mapper + # * A hash of options which the concern object may use + # + # Options may also be used by concerns defined in a block by accepting + # a block parameter. So, using a block, you might do something as + # simple as limit the actions available on certain resources, passing + # standard resource options through the concern: + # + # concern :commentable do |options| + # resources :comments, options + # end + # + # resources :posts, concerns: :commentable + # resources :archived_posts do + # # Don't allow comments on archived posts + # concerns :commentable, only: [:index, :show] + # end + # + # Or, using a callable object, you might implement something more + # specific to your application, which would be out of place in your + # routes file. + # + # # purchasable.rb + # class Purchasable + # def initialize(defaults = {}) + # @defaults = defaults + # end + # + # def call(mapper, options = {}) + # options = @defaults.merge(options) + # mapper.resources :purchases + # mapper.resources :receipts + # mapper.resources :returns if options[:returnable] + # end + # end + # + # # routes.rb + # concern :purchasable, Purchasable.new(returnable: true) + # + # resources :toys, concerns: :purchasable + # resources :electronics, concerns: :purchasable + # resources :pets do + # concerns :purchasable, returnable: false + # end + # + # Any routing helpers can be used inside a concern. If using a + # callable, they're accessible from the Mapper that's passed to + # call. + def concern(name, callable = nil, &block) + callable ||= lambda { |mapper, options| mapper.instance_exec(options, &block) } + @concerns[name] = callable + end + + # Use the named concerns + # + # resources :posts do + # concerns :commentable + # end + # + # concerns also work in any routes helper that you want to use: + # + # namespace :posts do + # concerns :commentable + # end + def concerns(*args) + options = args.extract_options! + args.flatten.each do |name| + if concern = @concerns[name] + concern.call(self, options) + else + raise ArgumentError, "No concern named #{name} was found!" + end + end + end + end + + class Scope # :nodoc: + OPTIONS = [:path, :shallow_path, :as, :shallow_prefix, :module, + :controller, :action, :path_names, :constraints, + :shallow, :blocks, :defaults, :options] + + RESOURCE_SCOPES = [:resource, :resources] + RESOURCE_METHOD_SCOPES = [:collection, :member, :new] + + attr_reader :parent, :scope_level + + def initialize(hash, parent = {}, scope_level = nil) + @hash = hash + @parent = parent + @scope_level = scope_level + end + + def nested? + scope_level == :nested + end + + def resources? + scope_level == :resources + end + + def resource_method_scope? + RESOURCE_METHOD_SCOPES.include? scope_level + end + + def action_name(name_prefix, prefix, collection_name, member_name) + case scope_level + when :nested + [name_prefix, prefix] + when :collection + [prefix, name_prefix, collection_name] + when :new + [prefix, :new, name_prefix, member_name] + when :member + [prefix, name_prefix, member_name] + when :root + [name_prefix, collection_name, prefix] + else + [name_prefix, member_name, prefix] + end + end + + def resource_scope? + RESOURCE_SCOPES.include? scope_level + end + + def options + OPTIONS + end + + def new(hash) + self.class.new hash, self, scope_level + end + + def new_level(level) + self.class.new(self, self, level) + end + + def fetch(key, &block) + @hash.fetch(key, &block) + end + + def [](key) + @hash.fetch(key) { @parent[key] } + end + + def []=(k,v) + @hash[k] = v + end + end + + def initialize(set) #:nodoc: + @set = set + @scope = Scope.new({ :path_names => @set.resources_path_names }) + @concerns = {} + @nesting = [] + end + + include Base + include HttpHelpers + include Redirection + include Scoping + include Concerns + include Resources + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/routing/polymorphic_routes.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/routing/polymorphic_routes.rb new file mode 100644 index 0000000..bb0f5f2 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/routing/polymorphic_routes.rb @@ -0,0 +1,330 @@ +require 'action_controller/model_naming' + +module ActionDispatch + module Routing + # Polymorphic URL helpers are methods for smart resolution to a named route call when + # given an Active Record model instance. They are to be used in combination with + # ActionController::Resources. + # + # These methods are useful when you want to generate correct URL or path to a RESTful + # resource without having to know the exact type of the record in question. + # + # Nested resources and/or namespaces are also supported, as illustrated in the example: + # + # polymorphic_url([:admin, @article, @comment]) + # + # results in: + # + # admin_article_comment_url(@article, @comment) + # + # == Usage within the framework + # + # Polymorphic URL helpers are used in a number of places throughout the \Rails framework: + # + # * url_for, so you can use it with a record as the argument, e.g. + # url_for(@article); + # * ActionView::Helpers::FormHelper uses polymorphic_path, so you can write + # form_for(@article) without having to specify :url parameter for the form + # action; + # * redirect_to (which, in fact, uses url_for) so you can write + # redirect_to(post) in your controllers; + # * ActionView::Helpers::AtomFeedHelper, so you don't have to explicitly specify URLs + # for feed entries. + # + # == Prefixed polymorphic helpers + # + # In addition to polymorphic_url and polymorphic_path methods, a + # number of prefixed helpers are available as a shorthand to action: "..." + # in options. Those are: + # + # * edit_polymorphic_url, edit_polymorphic_path + # * new_polymorphic_url, new_polymorphic_path + # + # Example usage: + # + # edit_polymorphic_path(@post) # => "/posts/1/edit" + # polymorphic_path(@post, format: :pdf) # => "/posts/1.pdf" + # + # == Usage with mounted engines + # + # If you are using a mounted engine and you need to use a polymorphic_url + # pointing at the engine's routes, pass in the engine's route proxy as the first + # argument to the method. For example: + # + # polymorphic_url([blog, @post]) # calls blog.post_path(@post) + # form_for([blog, @post]) # => "/blog/posts/1" + # + module PolymorphicRoutes + include ActionController::ModelNaming + + # Constructs a call to a named RESTful route for the given record and returns the + # resulting URL string. For example: + # + # # calls post_url(post) + # polymorphic_url(post) # => "http://example.com/posts/1" + # polymorphic_url([blog, post]) # => "http://example.com/blogs/1/posts/1" + # polymorphic_url([:admin, blog, post]) # => "http://example.com/admin/blogs/1/posts/1" + # polymorphic_url([user, :blog, post]) # => "http://example.com/users/1/blog/posts/1" + # polymorphic_url(Comment) # => "http://example.com/comments" + # + # ==== Options + # + # * :action - Specifies the action prefix for the named route: + # :new or :edit. Default is no prefix. + # * :routing_type - Allowed values are :path or :url. + # Default is :url. + # + # Also includes all the options from url_for. These include such + # things as :anchor or :trailing_slash. Example usage + # is given below: + # + # polymorphic_url([blog, post], anchor: 'my_anchor') + # # => "http://example.com/blogs/1/posts/1#my_anchor" + # polymorphic_url([blog, post], anchor: 'my_anchor', script_name: "/my_app") + # # => "http://example.com/my_app/blogs/1/posts/1#my_anchor" + # + # For all of these options, see the documentation for url_for. + # + # ==== Functionality + # + # # an Article record + # polymorphic_url(record) # same as article_url(record) + # + # # a Comment record + # polymorphic_url(record) # same as comment_url(record) + # + # # it recognizes new records and maps to the collection + # record = Comment.new + # polymorphic_url(record) # same as comments_url() + # + # # the class of a record will also map to the collection + # polymorphic_url(Comment) # same as comments_url() + # + def polymorphic_url(record_or_hash_or_array, options = {}) + if Hash === record_or_hash_or_array + options = record_or_hash_or_array.merge(options) + record = options.delete :id + return polymorphic_url record, options + end + + opts = options.dup + action = opts.delete :action + type = opts.delete(:routing_type) || :url + + HelperMethodBuilder.polymorphic_method self, + record_or_hash_or_array, + action, + type, + opts + end + + # Returns the path component of a URL for the given record. It uses + # polymorphic_url with routing_type: :path. + def polymorphic_path(record_or_hash_or_array, options = {}) + if Hash === record_or_hash_or_array + options = record_or_hash_or_array.merge(options) + record = options.delete :id + return polymorphic_path record, options + end + + opts = options.dup + action = opts.delete :action + type = :path + + HelperMethodBuilder.polymorphic_method self, + record_or_hash_or_array, + action, + type, + opts + end + + + %w(edit new).each do |action| + module_eval <<-EOT, __FILE__, __LINE__ + 1 + def #{action}_polymorphic_url(record_or_hash, options = {}) + polymorphic_url_for_action("#{action}", record_or_hash, options) + end + + def #{action}_polymorphic_path(record_or_hash, options = {}) + polymorphic_path_for_action("#{action}", record_or_hash, options) + end + EOT + end + + private + + def polymorphic_url_for_action(action, record_or_hash, options) + polymorphic_url(record_or_hash, options.merge(:action => action)) + end + + def polymorphic_path_for_action(action, record_or_hash, options) + polymorphic_path(record_or_hash, options.merge(:action => action)) + end + + class HelperMethodBuilder # :nodoc: + CACHE = { 'path' => {}, 'url' => {} } + + def self.get(action, type) + type = type.to_s + CACHE[type].fetch(action) { build action, type } + end + + def self.url; CACHE['url'.freeze][nil]; end + def self.path; CACHE['path'.freeze][nil]; end + + def self.build(action, type) + prefix = action ? "#{action}_" : "" + suffix = type + if action.to_s == 'new' + HelperMethodBuilder.singular prefix, suffix + else + HelperMethodBuilder.plural prefix, suffix + end + end + + def self.singular(prefix, suffix) + new(->(name) { name.singular_route_key }, prefix, suffix) + end + + def self.plural(prefix, suffix) + new(->(name) { name.route_key }, prefix, suffix) + end + + def self.polymorphic_method(recipient, record_or_hash_or_array, action, type, options) + builder = get action, type + + case record_or_hash_or_array + when Array + record_or_hash_or_array = record_or_hash_or_array.compact + if record_or_hash_or_array.empty? + raise ArgumentError, "Nil location provided. Can't build URI." + end + if record_or_hash_or_array.first.is_a?(ActionDispatch::Routing::RoutesProxy) + recipient = record_or_hash_or_array.shift + end + + method, args = builder.handle_list record_or_hash_or_array + when String, Symbol + method, args = builder.handle_string record_or_hash_or_array + when Class + method, args = builder.handle_class record_or_hash_or_array + + when nil + raise ArgumentError, "Nil location provided. Can't build URI." + else + method, args = builder.handle_model record_or_hash_or_array + end + + + if options.empty? + recipient.send(method, *args) + else + recipient.send(method, *args, options) + end + end + + attr_reader :suffix, :prefix + + def initialize(key_strategy, prefix, suffix) + @key_strategy = key_strategy + @prefix = prefix + @suffix = suffix + end + + def handle_string(record) + [get_method_for_string(record), []] + end + + def handle_string_call(target, str) + target.send get_method_for_string str + end + + def handle_class(klass) + [get_method_for_class(klass), []] + end + + def handle_class_call(target, klass) + target.send get_method_for_class klass + end + + def handle_model(record) + args = [] + + model = record.to_model + name = if model.persisted? + args << model + model.model_name.singular_route_key + else + @key_strategy.call model.model_name + end + + named_route = prefix + "#{name}_#{suffix}" + + [named_route, args] + end + + def handle_model_call(target, model) + method, args = handle_model model + target.send(method, *args) + end + + def handle_list(list) + record_list = list.dup + record = record_list.pop + + args = [] + + route = record_list.map { |parent| + case parent + when Symbol, String + parent.to_s + when Class + args << parent + parent.model_name.singular_route_key + else + args << parent.to_model + parent.to_model.model_name.singular_route_key + end + } + + route << + case record + when Symbol, String + record.to_s + when Class + @key_strategy.call record.model_name + else + model = record.to_model + if model.persisted? + args << model + model.model_name.singular_route_key + else + @key_strategy.call model.model_name + end + end + + route << suffix + + named_route = prefix + route.join("_") + [named_route, args] + end + + private + + def get_method_for_class(klass) + name = @key_strategy.call klass.model_name + prefix + "#{name}_#{suffix}" + end + + def get_method_for_string(str) + prefix + "#{str}_#{suffix}" + end + + [nil, 'new', 'edit'].each do |action| + CACHE['url'][action] = build action, 'url' + CACHE['path'][action] = build action, 'path' + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/routing/redirection.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/routing/redirection.rb new file mode 100644 index 0000000..3c1c4fa --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/routing/redirection.rb @@ -0,0 +1,191 @@ +require 'action_dispatch/http/request' +require 'active_support/core_ext/uri' +require 'active_support/core_ext/array/extract_options' +require 'rack/utils' +require 'action_controller/metal/exceptions' +require 'action_dispatch/routing/endpoint' + +module ActionDispatch + module Routing + class Redirect < Endpoint # :nodoc: + attr_reader :status, :block + + def initialize(status, block) + @status = status + @block = block + end + + def redirect?; true; end + + def call(env) + serve Request.new env + end + + def serve(req) + req.check_path_parameters! + uri = URI.parse(path(req.path_parameters, req)) + + unless uri.host + if relative_path?(uri.path) + uri.path = "#{req.script_name}/#{uri.path}" + elsif uri.path.empty? + uri.path = req.script_name.empty? ? "/" : req.script_name + end + end + + uri.scheme ||= req.scheme + uri.host ||= req.host + uri.port ||= req.port unless req.standard_port? + + body = %(You are being redirected.) + + headers = { + 'Location' => uri.to_s, + 'Content-Type' => 'text/html', + 'Content-Length' => body.length.to_s + } + + [ status, headers, [body] ] + end + + def path(params, request) + block.call params, request + end + + def inspect + "redirect(#{status})" + end + + private + def relative_path?(path) + path && !path.empty? && path[0] != '/' + end + + def escape(params) + Hash[params.map{ |k,v| [k, Rack::Utils.escape(v)] }] + end + + def escape_fragment(params) + Hash[params.map{ |k,v| [k, Journey::Router::Utils.escape_fragment(v)] }] + end + + def escape_path(params) + Hash[params.map{ |k,v| [k, Journey::Router::Utils.escape_path(v)] }] + end + end + + class PathRedirect < Redirect + URL_PARTS = /\A([^?]+)?(\?[^#]+)?(#.+)?\z/ + + def path(params, request) + if block.match(URL_PARTS) + path = interpolation_required?($1, params) ? $1 % escape_path(params) : $1 + query = interpolation_required?($2, params) ? $2 % escape(params) : $2 + fragment = interpolation_required?($3, params) ? $3 % escape_fragment(params) : $3 + + "#{path}#{query}#{fragment}" + else + interpolation_required?(block, params) ? block % escape(params) : block + end + end + + def inspect + "redirect(#{status}, #{block})" + end + + private + def interpolation_required?(string, params) + !params.empty? && string && string.match(/%\{\w*\}/) + end + end + + class OptionRedirect < Redirect # :nodoc: + alias :options :block + + def path(params, request) + url_options = { + :protocol => request.protocol, + :host => request.host, + :port => request.optional_port, + :path => request.path, + :params => request.query_parameters + }.merge! options + + if !params.empty? && url_options[:path].match(/%\{\w*\}/) + url_options[:path] = (url_options[:path] % escape_path(params)) + end + + unless options[:host] || options[:domain] + if relative_path?(url_options[:path]) + url_options[:path] = "/#{url_options[:path]}" + url_options[:script_name] = request.script_name + elsif url_options[:path].empty? + url_options[:path] = request.script_name.empty? ? "/" : "" + url_options[:script_name] = request.script_name + end + end + + ActionDispatch::Http::URL.url_for url_options + end + + def inspect + "redirect(#{status}, #{options.map{ |k,v| "#{k}: #{v}" }.join(', ')})" + end + end + + module Redirection + + # Redirect any path to another path: + # + # get "/stories" => redirect("/posts") + # + # You can also use interpolation in the supplied redirect argument: + # + # get 'docs/:article', to: redirect('/wiki/%{article}') + # + # Note that if you return a path without a leading slash then the url is prefixed with the + # current SCRIPT_NAME environment variable. This is typically '/' but may be different in + # a mounted engine or where the application is deployed to a subdirectory of a website. + # + # Alternatively you can use one of the other syntaxes: + # + # The block version of redirect allows for the easy encapsulation of any logic associated with + # the redirect in question. Either the params and request are supplied as arguments, or just + # params, depending of how many arguments your block accepts. A string is required as a + # return value. + # + # get 'jokes/:number', to: redirect { |params, request| + # path = (params[:number].to_i.even? ? "wheres-the-beef" : "i-love-lamp") + # "http://#{request.host_with_port}/#{path}" + # } + # + # Note that the +do end+ syntax for the redirect block wouldn't work, as Ruby would pass + # the block to +get+ instead of +redirect+. Use { ... } instead. + # + # The options version of redirect allows you to supply only the parts of the url which need + # to change, it also supports interpolation of the path similar to the first example. + # + # get 'stores/:name', to: redirect(subdomain: 'stores', path: '/%{name}') + # get 'stores/:name(*all)', to: redirect(subdomain: 'stores', path: '/%{name}%{all}') + # + # Finally, an object which responds to call can be supplied to redirect, allowing you to reuse + # common redirect routes. The call method must accept two arguments, params and request, and return + # a string. + # + # get 'accounts/:name' => redirect(SubdomainRedirector.new('api')) + # + def redirect(*args, &block) + options = args.extract_options! + status = options.delete(:status) || 301 + path = args.shift + + return OptionRedirect.new(status, options) if options.any? + return PathRedirect.new(status, path) if String === path + + block = path if path.respond_to? :call + raise ArgumentError, "redirection argument not supported" unless block + Redirect.new status, block + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/routing/route_set.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/routing/route_set.rb new file mode 100644 index 0000000..bd33251 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/routing/route_set.rb @@ -0,0 +1,860 @@ +require 'action_dispatch/journey' +require 'forwardable' +require 'active_support/concern' +require 'active_support/core_ext/object/to_query' +require 'active_support/core_ext/hash/slice' +require 'active_support/core_ext/module/remove_method' +require 'active_support/core_ext/array/extract_options' +require 'active_support/core_ext/string/filters' +require 'action_controller/metal/exceptions' +require 'action_dispatch/http/request' +require 'action_dispatch/routing/endpoint' + +module ActionDispatch + module Routing + # :stopdoc: + class RouteSet + # Since the router holds references to many parts of the system + # like engines, controllers and the application itself, inspecting + # the route set can actually be really slow, therefore we default + # alias inspect to to_s. + alias inspect to_s + + mattr_accessor :relative_url_root + + class Dispatcher < Routing::Endpoint + def initialize(defaults) + @defaults = defaults + end + + def dispatcher?; true; end + + def serve(req) + req.check_path_parameters! + params = req.path_parameters + + prepare_params!(params) + + # Just raise undefined constant errors if a controller was specified as default. + unless controller = controller(params, @defaults.key?(:controller)) + return [404, {'X-Cascade' => 'pass'}, []] + end + + dispatch(controller, params[:action], req.env) + end + + def prepare_params!(params) + normalize_controller!(params) + merge_default_action!(params) + end + + # If this is a default_controller (i.e. a controller specified by the user) + # we should raise an error in case it's not found, because it usually means + # a user error. However, if the controller was retrieved through a dynamic + # segment, as in :controller(/:action), we should simply return nil and + # delegate the control back to Rack cascade. Besides, if this is not a default + # controller, it means we should respect the @scope[:module] parameter. + def controller(params, default_controller=true) + if params && params.key?(:controller) + controller_param = params[:controller] + controller_reference(controller_param) + end + rescue NameError => e + raise ActionController::RoutingError, e.message, e.backtrace if default_controller + end + + private + + def controller_reference(controller_param) + const_name = "#{controller_param.camelize}Controller" + ActiveSupport::Dependencies.constantize(const_name) + end + + def dispatch(controller, action, env) + controller.action(action).call(env) + end + + def normalize_controller!(params) + params[:controller] = params[:controller].underscore if params.key?(:controller) + end + + def merge_default_action!(params) + params[:action] ||= 'index' + end + end + + # A NamedRouteCollection instance is a collection of named routes, and also + # maintains an anonymous module that can be used to install helpers for the + # named routes. + class NamedRouteCollection + include Enumerable + attr_reader :routes, :url_helpers_module + + def initialize + @routes = {} + @path_helpers = Set.new + @url_helpers = Set.new + @url_helpers_module = Module.new + @path_helpers_module = Module.new + end + + def route_defined?(name) + key = name.to_sym + @path_helpers.include?(key) || @url_helpers.include?(key) + end + + def helpers + ActiveSupport::Deprecation.warn(<<-MSG.squish) + `named_routes.helpers` is deprecated, please use `route_defined?(route_name)` + to see if a named route was defined. + MSG + @path_helpers + @url_helpers + end + + def helper_names + @path_helpers.map(&:to_s) + @url_helpers.map(&:to_s) + end + + def clear! + @path_helpers.each do |helper| + @path_helpers_module.send :undef_method, helper + end + + @url_helpers.each do |helper| + @url_helpers_module.send :undef_method, helper + end + + @routes.clear + @path_helpers.clear + @url_helpers.clear + end + + def add(name, route) + key = name.to_sym + path_name = :"#{name}_path" + url_name = :"#{name}_url" + + if routes.key? key + @path_helpers_module.send :undef_method, path_name + @url_helpers_module.send :undef_method, url_name + end + routes[key] = route + define_url_helper @path_helpers_module, route, path_name, route.defaults, name, LEGACY + define_url_helper @url_helpers_module, route, url_name, route.defaults, name, UNKNOWN + + @path_helpers << path_name + @url_helpers << url_name + end + + def get(name) + routes[name.to_sym] + end + + def key?(name) + routes.key? name.to_sym + end + + alias []= add + alias [] get + alias clear clear! + + def each + routes.each { |name, route| yield name, route } + self + end + + def names + routes.keys + end + + def length + routes.length + end + + def path_helpers_module(warn = false) + if warn + mod = @path_helpers_module + helpers = @path_helpers + Module.new do + include mod + + helpers.each do |meth| + define_method(meth) do |*args, &block| + ActiveSupport::Deprecation.warn("The method `#{meth}` cannot be used here as a full URL is required. Use `#{meth.to_s.sub(/_path$/, '_url')}` instead") + super(*args, &block) + end + end + end + else + @path_helpers_module + end + end + + class UrlHelper + def self.create(route, options, route_name, url_strategy) + if optimize_helper?(route) + OptimizedUrlHelper.new(route, options, route_name, url_strategy) + else + new route, options, route_name, url_strategy + end + end + + def self.optimize_helper?(route) + !route.glob? && route.path.requirements.empty? + end + + attr_reader :url_strategy, :route_name + + class OptimizedUrlHelper < UrlHelper + attr_reader :arg_size + + def initialize(route, options, route_name, url_strategy) + super + @required_parts = @route.required_parts + @arg_size = @required_parts.size + end + + def call(t, args, inner_options) + if args.size == arg_size && !inner_options && optimize_routes_generation?(t) + options = t.url_options.merge @options + options[:path] = optimized_helper(args) + url_strategy.call options + else + super + end + end + + private + + def optimized_helper(args) + params = parameterize_args(args) + missing_keys = missing_keys(params) + + unless missing_keys.empty? + raise_generation_error(params, missing_keys) + end + + @route.format params + end + + def optimize_routes_generation?(t) + t.send(:optimize_routes_generation?) + end + + def parameterize_args(args) + params = {} + @required_parts.zip(args.map(&:to_param)) { |k,v| params[k] = v } + params + end + + def missing_keys(args) + args.select{ |part, arg| arg.nil? || arg.empty? }.keys + end + + def raise_generation_error(args, missing_keys) + constraints = Hash[@route.requirements.merge(args).sort_by{|k,v| k.to_s}] + message = "No route matches #{constraints.inspect}" + message << " missing required keys: #{missing_keys.sort.inspect}" + + raise ActionController::UrlGenerationError, message + end + end + + def initialize(route, options, route_name, url_strategy) + @options = options + @segment_keys = route.segment_keys.uniq + @route = route + @url_strategy = url_strategy + @route_name = route_name + end + + def call(t, args, inner_options) + controller_options = t.url_options + options = controller_options.merge @options + hash = handle_positional_args(controller_options, + deprecate_string_options(inner_options) || {}, + args, + options, + @segment_keys) + + t._routes.url_for(hash, route_name, url_strategy) + end + + def handle_positional_args(controller_options, inner_options, args, result, path_params) + if args.size > 0 + # take format into account + if path_params.include?(:format) + path_params_size = path_params.size - 1 + else + path_params_size = path_params.size + end + + if args.size < path_params_size + path_params -= controller_options.keys + path_params -= result.keys + end + path_params.each { |param| + value = inner_options.fetch(param) { args.shift } + + unless param == :format && value.nil? + result[param] = value + end + } + end + + result.merge!(inner_options) + end + + DEPRECATED_STRING_OPTIONS = %w[controller action] + + def deprecate_string_options(options) + options ||= {} + deprecated_string_options = options.keys & DEPRECATED_STRING_OPTIONS + if deprecated_string_options.any? + msg = "Calling URL helpers with string keys #{deprecated_string_options.join(", ")} is deprecated. Use symbols instead." + ActiveSupport::Deprecation.warn(msg) + deprecated_string_options.each do |option| + value = options.delete(option) + options[option.to_sym] = value + end + end + options + end + end + + private + # Create a url helper allowing ordered parameters to be associated + # with corresponding dynamic segments, so you can do: + # + # foo_url(bar, baz, bang) + # + # Instead of: + # + # foo_url(bar: bar, baz: baz, bang: bang) + # + # Also allow options hash, so you can do: + # + # foo_url(bar, baz, bang, sort_by: 'baz') + # + def define_url_helper(mod, route, name, opts, route_key, url_strategy) + helper = UrlHelper.create(route, opts, route_key, url_strategy) + mod.module_eval do + define_method(name) do |*args| + options = nil + options = args.pop if args.last.is_a? Hash + helper.call self, args, options + end + end + end + end + + # strategy for building urls to send to the client + PATH = ->(options) { ActionDispatch::Http::URL.path_for(options) } + FULL = ->(options) { ActionDispatch::Http::URL.full_url_for(options) } + UNKNOWN = ->(options) { ActionDispatch::Http::URL.url_for(options) } + LEGACY = ->(options) { + if options.key?(:only_path) + if options[:only_path] + ActiveSupport::Deprecation.warn(<<-MSG.squish) + You are calling a `*_path` helper with the `only_path` option + explicitly set to `true`. This option will stop working on + path helpers in Rails 5. Simply remove the `only_path: true` + argument from your call as it is redundant when applied to a + path helper. + MSG + + PATH.call(options) + else + ActiveSupport::Deprecation.warn(<<-MSG.squish) + You are calling a `*_path` helper with the `only_path` option + explicitly set to `false`. This option will stop working on + path helpers in Rails 5. Use the corresponding `*_url` helper + instead. + MSG + + FULL.call(options) + end + else + PATH.call(options) + end + } + + attr_accessor :formatter, :set, :named_routes, :default_scope, :router + attr_accessor :disable_clear_and_finalize, :resources_path_names + attr_accessor :default_url_options, :request_class + + alias :routes :set + + def self.default_resources_path_names + { :new => 'new', :edit => 'edit' } + end + + def initialize(request_class = ActionDispatch::Request) + self.named_routes = NamedRouteCollection.new + self.resources_path_names = self.class.default_resources_path_names + self.default_url_options = {} + self.request_class = request_class + + @append = [] + @prepend = [] + @disable_clear_and_finalize = false + @finalized = false + + @set = Journey::Routes.new + @router = Journey::Router.new @set + @formatter = Journey::Formatter.new @set + end + + def draw(&block) + clear! unless @disable_clear_and_finalize + eval_block(block) + finalize! unless @disable_clear_and_finalize + nil + end + + def append(&block) + @append << block + end + + def prepend(&block) + @prepend << block + end + + def eval_block(block) + if block.arity == 1 + raise "You are using the old router DSL which has been removed in Rails 3.1. " << + "Please check how to update your routes file at: http://www.engineyard.com/blog/2010/the-lowdown-on-routes-in-rails-3/" + end + mapper = Mapper.new(self) + if default_scope + mapper.with_default_scope(default_scope, &block) + else + mapper.instance_exec(&block) + end + end + private :eval_block + + def finalize! + return if @finalized + @append.each { |blk| eval_block(blk) } + @finalized = true + end + + def clear! + @finalized = false + named_routes.clear + set.clear + formatter.clear + @prepend.each { |blk| eval_block(blk) } + end + + def dispatcher(defaults) + Routing::RouteSet::Dispatcher.new(defaults) + end + + module MountedHelpers + extend ActiveSupport::Concern + include UrlFor + end + + # Contains all the mounted helpers across different + # engines and the `main_app` helper for the application. + # You can include this in your classes if you want to + # access routes for other engines. + def mounted_helpers + MountedHelpers + end + + def define_mounted_helper(name) + return if MountedHelpers.method_defined?(name) + + routes = self + helpers = routes.url_helpers + + MountedHelpers.class_eval do + define_method "_#{name}" do + RoutesProxy.new(routes, _routes_context, helpers) + end + end + + MountedHelpers.class_eval(<<-RUBY, __FILE__, __LINE__ + 1) + def #{name} + @_#{name} ||= _#{name} + end + RUBY + end + + def url_helpers(supports_path = true) + routes = self + + Module.new do + extend ActiveSupport::Concern + include UrlFor + + # Define url_for in the singleton level so one can do: + # Rails.application.routes.url_helpers.url_for(args) + @_routes = routes + class << self + delegate :url_for, :optimize_routes_generation?, to: '@_routes' + attr_reader :_routes + def url_options; {}; end + end + + url_helpers = routes.named_routes.url_helpers_module + + # Make named_routes available in the module singleton + # as well, so one can do: + # Rails.application.routes.url_helpers.posts_path + extend url_helpers + + # Any class that includes this module will get all + # named routes... + include url_helpers + + if supports_path + path_helpers = routes.named_routes.path_helpers_module + else + path_helpers = routes.named_routes.path_helpers_module(true) + end + + include path_helpers + extend path_helpers + + # plus a singleton class method called _routes ... + included do + singleton_class.send(:redefine_method, :_routes) { routes } + end + + # And an instance method _routes. Note that + # UrlFor (included in this module) add extra + # conveniences for working with @_routes. + define_method(:_routes) { @_routes || routes } + + define_method(:_generate_paths_by_default) do + supports_path + end + + private :_generate_paths_by_default + end + end + + def empty? + routes.empty? + end + + def add_route(app, conditions = {}, requirements = {}, defaults = {}, name = nil, anchor = true) + raise ArgumentError, "Invalid route name: '#{name}'" unless name.blank? || name.to_s.match(/^[_a-z]\w*$/i) + + if name && named_routes[name] + raise ArgumentError, "Invalid route name, already in use: '#{name}' \n" \ + "You may have defined two routes with the same name using the `:as` option, or " \ + "you may be overriding a route already defined by a resource with the same naming. " \ + "For the latter, you can restrict the routes created with `resources` as explained here: \n" \ + "http://guides.rubyonrails.org/routing.html#restricting-the-routes-created" + end + + path = conditions.delete :path_info + ast = conditions.delete :parsed_path_info + path = build_path(path, ast, requirements, anchor) + conditions = build_conditions(conditions, path.names.map { |x| x.to_sym }) + + route = @set.add_route(app, path, conditions, defaults, name) + named_routes[name] = route if name + route + end + + def build_path(path, ast, requirements, anchor) + strexp = Journey::Router::Strexp.new( + ast, + path, + requirements, + SEPARATORS, + anchor) + + pattern = Journey::Path::Pattern.new(strexp) + + builder = Journey::GTG::Builder.new pattern.spec + + # Get all the symbol nodes followed by literals that are not the + # dummy node. + symbols = pattern.spec.grep(Journey::Nodes::Symbol).find_all { |n| + builder.followpos(n).first.literal? + } + + # Get all the symbol nodes preceded by literals. + symbols.concat pattern.spec.find_all(&:literal?).map { |n| + builder.followpos(n).first + }.find_all(&:symbol?) + + symbols.each { |x| + x.regexp = /(?:#{Regexp.union(x.regexp, '-')})+/ + } + + pattern + end + private :build_path + + def build_conditions(current_conditions, path_values) + conditions = current_conditions.dup + + # Rack-Mount requires that :request_method be a regular expression. + # :request_method represents the HTTP verb that matches this route. + # + # Here we munge values before they get sent on to rack-mount. + verbs = conditions[:request_method] || [] + unless verbs.empty? + conditions[:request_method] = %r[^#{verbs.join('|')}$] + end + + conditions.keep_if do |k, _| + k == :action || k == :controller || k == :required_defaults || + @request_class.public_method_defined?(k) || path_values.include?(k) + end + end + private :build_conditions + + class Generator + PARAMETERIZE = lambda do |name, value| + if name == :controller + value + elsif value.is_a?(Array) + value.map { |v| v.to_param }.join('/') + elsif param = value.to_param + param + end + end + + attr_reader :options, :recall, :set, :named_route + + def initialize(named_route, options, recall, set) + @named_route = named_route + @options = options.dup + @recall = recall.dup + @set = set + + normalize_recall! + normalize_options! + normalize_controller_action_id! + use_relative_controller! + normalize_controller! + normalize_action! + end + + def controller + @options[:controller] + end + + def current_controller + @recall[:controller] + end + + def use_recall_for(key) + if @recall[key] && (!@options.key?(key) || @options[key] == @recall[key]) + if !named_route_exists? || segment_keys.include?(key) + @options[key] = @recall.delete(key) + end + end + end + + # Set 'index' as default action for recall + def normalize_recall! + @recall[:action] ||= 'index' + end + + def normalize_options! + # If an explicit :controller was given, always make :action explicit + # too, so that action expiry works as expected for things like + # + # generate({controller: 'content'}, {controller: 'content', action: 'show'}) + # + # (the above is from the unit tests). In the above case, because the + # controller was explicitly given, but no action, the action is implied to + # be "index", not the recalled action of "show". + + if options[:controller] + options[:action] ||= 'index' + options[:controller] = options[:controller].to_s + end + + if options.key?(:action) + options[:action] = (options[:action] || 'index').to_s + end + end + + # This pulls :controller, :action, and :id out of the recall. + # The recall key is only used if there is no key in the options + # or if the key in the options is identical. If any of + # :controller, :action or :id is not found, don't pull any + # more keys from the recall. + def normalize_controller_action_id! + use_recall_for(:controller) or return + use_recall_for(:action) or return + use_recall_for(:id) + end + + # if the current controller is "foo/bar/baz" and controller: "baz/bat" + # is specified, the controller becomes "foo/baz/bat" + def use_relative_controller! + if !named_route && different_controller? && !controller.start_with?("/") + old_parts = current_controller.split('/') + size = controller.count("/") + 1 + parts = old_parts[0...-size] << controller + @options[:controller] = parts.join("/") + end + end + + # Remove leading slashes from controllers + def normalize_controller! + @options[:controller] = controller.sub(%r{^/}, '') if controller + end + + # Move 'index' action from options to recall + def normalize_action! + if @options[:action] == 'index' + @recall[:action] = @options.delete(:action) + end + end + + # Generates a path from routes, returns [path, params]. + # If no route is generated the formatter will raise ActionController::UrlGenerationError + def generate + @set.formatter.generate(named_route, options, recall, PARAMETERIZE) + end + + def different_controller? + return false unless current_controller + controller.to_param != current_controller.to_param + end + + private + def named_route_exists? + named_route && set.named_routes[named_route] + end + + def segment_keys + set.named_routes[named_route].segment_keys + end + end + + # Generate the path indicated by the arguments, and return an array of + # the keys that were not used to generate it. + def extra_keys(options, recall={}) + generate_extras(options, recall).last + end + + def generate_extras(options, recall={}) + route_key = options.delete :use_route + path, params = generate(route_key, options, recall) + return path, params.keys + end + + def generate(route_key, options, recall = {}) + Generator.new(route_key, options, recall, self).generate + end + private :generate + + RESERVED_OPTIONS = [:host, :protocol, :port, :subdomain, :domain, :tld_length, + :trailing_slash, :anchor, :params, :only_path, :script_name, + :original_script_name, :relative_url_root] + + def optimize_routes_generation? + default_url_options.empty? + end + + def find_script_name(options) + options.delete(:script_name) || find_relative_url_root(options) || '' + end + + def find_relative_url_root(options) + options.delete(:relative_url_root) || relative_url_root + end + + def path_for(options, route_name = nil) + url_for(options, route_name, PATH) + end + + # The +options+ argument must be a hash whose keys are *symbols*. + def url_for(options, route_name = nil, url_strategy = UNKNOWN) + options = default_url_options.merge options + + user = password = nil + + if options[:user] && options[:password] + user = options.delete :user + password = options.delete :password + end + + recall = options.delete(:_recall) { {} } + + original_script_name = options.delete(:original_script_name) + script_name = find_script_name options + + if original_script_name + script_name = original_script_name + script_name + end + + path_options = options.dup + RESERVED_OPTIONS.each { |ro| path_options.delete ro } + + path, params = generate(route_name, path_options, recall) + + if options.key? :params + params.merge! options[:params] + end + + options[:path] = path + options[:script_name] = script_name + options[:params] = params + options[:user] = user + options[:password] = password + + url_strategy.call options + end + + def call(env) + req = request_class.new(env) + req.path_info = Journey::Router::Utils.normalize_path(req.path_info) + @router.serve(req) + end + + def recognize_path(path, environment = {}) + method = (environment[:method] || "GET").to_s.upcase + path = Journey::Router::Utils.normalize_path(path) unless path =~ %r{://} + extras = environment[:extras] || {} + + begin + env = Rack::MockRequest.env_for(path, {:method => method}) + rescue URI::InvalidURIError => e + raise ActionController::RoutingError, e.message + end + + req = request_class.new(env) + @router.recognize(req) do |route, params| + params.merge!(extras) + params.each do |key, value| + if value.is_a?(String) + value = value.dup.force_encoding(Encoding::BINARY) + params[key] = URI.parser.unescape(value) + end + end + old_params = req.path_parameters + req.path_parameters = old_params.merge params + app = route.app + if app.matches?(req) && app.dispatcher? + dispatcher = app.app + + if dispatcher.controller(params, false) + dispatcher.prepare_params!(params) + return params + else + raise ActionController::RoutingError, "A route matches #{path.inspect}, but references missing controller: #{params[:controller].camelize}Controller" + end + end + end + + raise ActionController::RoutingError, "No route matches #{path.inspect}" + end + end + # :startdoc: + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/routing/routes_proxy.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/routing/routes_proxy.rb new file mode 100644 index 0000000..040ea04 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/routing/routes_proxy.rb @@ -0,0 +1,42 @@ +require 'active_support/core_ext/array/extract_options' + +module ActionDispatch + module Routing + class RoutesProxy #:nodoc: + include ActionDispatch::Routing::UrlFor + + attr_accessor :scope, :routes + alias :_routes :routes + + def initialize(routes, scope, helpers) + @routes, @scope = routes, scope + @helpers = helpers + end + + def url_options + scope.send(:_with_routes, routes) do + scope.url_options + end + end + + def respond_to?(method, include_private = false) + super || @helpers.respond_to?(method) + end + + def method_missing(method, *args) + if @helpers.respond_to?(method) + self.class.class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def #{method}(*args) + options = args.extract_options! + args << url_options.merge((options || {}).symbolize_keys) + @helpers.#{method}(*args) + end + RUBY + send(method, *args) + else + super + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/routing/url_for.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/routing/url_for.rb new file mode 100644 index 0000000..9780bd0 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/routing/url_for.rb @@ -0,0 +1,196 @@ +module ActionDispatch + module Routing + # In config/routes.rb you define URL-to-controller mappings, but the reverse + # is also possible: an URL can be generated from one of your routing definitions. + # URL generation functionality is centralized in this module. + # + # See ActionDispatch::Routing for general information about routing and routes.rb. + # + # Tip: If you need to generate URLs from your models or some other place, + # then ActionController::UrlFor is what you're looking for. Read on for + # an introduction. In general, this module should not be included on its own, + # as it is usually included by url_helpers (as in Rails.application.routes.url_helpers). + # + # == URL generation from parameters + # + # As you may know, some functions, such as ActionController::Base#url_for + # and ActionView::Helpers::UrlHelper#link_to, can generate URLs given a set + # of parameters. For example, you've probably had the chance to write code + # like this in one of your views: + # + # <%= link_to('Click here', controller: 'users', + # action: 'new', message: 'Welcome!') %> + # # => Click here + # + # link_to, and all other functions that require URL generation functionality, + # actually use ActionController::UrlFor under the hood. And in particular, + # they use the ActionController::UrlFor#url_for method. One can generate + # the same path as the above example by using the following code: + # + # include UrlFor + # url_for(controller: 'users', + # action: 'new', + # message: 'Welcome!', + # only_path: true) + # # => "/users/new?message=Welcome%21" + # + # Notice the only_path: true part. This is because UrlFor has no + # information about the website hostname that your Rails app is serving. So if you + # want to include the hostname as well, then you must also pass the :host + # argument: + # + # include UrlFor + # url_for(controller: 'users', + # action: 'new', + # message: 'Welcome!', + # host: 'www.example.com') + # # => "http://www.example.com/users/new?message=Welcome%21" + # + # By default, all controllers and views have access to a special version of url_for, + # that already knows what the current hostname is. So if you use url_for in your + # controllers or your views, then you don't need to explicitly pass the :host + # argument. + # + # For convenience reasons, mailers provide a shortcut for ActionController::UrlFor#url_for. + # So within mailers, you only have to type 'url_for' instead of 'ActionController::UrlFor#url_for' + # in full. However, mailers don't have hostname information, and that's why you'll still + # have to specify the :host argument when generating URLs in mailers. + # + # + # == URL generation for named routes + # + # UrlFor also allows one to access methods that have been auto-generated from + # named routes. For example, suppose that you have a 'users' resource in your + # config/routes.rb: + # + # resources :users + # + # This generates, among other things, the method users_path. By default, + # this method is accessible from your controllers, views and mailers. If you need + # to access this auto-generated method from other places (such as a model), then + # you can do that by including Rails.application.routes.url_helpers in your class: + # + # class User < ActiveRecord::Base + # include Rails.application.routes.url_helpers + # + # def base_uri + # user_path(self) + # end + # end + # + # User.find(1).base_uri # => "/users/1" + # + module UrlFor + extend ActiveSupport::Concern + include PolymorphicRoutes + + included do + unless method_defined?(:default_url_options) + # Including in a class uses an inheritable hash. Modules get a plain hash. + if respond_to?(:class_attribute) + class_attribute :default_url_options + else + mattr_writer :default_url_options + end + + self.default_url_options = {} + end + + include(*_url_for_modules) if respond_to?(:_url_for_modules) + end + + def initialize(*) + @_routes = nil + super + end + + # Hook overridden in controller to add request information + # with `default_url_options`. Application logic should not + # go into url_options. + def url_options + default_url_options + end + + # Generate a url based on the options provided, default_url_options and the + # routes defined in routes.rb. The following options are supported: + # + # * :only_path - If true, the relative url is returned. Defaults to +false+. + # * :protocol - The protocol to connect to. Defaults to 'http'. + # * :host - Specifies the host the link should be targeted at. + # If :only_path is false, this option must be + # provided either explicitly, or via +default_url_options+. + # * :subdomain - Specifies the subdomain of the link, using the +tld_length+ + # to split the subdomain from the host. + # If false, removes all subdomains from the host part of the link. + # * :domain - Specifies the domain of the link, using the +tld_length+ + # to split the domain from the host. + # * :tld_length - Number of labels the TLD id composed of, only used if + # :subdomain or :domain are supplied. Defaults to + # ActionDispatch::Http::URL.tld_length, which in turn defaults to 1. + # * :port - Optionally specify the port to connect to. + # * :anchor - An anchor name to be appended to the path. + # * :trailing_slash - If true, adds a trailing slash, as in "/archive/2009/" + # * :script_name - Specifies application path relative to domain root. If provided, prepends application path. + # + # Any other key (:controller, :action, etc.) given to + # +url_for+ is forwarded to the Routes module. + # + # url_for controller: 'tasks', action: 'testing', host: 'somehost.org', port: '8080' + # # => 'http://somehost.org:8080/tasks/testing' + # url_for controller: 'tasks', action: 'testing', host: 'somehost.org', anchor: 'ok', only_path: true + # # => '/tasks/testing#ok' + # url_for controller: 'tasks', action: 'testing', trailing_slash: true + # # => 'http://somehost.org/tasks/testing/' + # url_for controller: 'tasks', action: 'testing', host: 'somehost.org', number: '33' + # # => 'http://somehost.org/tasks/testing?number=33' + # url_for controller: 'tasks', action: 'testing', host: 'somehost.org', script_name: "/myapp" + # # => 'http://somehost.org/myapp/tasks/testing' + # url_for controller: 'tasks', action: 'testing', host: 'somehost.org', script_name: "/myapp", only_path: true + # # => '/myapp/tasks/testing' + def url_for(options = nil) + case options + when nil + _routes.url_for(url_options.symbolize_keys) + when Hash + route_name = options.delete :use_route + _routes.url_for(options.symbolize_keys.reverse_merge!(url_options), + route_name) + when String + options + when Symbol + HelperMethodBuilder.url.handle_string_call self, options + when Array + components = options.dup + polymorphic_url(components, components.extract_options!) + when Class + HelperMethodBuilder.url.handle_class_call self, options + else + HelperMethodBuilder.url.handle_model_call self, options + end + end + + protected + + def optimize_routes_generation? + _routes.optimize_routes_generation? && default_url_options.empty? + end + + def _with_routes(routes) + old_routes, @_routes = @_routes, routes + yield + ensure + @_routes = old_routes + end + + def _routes_context + self + end + + private + + def _generate_paths_by_default + true + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/testing/assertions.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/testing/assertions.rb new file mode 100644 index 0000000..715d94d --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/testing/assertions.rb @@ -0,0 +1,22 @@ +require 'rails-dom-testing' + +module ActionDispatch + module Assertions + autoload :ResponseAssertions, 'action_dispatch/testing/assertions/response' + autoload :RoutingAssertions, 'action_dispatch/testing/assertions/routing' + + extend ActiveSupport::Concern + + include ResponseAssertions + include RoutingAssertions + include Rails::Dom::Testing::Assertions + + def html_document + @html_document ||= if @response.content_type.to_s =~ /xml$/ + Nokogiri::XML::Document.parse(@response.body) + else + Nokogiri::HTML::Document.parse(@response.body) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/testing/assertions/dom.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/testing/assertions/dom.rb new file mode 100644 index 0000000..fb579b5 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/testing/assertions/dom.rb @@ -0,0 +1,3 @@ +require 'active_support/deprecation' + +ActiveSupport::Deprecation.warn("ActionDispatch::Assertions::DomAssertions has been extracted to the rails-dom-testing gem.") \ No newline at end of file diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/testing/assertions/response.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/testing/assertions/response.rb new file mode 100644 index 0000000..13a7222 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/testing/assertions/response.rb @@ -0,0 +1,82 @@ + +module ActionDispatch + module Assertions + # A small suite of assertions that test responses from \Rails applications. + module ResponseAssertions + # Asserts that the response is one of the following types: + # + # * :success - Status code was in the 200-299 range + # * :redirect - Status code was in the 300-399 range + # * :missing - Status code was 404 + # * :error - Status code was in the 500-599 range + # + # You can also pass an explicit status number like assert_response(501) + # or its symbolic equivalent assert_response(:not_implemented). + # See Rack::Utils::SYMBOL_TO_STATUS_CODE for a full list. + # + # # assert that the response was a redirection + # assert_response :redirect + # + # # assert that the response code was status code 401 (unauthorized) + # assert_response 401 + def assert_response(type, message = nil) + message ||= "Expected response to be a <#{type}>, but was <#{@response.response_code}>" + + if Symbol === type + if [:success, :missing, :redirect, :error].include?(type) + assert @response.send("#{type}?"), message + else + code = Rack::Utils::SYMBOL_TO_STATUS_CODE[type] + if code.nil? + raise ArgumentError, "Invalid response type :#{type}" + end + assert_equal code, @response.response_code, message + end + else + assert_equal type, @response.response_code, message + end + end + + # Assert that the redirection options passed in match those of the redirect called in the latest action. + # This match can be partial, such that assert_redirected_to(controller: "weblog") will also + # match the redirection of redirect_to(controller: "weblog", action: "show") and so on. + # + # # assert that the redirection was to the "index" action on the WeblogController + # assert_redirected_to controller: "weblog", action: "index" + # + # # assert that the redirection was to the named route login_url + # assert_redirected_to login_url + # + # # assert that the redirection was to the url for @customer + # assert_redirected_to @customer + # + # # asserts that the redirection matches the regular expression + # assert_redirected_to %r(\Ahttp://example.org) + def assert_redirected_to(options = {}, message=nil) + assert_response(:redirect, message) + return true if options === @response.location + + redirect_is = normalize_argument_to_redirection(@response.location) + redirect_expected = normalize_argument_to_redirection(options) + + message ||= "Expected response to be a redirect to <#{redirect_expected}> but was a redirect to <#{redirect_is}>" + assert_operator redirect_expected, :===, redirect_is, message + end + + private + # Proxy to to_param if the object will respond to it. + def parameterize(value) + value.respond_to?(:to_param) ? value.to_param : value + end + + def normalize_argument_to_redirection(fragment) + if Regexp === fragment + fragment + else + handle = @controller || ActionController::Redirecting + handle._compute_redirect_to_location(@request, fragment) + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/testing/assertions/routing.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/testing/assertions/routing.rb new file mode 100644 index 0000000..607ac7a --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/testing/assertions/routing.rb @@ -0,0 +1,218 @@ +require 'uri' +require 'active_support/core_ext/hash/indifferent_access' +require 'active_support/core_ext/string/access' +require 'action_controller/metal/exceptions' + +module ActionDispatch + module Assertions + # Suite of assertions to test routes generated by \Rails and the handling of requests made to them. + module RoutingAssertions + # Asserts that the routing of the given +path+ was handled correctly and that the parsed options (given in the +expected_options+ hash) + # match +path+. Basically, it asserts that \Rails recognizes the route given by +expected_options+. + # + # Pass a hash in the second argument (+path+) to specify the request method. This is useful for routes + # requiring a specific HTTP method. The hash should contain a :path with the incoming request path + # and a :method containing the required HTTP verb. + # + # # assert that POSTing to /items will call the create action on ItemsController + # assert_recognizes({controller: 'items', action: 'create'}, {path: 'items', method: :post}) + # + # You can also pass in +extras+ with a hash containing URL parameters that would normally be in the query string. This can be used + # to assert that values in the query string string will end up in the params hash correctly. To test query strings you must use the + # extras argument, appending the query string on the path directly will not work. For example: + # + # # assert that a path of '/items/list/1?view=print' returns the correct options + # assert_recognizes({controller: 'items', action: 'list', id: '1', view: 'print'}, 'items/list/1', { view: "print" }) + # + # The +message+ parameter allows you to pass in an error message that is displayed upon failure. + # + # # Check the default route (i.e., the index action) + # assert_recognizes({controller: 'items', action: 'index'}, 'items') + # + # # Test a specific action + # assert_recognizes({controller: 'items', action: 'list'}, 'items/list') + # + # # Test an action with a parameter + # assert_recognizes({controller: 'items', action: 'destroy', id: '1'}, 'items/destroy/1') + # + # # Test a custom route + # assert_recognizes({controller: 'items', action: 'show', id: '1'}, 'view/item1') + def assert_recognizes(expected_options, path, extras={}, msg=nil) + if path.is_a?(Hash) && path[:method].to_s == "all" + [:get, :post, :put, :delete].each do |method| + assert_recognizes(expected_options, path.merge(method: method), extras, msg) + end + else + request = recognized_request_for(path, extras, msg) + + expected_options = expected_options.clone + + expected_options.stringify_keys! + + msg = message(msg, "") { + sprintf("The recognized options <%s> did not match <%s>, difference:", + request.path_parameters, expected_options) + } + + assert_equal(expected_options, request.path_parameters, msg) + end + end + + # Asserts that the provided options can be used to generate the provided path. This is the inverse of +assert_recognizes+. + # The +extras+ parameter is used to tell the request the names and values of additional request parameters that would be in + # a query string. The +message+ parameter allows you to specify a custom error message for assertion failures. + # + # The +defaults+ parameter is unused. + # + # # Asserts that the default action is generated for a route with no action + # assert_generates "/items", controller: "items", action: "index" + # + # # Tests that the list action is properly routed + # assert_generates "/items/list", controller: "items", action: "list" + # + # # Tests the generation of a route with a parameter + # assert_generates "/items/list/1", { controller: "items", action: "list", id: "1" } + # + # # Asserts that the generated route gives us our custom route + # assert_generates "changesets/12", { controller: 'scm', action: 'show_diff', revision: "12" } + def assert_generates(expected_path, options, defaults={}, extras={}, message=nil) + if expected_path =~ %r{://} + fail_on(URI::InvalidURIError, message) do + uri = URI.parse(expected_path) + expected_path = uri.path.to_s.empty? ? "/" : uri.path + end + else + expected_path = "/#{expected_path}" unless expected_path.first == '/' + end + # Load routes.rb if it hasn't been loaded. + + generated_path, extra_keys = @routes.generate_extras(options, defaults) + found_extras = options.reject { |k, _| ! extra_keys.include? k } + + msg = message || sprintf("found extras <%s>, not <%s>", found_extras, extras) + assert_equal(extras, found_extras, msg) + + msg = message || sprintf("The generated path <%s> did not match <%s>", generated_path, + expected_path) + assert_equal(expected_path, generated_path, msg) + end + + # Asserts that path and options match both ways; in other words, it verifies that path generates + # options and then that options generates path. This essentially combines +assert_recognizes+ + # and +assert_generates+ into one step. + # + # The +extras+ hash allows you to specify options that would normally be provided as a query string to the action. The + # +message+ parameter allows you to specify a custom error message to display upon failure. + # + # # Assert a basic route: a controller with the default action (index) + # assert_routing '/home', controller: 'home', action: 'index' + # + # # Test a route generated with a specific controller, action, and parameter (id) + # assert_routing '/entries/show/23', controller: 'entries', action: 'show', id: 23 + # + # # Assert a basic route (controller + default action), with an error message if it fails + # assert_routing '/store', { controller: 'store', action: 'index' }, {}, {}, 'Route for store index not generated properly' + # + # # Tests a route, providing a defaults hash + # assert_routing 'controller/action/9', {id: "9", item: "square"}, {controller: "controller", action: "action"}, {}, {item: "square"} + # + # # Tests a route with a HTTP method + # assert_routing({ method: 'put', path: '/product/321' }, { controller: "product", action: "update", id: "321" }) + def assert_routing(path, options, defaults={}, extras={}, message=nil) + assert_recognizes(options, path, extras, message) + + controller, default_controller = options[:controller], defaults[:controller] + if controller && controller.include?(?/) && default_controller && default_controller.include?(?/) + options[:controller] = "/#{controller}" + end + + generate_options = options.dup.delete_if{ |k, _| defaults.key?(k) } + assert_generates(path.is_a?(Hash) ? path[:path] : path, generate_options, defaults, extras, message) + end + + # A helper to make it easier to test different route configurations. + # This method temporarily replaces @routes + # with a new RouteSet instance. + # + # The new instance is yielded to the passed block. Typically the block + # will create some routes using set.draw { match ... }: + # + # with_routing do |set| + # set.draw do + # resources :users + # end + # assert_equal "/users", users_path + # end + # + def with_routing + old_routes, @routes = @routes, ActionDispatch::Routing::RouteSet.new + if defined?(@controller) && @controller + old_controller, @controller = @controller, @controller.clone + _routes = @routes + + @controller.singleton_class.send(:include, _routes.url_helpers) + @controller.view_context_class = Class.new(@controller.view_context_class) do + include _routes.url_helpers + end + end + yield @routes + ensure + @routes = old_routes + if defined?(@controller) && @controller + @controller = old_controller + end + end + + # ROUTES TODO: These assertions should really work in an integration context + def method_missing(selector, *args, &block) + if defined?(@controller) && @controller && defined?(@routes) && @routes && @routes.named_routes.route_defined?(selector) + @controller.send(selector, *args, &block) + else + super + end + end + + private + # Recognizes the route for a given path. + def recognized_request_for(path, extras = {}, msg) + if path.is_a?(Hash) + method = path[:method] + path = path[:path] + else + method = :get + end + + # Assume given controller + request = ActionController::TestRequest.new + + if path =~ %r{://} + fail_on(URI::InvalidURIError, msg) do + uri = URI.parse(path) + request.env["rack.url_scheme"] = uri.scheme || "http" + request.host = uri.host if uri.host + request.port = uri.port if uri.port + request.path = uri.path.to_s.empty? ? "/" : uri.path + end + else + path = "/#{path}" unless path.first == "/" + request.path = path + end + + request.request_method = method if method + + params = fail_on(ActionController::RoutingError, msg) do + @routes.recognize_path(path, { :method => method, :extras => extras }) + end + request.path_parameters = params.with_indifferent_access + + request + end + + def fail_on(exception_class, message) + yield + rescue exception_class => e + raise Minitest::Assertion, message || e.message + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/testing/assertions/selector.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/testing/assertions/selector.rb new file mode 100644 index 0000000..7361e6c --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/testing/assertions/selector.rb @@ -0,0 +1,3 @@ +require 'active_support/deprecation' + +ActiveSupport::Deprecation.warn("ActionDispatch::Assertions::SelectorAssertions has been extracted to the rails-dom-testing gem.") diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/testing/assertions/tag.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/testing/assertions/tag.rb new file mode 100644 index 0000000..da98b1d --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/testing/assertions/tag.rb @@ -0,0 +1,3 @@ +require 'active_support/deprecation' + +ActiveSupport::Deprecation.warn('`ActionDispatch::Assertions::TagAssertions` has been extracted to the rails-dom-testing gem.') diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/testing/integration.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/testing/integration.rb new file mode 100644 index 0000000..9673cdb --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/testing/integration.rb @@ -0,0 +1,513 @@ +require 'stringio' +require 'uri' +require 'active_support/core_ext/kernel/singleton_class' +require 'active_support/core_ext/object/try' +require 'rack/test' +require 'minitest' + +module ActionDispatch + module Integration #:nodoc: + module RequestHelpers + # Performs a GET request with the given parameters. + # + # - +path+: The URI (as a String) on which you want to perform a GET + # request. + # - +parameters+: The HTTP parameters that you want to pass. This may + # be +nil+, + # a Hash, or a String that is appropriately encoded + # (application/x-www-form-urlencoded or + # multipart/form-data). + # - +headers_or_env+: Additional headers to pass, as a Hash. The headers will be + # merged into the Rack env hash. + # + # This method returns a Response object, which one can use to + # inspect the details of the response. Furthermore, if this method was + # called from an ActionDispatch::IntegrationTest object, then that + # object's @response instance variable will point to the same + # response object. + # + # You can also perform POST, PATCH, PUT, DELETE, and HEAD requests with + # +#post+, +#patch+, +#put+, +#delete+, and +#head+. + def get(path, parameters = nil, headers_or_env = nil) + process :get, path, parameters, headers_or_env + end + + # Performs a POST request with the given parameters. See +#get+ for more + # details. + def post(path, parameters = nil, headers_or_env = nil) + process :post, path, parameters, headers_or_env + end + + # Performs a PATCH request with the given parameters. See +#get+ for more + # details. + def patch(path, parameters = nil, headers_or_env = nil) + process :patch, path, parameters, headers_or_env + end + + # Performs a PUT request with the given parameters. See +#get+ for more + # details. + def put(path, parameters = nil, headers_or_env = nil) + process :put, path, parameters, headers_or_env + end + + # Performs a DELETE request with the given parameters. See +#get+ for + # more details. + def delete(path, parameters = nil, headers_or_env = nil) + process :delete, path, parameters, headers_or_env + end + + # Performs a HEAD request with the given parameters. See +#get+ for more + # details. + def head(path, parameters = nil, headers_or_env = nil) + process :head, path, parameters, headers_or_env + end + + # Performs an XMLHttpRequest request with the given parameters, mirroring + # a request from the Prototype library. + # + # The request_method is +:get+, +:post+, +:patch+, +:put+, +:delete+ or + # +:head+; the parameters are +nil+, a hash, or a url-encoded or multipart + # string; the headers are a hash. + def xml_http_request(request_method, path, parameters = nil, headers_or_env = nil) + headers_or_env ||= {} + headers_or_env['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest' + headers_or_env['HTTP_ACCEPT'] ||= [Mime::JS, Mime::HTML, Mime::XML, 'text/xml', Mime::ALL].join(', ') + process(request_method, path, parameters, headers_or_env) + end + alias xhr :xml_http_request + + # Follow a single redirect response. If the last response was not a + # redirect, an exception will be raised. Otherwise, the redirect is + # performed on the location header. + def follow_redirect! + raise "not a redirect! #{status} #{status_message}" unless redirect? + get(response.location) + status + end + + # Performs a request using the specified method, following any subsequent + # redirect. Note that the redirects are followed until the response is + # not a redirect--this means you may run into an infinite loop if your + # redirect loops back to itself. + def request_via_redirect(http_method, path, parameters = nil, headers_or_env = nil) + process(http_method, path, parameters, headers_or_env) + follow_redirect! while redirect? + status + end + + # Performs a GET request, following any subsequent redirect. + # See +request_via_redirect+ for more information. + def get_via_redirect(path, parameters = nil, headers_or_env = nil) + request_via_redirect(:get, path, parameters, headers_or_env) + end + + # Performs a POST request, following any subsequent redirect. + # See +request_via_redirect+ for more information. + def post_via_redirect(path, parameters = nil, headers_or_env = nil) + request_via_redirect(:post, path, parameters, headers_or_env) + end + + # Performs a PATCH request, following any subsequent redirect. + # See +request_via_redirect+ for more information. + def patch_via_redirect(path, parameters = nil, headers_or_env = nil) + request_via_redirect(:patch, path, parameters, headers_or_env) + end + + # Performs a PUT request, following any subsequent redirect. + # See +request_via_redirect+ for more information. + def put_via_redirect(path, parameters = nil, headers_or_env = nil) + request_via_redirect(:put, path, parameters, headers_or_env) + end + + # Performs a DELETE request, following any subsequent redirect. + # See +request_via_redirect+ for more information. + def delete_via_redirect(path, parameters = nil, headers_or_env = nil) + request_via_redirect(:delete, path, parameters, headers_or_env) + end + end + + # An instance of this class represents a set of requests and responses + # performed sequentially by a test process. Because you can instantiate + # multiple sessions and run them side-by-side, you can also mimic (to some + # limited extent) multiple simultaneous users interacting with your system. + # + # Typically, you will instantiate a new session using + # IntegrationTest#open_session, rather than instantiating + # Integration::Session directly. + class Session + DEFAULT_HOST = "www.example.com" + + include Minitest::Assertions + include TestProcess, RequestHelpers, Assertions + + %w( status status_message headers body redirect? ).each do |method| + delegate method, :to => :response, :allow_nil => true + end + + %w( path ).each do |method| + delegate method, :to => :request, :allow_nil => true + end + + # The hostname used in the last request. + def host + @host || DEFAULT_HOST + end + attr_writer :host + + # The remote_addr used in the last request. + attr_accessor :remote_addr + + # The Accept header to send. + attr_accessor :accept + + # A map of the cookies returned by the last response, and which will be + # sent with the next request. + def cookies + _mock_session.cookie_jar + end + + # A reference to the controller instance used by the last request. + attr_reader :controller + + # A reference to the request instance used by the last request. + attr_reader :request + + # A reference to the response instance used by the last request. + attr_reader :response + + # A running counter of the number of requests processed. + attr_accessor :request_count + + include ActionDispatch::Routing::UrlFor + + # Create and initialize a new Session instance. + def initialize(app) + super() + @app = app + + # If the app is a Rails app, make url_helpers available on the session + # This makes app.url_for and app.foo_path available in the console + if app.respond_to?(:routes) + singleton_class.class_eval do + include app.routes.url_helpers + include app.routes.mounted_helpers + end + end + + reset! + end + + def url_options + @url_options ||= default_url_options.dup.tap do |url_options| + url_options.reverse_merge!(controller.url_options) if controller + + if @app.respond_to?(:routes) + url_options.reverse_merge!(@app.routes.default_url_options) + end + + url_options.reverse_merge!(:host => host, :protocol => https? ? "https" : "http") + end + end + + # Resets the instance. This can be used to reset the state information + # in an existing session instance, so it can be used from a clean-slate + # condition. + # + # session.reset! + def reset! + @https = false + @controller = @request = @response = nil + @_mock_session = nil + @request_count = 0 + @url_options = nil + + self.host = DEFAULT_HOST + self.remote_addr = "127.0.0.1" + self.accept = "text/xml,application/xml,application/xhtml+xml," + + "text/html;q=0.9,text/plain;q=0.8,image/png," + + "*/*;q=0.5" + + unless defined? @named_routes_configured + # the helpers are made protected by default--we make them public for + # easier access during testing and troubleshooting. + @named_routes_configured = true + end + end + + # Specify whether or not the session should mimic a secure HTTPS request. + # + # session.https! + # session.https!(false) + def https!(flag = true) + @https = flag + end + + # Returns +true+ if the session is mimicking a secure HTTPS request. + # + # if session.https? + # ... + # end + def https? + @https + end + + # Set the host name to use in the next request. + # + # session.host! "www.example.com" + alias :host! :host= + + private + def _mock_session + @_mock_session ||= Rack::MockSession.new(@app, host) + end + + # Performs the actual request. + def process(method, path, parameters = nil, headers_or_env = nil) + if path =~ %r{://} + location = URI.parse(path) + https! URI::HTTPS === location if location.scheme + host! "#{location.host}:#{location.port}" if location.host + path = location.query ? "#{location.path}?#{location.query}" : location.path + end + + hostname, port = host.split(':') + + env = { + :method => method, + :params => parameters, + + "SERVER_NAME" => hostname, + "SERVER_PORT" => port || (https? ? "443" : "80"), + "HTTPS" => https? ? "on" : "off", + "rack.url_scheme" => https? ? "https" : "http", + + "REQUEST_URI" => path, + "HTTP_HOST" => host, + "REMOTE_ADDR" => remote_addr, + "CONTENT_TYPE" => "application/x-www-form-urlencoded", + "HTTP_ACCEPT" => accept + } + # this modifies the passed env directly + Http::Headers.new(env).merge!(headers_or_env || {}) + + session = Rack::Test::Session.new(_mock_session) + + # NOTE: rack-test v0.5 doesn't build a default uri correctly + # Make sure requested path is always a full uri + session.request(build_full_uri(path, env), env) + + @request_count += 1 + @request = ActionDispatch::Request.new(session.last_request.env) + response = _mock_session.last_response + @response = ActionDispatch::TestResponse.from_response(response) + @html_document = nil + @html_scanner_document = nil + @url_options = nil + + @controller = session.last_request.env['action_controller.instance'] + + return response.status + end + + def build_full_uri(path, env) + "#{env['rack.url_scheme']}://#{env['SERVER_NAME']}:#{env['SERVER_PORT']}#{path}" + end + end + + module Runner + include ActionDispatch::Assertions + + def app + @app ||= nil + end + + # Reset the current session. This is useful for testing multiple sessions + # in a single test case. + def reset! + @integration_session = Integration::Session.new(app) + end + + def remove! # :nodoc: + @integration_session = nil + end + + %w(get post patch put head delete cookies assigns + xml_http_request xhr get_via_redirect post_via_redirect).each do |method| + define_method(method) do |*args| + reset! unless integration_session + + # reset the html_document variable, except for cookies/assigns calls + unless method == 'cookies' || method == 'assigns' + @html_document = nil + @html_scanner_document = nil + reset_template_assertion + end + + integration_session.__send__(method, *args).tap do + copy_session_variables! + end + end + end + + # Open a new session instance. If a block is given, the new session is + # yielded to the block before being returned. + # + # session = open_session do |sess| + # sess.extend(CustomAssertions) + # end + # + # By default, a single session is automatically created for you, but you + # can use this method to open multiple sessions that ought to be tested + # simultaneously. + def open_session + dup.tap do |session| + yield session if block_given? + end + end + + # Copy the instance variables from the current session instance into the + # test instance. + def copy_session_variables! #:nodoc: + return unless integration_session + %w(controller response request).each do |var| + instance_variable_set("@#{var}", @integration_session.__send__(var)) + end + end + + def default_url_options + reset! unless integration_session + integration_session.default_url_options + end + + def default_url_options=(options) + reset! unless integration_session + integration_session.default_url_options = options + end + + def respond_to?(method, include_private = false) + integration_session.respond_to?(method, include_private) || super + end + + # Delegate unhandled messages to the current session instance. + def method_missing(sym, *args, &block) + reset! unless integration_session + if integration_session.respond_to?(sym) + integration_session.__send__(sym, *args, &block).tap do + copy_session_variables! + end + else + super + end + end + + private + def integration_session + @integration_session ||= nil + end + end + end + + # An integration test spans multiple controllers and actions, + # tying them all together to ensure they work together as expected. It tests + # more completely than either unit or functional tests do, exercising the + # entire stack, from the dispatcher to the database. + # + # At its simplest, you simply extend IntegrationTest and write your tests + # using the get/post methods: + # + # require "test_helper" + # + # class ExampleTest < ActionDispatch::IntegrationTest + # fixtures :people + # + # def test_login + # # get the login page + # get "/login" + # assert_equal 200, status + # + # # post the login and follow through to the home page + # post "/login", username: people(:jamis).username, + # password: people(:jamis).password + # follow_redirect! + # assert_equal 200, status + # assert_equal "/home", path + # end + # end + # + # However, you can also have multiple session instances open per test, and + # even extend those instances with assertions and methods to create a very + # powerful testing DSL that is specific for your application. You can even + # reference any named routes you happen to have defined. + # + # require "test_helper" + # + # class AdvancedTest < ActionDispatch::IntegrationTest + # fixtures :people, :rooms + # + # def test_login_and_speak + # jamis, david = login(:jamis), login(:david) + # room = rooms(:office) + # + # jamis.enter(room) + # jamis.speak(room, "anybody home?") + # + # david.enter(room) + # david.speak(room, "hello!") + # end + # + # private + # + # module CustomAssertions + # def enter(room) + # # reference a named route, for maximum internal consistency! + # get(room_url(id: room.id)) + # assert(...) + # ... + # end + # + # def speak(room, message) + # xml_http_request "/say/#{room.id}", message: message + # assert(...) + # ... + # end + # end + # + # def login(who) + # open_session do |sess| + # sess.extend(CustomAssertions) + # who = people(who) + # sess.post "/login", username: who.username, + # password: who.password + # assert(...) + # end + # end + # end + class IntegrationTest < ActiveSupport::TestCase + include Integration::Runner + include ActionController::TemplateAssertions + include ActionDispatch::Routing::UrlFor + + @@app = nil + + def self.app + @@app || ActionDispatch.test_app + end + + def self.app=(app) + @@app = app + end + + def app + super || self.class.app + end + + def url_options + reset! unless integration_session + integration_session.url_options + end + + def document_root_element + html_document.root + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/testing/test_process.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/testing/test_process.rb new file mode 100644 index 0000000..630e6a9 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/testing/test_process.rb @@ -0,0 +1,44 @@ +require 'action_dispatch/middleware/cookies' +require 'action_dispatch/middleware/flash' +require 'active_support/core_ext/hash/indifferent_access' + +module ActionDispatch + module TestProcess + def assigns(key = nil) + assigns = {}.with_indifferent_access + @controller.view_assigns.each { |k, v| assigns.regular_writer(k, v) } + key.nil? ? assigns : assigns[key] + end + + def session + @request.session + end + + def flash + @request.flash + end + + def cookies + @request.cookie_jar + end + + def redirect_to_url + @response.redirect_url + end + + # Shortcut for Rack::Test::UploadedFile.new(File.join(ActionController::TestCase.fixture_path, path), type): + # + # post :change_avatar, avatar: fixture_file_upload('files/spongebob.png', 'image/png') + # + # To upload binary files on Windows, pass :binary as the last parameter. + # This will not affect other platforms: + # + # post :change_avatar, avatar: fixture_file_upload('files/spongebob.png', 'image/png', :binary) + def fixture_file_upload(path, mime_type = nil, binary = false) + if self.class.respond_to?(:fixture_path) && self.class.fixture_path + path = File.join(self.class.fixture_path, path) + end + Rack::Test::UploadedFile.new(path, mime_type, binary) + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/testing/test_request.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/testing/test_request.rb new file mode 100644 index 0000000..de3dc5f --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/testing/test_request.rb @@ -0,0 +1,78 @@ +require 'active_support/core_ext/hash/indifferent_access' +require 'rack/utils' + +module ActionDispatch + class TestRequest < Request + DEFAULT_ENV = Rack::MockRequest.env_for('/', + 'HTTP_HOST' => 'test.host', + 'REMOTE_ADDR' => '0.0.0.0', + 'HTTP_USER_AGENT' => 'Rails Testing' + ) + + def self.new(env = {}) + super + end + + def initialize(env = {}) + env = Rails.application.env_config.merge(env) if defined?(Rails.application) && Rails.application + super(default_env.merge(env)) + end + + def request_method=(method) + @env['REQUEST_METHOD'] = method.to_s.upcase + end + + def host=(host) + @env['HTTP_HOST'] = host + end + + def port=(number) + @env['SERVER_PORT'] = number.to_i + end + + def request_uri=(uri) + @env['REQUEST_URI'] = uri + end + + def path=(path) + @env['PATH_INFO'] = path + end + + def action=(action_name) + path_parameters[:action] = action_name.to_s + end + + def if_modified_since=(last_modified) + @env['HTTP_IF_MODIFIED_SINCE'] = last_modified + end + + def if_none_match=(etag) + @env['HTTP_IF_NONE_MATCH'] = etag + end + + def remote_addr=(addr) + @env['REMOTE_ADDR'] = addr + end + + def user_agent=(user_agent) + @env['HTTP_USER_AGENT'] = user_agent + end + + def accept=(mime_types) + @env.delete('action_dispatch.request.accepts') + @env['HTTP_ACCEPT'] = Array(mime_types).collect { |mime_type| mime_type.to_s }.join(",") + end + + alias :rack_cookies :cookies + + def cookies + @cookies ||= {}.with_indifferent_access + end + + private + + def default_env + DEFAULT_ENV + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/testing/test_response.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/testing/test_response.rb new file mode 100644 index 0000000..a9b88ac --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_dispatch/testing/test_response.rb @@ -0,0 +1,25 @@ +module ActionDispatch + # Integration test methods such as ActionDispatch::Integration::Session#get + # and ActionDispatch::Integration::Session#post return objects of class + # TestResponse, which represent the HTTP response results of the requested + # controller actions. + # + # See Response for more information on controller response objects. + class TestResponse < Response + def self.from_response(response) + new response.status, response.headers, response.body, default_headers: nil + end + + # Was the response successful? + alias_method :success?, :successful? + + # Was the URL not found? + alias_method :missing?, :not_found? + + # Were we redirected? + alias_method :redirect?, :redirection? + + # Was there a server-side error? + alias_method :error?, :server_error? + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_pack.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_pack.rb new file mode 100644 index 0000000..77f656d --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_pack.rb @@ -0,0 +1,24 @@ +#-- +# Copyright (c) 2004-2014 David Heinemeier Hansson +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +#++ + +require 'action_pack/version' diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_pack/gem_version.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_pack/gem_version.rb new file mode 100644 index 0000000..15b7e6e --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_pack/gem_version.rb @@ -0,0 +1,15 @@ +module ActionPack + # Returns the version of the currently loaded Action Pack as a Gem::Version + def self.gem_version + Gem::Version.new VERSION::STRING + end + + module VERSION + MAJOR = 4 + MINOR = 2 + TINY = 6 + PRE = nil + + STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".") + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_pack/version.rb b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_pack/version.rb new file mode 100644 index 0000000..7088cd2 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionpack-4.2.6/lib/action_pack/version.rb @@ -0,0 +1,8 @@ +require_relative 'gem_version' + +module ActionPack + # Returns the version of the currently loaded ActionPack as a Gem::Version + def self.version + gem_version + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/CHANGELOG.md b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/CHANGELOG.md new file mode 100644 index 0000000..f3022cd --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/CHANGELOG.md @@ -0,0 +1,327 @@ +## Rails 4.2.6 (March 07, 2016) ## + +* Fix stripping the digest from the automatically generated img tag alt + attribute when assets are handled by Sprockets >=3.0. + + *Bart de Water* + +* Create a new `ActiveSupport::SafeBuffer` instance when `content_for` is flushed. + + Fixes #19890 + + *Yoong Kang Lim* + +* Respect value of `:object` if `:object` is false when rendering. + + Fixes #22260. + + *Yuichiro Kaneko* + +* Generate `week_field` input values using a 1-based index and not a 0-based index + as per the W3 spec: http://www.w3.org/TR/html-markup/datatypes.html#form.data.week + + *Christoph Geschwind* + + +## Rails 4.2.5.2 (February 26, 2016) ## + +* Do not allow render with unpermitted parameter. + + Fixes CVE-2016-2098. + + *Arthur Neves* + + +## Rails 4.2.5.1 (January 25, 2015) ## + +* Adds boolean argument outside_app_allowed to `ActionView::Resolver#find_templates` + method. + + *Aaron Patterson* + + +## Rails 4.2.5 (November 12, 2015) ## + +* Fix `mail_to` when called with `nil` as argument. + + *Rafael Mendonça França* + +* `url_for` does not modify its arguments when generating polymorphic URLs. + + *Bernerd Schaefer* + + +## Rails 4.2.4 (August 24, 2015) ## + +* No Changes * + + +## Rails 4.2.3 (June 25, 2015) ## + +* `translate` should handle `raise` flag correctly in case of both main and default + translation is missing. + + Fixes #19967 + + *Bernard Potocki* + +* `translate` allows `default: [[]]` again for a default value of `[]`. + + Fixes #19640. + + *Adam Prescott* + +* `translate` should accept nils as members of the `:default` + parameter without raising a translation missing error. Fixes a + regression introduced 362557e. + + Fixes #19419 + + *Justin Coyne* + +* `number_to_percentage` does not crash with `Float::NAN` or `Float::INFINITY` + as input when `precision: 0` is used. + + Fixes #19227. + + *Yves Senn* + + +## Rails 4.2.2 (June 16, 2015) ## + +* No Changes * + + +## Rails 4.2.1 (March 19, 2015) ## + +* Default translations that have a lower precedence than an html safe default, + but are not themselves safe, should not be marked as html_safe. + + *Justin Coyne* + +* Added an explicit error message, in `ActionView::PartialRenderer` + for partial `rendering`, when the value of option `as` has invalid characters. + + *Angelo Capilleri* + + +## Rails 4.2.0 (December 20, 2014) ## + +* Local variable in a partial is now available even if a falsy value is + passed to `:object` when rendering a partial. + + Fixes #17373. + + *Agis Anastasopoulos* + +* Add support for `:enforce_utf8` option in `form_for`. + + This is the same option that was added in 06388b0 to `form_tag` and allows + users to skip the insertion of the UTF8 enforcer tag in a form. + + * claudiob * + +* Fix a bug that <%= foo(){ %> and <%= foo()do %> in view templates were not regarded + as Ruby block calls. + + * Akira Matsuda * + +* Update `select_tag` to work correctly with `:include_blank` option passing a string. + + Fixes #16483. + + *Frank Groeneveld* + +* Changed the meaning of `render "foo/bar"`. + + Previously, calling `render "foo/bar"` in a controller action is equivalent + to `render file: "foo/bar"`. In Rails 4.2, this has been changed to mean + `render template: "foo/bar"` instead. If you need to render a file, please + change your code to use the explicit form (`render file: "foo/bar"`) instead. + + *Jeremy Jackson* + +* Add support for ARIA attributes in tags. + + Example: + + <%= f.text_field :name, aria: { required: "true", hidden: "false" } %> + + now generates: + + + + *Paola Garcia Casadiego* + +* Provide a `builder` object when using the `label` form helper in block form. + + The new `builder` object responds to `translation`, allowing I18n fallback support + when you want to customize how a particular label is presented. + + *Alex Robbin* + +* Add I18n support for input/textarea placeholder text. + + Placeholder I18n follows the same convention as `label` I18n. + + *Alex Robbin* + +* Fix that render layout: 'messages/layout' should also be added to the dependency tracker tree. + + *DHH* + +* Add `PartialIteration` object used when rendering collections. + + The iteration object is available as the local variable + `#{template_name}_iteration` when rendering partials with collections. + + It gives access to the `size` of the collection being iterated over, + the current `index` and two convenience methods `first?` and `last?`. + + *Joel Junström*, *Lucas Uyezu* + +* Return an absolute instead of relative path from an asset url in the case + of the `asset_host` proc returning nil. + + *Jolyon Pawlyn* + +* Fix `html_escape_once` to properly handle hex escape sequences (e.g. ᨫ). + + *John F. Douthat* + +* Added String support for min and max properties for date field helpers. + + *Todd Bealmear* + +* The `highlight` helper now accepts a block to be used instead of the `highlighter` + option. + + *Lucas Mazza* + +* The `except` and `highlight` helpers now accept regular expressions. + + *Jan Szumiec* + +* Flatten the array parameter in `safe_join`, so it behaves consistently with + `Array#join`. + + *Paul Grayson* + +* Honor `html_safe` on array elements in tag values, as we do for plain string + values. + + *Paul Grayson* + +* Add `ActionView::Template::Handler.unregister_template_handler`. + + It performs the opposite of `ActionView::Template::Handler.register_template_handler`. + + *Zuhao Wan* + +* Bring `cache_digest` rake tasks up-to-date with the latest API changes. + + *Jiri Pospisil* + +* Allow custom `:host` option to be passed to `asset_url` helper that + overwrites `config.action_controller.asset_host` for particular asset. + + *Hubert ÅÄ™picki* + +* Deprecate `AbstractController::Base.parent_prefixes`. + Override `AbstractController::Base.local_prefixes` when you want to change + where to find views. + + *Nick Sutterer* + +* Take label values into account when doing I18n lookups for model attributes. + + The following: + + # form.html.erb + <%= form_for @post do |f| %> + <%= f.label :type, value: "long" %> + <% end %> + + # en.yml + en: + activerecord: + attributes: + post/long: "Long-form Post" + + Used to simply return "long", but now it will return "Long-form + Post". + + *Joshua Cody* + +* Change `asset_path` to use File.join to create proper paths: + + Before: + + https://some.host.com//assets/some.js + + After: + + https://some.host.com/assets/some.js + + *Peter Schröder* + +* Change `favicon_link_tag` default mimetype from `image/vnd.microsoft.icon` to + `image/x-icon`. + + Before: + + # => favicon_link_tag 'myicon.ico' + + + After: + + # => favicon_link_tag 'myicon.ico' + + + *Geoffroy Lorieux* + +* Remove wrapping div with inline styles for hidden form fields. + + We are dropping HTML 4.01 and XHTML strict compliance since input tags directly + inside a form are valid HTML5, and the absence of inline styles help in validating + for Content Security Policy. + + *Joost Baaij* + +* `collection_check_boxes` respects `:index` option for the hidden field name. + + Fixes #14147. + + *Vasiliy Ermolovich* + +* `date_select` helper with option `with_css_classes: true` does not overwrite other classes. + + *Izumi Wong-Horiuchi* + +* `number_to_percentage` does not crash with `Float::NAN` or `Float::INFINITY` + as input. + + Fixes #14405. + + *Yves Senn* + +* Add `include_hidden` option to `collection_check_boxes` helper. + + *Vasiliy Ermolovich* + +* Fixed a problem where the default options for the `button_tag` helper are not + applied correctly. + + Fixes #14254. + + *Sergey Prikhodko* + +* Take variants into account when calculating template digests in ActionView::Digestor. + + The arguments to ActionView::Digestor#digest are now being passed as a hash + to support variants and allow more flexibility in the future. The support for + regular (required) arguments is deprecated and will be removed in Rails 5.0 or later. + + *Piotr Chmolowski, Åukasz StrzaÅ‚kowski* + +Please check [4-1-stable](https://github.com/rails/rails/blob/4-1-stable/actionview/CHANGELOG.md) for previous changes. diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/MIT-LICENSE b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/MIT-LICENSE new file mode 100644 index 0000000..d58dd9e --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/MIT-LICENSE @@ -0,0 +1,21 @@ +Copyright (c) 2004-2014 David Heinemeier Hansson + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/README.rdoc b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/README.rdoc new file mode 100644 index 0000000..6b74e24 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/README.rdoc @@ -0,0 +1,39 @@ += Action View + +Action View is a framework for handling view template lookup and rendering, and provides +view helpers that assist when building HTML forms, Atom feeds and more. +Template formats that Action View handles are ERB (embedded Ruby, typically +used to inline short Ruby snippets inside HTML), and XML Builder. + +== Download and installation + +The latest version of Action View can be installed with RubyGems: + + % [sudo] gem install actionview + +Source code can be downloaded as part of the Rails project on GitHub + +* https://github.com/rails/rails/tree/4-2-stable/actionview + + +== License + +Action View is released under the MIT license: + +* http://www.opensource.org/licenses/MIT + + +== Support + +API documentation is at + +* http://api.rubyonrails.org + +Bug reports can be filed for the Ruby on Rails project here: + +* https://github.com/rails/rails/issues + +Feature requests should be discussed on the rails-core mailing list here: + +* https://groups.google.com/forum/?fromgroups#!forum/rubyonrails-core + diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view.rb new file mode 100644 index 0000000..6a1837c --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view.rb @@ -0,0 +1,96 @@ +#-- +# Copyright (c) 2004-2014 David Heinemeier Hansson +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +#++ + +require 'active_support' +require 'active_support/rails' +require 'action_view/version' + +module ActionView + extend ActiveSupport::Autoload + + ENCODING_FLAG = '#.*coding[:=]\s*(\S+)[ \t]*' + + eager_autoload do + autoload :Base + autoload :Context + autoload :CompiledTemplates, "action_view/context" + autoload :Digestor + autoload :Helpers + autoload :LookupContext + autoload :Layouts + autoload :PathSet + autoload :RecordIdentifier + autoload :Rendering + autoload :RoutingUrlFor + autoload :Template + autoload :ViewPaths + + autoload_under "renderer" do + autoload :Renderer + autoload :AbstractRenderer + autoload :PartialRenderer + autoload :TemplateRenderer + autoload :StreamingTemplateRenderer + end + + autoload_at "action_view/template/resolver" do + autoload :Resolver + autoload :PathResolver + autoload :OptimizedFileSystemResolver + autoload :FallbackFileSystemResolver + end + + autoload_at "action_view/buffers" do + autoload :OutputBuffer + autoload :StreamingBuffer + end + + autoload_at "action_view/flows" do + autoload :OutputFlow + autoload :StreamingFlow + end + + autoload_at "action_view/template/error" do + autoload :MissingTemplate + autoload :ActionViewError + autoload :EncodingError + autoload :MissingRequestError + autoload :TemplateError + autoload :WrongEncodingError + end + end + + autoload :TestCase + + def self.eager_load! + super + ActionView::Helpers.eager_load! + ActionView::Template.eager_load! + end +end + +require 'active_support/core_ext/string/output_safety' + +ActiveSupport.on_load(:i18n) do + I18n.load_path << "#{File.dirname(__FILE__)}/action_view/locale/en.yml" +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/base.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/base.rb new file mode 100644 index 0000000..3071a13 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/base.rb @@ -0,0 +1,205 @@ +require 'active_support/core_ext/module/attr_internal' +require 'active_support/core_ext/module/attribute_accessors' +require 'active_support/ordered_options' +require 'action_view/log_subscriber' +require 'action_view/helpers' +require 'action_view/context' +require 'action_view/template' +require 'action_view/lookup_context' + +module ActionView #:nodoc: + # = Action View Base + # + # Action View templates can be written in several ways. + # If the template file has a .erb extension, then it uses the erubis[https://rubygems.org/gems/erubis] + # template system which can embed Ruby into an HTML document. + # If the template file has a .builder extension, then Jim Weirich's Builder::XmlMarkup library is used. + # + # == ERB + # + # You trigger ERB by using embeddings such as <% %>, <% -%>, and <%= %>. The <%= %> tag set is used when you want output. Consider the + # following loop for names: + # + # Names of all the people + # <% @people.each do |person| %> + # Name: <%= person.name %>
+ # <% end %> + # + # The loop is setup in regular embedding tags <% %> and the name is written using the output embedding tag <%= %>. Note that this + # is not just a usage suggestion. Regular output functions like print or puts won't work with ERB templates. So this would be wrong: + # + # <%# WRONG %> + # Hi, Mr. <% puts "Frodo" %> + # + # If you absolutely must write from within a function use +concat+. + # + # When on a line that only contains whitespaces except for the tag, <% %> suppress leading and trailing whitespace, + # including the trailing newline. <% %> and <%- -%> are the same. + # Note however that <%= %> and <%= -%> are different: only the latter removes trailing whitespaces. + # + # === Using sub templates + # + # Using sub templates allows you to sidestep tedious replication and extract common display structures in shared templates. The + # classic example is the use of a header and footer (even though the Action Pack-way would be to use Layouts): + # + # <%= render "shared/header" %> + # Something really specific and terrific + # <%= render "shared/footer" %> + # + # As you see, we use the output embeddings for the render methods. The render call itself will just return a string holding the + # result of the rendering. The output embedding writes it to the current template. + # + # But you don't have to restrict yourself to static includes. Templates can share variables amongst themselves by using instance + # variables defined using the regular embedding tags. Like this: + # + # <% @page_title = "A Wonderful Hello" %> + # <%= render "shared/header" %> + # + # Now the header can pick up on the @page_title variable and use it for outputting a title tag: + # + # <%= @page_title %> + # + # === Passing local variables to sub templates + # + # You can pass local variables to sub templates by using a hash with the variable names as keys and the objects as values: + # + # <%= render "shared/header", { headline: "Welcome", person: person } %> + # + # These can now be accessed in shared/header with: + # + # Headline: <%= headline %> + # First name: <%= person.first_name %> + # + # === Template caching + # + # By default, Rails will compile each template to a method in order to render it. When you alter a template, + # Rails will check the file's modification time and recompile it in development mode. + # + # == Builder + # + # Builder templates are a more programmatic alternative to ERB. They are especially useful for generating XML content. An XmlMarkup object + # named +xml+ is automatically made available to templates with a .builder extension. + # + # Here are some basic examples: + # + # xml.em("emphasized") # => emphasized + # xml.em { xml.b("emph & bold") } # => emph & bold + # xml.a("A Link", "href" => "http://onestepback.org") # => A Link + # xml.target("name" => "compile", "option" => "fast") # => + # # NOTE: order of attributes is not specified. + # + # Any method with a block will be treated as an XML markup tag with nested markup in the block. For example, the following: + # + # xml.div do + # xml.h1(@person.name) + # xml.p(@person.bio) + # end + # + # would produce something like: + # + #
+ #

David Heinemeier Hansson

+ #

A product of Danish Design during the Winter of '79...

+ #
+ # + # A full-length RSS example actually used on Basecamp: + # + # xml.rss("version" => "2.0", "xmlns:dc" => "http://purl.org/dc/elements/1.1/") do + # xml.channel do + # xml.title(@feed_title) + # xml.link(@url) + # xml.description "Basecamp: Recent items" + # xml.language "en-us" + # xml.ttl "40" + # + # @recent_items.each do |item| + # xml.item do + # xml.title(item_title(item)) + # xml.description(item_description(item)) if item_description(item) + # xml.pubDate(item_pubDate(item)) + # xml.guid(@person.firm.account.url + @recent_items.url(item)) + # xml.link(@person.firm.account.url + @recent_items.url(item)) + # + # xml.tag!("dc:creator", item.author_name) if item_has_creator?(item) + # end + # end + # end + # end + # + # For more information on Builder please consult the [source + # code](https://github.com/jimweirich/builder). + class Base + include Helpers, ::ERB::Util, Context + + # Specify the proc used to decorate input tags that refer to attributes with errors. + cattr_accessor :field_error_proc + @@field_error_proc = Proc.new{ |html_tag, instance| "
#{html_tag}
".html_safe } + + # How to complete the streaming when an exception occurs. + # This is our best guess: first try to close the attribute, then the tag. + cattr_accessor :streaming_completion_on_exception + @@streaming_completion_on_exception = %(">) + + # Specify whether rendering within namespaced controllers should prefix + # the partial paths for ActiveModel objects with the namespace. + # (e.g., an Admin::PostsController would render @post using /admin/posts/_post.erb) + cattr_accessor :prefix_partial_path_with_controller_namespace + @@prefix_partial_path_with_controller_namespace = true + + # Specify default_formats that can be rendered. + cattr_accessor :default_formats + + # Specify whether an error should be raised for missing translations + cattr_accessor :raise_on_missing_translations + @@raise_on_missing_translations = false + + class_attribute :_routes + class_attribute :logger + + class << self + delegate :erb_trim_mode=, :to => 'ActionView::Template::Handlers::ERB' + + def cache_template_loading + ActionView::Resolver.caching? + end + + def cache_template_loading=(value) + ActionView::Resolver.caching = value + end + + def xss_safe? #:nodoc: + true + end + end + + attr_accessor :view_renderer + attr_internal :config, :assigns + + delegate :lookup_context, :to => :view_renderer + delegate :formats, :formats=, :locale, :locale=, :view_paths, :view_paths=, :to => :lookup_context + + def assign(new_assigns) # :nodoc: + @_assigns = new_assigns.each { |key, value| instance_variable_set("@#{key}", value) } + end + + def initialize(context = nil, assigns = {}, controller = nil, formats = nil) #:nodoc: + @_config = ActiveSupport::InheritableOptions.new + + if context.is_a?(ActionView::Renderer) + @view_renderer = context + else + lookup_context = context.is_a?(ActionView::LookupContext) ? + context : ActionView::LookupContext.new(context) + lookup_context.formats = formats if formats + lookup_context.prefixes = controller._prefixes if controller + @view_renderer = ActionView::Renderer.new(lookup_context) + end + + assign(assigns) + assign_controller(controller) + _prepare_context + end + + ActiveSupport.run_load_hooks(:action_view, self) + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/buffers.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/buffers.rb new file mode 100644 index 0000000..be5d86b --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/buffers.rb @@ -0,0 +1,50 @@ +require 'active_support/core_ext/string/output_safety' + +module ActionView + class OutputBuffer < ActiveSupport::SafeBuffer #:nodoc: + def initialize(*) + super + encode! + end + + def <<(value) + return self if value.nil? + super(value.to_s) + end + alias :append= :<< + + def safe_expr_append=(val) + return self if val.nil? + safe_concat val.to_s + end + + alias :safe_append= :safe_concat + end + + class StreamingBuffer #:nodoc: + def initialize(block) + @block = block + end + + def <<(value) + value = value.to_s + value = ERB::Util.h(value) unless value.html_safe? + @block.call(value) + end + alias :concat :<< + alias :append= :<< + + def safe_concat(value) + @block.call(value.to_s) + end + alias :safe_append= :safe_concat + + def html_safe? + true + end + + def html_safe + self + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/context.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/context.rb new file mode 100644 index 0000000..ee263df --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/context.rb @@ -0,0 +1,36 @@ +module ActionView + module CompiledTemplates #:nodoc: + # holds compiled template code + end + + # = Action View Context + # + # Action View contexts are supplied to Action Controller to render a template. + # The default Action View context is ActionView::Base. + # + # In order to work with ActionController, a Context must just include this module. + # The initialization of the variables used by the context (@output_buffer, @view_flow, + # and @virtual_path) is responsibility of the object that includes this module + # (although you can call _prepare_context defined below). + module Context + include CompiledTemplates + attr_accessor :output_buffer, :view_flow + + # Prepares the context by setting the appropriate instance variables. + # :api: plugin + def _prepare_context + @view_flow = OutputFlow.new + @output_buffer = nil + @virtual_path = nil + end + + # Encapsulates the interaction with the view flow so it + # returns the correct buffer on +yield+. This is usually + # overwritten by helpers to add more behavior. + # :api: plugin + def _layout_for(name=nil) + name ||= :layout + view_flow.get(name).html_safe + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/dependency_tracker.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/dependency_tracker.rb new file mode 100644 index 0000000..e34bdd4 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/dependency_tracker.rb @@ -0,0 +1,141 @@ +require 'thread_safe' + +module ActionView + class DependencyTracker # :nodoc: + @trackers = ThreadSafe::Cache.new + + def self.find_dependencies(name, template) + tracker = @trackers[template.handler] + + if tracker.present? + tracker.call(name, template) + else + [] + end + end + + def self.register_tracker(extension, tracker) + handler = Template.handler_for_extension(extension) + @trackers[handler] = tracker + end + + def self.remove_tracker(handler) + @trackers.delete(handler) + end + + class ERBTracker # :nodoc: + EXPLICIT_DEPENDENCY = /# Template Dependency: (\S+)/ + + # A valid ruby identifier - suitable for class, method and specially variable names + IDENTIFIER = / + [[:alpha:]_] # at least one uppercase letter, lowercase letter or underscore + [[:word:]]* # followed by optional letters, numbers or underscores + /x + + # Any kind of variable name. e.g. @instance, @@class, $global or local. + # Possibly following a method call chain + VARIABLE_OR_METHOD_CHAIN = / + (?:\$|@{1,2})? # optional global, instance or class variable indicator + (?:#{IDENTIFIER}\.)* # followed by an optional chain of zero-argument method calls + (?#{IDENTIFIER}) # and a final valid identifier, captured as DYNAMIC + /x + + # A simple string literal. e.g. "School's out!" + STRING = / + (?['"]) # an opening quote + (?.*?) # with anything inside, captured as STATIC + \k # and a matching closing quote + /x + + # Part of any hash containing the :partial key + PARTIAL_HASH_KEY = / + (?:\bpartial:|:partial\s*=>) # partial key in either old or new style hash syntax + \s* # followed by optional spaces + /x + + # Part of any hash containing the :layout key + LAYOUT_HASH_KEY = / + (?:\blayout:|:layout\s*=>) # layout key in either old or new style hash syntax + \s* # followed by optional spaces + /x + + # Matches: + # partial: "comments/comment", collection: @all_comments => "comments/comment" + # (object: @single_comment, partial: "comments/comment") => "comments/comment" + # + # "comments/comments" + # 'comments/comments' + # ('comments/comments') + # + # (@topic) => "topics/topic" + # topics => "topics/topic" + # (message.topics) => "topics/topic" + RENDER_ARGUMENTS = /\A + (?:\s*\(?\s*) # optional opening paren surrounded by spaces + (?:.*?#{PARTIAL_HASH_KEY}|#{LAYOUT_HASH_KEY})? # optional hash, up to the partial or layout key declaration + (?:#{STRING}|#{VARIABLE_OR_METHOD_CHAIN}) # finally, the dependency name of interest + /xm + + def self.call(name, template) + new(name, template).dependencies + end + + def initialize(name, template) + @name, @template = name, template + end + + def dependencies + render_dependencies + explicit_dependencies + end + + attr_reader :name, :template + private :name, :template + + + private + def source + template.source + end + + def directory + name.split("/")[0..-2].join("/") + end + + def render_dependencies + render_dependencies = [] + render_calls = source.split(/\brender\b/).drop(1) + + render_calls.each do |arguments| + arguments.scan(RENDER_ARGUMENTS) do + add_dynamic_dependency(render_dependencies, Regexp.last_match[:dynamic]) + add_static_dependency(render_dependencies, Regexp.last_match[:static]) + end + end + + render_dependencies.uniq + end + + def add_dynamic_dependency(dependencies, dependency) + if dependency + dependencies << "#{dependency.pluralize}/#{dependency.singularize}" + end + end + + def add_static_dependency(dependencies, dependency) + if dependency + if dependency.include?('/') + dependencies << dependency + else + dependencies << "#{directory}/#{dependency}" + end + end + end + + def explicit_dependencies + source.scan(EXPLICIT_DEPENDENCY).flatten.uniq + end + end + + register_tracker :erb, ERBTracker + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/digestor.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/digestor.rb new file mode 100644 index 0000000..b29eb48 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/digestor.rb @@ -0,0 +1,123 @@ +require 'thread_safe' +require 'action_view/dependency_tracker' +require 'monitor' + +module ActionView + class Digestor + cattr_reader(:cache) + @@cache = ThreadSafe::Cache.new + @@digest_monitor = Monitor.new + + class << self + # Supported options: + # + # * name - Template name + # * finder - An instance of ActionView::LookupContext + # * dependencies - An array of dependent views + # * partial - Specifies whether the template is a partial + def digest(options) + options.assert_valid_keys(:name, :finder, :dependencies, :partial) + + cache_key = ([ options[:name], options[:finder].details_key.hash ].compact + Array.wrap(options[:dependencies])).join('.') + + # this is a correctly done double-checked locking idiom + # (ThreadSafe::Cache's lookups have volatile semantics) + @@cache[cache_key] || @@digest_monitor.synchronize do + @@cache.fetch(cache_key) do # re-check under lock + compute_and_store_digest(cache_key, options) + end + end + end + + private + def compute_and_store_digest(cache_key, options) # called under @@digest_monitor lock + klass = if options[:partial] || options[:name].include?("/_") + # Prevent re-entry or else recursive templates will blow the stack. + # There is no need to worry about other threads seeing the +false+ value, + # as they will then have to wait for this thread to let go of the @@digest_monitor lock. + pre_stored = @@cache.put_if_absent(cache_key, false).nil? # put_if_absent returns nil on insertion + PartialDigestor + else + Digestor + end + + digest = klass.new(options).digest + # Store the actual digest if config.cache_template_loading is true + @@cache[cache_key] = stored_digest = digest if ActionView::Resolver.caching? + digest + ensure + # something went wrong or ActionView::Resolver.caching? is false, make sure not to corrupt the @@cache + @@cache.delete_pair(cache_key, false) if pre_stored && !stored_digest + end + end + + attr_reader :name, :finder, :options + + def initialize(options) + @name, @finder = options.values_at(:name, :finder) + @options = options.except(:name, :finder) + end + + def digest + Digest::MD5.hexdigest("#{source}-#{dependency_digest}").tap do |digest| + logger.try :debug, " Cache digest for #{template.inspect}: #{digest}" + end + rescue ActionView::MissingTemplate + logger.try :error, " Couldn't find template for digesting: #{name}" + '' + end + + def dependencies + DependencyTracker.find_dependencies(name, template) + rescue ActionView::MissingTemplate + logger.try :error, " '#{name}' file doesn't exist, so no dependencies" + [] + end + + def nested_dependencies + dependencies.collect do |dependency| + dependencies = PartialDigestor.new(name: dependency, finder: finder).nested_dependencies + dependencies.any? ? { dependency => dependencies } : dependency + end + end + + private + def logger + ActionView::Base.logger + end + + def logical_name + name.gsub(%r|/_|, "/") + end + + def partial? + false + end + + def template + @template ||= finder.disable_cache { finder.find(logical_name, [], partial?) } + end + + def source + template.source + end + + def dependency_digest + template_digests = dependencies.collect do |template_name| + Digestor.digest(name: template_name, finder: finder, partial: true) + end + + (template_digests + injected_dependencies).join("-") + end + + def injected_dependencies + Array.wrap(options[:dependencies]) + end + end + + class PartialDigestor < Digestor # :nodoc: + def partial? + true + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/flows.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/flows.rb new file mode 100644 index 0000000..bc61920 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/flows.rb @@ -0,0 +1,76 @@ +require 'active_support/core_ext/string/output_safety' + +module ActionView + class OutputFlow #:nodoc: + attr_reader :content + + def initialize + @content = Hash.new { |h,k| h[k] = ActiveSupport::SafeBuffer.new } + end + + # Called by _layout_for to read stored values. + def get(key) + @content[key] + end + + # Called by each renderer object to set the layout contents. + def set(key, value) + @content[key] = ActiveSupport::SafeBuffer.new(value) + end + + # Called by content_for + def append(key, value) + @content[key] << value + end + alias_method :append!, :append + + end + + class StreamingFlow < OutputFlow #:nodoc: + def initialize(view, fiber) + @view = view + @parent = nil + @child = view.output_buffer + @content = view.view_flow.content + @fiber = fiber + @root = Fiber.current.object_id + end + + # Try to get stored content. If the content + # is not available and we are inside the layout + # fiber, we set that we are waiting for the given + # key and yield. + def get(key) + return super if @content.key?(key) + + if inside_fiber? + view = @view + + begin + @waiting_for = key + view.output_buffer, @parent = @child, view.output_buffer + Fiber.yield + ensure + @waiting_for = nil + view.output_buffer, @child = @parent, view.output_buffer + end + end + + super + end + + # Appends the contents for the given key. This is called + # by provides and resumes back to the fiber if it is + # the key it is waiting for. + def append!(key, value) + super + @fiber.resume if @waiting_for == key + end + + private + + def inside_fiber? + Fiber.current.object_id != @root + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/gem_version.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/gem_version.rb new file mode 100644 index 0000000..4b81d0c --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/gem_version.rb @@ -0,0 +1,15 @@ +module ActionView + # Returns the version of the currently loaded Action View as a Gem::Version + def self.gem_version + Gem::Version.new VERSION::STRING + end + + module VERSION + MAJOR = 4 + MINOR = 2 + TINY = 6 + PRE = nil + + STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".") + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers.rb new file mode 100644 index 0000000..787e9d6 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers.rb @@ -0,0 +1,64 @@ +require 'active_support/benchmarkable' + +module ActionView #:nodoc: + module Helpers #:nodoc: + extend ActiveSupport::Autoload + + autoload :ActiveModelHelper + autoload :AssetTagHelper + autoload :AssetUrlHelper + autoload :AtomFeedHelper + autoload :CacheHelper + autoload :CaptureHelper + autoload :ControllerHelper + autoload :CsrfHelper + autoload :DateHelper + autoload :DebugHelper + autoload :FormHelper + autoload :FormOptionsHelper + autoload :FormTagHelper + autoload :JavaScriptHelper, "action_view/helpers/javascript_helper" + autoload :NumberHelper + autoload :OutputSafetyHelper + autoload :RecordTagHelper + autoload :RenderingHelper + autoload :SanitizeHelper + autoload :TagHelper + autoload :TextHelper + autoload :TranslationHelper + autoload :UrlHelper + autoload :Tags + + def self.eager_load! + super + Tags.eager_load! + end + + extend ActiveSupport::Concern + + include ActiveSupport::Benchmarkable + include ActiveModelHelper + include AssetTagHelper + include AssetUrlHelper + include AtomFeedHelper + include CacheHelper + include CaptureHelper + include ControllerHelper + include CsrfHelper + include DateHelper + include DebugHelper + include FormHelper + include FormOptionsHelper + include FormTagHelper + include JavaScriptHelper + include NumberHelper + include OutputSafetyHelper + include RecordTagHelper + include RenderingHelper + include SanitizeHelper + include TagHelper + include TextHelper + include TranslationHelper + include UrlHelper + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/active_model_helper.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/active_model_helper.rb new file mode 100644 index 0000000..d5222e3 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/active_model_helper.rb @@ -0,0 +1,49 @@ +require 'active_support/core_ext/module/attribute_accessors' +require 'active_support/core_ext/enumerable' + +module ActionView + # = Active Model Helpers + module Helpers + module ActiveModelHelper + end + + module ActiveModelInstanceTag + def object + @active_model_object ||= begin + object = super + object.respond_to?(:to_model) ? object.to_model : object + end + end + + def content_tag(*) + error_wrapping(super) + end + + def tag(type, options, *) + tag_generate_errors?(options) ? error_wrapping(super) : super + end + + def error_wrapping(html_tag) + if object_has_errors? + Base.field_error_proc.call(html_tag, self) + else + html_tag + end + end + + def error_message + object.errors[@method_name] + end + + private + + def object_has_errors? + object.respond_to?(:errors) && object.errors.respond_to?(:[]) && error_message.present? + end + + def tag_generate_errors?(options) + options['type'] != 'hidden' + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/asset_tag_helper.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/asset_tag_helper.rb new file mode 100644 index 0000000..c46003c --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/asset_tag_helper.rb @@ -0,0 +1,329 @@ +require 'active_support/core_ext/array/extract_options' +require 'active_support/core_ext/hash/keys' +require 'action_view/helpers/asset_url_helper' +require 'action_view/helpers/tag_helper' + +module ActionView + # = Action View Asset Tag Helpers + module Helpers #:nodoc: + # This module provides methods for generating HTML that links views to assets such + # as images, JavaScripts, stylesheets, and feeds. These methods do not verify + # the assets exist before linking to them: + # + # image_tag("rails.png") + # # => Rails + # stylesheet_link_tag("application") + # # => + module AssetTagHelper + extend ActiveSupport::Concern + + include AssetUrlHelper + include TagHelper + + # Returns an HTML script tag for each of the +sources+ provided. + # + # Sources may be paths to JavaScript files. Relative paths are assumed to be relative + # to assets/javascripts, full paths are assumed to be relative to the document + # root. Relative paths are idiomatic, use absolute paths only when needed. + # + # When passing paths, the ".js" extension is optional. If you do not want ".js" + # appended to the path extname: false can be set on the options. + # + # You can modify the HTML attributes of the script tag by passing a hash as the + # last argument. + # + # When the Asset Pipeline is enabled, you can pass the name of your manifest as + # source, and include other JavaScript or CoffeeScript files inside the manifest. + # + # javascript_include_tag "xmlhr" + # # => + # + # javascript_include_tag "template.jst", extname: false + # # => + # + # javascript_include_tag "xmlhr.js" + # # => + # + # javascript_include_tag "common.javascript", "/elsewhere/cools" + # # => + # # + # + # javascript_include_tag "http://www.example.com/xmlhr" + # # => + # + # javascript_include_tag "http://www.example.com/xmlhr.js" + # # => + def javascript_include_tag(*sources) + options = sources.extract_options!.stringify_keys + path_options = options.extract!('protocol', 'extname').symbolize_keys + sources.uniq.map { |source| + tag_options = { + "src" => path_to_javascript(source, path_options) + }.merge!(options) + content_tag(:script, "", tag_options) + }.join("\n").html_safe + end + + # Returns a stylesheet link tag for the sources specified as arguments. If + # you don't specify an extension, .css will be appended automatically. + # You can modify the link attributes by passing a hash as the last argument. + # For historical reasons, the 'media' attribute will always be present and defaults + # to "screen", so you must explicitly set it to "all" for the stylesheet(s) to + # apply to all media types. + # + # stylesheet_link_tag "style" + # # => + # + # stylesheet_link_tag "style.css" + # # => + # + # stylesheet_link_tag "http://www.example.com/style.css" + # # => + # + # stylesheet_link_tag "style", media: "all" + # # => + # + # stylesheet_link_tag "style", media: "print" + # # => + # + # stylesheet_link_tag "random.styles", "/css/stylish" + # # => + # # + def stylesheet_link_tag(*sources) + options = sources.extract_options!.stringify_keys + path_options = options.extract!('protocol').symbolize_keys + + sources.uniq.map { |source| + tag_options = { + "rel" => "stylesheet", + "media" => "screen", + "href" => path_to_stylesheet(source, path_options) + }.merge!(options) + tag(:link, tag_options) + }.join("\n").html_safe + end + + # Returns a link tag that browsers and feed readers can use to auto-detect + # an RSS or Atom feed. The +type+ can either be :rss (default) or + # :atom. Control the link options in url_for format using the + # +url_options+. You can modify the LINK tag itself in +tag_options+. + # + # ==== Options + # + # * :rel - Specify the relation of this link, defaults to "alternate" + # * :type - Override the auto-generated mime type + # * :title - Specify the title of the link, defaults to the +type+ + # + # ==== Examples + # + # auto_discovery_link_tag + # # => + # auto_discovery_link_tag(:atom) + # # => + # auto_discovery_link_tag(:rss, {action: "feed"}) + # # => + # auto_discovery_link_tag(:rss, {action: "feed"}, {title: "My RSS"}) + # # => + # auto_discovery_link_tag(:rss, {controller: "news", action: "feed"}) + # # => + # auto_discovery_link_tag(:rss, "http://www.example.com/feed.rss", {title: "Example RSS"}) + # # => + def auto_discovery_link_tag(type = :rss, url_options = {}, tag_options = {}) + if !(type == :rss || type == :atom) && tag_options[:type].blank? + raise ArgumentError.new("You should pass :type tag_option key explicitly, because you have passed #{type} type other than :rss or :atom.") + end + + tag( + "link", + "rel" => tag_options[:rel] || "alternate", + "type" => tag_options[:type] || Mime::Type.lookup_by_extension(type.to_s).to_s, + "title" => tag_options[:title] || type.to_s.upcase, + "href" => url_options.is_a?(Hash) ? url_for(url_options.merge(:only_path => false)) : url_options + ) + end + + # Returns a link tag for a favicon managed by the asset pipeline. + # + # If a page has no link like the one generated by this helper, browsers + # ask for /favicon.ico automatically, and cache the file if the + # request succeeds. If the favicon changes it is hard to get it updated. + # + # To have better control applications may let the asset pipeline manage + # their favicon storing the file under app/assets/images, and + # using this helper to generate its corresponding link tag. + # + # The helper gets the name of the favicon file as first argument, which + # defaults to "favicon.ico", and also supports +:rel+ and +:type+ options + # to override their defaults, "shortcut icon" and "image/x-icon" + # respectively: + # + # favicon_link_tag + # # => + # + # favicon_link_tag 'myicon.ico' + # # => + # + # Mobile Safari looks for a different link tag, pointing to an image that + # will be used if you add the page to the home screen of an iOS device. + # The following call would generate such a tag: + # + # favicon_link_tag 'mb-icon.png', rel: 'apple-touch-icon', type: 'image/png' + # # => + def favicon_link_tag(source='favicon.ico', options={}) + tag('link', { + :rel => 'shortcut icon', + :type => 'image/x-icon', + :href => path_to_image(source) + }.merge!(options.symbolize_keys)) + end + + # Returns an HTML image tag for the +source+. The +source+ can be a full + # path or a file. + # + # ==== Options + # + # You can add HTML attributes using the +options+. The +options+ supports + # two additional keys for convenience and conformance: + # + # * :alt - If no alt text is given, the file name part of the + # +source+ is used (capitalized and without the extension) + # * :size - Supplied as "{Width}x{Height}" or "{Number}", so "30x45" becomes + # width="30" and height="45", and "50" becomes width="50" and height="50". + # :size will be ignored if the value is not in the correct format. + # + # ==== Examples + # + # image_tag("icon") + # # => Icon + # image_tag("icon.png") + # # => Icon + # image_tag("icon.png", size: "16x10", alt: "Edit Entry") + # # => Edit Entry + # image_tag("/icons/icon.gif", size: "16") + # # => Icon + # image_tag("/icons/icon.gif", height: '32', width: '32') + # # => Icon + # image_tag("/icons/icon.gif", class: "menu_icon") + # # => Icon + def image_tag(source, options={}) + options = options.symbolize_keys + + src = options[:src] = path_to_image(source) + + unless src =~ /^(?:cid|data):/ || src.blank? + options[:alt] = options.fetch(:alt){ image_alt(src) } + end + + options[:width], options[:height] = extract_dimensions(options.delete(:size)) if options[:size] + tag("img", options) + end + + # Returns a string suitable for an HTML image tag alt attribute. + # The +src+ argument is meant to be an image file path. + # The method removes the basename of the file path and the digest, + # if any. It also removes hyphens and underscores from file names and + # replaces them with spaces, returning a space-separated, titleized + # string. + # + # ==== Examples + # + # image_alt('rails.png') + # # => Rails + # + # image_alt('hyphenated-file-name.png') + # # => Hyphenated file name + # + # image_alt('underscored_file_name.png') + # # => Underscored file name + def image_alt(src) + File.basename(src, '.*').sub(/-[[:xdigit:]]{32,64}\z/, '').tr('-_', ' ').capitalize + end + + # Returns an HTML video tag for the +sources+. If +sources+ is a string, + # a single video tag will be returned. If +sources+ is an array, a video + # tag with nested source tags for each source will be returned. The + # +sources+ can be full paths or files that exists in your public videos + # directory. + # + # ==== Options + # You can add HTML attributes using the +options+. The +options+ supports + # two additional keys for convenience and conformance: + # + # * :poster - Set an image (like a screenshot) to be shown + # before the video loads. The path is calculated like the +src+ of +image_tag+. + # * :size - Supplied as "{Width}x{Height}" or "{Number}", so "30x45" becomes + # width="30" and height="45", and "50" becomes width="50" and height="50". + # :size will be ignored if the value is not in the correct format. + # + # ==== Examples + # + # video_tag("trailer") + # # => + # video_tag("trailer.ogg") + # # => + # video_tag("trailer.ogg", controls: true, autobuffer: true) + # # => + # video_tag("trailer.m4v", size: "16x10", poster: "screenshot.png") + # # => + # video_tag("/trailers/hd.avi", size: "16x16") + # # => + # video_tag("/trailers/hd.avi", size: "16") + # # => + # video_tag("/trailers/hd.avi", height: '32', width: '32') + # # => + # video_tag("trailer.ogg", "trailer.flv") + # # => + # video_tag(["trailer.ogg", "trailer.flv"]) + # # => + # video_tag(["trailer.ogg", "trailer.flv"], size: "160x120") + # # => + def video_tag(*sources) + multiple_sources_tag('video', sources) do |options| + options[:poster] = path_to_image(options[:poster]) if options[:poster] + options[:width], options[:height] = extract_dimensions(options.delete(:size)) if options[:size] + end + end + + # Returns an HTML audio tag for the +source+. + # The +source+ can be full path or file that exists in + # your public audios directory. + # + # audio_tag("sound") + # # => + # audio_tag("sound.wav") + # # => + # audio_tag("sound.wav", autoplay: true, controls: true) + # # => + # audio_tag("sound.wav", "sound.mid") + # # => + def audio_tag(*sources) + multiple_sources_tag('audio', sources) + end + + private + def multiple_sources_tag(type, sources) + options = sources.extract_options!.symbolize_keys + sources.flatten! + + yield options if block_given? + + if sources.size > 1 + content_tag(type, options) do + safe_join sources.map { |source| tag("source", :src => send("path_to_#{type}", source)) } + end + else + options[:src] = send("path_to_#{type}", sources.first) + content_tag(type, nil, options) + end + end + + def extract_dimensions(size) + if size =~ %r{\A\d+x\d+\z} + size.split('x') + elsif size =~ %r{\A\d+\z} + [size, size] + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/asset_url_helper.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/asset_url_helper.rb new file mode 100644 index 0000000..2973344 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/asset_url_helper.rb @@ -0,0 +1,366 @@ +require 'zlib' + +module ActionView + # = Action View Asset URL Helpers + module Helpers + # This module provides methods for generating asset paths and + # urls. + # + # image_path("rails.png") + # # => "/assets/rails.png" + # + # image_url("rails.png") + # # => "http://www.example.com/assets/rails.png" + # + # === Using asset hosts + # + # By default, Rails links to these assets on the current host in the public + # folder, but you can direct Rails to link to assets from a dedicated asset + # server by setting ActionController::Base.asset_host in the application + # configuration, typically in config/environments/production.rb. + # For example, you'd define assets.example.com to be your asset + # host this way, inside the configure block of your environment-specific + # configuration files or config/application.rb: + # + # config.action_controller.asset_host = "assets.example.com" + # + # Helpers take that into account: + # + # image_tag("rails.png") + # # => Rails + # stylesheet_link_tag("application") + # # => + # + # Browsers typically open at most two simultaneous connections to a single + # host, which means your assets often have to wait for other assets to finish + # downloading. You can alleviate this by using a %d wildcard in the + # +asset_host+. For example, "assets%d.example.com". If that wildcard is + # present Rails distributes asset requests among the corresponding four hosts + # "assets0.example.com", ..., "assets3.example.com". With this trick browsers + # will open eight simultaneous connections rather than two. + # + # image_tag("rails.png") + # # => Rails + # stylesheet_link_tag("application") + # # => + # + # To do this, you can either setup four actual hosts, or you can use wildcard + # DNS to CNAME the wildcard to a single asset host. You can read more about + # setting up your DNS CNAME records from your ISP. + # + # Note: This is purely a browser performance optimization and is not meant + # for server load balancing. See http://www.die.net/musings/page_load_time/ + # for background. + # + # Alternatively, you can exert more control over the asset host by setting + # +asset_host+ to a proc like this: + # + # ActionController::Base.asset_host = Proc.new { |source| + # "http://assets#{Digest::MD5.hexdigest(source).to_i(16) % 2 + 1}.example.com" + # } + # image_tag("rails.png") + # # => Rails + # stylesheet_link_tag("application") + # # => + # + # The example above generates "http://assets1.example.com" and + # "http://assets2.example.com". This option is useful for example if + # you need fewer/more than four hosts, custom host names, etc. + # + # As you see the proc takes a +source+ parameter. That's a string with the + # absolute path of the asset, for example "/assets/rails.png". + # + # ActionController::Base.asset_host = Proc.new { |source| + # if source.ends_with?('.css') + # "http://stylesheets.example.com" + # else + # "http://assets.example.com" + # end + # } + # image_tag("rails.png") + # # => Rails + # stylesheet_link_tag("application") + # # => + # + # Alternatively you may ask for a second parameter +request+. That one is + # particularly useful for serving assets from an SSL-protected page. The + # example proc below disables asset hosting for HTTPS connections, while + # still sending assets for plain HTTP requests from asset hosts. If you don't + # have SSL certificates for each of the asset hosts this technique allows you + # to avoid warnings in the client about mixed media. + # Note that the request parameter might not be supplied, e.g. when the assets + # are precompiled via a Rake task. Make sure to use a Proc instead of a lambda, + # since a Proc allows missing parameters and sets them to nil. + # + # config.action_controller.asset_host = Proc.new { |source, request| + # if request && request.ssl? + # "#{request.protocol}#{request.host_with_port}" + # else + # "#{request.protocol}assets.example.com" + # end + # } + # + # You can also implement a custom asset host object that responds to +call+ + # and takes either one or two parameters just like the proc. + # + # config.action_controller.asset_host = AssetHostingWithMinimumSsl.new( + # "http://asset%d.example.com", "https://asset1.example.com" + # ) + # + module AssetUrlHelper + URI_REGEXP = %r{^[-a-z]+://|^(?:cid|data):|^//}i + + # Computes the path to asset in public directory. If :type + # options is set, a file extension will be appended and scoped + # to the corresponding public directory. + # + # All other asset *_path helpers delegate through this method. + # + # asset_path "application.js" # => /assets/application.js + # asset_path "application", type: :javascript # => /assets/application.js + # asset_path "application", type: :stylesheet # => /assets/application.css + # asset_path "http://www.example.com/js/xmlhr.js" # => http://www.example.com/js/xmlhr.js + def asset_path(source, options = {}) + source = source.to_s + return "" unless source.present? + return source if source =~ URI_REGEXP + + tail, source = source[/([\?#].+)$/], source.sub(/([\?#].+)$/, '') + + if extname = compute_asset_extname(source, options) + source = "#{source}#{extname}" + end + + if source[0] != ?/ + source = compute_asset_path(source, options) + end + + relative_url_root = defined?(config.relative_url_root) && config.relative_url_root + if relative_url_root + source = File.join(relative_url_root, source) unless source.starts_with?("#{relative_url_root}/") + end + + if host = compute_asset_host(source, options) + source = File.join(host, source) + end + + "#{source}#{tail}" + end + alias_method :path_to_asset, :asset_path # aliased to avoid conflicts with an asset_path named route + + # Computes the full URL to an asset in the public directory. This + # will use +asset_path+ internally, so most of their behaviors + # will be the same. If :host options is set, it overwrites global + # +config.action_controller.asset_host+ setting. + # + # All other options provided are forwarded to +asset_path+ call. + # + # asset_url "application.js" # => http://example.com/assets/application.js + # asset_url "application.js", host: "http://cdn.example.com" # => http://cdn.example.com/assets/application.js + # + def asset_url(source, options = {}) + path_to_asset(source, options.merge(:protocol => :request)) + end + alias_method :url_to_asset, :asset_url # aliased to avoid conflicts with an asset_url named route + + ASSET_EXTENSIONS = { + javascript: '.js', + stylesheet: '.css' + } + + # Compute extname to append to asset path. Returns nil if + # nothing should be added. + def compute_asset_extname(source, options = {}) + return if options[:extname] == false + extname = options[:extname] || ASSET_EXTENSIONS[options[:type]] + extname if extname && File.extname(source) != extname + end + + # Maps asset types to public directory. + ASSET_PUBLIC_DIRECTORIES = { + audio: '/audios', + font: '/fonts', + image: '/images', + javascript: '/javascripts', + stylesheet: '/stylesheets', + video: '/videos' + } + + # Computes asset path to public directory. Plugins and + # extensions can override this method to point to custom assets + # or generate digested paths or query strings. + def compute_asset_path(source, options = {}) + dir = ASSET_PUBLIC_DIRECTORIES[options[:type]] || "" + File.join(dir, source) + end + + # Pick an asset host for this source. Returns +nil+ if no host is set, + # the host if no wildcard is set, the host interpolated with the + # numbers 0-3 if it contains %d (the number is the source hash mod 4), + # or the value returned from invoking call on an object responding to call + # (proc or otherwise). + def compute_asset_host(source = "", options = {}) + request = self.request if respond_to?(:request) + host = options[:host] + host ||= config.asset_host if defined? config.asset_host + + if host.respond_to?(:call) + arity = host.respond_to?(:arity) ? host.arity : host.method(:call).arity + args = [source] + args << request if request && (arity > 1 || arity < 0) + host = host.call(*args) + elsif host =~ /%d/ + host = host % (Zlib.crc32(source) % 4) + end + + host ||= request.base_url if request && options[:protocol] == :request + return unless host + + if host =~ URI_REGEXP + host + else + protocol = options[:protocol] || config.default_asset_host_protocol || (request ? :request : :relative) + case protocol + when :relative + "//#{host}" + when :request + "#{request.protocol}#{host}" + else + "#{protocol}://#{host}" + end + end + end + + # Computes the path to a JavaScript asset in the public javascripts directory. + # If the +source+ filename has no extension, .js will be appended (except for explicit URIs) + # Full paths from the document root will be passed through. + # Used internally by +javascript_include_tag+ to build the script path. + # + # javascript_path "xmlhr" # => /assets/xmlhr.js + # javascript_path "dir/xmlhr.js" # => /assets/dir/xmlhr.js + # javascript_path "/dir/xmlhr" # => /dir/xmlhr.js + # javascript_path "http://www.example.com/js/xmlhr" # => http://www.example.com/js/xmlhr + # javascript_path "http://www.example.com/js/xmlhr.js" # => http://www.example.com/js/xmlhr.js + def javascript_path(source, options = {}) + path_to_asset(source, {type: :javascript}.merge!(options)) + end + alias_method :path_to_javascript, :javascript_path # aliased to avoid conflicts with a javascript_path named route + + # Computes the full URL to a JavaScript asset in the public javascripts directory. + # This will use +javascript_path+ internally, so most of their behaviors will be the same. + def javascript_url(source, options = {}) + url_to_asset(source, {type: :javascript}.merge!(options)) + end + alias_method :url_to_javascript, :javascript_url # aliased to avoid conflicts with a javascript_url named route + + # Computes the path to a stylesheet asset in the public stylesheets directory. + # If the +source+ filename has no extension, .css will be appended (except for explicit URIs). + # Full paths from the document root will be passed through. + # Used internally by +stylesheet_link_tag+ to build the stylesheet path. + # + # stylesheet_path "style" # => /assets/style.css + # stylesheet_path "dir/style.css" # => /assets/dir/style.css + # stylesheet_path "/dir/style.css" # => /dir/style.css + # stylesheet_path "http://www.example.com/css/style" # => http://www.example.com/css/style + # stylesheet_path "http://www.example.com/css/style.css" # => http://www.example.com/css/style.css + def stylesheet_path(source, options = {}) + path_to_asset(source, {type: :stylesheet}.merge!(options)) + end + alias_method :path_to_stylesheet, :stylesheet_path # aliased to avoid conflicts with a stylesheet_path named route + + # Computes the full URL to a stylesheet asset in the public stylesheets directory. + # This will use +stylesheet_path+ internally, so most of their behaviors will be the same. + def stylesheet_url(source, options = {}) + url_to_asset(source, {type: :stylesheet}.merge!(options)) + end + alias_method :url_to_stylesheet, :stylesheet_url # aliased to avoid conflicts with a stylesheet_url named route + + # Computes the path to an image asset. + # Full paths from the document root will be passed through. + # Used internally by +image_tag+ to build the image path: + # + # image_path("edit") # => "/assets/edit" + # image_path("edit.png") # => "/assets/edit.png" + # image_path("icons/edit.png") # => "/assets/icons/edit.png" + # image_path("/icons/edit.png") # => "/icons/edit.png" + # image_path("http://www.example.com/img/edit.png") # => "http://www.example.com/img/edit.png" + # + # If you have images as application resources this method may conflict with their named routes. + # The alias +path_to_image+ is provided to avoid that. Rails uses the alias internally, and + # plugin authors are encouraged to do so. + def image_path(source, options = {}) + path_to_asset(source, {type: :image}.merge!(options)) + end + alias_method :path_to_image, :image_path # aliased to avoid conflicts with an image_path named route + + # Computes the full URL to an image asset. + # This will use +image_path+ internally, so most of their behaviors will be the same. + def image_url(source, options = {}) + url_to_asset(source, {type: :image}.merge!(options)) + end + alias_method :url_to_image, :image_url # aliased to avoid conflicts with an image_url named route + + # Computes the path to a video asset in the public videos directory. + # Full paths from the document root will be passed through. + # Used internally by +video_tag+ to build the video path. + # + # video_path("hd") # => /videos/hd + # video_path("hd.avi") # => /videos/hd.avi + # video_path("trailers/hd.avi") # => /videos/trailers/hd.avi + # video_path("/trailers/hd.avi") # => /trailers/hd.avi + # video_path("http://www.example.com/vid/hd.avi") # => http://www.example.com/vid/hd.avi + def video_path(source, options = {}) + path_to_asset(source, {type: :video}.merge!(options)) + end + alias_method :path_to_video, :video_path # aliased to avoid conflicts with a video_path named route + + # Computes the full URL to a video asset in the public videos directory. + # This will use +video_path+ internally, so most of their behaviors will be the same. + def video_url(source, options = {}) + url_to_asset(source, {type: :video}.merge!(options)) + end + alias_method :url_to_video, :video_url # aliased to avoid conflicts with an video_url named route + + # Computes the path to an audio asset in the public audios directory. + # Full paths from the document root will be passed through. + # Used internally by +audio_tag+ to build the audio path. + # + # audio_path("horse") # => /audios/horse + # audio_path("horse.wav") # => /audios/horse.wav + # audio_path("sounds/horse.wav") # => /audios/sounds/horse.wav + # audio_path("/sounds/horse.wav") # => /sounds/horse.wav + # audio_path("http://www.example.com/sounds/horse.wav") # => http://www.example.com/sounds/horse.wav + def audio_path(source, options = {}) + path_to_asset(source, {type: :audio}.merge!(options)) + end + alias_method :path_to_audio, :audio_path # aliased to avoid conflicts with an audio_path named route + + # Computes the full URL to an audio asset in the public audios directory. + # This will use +audio_path+ internally, so most of their behaviors will be the same. + def audio_url(source, options = {}) + url_to_asset(source, {type: :audio}.merge!(options)) + end + alias_method :url_to_audio, :audio_url # aliased to avoid conflicts with an audio_url named route + + # Computes the path to a font asset. + # Full paths from the document root will be passed through. + # + # font_path("font") # => /fonts/font + # font_path("font.ttf") # => /fonts/font.ttf + # font_path("dir/font.ttf") # => /fonts/dir/font.ttf + # font_path("/dir/font.ttf") # => /dir/font.ttf + # font_path("http://www.example.com/dir/font.ttf") # => http://www.example.com/dir/font.ttf + def font_path(source, options = {}) + path_to_asset(source, {type: :font}.merge!(options)) + end + alias_method :path_to_font, :font_path # aliased to avoid conflicts with an font_path named route + + # Computes the full URL to a font asset. + # This will use +font_path+ internally, so most of their behaviors will be the same. + def font_url(source, options = {}) + url_to_asset(source, {type: :font}.merge!(options)) + end + alias_method :url_to_font, :font_url # aliased to avoid conflicts with an font_url named route + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/atom_feed_helper.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/atom_feed_helper.rb new file mode 100644 index 0000000..227ad4c --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/atom_feed_helper.rb @@ -0,0 +1,203 @@ +require 'set' + +module ActionView + # = Action View Atom Feed Helpers + module Helpers + module AtomFeedHelper + # Adds easy defaults to writing Atom feeds with the Builder template engine (this does not work on ERB or any other + # template languages). + # + # Full usage example: + # + # config/routes.rb: + # Rails.application.routes.draw do + # resources :posts + # root to: "posts#index" + # end + # + # app/controllers/posts_controller.rb: + # class PostsController < ApplicationController::Base + # # GET /posts.html + # # GET /posts.atom + # def index + # @posts = Post.all + # + # respond_to do |format| + # format.html + # format.atom + # end + # end + # end + # + # app/views/posts/index.atom.builder: + # atom_feed do |feed| + # feed.title("My great blog!") + # feed.updated(@posts[0].created_at) if @posts.length > 0 + # + # @posts.each do |post| + # feed.entry(post) do |entry| + # entry.title(post.title) + # entry.content(post.body, type: 'html') + # + # entry.author do |author| + # author.name("DHH") + # end + # end + # end + # end + # + # The options for atom_feed are: + # + # * :language: Defaults to "en-US". + # * :root_url: The HTML alternative that this feed is doubling for. Defaults to / on the current host. + # * :url: The URL for this feed. Defaults to the current URL. + # * :id: The id for this feed. Defaults to "tag:#{request.host},#{options[:schema_date]}:#{request.fullpath.split(".")[0]}" + # * :schema_date: The date at which the tag scheme for the feed was first used. A good default is the year you + # created the feed. See http://feedvalidator.org/docs/error/InvalidTAG.html for more information. If not specified, + # 2005 is used (as an "I don't care" value). + # * :instruct: Hash of XML processing instructions in the form {target => {attribute => value, }} or {target => [{attribute => value, }, ]} + # + # Other namespaces can be added to the root element: + # + # app/views/posts/index.atom.builder: + # atom_feed({'xmlns:app' => 'http://www.w3.org/2007/app', + # 'xmlns:openSearch' => 'http://a9.com/-/spec/opensearch/1.1/'}) do |feed| + # feed.title("My great blog!") + # feed.updated((@posts.first.created_at)) + # feed.tag!('openSearch:totalResults', 10) + # + # @posts.each do |post| + # feed.entry(post) do |entry| + # entry.title(post.title) + # entry.content(post.body, type: 'html') + # entry.tag!('app:edited', Time.now) + # + # entry.author do |author| + # author.name("DHH") + # end + # end + # end + # end + # + # The Atom spec defines five elements (content rights title subtitle + # summary) which may directly contain xhtml content if type: 'xhtml' + # is specified as an attribute. If so, this helper will take care of + # the enclosing div and xhtml namespace declaration. Example usage: + # + # entry.summary type: 'xhtml' do |xhtml| + # xhtml.p pluralize(order.line_items.count, "line item") + # xhtml.p "Shipped to #{order.address}" + # xhtml.p "Paid by #{order.pay_type}" + # end + # + # + # atom_feed yields an +AtomFeedBuilder+ instance. Nested elements yield + # an +AtomBuilder+ instance. + def atom_feed(options = {}, &block) + if options[:schema_date] + options[:schema_date] = options[:schema_date].strftime("%Y-%m-%d") if options[:schema_date].respond_to?(:strftime) + else + options[:schema_date] = "2005" # The Atom spec copyright date + end + + xml = options.delete(:xml) || eval("xml", block.binding) + xml.instruct! + if options[:instruct] + options[:instruct].each do |target,attrs| + if attrs.respond_to?(:keys) + xml.instruct!(target, attrs) + elsif attrs.respond_to?(:each) + attrs.each { |attr_group| xml.instruct!(target, attr_group) } + end + end + end + + feed_opts = {"xml:lang" => options[:language] || "en-US", "xmlns" => 'http://www.w3.org/2005/Atom'} + feed_opts.merge!(options).reject!{|k,v| !k.to_s.match(/^xml/)} + + xml.feed(feed_opts) do + xml.id(options[:id] || "tag:#{request.host},#{options[:schema_date]}:#{request.fullpath.split(".")[0]}") + xml.link(:rel => 'alternate', :type => 'text/html', :href => options[:root_url] || (request.protocol + request.host_with_port)) + xml.link(:rel => 'self', :type => 'application/atom+xml', :href => options[:url] || request.url) + + yield AtomFeedBuilder.new(xml, self, options) + end + end + + class AtomBuilder #:nodoc: + XHTML_TAG_NAMES = %w(content rights title subtitle summary).to_set + + def initialize(xml) + @xml = xml + end + + private + # Delegate to xml builder, first wrapping the element in a xhtml + # namespaced div element if the method and arguments indicate + # that an xhtml_block? is desired. + def method_missing(method, *arguments, &block) + if xhtml_block?(method, arguments) + @xml.__send__(method, *arguments) do + @xml.div(:xmlns => 'http://www.w3.org/1999/xhtml') do |xhtml| + block.call(xhtml) + end + end + else + @xml.__send__(method, *arguments, &block) + end + end + + # True if the method name matches one of the five elements defined + # in the Atom spec as potentially containing XHTML content and + # if type: 'xhtml' is, in fact, specified. + def xhtml_block?(method, arguments) + if XHTML_TAG_NAMES.include?(method.to_s) + last = arguments.last + last.is_a?(Hash) && last[:type].to_s == 'xhtml' + end + end + end + + class AtomFeedBuilder < AtomBuilder #:nodoc: + def initialize(xml, view, feed_options = {}) + @xml, @view, @feed_options = xml, view, feed_options + end + + # Accepts a Date or Time object and inserts it in the proper format. If nil is passed, current time in UTC is used. + def updated(date_or_time = nil) + @xml.updated((date_or_time || Time.now.utc).xmlschema) + end + + # Creates an entry tag for a specific record and prefills the id using class and id. + # + # Options: + # + # * :published: Time first published. Defaults to the created_at attribute on the record if one such exists. + # * :updated: Time of update. Defaults to the updated_at attribute on the record if one such exists. + # * :url: The URL for this entry. Defaults to the polymorphic_url for the record. + # * :id: The ID for this entry. Defaults to "tag:#{@view.request.host},#{@feed_options[:schema_date]}:#{record.class}/#{record.id}" + # * :type: The TYPE for this entry. Defaults to "text/html". + def entry(record, options = {}) + @xml.entry do + @xml.id(options[:id] || "tag:#{@view.request.host},#{@feed_options[:schema_date]}:#{record.class}/#{record.id}") + + if options[:published] || (record.respond_to?(:created_at) && record.created_at) + @xml.published((options[:published] || record.created_at).xmlschema) + end + + if options[:updated] || (record.respond_to?(:updated_at) && record.updated_at) + @xml.updated((options[:updated] || record.updated_at).xmlschema) + end + + type = options.fetch(:type, 'text/html') + + @xml.link(:rel => 'alternate', :type => type, :href => options[:url] || @view.polymorphic_url(record)) + + yield AtomBuilder.new(@xml) + end + end + end + + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/cache_helper.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/cache_helper.rb new file mode 100644 index 0000000..06b6312 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/cache_helper.rb @@ -0,0 +1,200 @@ +module ActionView + # = Action View Cache Helper + module Helpers + module CacheHelper + # This helper exposes a method for caching fragments of a view + # rather than an entire action or page. This technique is useful + # caching pieces like menus, lists of new topics, static HTML + # fragments, and so on. This method takes a block that contains + # the content you wish to cache. + # + # The best way to use this is by doing key-based cache expiration + # on top of a cache store like Memcached that'll automatically + # kick out old entries. For more on key-based expiration, see: + # http://signalvnoise.com/posts/3113-how-key-based-cache-expiration-works + # + # When using this method, you list the cache dependency as the name of the cache, like so: + # + # <% cache project do %> + # All the topics on this project + # <%= render project.topics %> + # <% end %> + # + # This approach will assume that when a new topic is added, you'll touch + # the project. The cache key generated from this call will be something like: + # + # views/projects/123-20120806214154/7a1156131a6928cb0026877f8b749ac9 + # ^class ^id ^updated_at ^template tree digest + # + # The cache is thus automatically bumped whenever the project updated_at is touched. + # + # If your template cache depends on multiple sources (try to avoid this to keep things simple), + # you can name all these dependencies as part of an array: + # + # <% cache [ project, current_user ] do %> + # All the topics on this project + # <%= render project.topics %> + # <% end %> + # + # This will include both records as part of the cache key and updating either of them will + # expire the cache. + # + # ==== Template digest + # + # The template digest that's added to the cache key is computed by taking an md5 of the + # contents of the entire template file. This ensures that your caches will automatically + # expire when you change the template file. + # + # Note that the md5 is taken of the entire template file, not just what's within the + # cache do/end call. So it's possible that changing something outside of that call will + # still expire the cache. + # + # Additionally, the digestor will automatically look through your template file for + # explicit and implicit dependencies, and include those as part of the digest. + # + # The digestor can be bypassed by passing skip_digest: true as an option to the cache call: + # + # <% cache project, skip_digest: true do %> + # All the topics on this project + # <%= render project.topics %> + # <% end %> + # + # ==== Implicit dependencies + # + # Most template dependencies can be derived from calls to render in the template itself. + # Here are some examples of render calls that Cache Digests knows how to decode: + # + # render partial: "comments/comment", collection: commentable.comments + # render "comments/comments" + # render 'comments/comments' + # render('comments/comments') + # + # render "header" => render("comments/header") + # + # render(@topic) => render("topics/topic") + # render(topics) => render("topics/topic") + # render(message.topics) => render("topics/topic") + # + # It's not possible to derive all render calls like that, though. Here are a few examples of things that can't be derived: + # + # render group_of_attachments + # render @project.documents.where(published: true).order('created_at') + # + # You will have to rewrite those to the explicit form: + # + # render partial: 'attachments/attachment', collection: group_of_attachments + # render partial: 'documents/document', collection: @project.documents.where(published: true).order('created_at') + # + # === Explicit dependencies + # + # Some times you'll have template dependencies that can't be derived at all. This is typically + # the case when you have template rendering that happens in helpers. Here's an example: + # + # <%= render_sortable_todolists @project.todolists %> + # + # You'll need to use a special comment format to call those out: + # + # <%# Template Dependency: todolists/todolist %> + # <%= render_sortable_todolists @project.todolists %> + # + # The pattern used to match these is /# Template Dependency: ([^ ]+)/, so it's important that you type it out just so. + # You can only declare one template dependency per line. + # + # === External dependencies + # + # If you use a helper method, for example, inside of a cached block and you then update that helper, + # you'll have to bump the cache as well. It doesn't really matter how you do it, but the md5 of the template file + # must change. One recommendation is to simply be explicit in a comment, like: + # + # <%# Helper Dependency Updated: May 6, 2012 at 6pm %> + # <%= some_helper_method(person) %> + # + # Now all you'll have to do is change that timestamp when the helper method changes. + def cache(name = {}, options = nil, &block) + if controller.respond_to?(:perform_caching) && controller.perform_caching + safe_concat(fragment_for(cache_fragment_name(name, options), options, &block)) + else + yield + end + + nil + end + + # Cache fragments of a view if +condition+ is true + # + # <% cache_if admin?, project do %> + # All the topics on this project + # <%= render project.topics %> + # <% end %> + def cache_if(condition, name = {}, options = nil, &block) + if condition + cache(name, options, &block) + else + yield + end + + nil + end + + # Cache fragments of a view unless +condition+ is true + # + # <% cache_unless admin?, project do %> + # All the topics on this project + # <%= render project.topics %> + # <% end %> + def cache_unless(condition, name = {}, options = nil, &block) + cache_if !condition, name, options, &block + end + + # This helper returns the name of a cache key for a given fragment cache + # call. By supplying skip_digest: true to cache, the digestion of cache + # fragments can be manually bypassed. This is useful when cache fragments + # cannot be manually expired unless you know the exact key which is the + # case when using memcached. + def cache_fragment_name(name = {}, options = nil) + skip_digest = options && options[:skip_digest] + + if skip_digest + name + else + fragment_name_with_digest(name) + end + end + + private + + def fragment_name_with_digest(name) #:nodoc: + if @virtual_path + names = Array(name.is_a?(Hash) ? controller.url_for(name).split("://").last : name) + digest = Digestor.digest name: @virtual_path, finder: lookup_context, dependencies: view_cache_dependencies + + [ *names, digest ] + else + name + end + end + + # TODO: Create an object that has caching read/write on it + def fragment_for(name = {}, options = nil, &block) #:nodoc: + read_fragment_for(name, options) || write_fragment_for(name, options, &block) + end + + def read_fragment_for(name, options) #:nodoc: + controller.read_fragment(name, options) + end + + def write_fragment_for(name, options) #:nodoc: + # VIEW TODO: Make #capture usable outside of ERB + # This dance is needed because Builder can't use capture + pos = output_buffer.length + yield + output_safe = output_buffer.html_safe? + fragment = output_buffer.slice!(pos..-1) + if output_safe + self.output_buffer = output_buffer.class.new(output_buffer) + end + controller.write_fragment(name, fragment, options) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/capture_helper.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/capture_helper.rb new file mode 100644 index 0000000..8f9d731 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/capture_helper.rb @@ -0,0 +1,209 @@ +require 'active_support/core_ext/string/output_safety' + +module ActionView + # = Action View Capture Helper + module Helpers + # CaptureHelper exposes methods to let you extract generated markup which + # can be used in other parts of a template or layout file. + # + # It provides a method to capture blocks into variables through capture and + # a way to capture a block of markup for use in a layout through content_for. + module CaptureHelper + # The capture method allows you to extract part of a template into a + # variable. You can then use this variable anywhere in your templates or layout. + # + # The capture method can be used in ERB templates... + # + # <% @greeting = capture do %> + # Welcome to my shiny new web page! The date and time is + # <%= Time.now %> + # <% end %> + # + # ...and Builder (RXML) templates. + # + # @timestamp = capture do + # "The current timestamp is #{Time.now}." + # end + # + # You can then use that variable anywhere else. For example: + # + # + # <%= @greeting %> + # + # <%= @greeting %> + # + # + def capture(*args) + value = nil + buffer = with_output_buffer { value = yield(*args) } + if string = buffer.presence || value and string.is_a?(String) + ERB::Util.html_escape string + end + end + + # Calling content_for stores a block of markup in an identifier for later use. + # In order to access this stored content in other templates, helper modules + # or the layout, you would pass the identifier as an argument to content_for. + # + # Note: yield can still be used to retrieve the stored content, but calling + # yield doesn't work in helper modules, while content_for does. + # + # <% content_for :not_authorized do %> + # alert('You are not authorized to do that!') + # <% end %> + # + # You can then use content_for :not_authorized anywhere in your templates. + # + # <%= content_for :not_authorized if current_user.nil? %> + # + # This is equivalent to: + # + # <%= yield :not_authorized if current_user.nil? %> + # + # content_for, however, can also be used in helper modules. + # + # module StorageHelper + # def stored_content + # content_for(:storage) || "Your storage is empty" + # end + # end + # + # This helper works just like normal helpers. + # + # <%= stored_content %> + # + # You can also use the yield syntax alongside an existing call to + # yield in a layout. For example: + # + # <%# This is the layout %> + # + # + # My Website + # <%= yield :script %> + # + # + # <%= yield %> + # + # + # + # And now, we'll create a view that has a content_for call that + # creates the script identifier. + # + # <%# This is our view %> + # Please login! + # + # <% content_for :script do %> + # + # <% end %> + # + # Then, in another view, you could to do something like this: + # + # <%= link_to 'Logout', action: 'logout', remote: true %> + # + # <% content_for :script do %> + # <%= javascript_include_tag :defaults %> + # <% end %> + # + # That will place +script+ tags for your default set of JavaScript files on the page; + # this technique is useful if you'll only be using these scripts in a few views. + # + # Note that content_for concatenates (default) the blocks it is given for a particular + # identifier in order. For example: + # + # <% content_for :navigation do %> + #
  • <%= link_to 'Home', action: 'index' %>
  • + # <% end %> + # + # And in other place: + # + # <% content_for :navigation do %> + #
  • <%= link_to 'Login', action: 'login' %>
  • + # <% end %> + # + # Then, in another template or layout, this code would render both links in order: + # + #
      <%= content_for :navigation %>
    + # + # If the flush parameter is true content_for replaces the blocks it is given. For example: + # + # <% content_for :navigation do %> + #
  • <%= link_to 'Home', action: 'index' %>
  • + # <% end %> + # + # <%# Add some other content, or use a different template: %> + # + # <% content_for :navigation, flush: true do %> + #
  • <%= link_to 'Login', action: 'login' %>
  • + # <% end %> + # + # Then, in another template or layout, this code would render only the last link: + # + #
      <%= content_for :navigation %>
    + # + # Lastly, simple content can be passed as a parameter: + # + # <% content_for :script, javascript_include_tag(:defaults) %> + # + # WARNING: content_for is ignored in caches. So you shouldn't use it for elements that will be fragment cached. + def content_for(name, content = nil, options = {}, &block) + if content || block_given? + if block_given? + options = content if content + content = capture(&block) + end + if content + options[:flush] ? @view_flow.set(name, content) : @view_flow.append(name, content) + end + nil + else + @view_flow.get(name).presence + end + end + + # The same as +content_for+ but when used with streaming flushes + # straight back to the layout. In other words, if you want to + # concatenate several times to the same buffer when rendering a given + # template, you should use +content_for+, if not, use +provide+ to tell + # the layout to stop looking for more contents. + def provide(name, content = nil, &block) + content = capture(&block) if block_given? + result = @view_flow.append!(name, content) if content + result unless content + end + + # content_for? checks whether any content has been captured yet using `content_for`. + # Useful to render parts of your layout differently based on what is in your views. + # + # <%# This is the layout %> + # + # + # My Website + # <%= yield :script %> + # + # + # <%= yield %> + # <%= yield :right_col %> + # + # + def content_for?(name) + @view_flow.get(name).present? + end + + # Use an alternate output buffer for the duration of the block. + # Defaults to a new empty string. + def with_output_buffer(buf = nil) #:nodoc: + unless buf + buf = ActionView::OutputBuffer.new + if output_buffer && output_buffer.respond_to?(:encoding) + buf.force_encoding(output_buffer.encoding) + end + end + self.output_buffer, old_buffer = buf, output_buffer + yield + output_buffer + ensure + self.output_buffer = old_buffer + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/controller_helper.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/controller_helper.rb new file mode 100644 index 0000000..74ef25f --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/controller_helper.rb @@ -0,0 +1,25 @@ +require 'active_support/core_ext/module/attr_internal' + +module ActionView + module Helpers + # This module keeps all methods and behavior in ActionView + # that simply delegates to the controller. + module ControllerHelper #:nodoc: + attr_internal :controller, :request + + delegate :request_forgery_protection_token, :params, :session, :cookies, :response, :headers, + :flash, :action_name, :controller_name, :controller_path, :to => :controller + + def assign_controller(controller) + if @_controller = controller + @_request = controller.request if controller.respond_to?(:request) + @_config = controller.config.inheritable_copy if controller.respond_to?(:config) + end + end + + def logger + controller.logger if controller.respond_to?(:logger) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/csrf_helper.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/csrf_helper.rb new file mode 100644 index 0000000..5af92c4 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/csrf_helper.rb @@ -0,0 +1,33 @@ +module ActionView + # = Action View CSRF Helper + module Helpers + module CsrfHelper + # Returns meta tags "csrf-param" and "csrf-token" with the name of the cross-site + # request forgery protection parameter and token, respectively. + # + # + # <%= csrf_meta_tags %> + # + # + # These are used to generate the dynamic forms that implement non-remote links with + # :method. + # + # You don't need to use these tags for regular forms as they generate their own hidden fields. + # + # For AJAX requests other than GETs, extract the "csrf-token" from the meta-tag and send as the + # "X-CSRF-Token" HTTP header. If you are using jQuery with jquery-rails this happens automatically. + # + def csrf_meta_tags + if protect_against_forgery? + [ + tag('meta', :name => 'csrf-param', :content => request_forgery_protection_token), + tag('meta', :name => 'csrf-token', :content => form_authenticity_token) + ].join("\n").html_safe + end + end + + # For backwards compatibility. + alias csrf_meta_tag csrf_meta_tags + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/date_helper.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/date_helper.rb new file mode 100644 index 0000000..bd7b36c --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/date_helper.rb @@ -0,0 +1,1098 @@ +require 'date' +require 'action_view/helpers/tag_helper' +require 'active_support/core_ext/array/extract_options' +require 'active_support/core_ext/date/conversions' +require 'active_support/core_ext/hash/slice' +require 'active_support/core_ext/object/with_options' + +module ActionView + module Helpers + # = Action View Date Helpers + # + # The Date Helper primarily creates select/option tags for different kinds of dates and times or date and time + # elements. All of the select-type methods share a number of common options that are as follows: + # + # * :prefix - overwrites the default prefix of "date" used for the select names. So specifying "birthday" + # would give \birthday[month] instead of \date[month] if passed to the select_month method. + # * :include_blank - set to true if it should be possible to set an empty date. + # * :discard_type - set to true if you want to discard the type part of the select name. If set to true, + # the select_month method would use simply "date" (which can be overwritten using :prefix) instead + # of \date[month]. + module DateHelper + MINUTES_IN_YEAR = 525600 + MINUTES_IN_QUARTER_YEAR = 131400 + MINUTES_IN_THREE_QUARTERS_YEAR = 394200 + + # Reports the approximate distance in time between two Time, Date or DateTime objects or integers as seconds. + # Pass include_seconds: true if you want more detailed approximations when distance < 1 min, 29 secs. + # Distances are reported based on the following table: + # + # 0 <-> 29 secs # => less than a minute + # 30 secs <-> 1 min, 29 secs # => 1 minute + # 1 min, 30 secs <-> 44 mins, 29 secs # => [2..44] minutes + # 44 mins, 30 secs <-> 89 mins, 29 secs # => about 1 hour + # 89 mins, 30 secs <-> 23 hrs, 59 mins, 29 secs # => about [2..24] hours + # 23 hrs, 59 mins, 30 secs <-> 41 hrs, 59 mins, 29 secs # => 1 day + # 41 hrs, 59 mins, 30 secs <-> 29 days, 23 hrs, 59 mins, 29 secs # => [2..29] days + # 29 days, 23 hrs, 59 mins, 30 secs <-> 44 days, 23 hrs, 59 mins, 29 secs # => about 1 month + # 44 days, 23 hrs, 59 mins, 30 secs <-> 59 days, 23 hrs, 59 mins, 29 secs # => about 2 months + # 59 days, 23 hrs, 59 mins, 30 secs <-> 1 yr minus 1 sec # => [2..12] months + # 1 yr <-> 1 yr, 3 months # => about 1 year + # 1 yr, 3 months <-> 1 yr, 9 months # => over 1 year + # 1 yr, 9 months <-> 2 yr minus 1 sec # => almost 2 years + # 2 yrs <-> max time or date # => (same rules as 1 yr) + # + # With include_seconds: true and the difference < 1 minute 29 seconds: + # 0-4 secs # => less than 5 seconds + # 5-9 secs # => less than 10 seconds + # 10-19 secs # => less than 20 seconds + # 20-39 secs # => half a minute + # 40-59 secs # => less than a minute + # 60-89 secs # => 1 minute + # + # from_time = Time.now + # distance_of_time_in_words(from_time, from_time + 50.minutes) # => about 1 hour + # distance_of_time_in_words(from_time, 50.minutes.from_now) # => about 1 hour + # distance_of_time_in_words(from_time, from_time + 15.seconds) # => less than a minute + # distance_of_time_in_words(from_time, from_time + 15.seconds, include_seconds: true) # => less than 20 seconds + # distance_of_time_in_words(from_time, 3.years.from_now) # => about 3 years + # distance_of_time_in_words(from_time, from_time + 60.hours) # => 3 days + # distance_of_time_in_words(from_time, from_time + 45.seconds, include_seconds: true) # => less than a minute + # distance_of_time_in_words(from_time, from_time - 45.seconds, include_seconds: true) # => less than a minute + # distance_of_time_in_words(from_time, 76.seconds.from_now) # => 1 minute + # distance_of_time_in_words(from_time, from_time + 1.year + 3.days) # => about 1 year + # distance_of_time_in_words(from_time, from_time + 3.years + 6.months) # => over 3 years + # distance_of_time_in_words(from_time, from_time + 4.years + 9.days + 30.minutes + 5.seconds) # => about 4 years + # + # to_time = Time.now + 6.years + 19.days + # distance_of_time_in_words(from_time, to_time, include_seconds: true) # => about 6 years + # distance_of_time_in_words(to_time, from_time, include_seconds: true) # => about 6 years + # distance_of_time_in_words(Time.now, Time.now) # => less than a minute + def distance_of_time_in_words(from_time, to_time = 0, options = {}) + options = { + scope: :'datetime.distance_in_words' + }.merge!(options) + + from_time = from_time.to_time if from_time.respond_to?(:to_time) + to_time = to_time.to_time if to_time.respond_to?(:to_time) + from_time, to_time = to_time, from_time if from_time > to_time + distance_in_minutes = ((to_time - from_time)/60.0).round + distance_in_seconds = (to_time - from_time).round + + I18n.with_options :locale => options[:locale], :scope => options[:scope] do |locale| + case distance_in_minutes + when 0..1 + return distance_in_minutes == 0 ? + locale.t(:less_than_x_minutes, :count => 1) : + locale.t(:x_minutes, :count => distance_in_minutes) unless options[:include_seconds] + + case distance_in_seconds + when 0..4 then locale.t :less_than_x_seconds, :count => 5 + when 5..9 then locale.t :less_than_x_seconds, :count => 10 + when 10..19 then locale.t :less_than_x_seconds, :count => 20 + when 20..39 then locale.t :half_a_minute + when 40..59 then locale.t :less_than_x_minutes, :count => 1 + else locale.t :x_minutes, :count => 1 + end + + when 2...45 then locale.t :x_minutes, :count => distance_in_minutes + when 45...90 then locale.t :about_x_hours, :count => 1 + # 90 mins up to 24 hours + when 90...1440 then locale.t :about_x_hours, :count => (distance_in_minutes.to_f / 60.0).round + # 24 hours up to 42 hours + when 1440...2520 then locale.t :x_days, :count => 1 + # 42 hours up to 30 days + when 2520...43200 then locale.t :x_days, :count => (distance_in_minutes.to_f / 1440.0).round + # 30 days up to 60 days + when 43200...86400 then locale.t :about_x_months, :count => (distance_in_minutes.to_f / 43200.0).round + # 60 days up to 365 days + when 86400...525600 then locale.t :x_months, :count => (distance_in_minutes.to_f / 43200.0).round + else + if from_time.acts_like?(:time) && to_time.acts_like?(:time) + fyear = from_time.year + fyear += 1 if from_time.month >= 3 + tyear = to_time.year + tyear -= 1 if to_time.month < 3 + leap_years = (fyear > tyear) ? 0 : (fyear..tyear).count{|x| Date.leap?(x)} + minute_offset_for_leap_year = leap_years * 1440 + # Discount the leap year days when calculating year distance. + # e.g. if there are 20 leap year days between 2 dates having the same day + # and month then the based on 365 days calculation + # the distance in years will come out to over 80 years when in written + # English it would read better as about 80 years. + minutes_with_offset = distance_in_minutes - minute_offset_for_leap_year + else + minutes_with_offset = distance_in_minutes + end + remainder = (minutes_with_offset % MINUTES_IN_YEAR) + distance_in_years = (minutes_with_offset.div MINUTES_IN_YEAR) + if remainder < MINUTES_IN_QUARTER_YEAR + locale.t(:about_x_years, :count => distance_in_years) + elsif remainder < MINUTES_IN_THREE_QUARTERS_YEAR + locale.t(:over_x_years, :count => distance_in_years) + else + locale.t(:almost_x_years, :count => distance_in_years + 1) + end + end + end + end + + # Like distance_of_time_in_words, but where to_time is fixed to Time.now. + # + # time_ago_in_words(3.minutes.from_now) # => 3 minutes + # time_ago_in_words(3.minutes.ago) # => 3 minutes + # time_ago_in_words(Time.now - 15.hours) # => about 15 hours + # time_ago_in_words(Time.now) # => less than a minute + # time_ago_in_words(Time.now, include_seconds: true) # => less than 5 seconds + # + # from_time = Time.now - 3.days - 14.minutes - 25.seconds + # time_ago_in_words(from_time) # => 3 days + # + # from_time = (3.days + 14.minutes + 25.seconds).ago + # time_ago_in_words(from_time) # => 3 days + # + # Note that you cannot pass a Numeric value to time_ago_in_words. + # + def time_ago_in_words(from_time, options = {}) + distance_of_time_in_words(from_time, Time.now, options) + end + + alias_method :distance_of_time_in_words_to_now, :time_ago_in_words + + # Returns a set of select tags (one for year, month, and day) pre-selected for accessing a specified date-based + # attribute (identified by +method+) on an object assigned to the template (identified by +object+). + # + # ==== Options + # * :use_month_numbers - Set to true if you want to use month numbers rather than month names (e.g. + # "2" instead of "February"). + # * :use_two_digit_numbers - Set to true if you want to display two digit month and day numbers (e.g. + # "02" instead of "February" and "08" instead of "8"). + # * :use_short_month - Set to true if you want to use abbreviated month names instead of full + # month names (e.g. "Feb" instead of "February"). + # * :add_month_numbers - Set to true if you want to use both month numbers and month names (e.g. + # "2 - February" instead of "February"). + # * :use_month_names - Set to an array with 12 month names if you want to customize month names. + # Note: You can also use Rails' i18n functionality for this. + # * :month_format_string - Set to a format string. The string gets passed keys +:number+ (integer) + # and +:name+ (string). A format string would be something like "%{name} (%02d)" for example. + # See Kernel.sprintf for documentation on format sequences. + # * :date_separator - Specifies a string to separate the date fields. Default is "" (i.e. nothing). + # * :start_year - Set the start year for the year select. Default is Date.today.year - 5 if + # you are creating new record. While editing existing record, :start_year defaults to + # the current selected year minus 5. + # * :end_year - Set the end year for the year select. Default is Date.today.year + 5 if + # you are creating new record. While editing existing record, :end_year defaults to + # the current selected year plus 5. + # * :discard_day - Set to true if you don't want to show a day select. This includes the day + # as a hidden field instead of showing a select field. Also note that this implicitly sets the day to be the + # first of the given month in order to not create invalid dates like 31 February. + # * :discard_month - Set to true if you don't want to show a month select. This includes the month + # as a hidden field instead of showing a select field. Also note that this implicitly sets :discard_day to true. + # * :discard_year - Set to true if you don't want to show a year select. This includes the year + # as a hidden field instead of showing a select field. + # * :order - Set to an array containing :day, :month and :year to + # customize the order in which the select fields are shown. If you leave out any of the symbols, the respective + # select will not be shown (like when you set discard_xxx: true. Defaults to the order defined in + # the respective locale (e.g. [:year, :month, :day] in the en locale that ships with Rails). + # * :include_blank - Include a blank option in every select field so it's possible to set empty + # dates. + # * :default - Set a default date if the affected date isn't set or is nil. + # * :selected - Set a date that overrides the actual value. + # * :disabled - Set to true if you want show the select fields as disabled. + # * :prompt - Set to true (for a generic prompt), a prompt string or a hash of prompt strings + # for :year, :month, :day, :hour, :minute and :second. + # Setting this option prepends a select option with a generic prompt (Day, Month, Year, Hour, Minute, Seconds) + # or the given prompt string. + # * :with_css_classes - Set to true if you want assign different styles for 'select' tags. This option + # automatically set classes 'year', 'month', 'day', 'hour', 'minute' and 'second' for your 'select' tags. + # + # If anything is passed in the +html_options+ hash it will be applied to every select tag in the set. + # + # NOTE: Discarded selects will default to 1. So if no month select is available, January will be assumed. + # + # # Generates a date select that when POSTed is stored in the article variable, in the written_on attribute. + # date_select("article", "written_on") + # + # # Generates a date select that when POSTed is stored in the article variable, in the written_on attribute, + # # with the year in the year drop down box starting at 1995. + # date_select("article", "written_on", start_year: 1995) + # + # # Generates a date select that when POSTed is stored in the article variable, in the written_on attribute, + # # with the year in the year drop down box starting at 1995, numbers used for months instead of words, + # # and without a day select box. + # date_select("article", "written_on", start_year: 1995, use_month_numbers: true, + # discard_day: true, include_blank: true) + # + # # Generates a date select that when POSTed is stored in the article variable, in the written_on attribute, + # # with two digit numbers used for months and days. + # date_select("article", "written_on", use_two_digit_numbers: true) + # + # # Generates a date select that when POSTed is stored in the article variable, in the written_on attribute + # # with the fields ordered as day, month, year rather than month, day, year. + # date_select("article", "written_on", order: [:day, :month, :year]) + # + # # Generates a date select that when POSTed is stored in the user variable, in the birthday attribute + # # lacking a year field. + # date_select("user", "birthday", order: [:month, :day]) + # + # # Generates a date select that when POSTed is stored in the article variable, in the written_on attribute + # # which is initially set to the date 3 days from the current date + # date_select("article", "written_on", default: 3.days.from_now) + # + # # Generates a date select that when POSTed is stored in the article variable, in the written_on attribute + # # which is set in the form with todays date, regardless of the value in the Active Record object. + # date_select("article", "written_on", selected: Date.today) + # + # # Generates a date select that when POSTed is stored in the credit_card variable, in the bill_due attribute + # # that will have a default day of 20. + # date_select("credit_card", "bill_due", default: { day: 20 }) + # + # # Generates a date select with custom prompts. + # date_select("article", "written_on", prompt: { day: 'Select day', month: 'Select month', year: 'Select year' }) + # + # The selects are prepared for multi-parameter assignment to an Active Record object. + # + # Note: If the day is not included as an option but the month is, the day will be set to the 1st to ensure that + # all month choices are valid. + def date_select(object_name, method, options = {}, html_options = {}) + Tags::DateSelect.new(object_name, method, self, options, html_options).render + end + + # Returns a set of select tags (one for hour, minute and optionally second) pre-selected for accessing a + # specified time-based attribute (identified by +method+) on an object assigned to the template (identified by + # +object+). You can include the seconds with :include_seconds. You can get hours in the AM/PM format + # with :ampm option. + # + # This method will also generate 3 input hidden tags, for the actual year, month and day unless the option + # :ignore_date is set to +true+. If you set the :ignore_date to +true+, you must have a + # +date_select+ on the same method within the form otherwise an exception will be raised. + # + # If anything is passed in the html_options hash it will be applied to every select tag in the set. + # + # # Creates a time select tag that, when POSTed, will be stored in the article variable in the sunrise attribute. + # time_select("article", "sunrise") + # + # # Creates a time select tag with a seconds field that, when POSTed, will be stored in the article variables in + # # the sunrise attribute. + # time_select("article", "start_time", include_seconds: true) + # + # # You can set the :minute_step to 15 which will give you: 00, 15, 30 and 45. + # time_select 'game', 'game_time', {minute_step: 15} + # + # # Creates a time select tag with a custom prompt. Use prompt: true for generic prompts. + # time_select("article", "written_on", prompt: {hour: 'Choose hour', minute: 'Choose minute', second: 'Choose seconds'}) + # time_select("article", "written_on", prompt: {hour: true}) # generic prompt for hours + # time_select("article", "written_on", prompt: true) # generic prompts for all + # + # # You can set :ampm option to true which will show the hours as: 12 PM, 01 AM .. 11 PM. + # time_select 'game', 'game_time', {ampm: true} + # + # The selects are prepared for multi-parameter assignment to an Active Record object. + # + # Note: If the day is not included as an option but the month is, the day will be set to the 1st to ensure that + # all month choices are valid. + def time_select(object_name, method, options = {}, html_options = {}) + Tags::TimeSelect.new(object_name, method, self, options, html_options).render + end + + # Returns a set of select tags (one for year, month, day, hour, and minute) pre-selected for accessing a + # specified datetime-based attribute (identified by +method+) on an object assigned to the template (identified + # by +object+). + # + # If anything is passed in the html_options hash it will be applied to every select tag in the set. + # + # # Generates a datetime select that, when POSTed, will be stored in the article variable in the written_on + # # attribute. + # datetime_select("article", "written_on") + # + # # Generates a datetime select with a year select that starts at 1995 that, when POSTed, will be stored in the + # # article variable in the written_on attribute. + # datetime_select("article", "written_on", start_year: 1995) + # + # # Generates a datetime select with a default value of 3 days from the current time that, when POSTed, will + # # be stored in the trip variable in the departing attribute. + # datetime_select("trip", "departing", default: 3.days.from_now) + # + # # Generate a datetime select with hours in the AM/PM format + # datetime_select("article", "written_on", ampm: true) + # + # # Generates a datetime select that discards the type that, when POSTed, will be stored in the article variable + # # as the written_on attribute. + # datetime_select("article", "written_on", discard_type: true) + # + # # Generates a datetime select with a custom prompt. Use prompt: true for generic prompts. + # datetime_select("article", "written_on", prompt: {day: 'Choose day', month: 'Choose month', year: 'Choose year'}) + # datetime_select("article", "written_on", prompt: {hour: true}) # generic prompt for hours + # datetime_select("article", "written_on", prompt: true) # generic prompts for all + # + # The selects are prepared for multi-parameter assignment to an Active Record object. + def datetime_select(object_name, method, options = {}, html_options = {}) + Tags::DatetimeSelect.new(object_name, method, self, options, html_options).render + end + + # Returns a set of HTML select-tags (one for year, month, day, hour, minute, and second) pre-selected with the + # +datetime+. It's also possible to explicitly set the order of the tags using the :order option with + # an array of symbols :year, :month and :day in the desired order. If you do not + # supply a Symbol, it will be appended onto the :order passed in. You can also add + # :date_separator, :datetime_separator and :time_separator keys to the +options+ to + # control visual display of the elements. + # + # If anything is passed in the html_options hash it will be applied to every select tag in the set. + # + # my_date_time = Time.now + 4.days + # + # # Generates a datetime select that defaults to the datetime in my_date_time (four days after today). + # select_datetime(my_date_time) + # + # # Generates a datetime select that defaults to today (no specified datetime) + # select_datetime() + # + # # Generates a datetime select that defaults to the datetime in my_date_time (four days after today) + # # with the fields ordered year, month, day rather than month, day, year. + # select_datetime(my_date_time, order: [:year, :month, :day]) + # + # # Generates a datetime select that defaults to the datetime in my_date_time (four days after today) + # # with a '/' between each date field. + # select_datetime(my_date_time, date_separator: '/') + # + # # Generates a datetime select that defaults to the datetime in my_date_time (four days after today) + # # with a date fields separated by '/', time fields separated by '' and the date and time fields + # # separated by a comma (','). + # select_datetime(my_date_time, date_separator: '/', time_separator: '', datetime_separator: ',') + # + # # Generates a datetime select that discards the type of the field and defaults to the datetime in + # # my_date_time (four days after today) + # select_datetime(my_date_time, discard_type: true) + # + # # Generate a datetime field with hours in the AM/PM format + # select_datetime(my_date_time, ampm: true) + # + # # Generates a datetime select that defaults to the datetime in my_date_time (four days after today) + # # prefixed with 'payday' rather than 'date' + # select_datetime(my_date_time, prefix: 'payday') + # + # # Generates a datetime select with a custom prompt. Use prompt: true for generic prompts. + # select_datetime(my_date_time, prompt: {day: 'Choose day', month: 'Choose month', year: 'Choose year'}) + # select_datetime(my_date_time, prompt: {hour: true}) # generic prompt for hours + # select_datetime(my_date_time, prompt: true) # generic prompts for all + def select_datetime(datetime = Time.current, options = {}, html_options = {}) + DateTimeSelector.new(datetime, options, html_options).select_datetime + end + + # Returns a set of HTML select-tags (one for year, month, and day) pre-selected with the +date+. + # It's possible to explicitly set the order of the tags using the :order option with an array of + # symbols :year, :month and :day in the desired order. + # If the array passed to the :order option does not contain all the three symbols, all tags will be hidden. + # + # If anything is passed in the html_options hash it will be applied to every select tag in the set. + # + # my_date = Time.now + 6.days + # + # # Generates a date select that defaults to the date in my_date (six days after today). + # select_date(my_date) + # + # # Generates a date select that defaults to today (no specified date). + # select_date() + # + # # Generates a date select that defaults to the date in my_date (six days after today) + # # with the fields ordered year, month, day rather than month, day, year. + # select_date(my_date, order: [:year, :month, :day]) + # + # # Generates a date select that discards the type of the field and defaults to the date in + # # my_date (six days after today). + # select_date(my_date, discard_type: true) + # + # # Generates a date select that defaults to the date in my_date, + # # which has fields separated by '/'. + # select_date(my_date, date_separator: '/') + # + # # Generates a date select that defaults to the datetime in my_date (six days after today) + # # prefixed with 'payday' rather than 'date'. + # select_date(my_date, prefix: 'payday') + # + # # Generates a date select with a custom prompt. Use prompt: true for generic prompts. + # select_date(my_date, prompt: {day: 'Choose day', month: 'Choose month', year: 'Choose year'}) + # select_date(my_date, prompt: {hour: true}) # generic prompt for hours + # select_date(my_date, prompt: true) # generic prompts for all + def select_date(date = Date.current, options = {}, html_options = {}) + DateTimeSelector.new(date, options, html_options).select_date + end + + # Returns a set of HTML select-tags (one for hour and minute). + # You can set :time_separator key to format the output, and + # the :include_seconds option to include an input for seconds. + # + # If anything is passed in the html_options hash it will be applied to every select tag in the set. + # + # my_time = Time.now + 5.days + 7.hours + 3.minutes + 14.seconds + # + # # Generates a time select that defaults to the time in my_time. + # select_time(my_time) + # + # # Generates a time select that defaults to the current time (no specified time). + # select_time() + # + # # Generates a time select that defaults to the time in my_time, + # # which has fields separated by ':'. + # select_time(my_time, time_separator: ':') + # + # # Generates a time select that defaults to the time in my_time, + # # that also includes an input for seconds. + # select_time(my_time, include_seconds: true) + # + # # Generates a time select that defaults to the time in my_time, that has fields + # # separated by ':' and includes an input for seconds. + # select_time(my_time, time_separator: ':', include_seconds: true) + # + # # Generate a time select field with hours in the AM/PM format + # select_time(my_time, ampm: true) + # + # # Generates a time select field with hours that range from 2 to 14 + # select_time(my_time, start_hour: 2, end_hour: 14) + # + # # Generates a time select with a custom prompt. Use :prompt to true for generic prompts. + # select_time(my_time, prompt: {day: 'Choose day', month: 'Choose month', year: 'Choose year'}) + # select_time(my_time, prompt: {hour: true}) # generic prompt for hours + # select_time(my_time, prompt: true) # generic prompts for all + def select_time(datetime = Time.current, options = {}, html_options = {}) + DateTimeSelector.new(datetime, options, html_options).select_time + end + + # Returns a select tag with options for each of the seconds 0 through 59 with the current second selected. + # The datetime can be either a +Time+ or +DateTime+ object or an integer. + # Override the field name using the :field_name option, 'second' by default. + # + # my_time = Time.now + 16.minutes + # + # # Generates a select field for seconds that defaults to the seconds for the time in my_time. + # select_second(my_time) + # + # # Generates a select field for seconds that defaults to the number given. + # select_second(33) + # + # # Generates a select field for seconds that defaults to the seconds for the time in my_time + # # that is named 'interval' rather than 'second'. + # select_second(my_time, field_name: 'interval') + # + # # Generates a select field for seconds with a custom prompt. Use prompt: true for a + # # generic prompt. + # select_second(14, prompt: 'Choose seconds') + def select_second(datetime, options = {}, html_options = {}) + DateTimeSelector.new(datetime, options, html_options).select_second + end + + # Returns a select tag with options for each of the minutes 0 through 59 with the current minute selected. + # Also can return a select tag with options by minute_step from 0 through 59 with the 00 minute + # selected. The datetime can be either a +Time+ or +DateTime+ object or an integer. + # Override the field name using the :field_name option, 'minute' by default. + # + # my_time = Time.now + 6.hours + # + # # Generates a select field for minutes that defaults to the minutes for the time in my_time. + # select_minute(my_time) + # + # # Generates a select field for minutes that defaults to the number given. + # select_minute(14) + # + # # Generates a select field for minutes that defaults to the minutes for the time in my_time + # # that is named 'moment' rather than 'minute'. + # select_minute(my_time, field_name: 'moment') + # + # # Generates a select field for minutes with a custom prompt. Use prompt: true for a + # # generic prompt. + # select_minute(14, prompt: 'Choose minutes') + def select_minute(datetime, options = {}, html_options = {}) + DateTimeSelector.new(datetime, options, html_options).select_minute + end + + # Returns a select tag with options for each of the hours 0 through 23 with the current hour selected. + # The datetime can be either a +Time+ or +DateTime+ object or an integer. + # Override the field name using the :field_name option, 'hour' by default. + # + # my_time = Time.now + 6.hours + # + # # Generates a select field for hours that defaults to the hour for the time in my_time. + # select_hour(my_time) + # + # # Generates a select field for hours that defaults to the number given. + # select_hour(13) + # + # # Generates a select field for hours that defaults to the hour for the time in my_time + # # that is named 'stride' rather than 'hour'. + # select_hour(my_time, field_name: 'stride') + # + # # Generates a select field for hours with a custom prompt. Use prompt: true for a + # # generic prompt. + # select_hour(13, prompt: 'Choose hour') + # + # # Generate a select field for hours in the AM/PM format + # select_hour(my_time, ampm: true) + # + # # Generates a select field that includes options for hours from 2 to 14. + # select_hour(my_time, start_hour: 2, end_hour: 14) + def select_hour(datetime, options = {}, html_options = {}) + DateTimeSelector.new(datetime, options, html_options).select_hour + end + + # Returns a select tag with options for each of the days 1 through 31 with the current day selected. + # The date can also be substituted for a day number. + # If you want to display days with a leading zero set the :use_two_digit_numbers key in +options+ to true. + # Override the field name using the :field_name option, 'day' by default. + # + # my_date = Time.now + 2.days + # + # # Generates a select field for days that defaults to the day for the date in my_date. + # select_day(my_date) + # + # # Generates a select field for days that defaults to the number given. + # select_day(5) + # + # # Generates a select field for days that defaults to the number given, but displays it with two digits. + # select_day(5, use_two_digit_numbers: true) + # + # # Generates a select field for days that defaults to the day for the date in my_date + # # that is named 'due' rather than 'day'. + # select_day(my_date, field_name: 'due') + # + # # Generates a select field for days with a custom prompt. Use prompt: true for a + # # generic prompt. + # select_day(5, prompt: 'Choose day') + def select_day(date, options = {}, html_options = {}) + DateTimeSelector.new(date, options, html_options).select_day + end + + # Returns a select tag with options for each of the months January through December with the current month + # selected. The month names are presented as keys (what's shown to the user) and the month numbers (1-12) are + # used as values (what's submitted to the server). It's also possible to use month numbers for the presentation + # instead of names -- set the :use_month_numbers key in +options+ to true for this to happen. If you + # want both numbers and names, set the :add_month_numbers key in +options+ to true. If you would prefer + # to show month names as abbreviations, set the :use_short_month key in +options+ to true. If you want + # to use your own month names, set the :use_month_names key in +options+ to an array of 12 month names. + # If you want to display months with a leading zero set the :use_two_digit_numbers key in +options+ to true. + # Override the field name using the :field_name option, 'month' by default. + # + # # Generates a select field for months that defaults to the current month that + # # will use keys like "January", "March". + # select_month(Date.today) + # + # # Generates a select field for months that defaults to the current month that + # # is named "start" rather than "month". + # select_month(Date.today, field_name: 'start') + # + # # Generates a select field for months that defaults to the current month that + # # will use keys like "1", "3". + # select_month(Date.today, use_month_numbers: true) + # + # # Generates a select field for months that defaults to the current month that + # # will use keys like "1 - January", "3 - March". + # select_month(Date.today, add_month_numbers: true) + # + # # Generates a select field for months that defaults to the current month that + # # will use keys like "Jan", "Mar". + # select_month(Date.today, use_short_month: true) + # + # # Generates a select field for months that defaults to the current month that + # # will use keys like "Januar", "Marts." + # select_month(Date.today, use_month_names: %w(Januar Februar Marts ...)) + # + # # Generates a select field for months that defaults to the current month that + # # will use keys with two digit numbers like "01", "03". + # select_month(Date.today, use_two_digit_numbers: true) + # + # # Generates a select field for months with a custom prompt. Use prompt: true for a + # # generic prompt. + # select_month(14, prompt: 'Choose month') + def select_month(date, options = {}, html_options = {}) + DateTimeSelector.new(date, options, html_options).select_month + end + + # Returns a select tag with options for each of the five years on each side of the current, which is selected. + # The five year radius can be changed using the :start_year and :end_year keys in the + # +options+. Both ascending and descending year lists are supported by making :start_year less than or + # greater than :end_year. The date can also be substituted for a year given as a number. + # Override the field name using the :field_name option, 'year' by default. + # + # # Generates a select field for years that defaults to the current year that + # # has ascending year values. + # select_year(Date.today, start_year: 1992, end_year: 2007) + # + # # Generates a select field for years that defaults to the current year that + # # is named 'birth' rather than 'year'. + # select_year(Date.today, field_name: 'birth') + # + # # Generates a select field for years that defaults to the current year that + # # has descending year values. + # select_year(Date.today, start_year: 2005, end_year: 1900) + # + # # Generates a select field for years that defaults to the year 2006 that + # # has ascending year values. + # select_year(2006, start_year: 2000, end_year: 2010) + # + # # Generates a select field for years with a custom prompt. Use prompt: true for a + # # generic prompt. + # select_year(14, prompt: 'Choose year') + def select_year(date, options = {}, html_options = {}) + DateTimeSelector.new(date, options, html_options).select_year + end + + # Returns an HTML time tag for the given date or time. + # + # time_tag Date.today # => + # + # time_tag Time.now # => + # + # time_tag Date.yesterday, 'Yesterday' # => + # + # time_tag Date.today, pubdate: true # => + # + # time_tag Date.today, datetime: Date.today.strftime('%G-W%V') # => + # + # + # <%= time_tag Time.now do %> + # Right now + # <% end %> + # # => + def time_tag(date_or_time, *args, &block) + options = args.extract_options! + format = options.delete(:format) || :long + content = args.first || I18n.l(date_or_time, :format => format) + datetime = date_or_time.acts_like?(:time) ? date_or_time.xmlschema : date_or_time.iso8601 + + content_tag(:time, content, options.reverse_merge(:datetime => datetime), &block) + end + end + + class DateTimeSelector #:nodoc: + include ActionView::Helpers::TagHelper + + DEFAULT_PREFIX = 'date'.freeze + POSITION = { + :year => 1, :month => 2, :day => 3, :hour => 4, :minute => 5, :second => 6 + }.freeze + + AMPM_TRANSLATION = Hash[ + [[0, "12 AM"], [1, "01 AM"], [2, "02 AM"], [3, "03 AM"], + [4, "04 AM"], [5, "05 AM"], [6, "06 AM"], [7, "07 AM"], + [8, "08 AM"], [9, "09 AM"], [10, "10 AM"], [11, "11 AM"], + [12, "12 PM"], [13, "01 PM"], [14, "02 PM"], [15, "03 PM"], + [16, "04 PM"], [17, "05 PM"], [18, "06 PM"], [19, "07 PM"], + [20, "08 PM"], [21, "09 PM"], [22, "10 PM"], [23, "11 PM"]] + ].freeze + + def initialize(datetime, options = {}, html_options = {}) + @options = options.dup + @html_options = html_options.dup + @datetime = datetime + @options[:datetime_separator] ||= ' — ' + @options[:time_separator] ||= ' : ' + end + + def select_datetime + order = date_order.dup + order -= [:hour, :minute, :second] + @options[:discard_year] ||= true unless order.include?(:year) + @options[:discard_month] ||= true unless order.include?(:month) + @options[:discard_day] ||= true if @options[:discard_month] || !order.include?(:day) + @options[:discard_minute] ||= true if @options[:discard_hour] + @options[:discard_second] ||= true unless @options[:include_seconds] && !@options[:discard_minute] + + set_day_if_discarded + + if @options[:tag] && @options[:ignore_date] + select_time + else + [:day, :month, :year].each { |o| order.unshift(o) unless order.include?(o) } + order += [:hour, :minute, :second] unless @options[:discard_hour] + + build_selects_from_types(order) + end + end + + def select_date + order = date_order.dup + + @options[:discard_hour] = true + @options[:discard_minute] = true + @options[:discard_second] = true + + @options[:discard_year] ||= true unless order.include?(:year) + @options[:discard_month] ||= true unless order.include?(:month) + @options[:discard_day] ||= true if @options[:discard_month] || !order.include?(:day) + + set_day_if_discarded + + [:day, :month, :year].each { |o| order.unshift(o) unless order.include?(o) } + + build_selects_from_types(order) + end + + def select_time + order = [] + + @options[:discard_month] = true + @options[:discard_year] = true + @options[:discard_day] = true + @options[:discard_second] ||= true unless @options[:include_seconds] + + order += [:year, :month, :day] unless @options[:ignore_date] + + order += [:hour, :minute] + order << :second if @options[:include_seconds] + + build_selects_from_types(order) + end + + def select_second + if @options[:use_hidden] || @options[:discard_second] + build_hidden(:second, sec) if @options[:include_seconds] + else + build_options_and_select(:second, sec) + end + end + + def select_minute + if @options[:use_hidden] || @options[:discard_minute] + build_hidden(:minute, min) + else + build_options_and_select(:minute, min, :step => @options[:minute_step]) + end + end + + def select_hour + if @options[:use_hidden] || @options[:discard_hour] + build_hidden(:hour, hour) + else + options = {} + options[:ampm] = @options[:ampm] || false + options[:start] = @options[:start_hour] || 0 + options[:end] = @options[:end_hour] || 23 + build_options_and_select(:hour, hour, options) + end + end + + def select_day + if @options[:use_hidden] || @options[:discard_day] + build_hidden(:day, day || 1) + else + build_options_and_select(:day, day, :start => 1, :end => 31, :leading_zeros => false, :use_two_digit_numbers => @options[:use_two_digit_numbers]) + end + end + + def select_month + if @options[:use_hidden] || @options[:discard_month] + build_hidden(:month, month || 1) + else + month_options = [] + 1.upto(12) do |month_number| + options = { :value => month_number } + options[:selected] = "selected" if month == month_number + month_options << content_tag(:option, month_name(month_number), options) + "\n" + end + build_select(:month, month_options.join) + end + end + + def select_year + if !@datetime || @datetime == 0 + val = '1' + middle_year = Date.today.year + else + val = middle_year = year + end + + if @options[:use_hidden] || @options[:discard_year] + build_hidden(:year, val) + else + options = {} + options[:start] = @options[:start_year] || middle_year - 5 + options[:end] = @options[:end_year] || middle_year + 5 + options[:step] = options[:start] < options[:end] ? 1 : -1 + options[:leading_zeros] = false + options[:max_years_allowed] = @options[:max_years_allowed] || 1000 + + if (options[:end] - options[:start]).abs > options[:max_years_allowed] + raise ArgumentError, "There are too many years options to be built. Are you sure you haven't mistyped something? You can provide the :max_years_allowed parameter." + end + + build_options_and_select(:year, val, options) + end + end + + private + %w( sec min hour day month year ).each do |method| + define_method(method) do + @datetime.kind_of?(Numeric) ? @datetime : @datetime.send(method) if @datetime + end + end + + # If the day is hidden, the day should be set to the 1st so all month and year choices are + # valid. Otherwise, February 31st or February 29th, 2011 can be selected, which are invalid. + def set_day_if_discarded + if @datetime && @options[:discard_day] + @datetime = @datetime.change(:day => 1) + end + end + + # Returns translated month names, but also ensures that a custom month + # name array has a leading nil element. + def month_names + @month_names ||= begin + month_names = @options[:use_month_names] || translated_month_names + month_names.unshift(nil) if month_names.size < 13 + month_names + end + end + + # Returns translated month names. + # => [nil, "January", "February", "March", + # "April", "May", "June", "July", + # "August", "September", "October", + # "November", "December"] + # + # If :use_short_month option is set + # => [nil, "Jan", "Feb", "Mar", "Apr", "May", "Jun", + # "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] + def translated_month_names + key = @options[:use_short_month] ? :'date.abbr_month_names' : :'date.month_names' + I18n.translate(key, :locale => @options[:locale]) + end + + # Looks up month names by number (1-based): + # + # month_name(1) # => "January" + # + # If the :use_month_numbers option is passed: + # + # month_name(1) # => 1 + # + # If the :use_two_month_numbers option is passed: + # + # month_name(1) # => '01' + # + # If the :add_month_numbers option is passed: + # + # month_name(1) # => "1 - January" + # + # If the :month_format_string option is passed: + # + # month_name(1) # => "January (01)" + # + # depending on the format string. + def month_name(number) + if @options[:use_month_numbers] + number + elsif @options[:use_two_digit_numbers] + '%02d' % number + elsif @options[:add_month_numbers] + "#{number} - #{month_names[number]}" + elsif format_string = @options[:month_format_string] + format_string % {number: number, name: month_names[number]} + else + month_names[number] + end + end + + def date_order + @date_order ||= @options[:order] || translated_date_order + end + + def translated_date_order + date_order = I18n.translate(:'date.order', :locale => @options[:locale], :default => []) + date_order = date_order.map { |element| element.to_sym } + + forbidden_elements = date_order - [:year, :month, :day] + if forbidden_elements.any? + raise StandardError, + "#{@options[:locale]}.date.order only accepts :year, :month and :day" + end + + date_order + end + + # Build full select tag from date type and options. + def build_options_and_select(type, selected, options = {}) + build_select(type, build_options(selected, options)) + end + + # Build select option HTML from date value and options. + # build_options(15, start: 1, end: 31) + # => " + # + # ..." + # + # If use_two_digit_numbers: true option is passed + # build_options(15, start: 1, end: 31, use_two_digit_numbers: true) + # => " + # + # ..." + # + # If :step options is passed + # build_options(15, start: 1, end: 31, step: 2) + # => " + # + # ..." + def build_options(selected, options = {}) + options = { + leading_zeros: true, ampm: false, use_two_digit_numbers: false + }.merge!(options) + + start = options.delete(:start) || 0 + stop = options.delete(:end) || 59 + step = options.delete(:step) || 1 + leading_zeros = options.delete(:leading_zeros) + + select_options = [] + start.step(stop, step) do |i| + value = leading_zeros ? sprintf("%02d", i) : i + tag_options = { :value => value } + tag_options[:selected] = "selected" if selected == i + text = options[:use_two_digit_numbers] ? sprintf("%02d", i) : value + text = options[:ampm] ? AMPM_TRANSLATION[i] : text + select_options << content_tag(:option, text, tag_options) + end + + (select_options.join("\n") + "\n").html_safe + end + + # Builds select tag from date type and HTML select options. + # build_select(:month, "...") + # => "" + def build_select(type, select_options_as_html) + select_options = { + :id => input_id_from_type(type), + :name => input_name_from_type(type) + }.merge!(@html_options) + select_options[:disabled] = 'disabled' if @options[:disabled] + select_options[:class] = [select_options[:class], type].compact.join(' ') if @options[:with_css_classes] + + select_html = "\n" + select_html << content_tag(:option, '', :value => '') + "\n" if @options[:include_blank] + select_html << prompt_option_tag(type, @options[:prompt]) + "\n" if @options[:prompt] + select_html << select_options_as_html + + (content_tag(:select, select_html.html_safe, select_options) + "\n").html_safe + end + + # Builds a prompt option tag with supplied options or from default options. + # prompt_option_tag(:month, prompt: 'Select month') + # => "" + def prompt_option_tag(type, options) + prompt = case options + when Hash + default_options = {:year => false, :month => false, :day => false, :hour => false, :minute => false, :second => false} + default_options.merge!(options)[type.to_sym] + when String + options + else + I18n.translate(:"datetime.prompts.#{type}", :locale => @options[:locale]) + end + + prompt ? content_tag(:option, prompt, :value => '') : '' + end + + # Builds hidden input tag for date part and value. + # build_hidden(:year, 2008) + # => "" + def build_hidden(type, value) + select_options = { + :type => "hidden", + :id => input_id_from_type(type), + :name => input_name_from_type(type), + :value => value + }.merge!(@html_options.slice(:disabled)) + select_options[:disabled] = 'disabled' if @options[:disabled] + + tag(:input, select_options) + "\n".html_safe + end + + # Returns the name attribute for the input tag. + # => post[written_on(1i)] + def input_name_from_type(type) + prefix = @options[:prefix] || ActionView::Helpers::DateTimeSelector::DEFAULT_PREFIX + prefix += "[#{@options[:index]}]" if @options.has_key?(:index) + + field_name = @options[:field_name] || type + if @options[:include_position] + field_name += "(#{ActionView::Helpers::DateTimeSelector::POSITION[type]}i)" + end + + @options[:discard_type] ? prefix : "#{prefix}[#{field_name}]" + end + + # Returns the id attribute for the input tag. + # => "post_written_on_1i" + def input_id_from_type(type) + id = input_name_from_type(type).gsub(/([\[\(])|(\]\[)/, '_').gsub(/[\]\)]/, '') + id = @options[:namespace] + '_' + id if @options[:namespace] + + id + end + + # Given an ordering of datetime components, create the selection HTML + # and join them with their appropriate separators. + def build_selects_from_types(order) + select = '' + first_visible = order.find { |type| !@options[:"discard_#{type}"] } + order.reverse_each do |type| + separator = separator(type) unless type == first_visible # don't add before first visible field + select.insert(0, separator.to_s + send("select_#{type}").to_s) + end + select.html_safe + end + + # Returns the separator for a given datetime component. + def separator(type) + return "" if @options[:use_hidden] + + case type + when :year, :month, :day + @options[:"discard_#{type}"] ? "" : @options[:date_separator] + when :hour + (@options[:discard_year] && @options[:discard_day]) ? "" : @options[:datetime_separator] + when :minute, :second + @options[:"discard_#{type}"] ? "" : @options[:time_separator] + end + end + end + + class FormBuilder + # Wraps ActionView::Helpers::DateHelper#date_select for form builders: + # + # <%= form_for @person do |f| %> + # <%= f.date_select :birth_date %> + # <%= f.submit %> + # <% end %> + # + # Please refer to the documentation of the base helper for details. + def date_select(method, options = {}, html_options = {}) + @template.date_select(@object_name, method, objectify_options(options), html_options) + end + + # Wraps ActionView::Helpers::DateHelper#time_select for form builders: + # + # <%= form_for @race do |f| %> + # <%= f.time_select :average_lap %> + # <%= f.submit %> + # <% end %> + # + # Please refer to the documentation of the base helper for details. + def time_select(method, options = {}, html_options = {}) + @template.time_select(@object_name, method, objectify_options(options), html_options) + end + + # Wraps ActionView::Helpers::DateHelper#datetime_select for form builders: + # + # <%= form_for @person do |f| %> + # <%= f.datetime_select :last_request_at %> + # <%= f.submit %> + # <% end %> + # + # Please refer to the documentation of the base helper for details. + def datetime_select(method, options = {}, html_options = {}) + @template.datetime_select(@object_name, method, objectify_options(options), html_options) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/debug_helper.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/debug_helper.rb new file mode 100644 index 0000000..ba47eee --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/debug_helper.rb @@ -0,0 +1,35 @@ +module ActionView + # = Action View Debug Helper + # + # Provides a set of methods for making it easier to debug Rails objects. + module Helpers + module DebugHelper + + include TagHelper + + # Returns a YAML representation of +object+ wrapped with
     and 
    . + # If the object cannot be converted to YAML using +to_yaml+, +inspect+ will be called instead. + # Useful for inspecting an object at the time of rendering. + # + # @user = User.new({ username: 'testing', password: 'xyz', age: 42}) + # debug(@user) + # # => + #
    --- !ruby/object:User
    +      #   attributes:
    +      #     updated_at:
    +      #     username: testing
    +      #     age: 42
    +      #     password: xyz
    +      #     created_at:
    +      #   
    + def debug(object) + Marshal::dump(object) + object = ERB::Util.html_escape(object.to_yaml) + content_tag(:pre, object, :class => "debug_dump") + rescue Exception # errors from Marshal or YAML + # Object couldn't be dumped, perhaps because of singleton methods -- this is the fallback + content_tag(:code, object.inspect, :class => "debug_dump") + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/form_helper.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/form_helper.rb new file mode 100644 index 0000000..490e517 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/form_helper.rb @@ -0,0 +1,1943 @@ +require 'cgi' +require 'action_view/helpers/date_helper' +require 'action_view/helpers/tag_helper' +require 'action_view/helpers/form_tag_helper' +require 'action_view/helpers/active_model_helper' +require 'action_view/model_naming' +require 'active_support/core_ext/module/attribute_accessors' +require 'active_support/core_ext/hash/slice' +require 'active_support/core_ext/string/output_safety' +require 'active_support/core_ext/string/inflections' + +module ActionView + # = Action View Form Helpers + module Helpers + # Form helpers are designed to make working with resources much easier + # compared to using vanilla HTML. + # + # Typically, a form designed to create or update a resource reflects the + # identity of the resource in several ways: (i) the url that the form is + # sent to (the form element's +action+ attribute) should result in a request + # being routed to the appropriate controller action (with the appropriate :id + # parameter in the case of an existing resource), (ii) input fields should + # be named in such a way that in the controller their values appear in the + # appropriate places within the +params+ hash, and (iii) for an existing record, + # when the form is initially displayed, input fields corresponding to attributes + # of the resource should show the current values of those attributes. + # + # In Rails, this is usually achieved by creating the form using +form_for+ and + # a number of related helper methods. +form_for+ generates an appropriate form + # tag and yields a form builder object that knows the model the form is about. + # Input fields are created by calling methods defined on the form builder, which + # means they are able to generate the appropriate names and default values + # corresponding to the model attributes, as well as convenient IDs, etc. + # Conventions in the generated field names allow controllers to receive form data + # nicely structured in +params+ with no effort on your side. + # + # For example, to create a new person you typically set up a new instance of + # +Person+ in the PeopleController#new action, @person, and + # in the view template pass that object to +form_for+: + # + # <%= form_for @person do |f| %> + # <%= f.label :first_name %>: + # <%= f.text_field :first_name %>
    + # + # <%= f.label :last_name %>: + # <%= f.text_field :last_name %>
    + # + # <%= f.submit %> + # <% end %> + # + # The HTML generated for this would be (modulus formatting): + # + #
    + # + # : + #
    + # + # : + #
    + # + # + #
    + # + # As you see, the HTML reflects knowledge about the resource in several spots, + # like the path the form should be submitted to, or the names of the input fields. + # + # In particular, thanks to the conventions followed in the generated field names, the + # controller gets a nested hash params[:person] with the person attributes + # set in the form. That hash is ready to be passed to Person.create: + # + # if @person = Person.create(params[:person]) + # # success + # else + # # error handling + # end + # + # Interestingly, the exact same view code in the previous example can be used to edit + # a person. If @person is an existing record with name "John Smith" and ID 256, + # the code above as is would yield instead: + # + #
    + # + # + # : + #
    + # + # : + #
    + # + # + #
    + # + # Note that the endpoint, default values, and submit button label are tailored for @person. + # That works that way because the involved helpers know whether the resource is a new record or not, + # and generate HTML accordingly. + # + # The controller would receive the form data again in params[:person], ready to be + # passed to Person#update: + # + # if @person.update(params[:person]) + # # success + # else + # # error handling + # end + # + # That's how you typically work with resources. + module FormHelper + extend ActiveSupport::Concern + + include FormTagHelper + include UrlHelper + include ModelNaming + + # Creates a form that allows the user to create or update the attributes + # of a specific model object. + # + # The method can be used in several slightly different ways, depending on + # how much you wish to rely on Rails to infer automatically from the model + # how the form should be constructed. For a generic model object, a form + # can be created by passing +form_for+ a string or symbol representing + # the object we are concerned with: + # + # <%= form_for :person do |f| %> + # First name: <%= f.text_field :first_name %>
    + # Last name : <%= f.text_field :last_name %>
    + # Biography : <%= f.text_area :biography %>
    + # Admin? : <%= f.check_box :admin %>
    + # <%= f.submit %> + # <% end %> + # + # The variable +f+ yielded to the block is a FormBuilder object that + # incorporates the knowledge about the model object represented by + # :person passed to +form_for+. Methods defined on the FormBuilder + # are used to generate fields bound to this model. Thus, for example, + # + # <%= f.text_field :first_name %> + # + # will get expanded to + # + # <%= text_field :person, :first_name %> + # which results in an HTML tag whose +name+ attribute is + # person[first_name]. This means that when the form is submitted, + # the value entered by the user will be available in the controller as + # params[:person][:first_name]. + # + # For fields generated in this way using the FormBuilder, + # if :person also happens to be the name of an instance variable + # @person, the default value of the field shown when the form is + # initially displayed (e.g. in the situation where you are editing an + # existing record) will be the value of the corresponding attribute of + # @person. + # + # The rightmost argument to +form_for+ is an + # optional hash of options - + # + # * :url - The URL the form is to be submitted to. This may be + # represented in the same way as values passed to +url_for+ or +link_to+. + # So for example you may use a named route directly. When the model is + # represented by a string or symbol, as in the example above, if the + # :url option is not specified, by default the form will be + # sent back to the current url (We will describe below an alternative + # resource-oriented usage of +form_for+ in which the URL does not need + # to be specified explicitly). + # * :namespace - A namespace for your form to ensure uniqueness of + # id attributes on form elements. The namespace attribute will be prefixed + # with underscore on the generated HTML id. + # * :method - The method to use when submitting the form, usually + # either "get" or "post". If "patch", "put", "delete", or another verb + # is used, a hidden input with name _method is added to + # simulate the verb over post. + # * :authenticity_token - Authenticity token to use in the form. + # Use only if you need to pass custom authenticity token string, or to + # not add authenticity_token field at all (by passing false). + # Remote forms may omit the embedded authenticity token by setting + # config.action_view.embed_authenticity_token_in_remote_forms = false. + # This is helpful when you're fragment-caching the form. Remote forms + # get the authenticity token from the meta tag, so embedding is + # unnecessary unless you support browsers without JavaScript. + # * :remote - If set to true, will allow the Unobtrusive + # JavaScript drivers to control the submit behavior. By default this + # behavior is an ajax submit. + # * :enforce_utf8 - If set to false, a hidden input with name + # utf8 is not output. + # * :html - Optional HTML attributes for the form tag. + # + # Also note that +form_for+ doesn't create an exclusive scope. It's still + # possible to use both the stand-alone FormHelper methods and methods + # from FormTagHelper. For example: + # + # <%= form_for :person do |f| %> + # First name: <%= f.text_field :first_name %> + # Last name : <%= f.text_field :last_name %> + # Biography : <%= text_area :person, :biography %> + # Admin? : <%= check_box_tag "person[admin]", "1", @person.company.admin? %> + # <%= f.submit %> + # <% end %> + # + # This also works for the methods in FormOptionHelper and DateHelper that + # are designed to work with an object as base, like + # FormOptionHelper#collection_select and DateHelper#datetime_select. + # + # === #form_for with a model object + # + # In the examples above, the object to be created or edited was + # represented by a symbol passed to +form_for+, and we noted that + # a string can also be used equivalently. It is also possible, however, + # to pass a model object itself to +form_for+. For example, if @post + # is an existing record you wish to edit, you can create the form using + # + # <%= form_for @post do |f| %> + # ... + # <% end %> + # + # This behaves in almost the same way as outlined previously, with a + # couple of small exceptions. First, the prefix used to name the input + # elements within the form (hence the key that denotes them in the +params+ + # hash) is actually derived from the object's _class_, e.g. params[:post] + # if the object's class is +Post+. However, this can be overwritten using + # the :as option, e.g. - + # + # <%= form_for(@person, as: :client) do |f| %> + # ... + # <% end %> + # + # would result in params[:client]. + # + # Secondly, the field values shown when the form is initially displayed + # are taken from the attributes of the object passed to +form_for+, + # regardless of whether the object is an instance + # variable. So, for example, if we had a _local_ variable +post+ + # representing an existing record, + # + # <%= form_for post do |f| %> + # ... + # <% end %> + # + # would produce a form with fields whose initial state reflect the current + # values of the attributes of +post+. + # + # === Resource-oriented style + # + # In the examples just shown, although not indicated explicitly, we still + # need to use the :url option in order to specify where the + # form is going to be sent. However, further simplification is possible + # if the record passed to +form_for+ is a _resource_, i.e. it corresponds + # to a set of RESTful routes, e.g. defined using the +resources+ method + # in config/routes.rb. In this case Rails will simply infer the + # appropriate URL from the record itself. For example, + # + # <%= form_for @post do |f| %> + # ... + # <% end %> + # + # is then equivalent to something like: + # + # <%= form_for @post, as: :post, url: post_path(@post), method: :patch, html: { class: "edit_post", id: "edit_post_45" } do |f| %> + # ... + # <% end %> + # + # And for a new record + # + # <%= form_for(Post.new) do |f| %> + # ... + # <% end %> + # + # is equivalent to something like: + # + # <%= form_for @post, as: :post, url: posts_path, html: { class: "new_post", id: "new_post" } do |f| %> + # ... + # <% end %> + # + # However you can still overwrite individual conventions, such as: + # + # <%= form_for(@post, url: super_posts_path) do |f| %> + # ... + # <% end %> + # + # You can also set the answer format, like this: + # + # <%= form_for(@post, format: :json) do |f| %> + # ... + # <% end %> + # + # For namespaced routes, like +admin_post_url+: + # + # <%= form_for([:admin, @post]) do |f| %> + # ... + # <% end %> + # + # If your resource has associations defined, for example, you want to add comments + # to the document given that the routes are set correctly: + # + # <%= form_for([@document, @comment]) do |f| %> + # ... + # <% end %> + # + # Where @document = Document.find(params[:id]) and + # @comment = Comment.new. + # + # === Setting the method + # + # You can force the form to use the full array of HTTP verbs by setting + # + # method: (:get|:post|:patch|:put|:delete) + # + # in the options hash. If the verb is not GET or POST, which are natively + # supported by HTML forms, the form will be set to POST and a hidden input + # called _method will carry the intended verb for the server to interpret. + # + # === Unobtrusive JavaScript + # + # Specifying: + # + # remote: true + # + # in the options hash creates a form that will allow the unobtrusive JavaScript drivers to modify its + # behavior. The expected default behavior is an XMLHttpRequest in the background instead of the regular + # POST arrangement, but ultimately the behavior is the choice of the JavaScript driver implementor. + # Even though it's using JavaScript to serialize the form elements, the form submission will work just like + # a regular submission as viewed by the receiving side (all elements available in params). + # + # Example: + # + # <%= form_for(@post, remote: true) do |f| %> + # ... + # <% end %> + # + # The HTML generated for this would be: + # + #
    + # + # ... + #
    + # + # === Setting HTML options + # + # You can set data attributes directly by passing in a data hash, but all other HTML options must be wrapped in + # the HTML key. Example: + # + # <%= form_for(@post, data: { behavior: "autosave" }, html: { name: "go" }) do |f| %> + # ... + # <% end %> + # + # The HTML generated for this would be: + # + #
    + # + # ... + #
    + # + # === Removing hidden model id's + # + # The form_for method automatically includes the model id as a hidden field in the form. + # This is used to maintain the correlation between the form data and its associated model. + # Some ORM systems do not use IDs on nested models so in this case you want to be able + # to disable the hidden id. + # + # In the following example the Post model has many Comments stored within it in a NoSQL database, + # thus there is no primary key for comments. + # + # Example: + # + # <%= form_for(@post) do |f| %> + # <%= f.fields_for(:comments, include_id: false) do |cf| %> + # ... + # <% end %> + # <% end %> + # + # === Customized form builders + # + # You can also build forms using a customized FormBuilder class. Subclass + # FormBuilder and override or define some more helpers, then use your + # custom builder. For example, let's say you made a helper to + # automatically add labels to form inputs. + # + # <%= form_for @person, url: { action: "create" }, builder: LabellingFormBuilder do |f| %> + # <%= f.text_field :first_name %> + # <%= f.text_field :last_name %> + # <%= f.text_area :biography %> + # <%= f.check_box :admin %> + # <%= f.submit %> + # <% end %> + # + # In this case, if you use this: + # + # <%= render f %> + # + # The rendered template is people/_labelling_form and the local + # variable referencing the form builder is called + # labelling_form. + # + # The custom FormBuilder class is automatically merged with the options + # of a nested fields_for call, unless it's explicitly set. + # + # In many cases you will want to wrap the above in another helper, so you + # could do something like the following: + # + # def labelled_form_for(record_or_name_or_array, *args, &block) + # options = args.extract_options! + # form_for(record_or_name_or_array, *(args << options.merge(builder: LabellingFormBuilder)), &block) + # end + # + # If you don't need to attach a form to a model instance, then check out + # FormTagHelper#form_tag. + # + # === Form to external resources + # + # When you build forms to external resources sometimes you need to set an authenticity token or just render a form + # without it, for example when you submit data to a payment gateway number and types of fields could be limited. + # + # To set an authenticity token you need to pass an :authenticity_token parameter + # + # <%= form_for @invoice, url: external_url, authenticity_token: 'external_token' do |f| + # ... + # <% end %> + # + # If you don't want to an authenticity token field be rendered at all just pass false: + # + # <%= form_for @invoice, url: external_url, authenticity_token: false do |f| + # ... + # <% end %> + def form_for(record, options = {}, &block) + raise ArgumentError, "Missing block" unless block_given? + html_options = options[:html] ||= {} + + case record + when String, Symbol + object_name = record + object = nil + else + object = record.is_a?(Array) ? record.last : record + raise ArgumentError, "First argument in form cannot contain nil or be empty" unless object + object_name = options[:as] || model_name_from_record_or_class(object).param_key + apply_form_for_options!(record, object, options) + end + + html_options[:data] = options.delete(:data) if options.has_key?(:data) + html_options[:remote] = options.delete(:remote) if options.has_key?(:remote) + html_options[:method] = options.delete(:method) if options.has_key?(:method) + html_options[:enforce_utf8] = options.delete(:enforce_utf8) if options.has_key?(:enforce_utf8) + html_options[:authenticity_token] = options.delete(:authenticity_token) + + builder = instantiate_builder(object_name, object, options) + output = capture(builder, &block) + html_options[:multipart] ||= builder.multipart? + + html_options = html_options_for_form(options[:url] || {}, html_options) + form_tag_with_body(html_options, output) + end + + def apply_form_for_options!(record, object, options) #:nodoc: + object = convert_to_model(object) + + as = options[:as] + namespace = options[:namespace] + action, method = object.respond_to?(:persisted?) && object.persisted? ? [:edit, :patch] : [:new, :post] + options[:html].reverse_merge!( + class: as ? "#{action}_#{as}" : dom_class(object, action), + id: (as ? [namespace, action, as] : [namespace, dom_id(object, action)]).compact.join("_").presence, + method: method + ) + + options[:url] ||= if options.key?(:format) + polymorphic_path(record, format: options.delete(:format)) + else + polymorphic_path(record, {}) + end + end + private :apply_form_for_options! + + # Creates a scope around a specific model object like form_for, but + # doesn't create the form tags themselves. This makes fields_for suitable + # for specifying additional model objects in the same form. + # + # Although the usage and purpose of +fields_for+ is similar to +form_for+'s, + # its method signature is slightly different. Like +form_for+, it yields + # a FormBuilder object associated with a particular model object to a block, + # and within the block allows methods to be called on the builder to + # generate fields associated with the model object. Fields may reflect + # a model object in two ways - how they are named (hence how submitted + # values appear within the +params+ hash in the controller) and what + # default values are shown when the form the fields appear in is first + # displayed. In order for both of these features to be specified independently, + # both an object name (represented by either a symbol or string) and the + # object itself can be passed to the method separately - + # + # <%= form_for @person do |person_form| %> + # First name: <%= person_form.text_field :first_name %> + # Last name : <%= person_form.text_field :last_name %> + # + # <%= fields_for :permission, @person.permission do |permission_fields| %> + # Admin? : <%= permission_fields.check_box :admin %> + # <% end %> + # + # <%= person_form.submit %> + # <% end %> + # + # In this case, the checkbox field will be represented by an HTML +input+ + # tag with the +name+ attribute permission[admin], and the submitted + # value will appear in the controller as params[:permission][:admin]. + # If @person.permission is an existing record with an attribute + # +admin+, the initial state of the checkbox when first displayed will + # reflect the value of @person.permission.admin. + # + # Often this can be simplified by passing just the name of the model + # object to +fields_for+ - + # + # <%= fields_for :permission do |permission_fields| %> + # Admin?: <%= permission_fields.check_box :admin %> + # <% end %> + # + # ...in which case, if :permission also happens to be the name of an + # instance variable @permission, the initial state of the input + # field will reflect the value of that variable's attribute @permission.admin. + # + # Alternatively, you can pass just the model object itself (if the first + # argument isn't a string or symbol +fields_for+ will realize that the + # name has been omitted) - + # + # <%= fields_for @person.permission do |permission_fields| %> + # Admin?: <%= permission_fields.check_box :admin %> + # <% end %> + # + # and +fields_for+ will derive the required name of the field from the + # _class_ of the model object, e.g. if @person.permission, is + # of class +Permission+, the field will still be named permission[admin]. + # + # Note: This also works for the methods in FormOptionHelper and + # DateHelper that are designed to work with an object as base, like + # FormOptionHelper#collection_select and DateHelper#datetime_select. + # + # === Nested Attributes Examples + # + # When the object belonging to the current scope has a nested attribute + # writer for a certain attribute, fields_for will yield a new scope + # for that attribute. This allows you to create forms that set or change + # the attributes of a parent object and its associations in one go. + # + # Nested attribute writers are normal setter methods named after an + # association. The most common way of defining these writers is either + # with +accepts_nested_attributes_for+ in a model definition or by + # defining a method with the proper name. For example: the attribute + # writer for the association :address is called + # address_attributes=. + # + # Whether a one-to-one or one-to-many style form builder will be yielded + # depends on whether the normal reader method returns a _single_ object + # or an _array_ of objects. + # + # ==== One-to-one + # + # Consider a Person class which returns a _single_ Address from the + # address reader method and responds to the + # address_attributes= writer method: + # + # class Person + # def address + # @address + # end + # + # def address_attributes=(attributes) + # # Process the attributes hash + # end + # end + # + # This model can now be used with a nested fields_for, like so: + # + # <%= form_for @person do |person_form| %> + # ... + # <%= person_form.fields_for :address do |address_fields| %> + # Street : <%= address_fields.text_field :street %> + # Zip code: <%= address_fields.text_field :zip_code %> + # <% end %> + # ... + # <% end %> + # + # When address is already an association on a Person you can use + # +accepts_nested_attributes_for+ to define the writer method for you: + # + # class Person < ActiveRecord::Base + # has_one :address + # accepts_nested_attributes_for :address + # end + # + # If you want to destroy the associated model through the form, you have + # to enable it first using the :allow_destroy option for + # +accepts_nested_attributes_for+: + # + # class Person < ActiveRecord::Base + # has_one :address + # accepts_nested_attributes_for :address, allow_destroy: true + # end + # + # Now, when you use a form element with the _destroy parameter, + # with a value that evaluates to +true+, you will destroy the associated + # model (eg. 1, '1', true, or 'true'): + # + # <%= form_for @person do |person_form| %> + # ... + # <%= person_form.fields_for :address do |address_fields| %> + # ... + # Delete: <%= address_fields.check_box :_destroy %> + # <% end %> + # ... + # <% end %> + # + # ==== One-to-many + # + # Consider a Person class which returns an _array_ of Project instances + # from the projects reader method and responds to the + # projects_attributes= writer method: + # + # class Person + # def projects + # [@project1, @project2] + # end + # + # def projects_attributes=(attributes) + # # Process the attributes hash + # end + # end + # + # Note that the projects_attributes= writer method is in fact + # required for fields_for to correctly identify :projects as a + # collection, and the correct indices to be set in the form markup. + # + # When projects is already an association on Person you can use + # +accepts_nested_attributes_for+ to define the writer method for you: + # + # class Person < ActiveRecord::Base + # has_many :projects + # accepts_nested_attributes_for :projects + # end + # + # This model can now be used with a nested fields_for. The block given to + # the nested fields_for call will be repeated for each instance in the + # collection: + # + # <%= form_for @person do |person_form| %> + # ... + # <%= person_form.fields_for :projects do |project_fields| %> + # <% if project_fields.object.active? %> + # Name: <%= project_fields.text_field :name %> + # <% end %> + # <% end %> + # ... + # <% end %> + # + # It's also possible to specify the instance to be used: + # + # <%= form_for @person do |person_form| %> + # ... + # <% @person.projects.each do |project| %> + # <% if project.active? %> + # <%= person_form.fields_for :projects, project do |project_fields| %> + # Name: <%= project_fields.text_field :name %> + # <% end %> + # <% end %> + # <% end %> + # ... + # <% end %> + # + # Or a collection to be used: + # + # <%= form_for @person do |person_form| %> + # ... + # <%= person_form.fields_for :projects, @active_projects do |project_fields| %> + # Name: <%= project_fields.text_field :name %> + # <% end %> + # ... + # <% end %> + # + # If you want to destroy any of the associated models through the + # form, you have to enable it first using the :allow_destroy + # option for +accepts_nested_attributes_for+: + # + # class Person < ActiveRecord::Base + # has_many :projects + # accepts_nested_attributes_for :projects, allow_destroy: true + # end + # + # This will allow you to specify which models to destroy in the + # attributes hash by adding a form element for the _destroy + # parameter with a value that evaluates to +true+ + # (eg. 1, '1', true, or 'true'): + # + # <%= form_for @person do |person_form| %> + # ... + # <%= person_form.fields_for :projects do |project_fields| %> + # Delete: <%= project_fields.check_box :_destroy %> + # <% end %> + # ... + # <% end %> + # + # When a collection is used you might want to know the index of each + # object into the array. For this purpose, the index method + # is available in the FormBuilder object. + # + # <%= form_for @person do |person_form| %> + # ... + # <%= person_form.fields_for :projects do |project_fields| %> + # Project #<%= project_fields.index %> + # ... + # <% end %> + # ... + # <% end %> + # + # Note that fields_for will automatically generate a hidden field + # to store the ID of the record. There are circumstances where this + # hidden field is not needed and you can pass include_id: false + # to prevent fields_for from rendering it automatically. + def fields_for(record_name, record_object = nil, options = {}, &block) + builder = instantiate_builder(record_name, record_object, options) + capture(builder, &block) + end + + # Returns a label tag tailored for labelling an input field for a specified attribute (identified by +method+) on an object + # assigned to the template (identified by +object+). The text of label will default to the attribute name unless a translation + # is found in the current I18n locale (through helpers.label..) or you specify it explicitly. + # Additional options on the label tag can be passed as a hash with +options+. These options will be tagged + # onto the HTML as an HTML element attribute as in the example shown, except for the :value option, which is designed to + # target labels for radio_button tags (where the value is used in the ID of the input tag). + # + # ==== Examples + # label(:post, :title) + # # => + # + # You can localize your labels based on model and attribute names. + # For example you can define the following in your locale (e.g. en.yml) + # + # helpers: + # label: + # post: + # body: "Write your entire text here" + # + # Which then will result in + # + # label(:post, :body) + # # => + # + # Localization can also be based purely on the translation of the attribute-name + # (if you are using ActiveRecord): + # + # activerecord: + # attributes: + # post: + # cost: "Total cost" + # + # label(:post, :cost) + # # => + # + # label(:post, :title, "A short title") + # # => + # + # label(:post, :title, "A short title", class: "title_label") + # # => + # + # label(:post, :privacy, "Public Post", value: "public") + # # => + # + # label(:post, :terms) do + # 'Accept Terms.'.html_safe + # end + # # => + def label(object_name, method, content_or_options = nil, options = nil, &block) + Tags::Label.new(object_name, method, self, content_or_options, options).render(&block) + end + + # Returns an input tag of the "text" type tailored for accessing a specified attribute (identified by +method+) on an object + # assigned to the template (identified by +object+). Additional options on the input tag can be passed as a + # hash with +options+. These options will be tagged onto the HTML as an HTML element attribute as in the example + # shown. + # + # ==== Examples + # text_field(:post, :title, size: 20) + # # => + # + # text_field(:post, :title, class: "create_input") + # # => + # + # text_field(:session, :user, onchange: "if ($('#session_user').val() === 'admin') { alert('Your login cannot be admin!'); }") + # # => + # + # text_field(:snippet, :code, size: 20, class: 'code_input') + # # => + def text_field(object_name, method, options = {}) + Tags::TextField.new(object_name, method, self, options).render + end + + # Returns an input tag of the "password" type tailored for accessing a specified attribute (identified by +method+) on an object + # assigned to the template (identified by +object+). Additional options on the input tag can be passed as a + # hash with +options+. These options will be tagged onto the HTML as an HTML element attribute as in the example + # shown. For security reasons this field is blank by default; pass in a value via +options+ if this is not desired. + # + # ==== Examples + # password_field(:login, :pass, size: 20) + # # => + # + # password_field(:account, :secret, class: "form_input", value: @account.secret) + # # => + # + # password_field(:user, :password, onchange: "if ($('#user_password').val().length > 30) { alert('Your password needs to be shorter!'); }") + # # => + # + # password_field(:account, :pin, size: 20, class: 'form_input') + # # => + def password_field(object_name, method, options = {}) + Tags::PasswordField.new(object_name, method, self, options).render + end + + # Returns a hidden input tag tailored for accessing a specified attribute (identified by +method+) on an object + # assigned to the template (identified by +object+). Additional options on the input tag can be passed as a + # hash with +options+. These options will be tagged onto the HTML as an HTML element attribute as in the example + # shown. + # + # ==== Examples + # hidden_field(:signup, :pass_confirm) + # # => + # + # hidden_field(:post, :tag_list) + # # => + # + # hidden_field(:user, :token) + # # => + def hidden_field(object_name, method, options = {}) + Tags::HiddenField.new(object_name, method, self, options).render + end + + # Returns a file upload input tag tailored for accessing a specified attribute (identified by +method+) on an object + # assigned to the template (identified by +object+). Additional options on the input tag can be passed as a + # hash with +options+. These options will be tagged onto the HTML as an HTML element attribute as in the example + # shown. + # + # Using this method inside a +form_for+ block will set the enclosing form's encoding to multipart/form-data. + # + # ==== Options + # * Creates standard HTML attributes for the tag. + # * :disabled - If set to true, the user will not be able to use this input. + # * :multiple - If set to true, *in most updated browsers* the user will be allowed to select multiple files. + # * :accept - If set to one or multiple mime-types, the user will be suggested a filter when choosing a file. You still need to set up model validations. + # + # ==== Examples + # file_field(:user, :avatar) + # # => + # + # file_field(:post, :image, :multiple => true) + # # => + # + # file_field(:post, :attached, accept: 'text/html') + # # => + # + # file_field(:post, :image, accept: 'image/png,image/gif,image/jpeg') + # # => + # + # file_field(:attachment, :file, class: 'file_input') + # # => + def file_field(object_name, method, options = {}) + Tags::FileField.new(object_name, method, self, options).render + end + + # Returns a textarea opening and closing tag set tailored for accessing a specified attribute (identified by +method+) + # on an object assigned to the template (identified by +object+). Additional options on the input tag can be passed as a + # hash with +options+. + # + # ==== Examples + # text_area(:post, :body, cols: 20, rows: 40) + # # => + # + # text_area(:comment, :text, size: "20x30") + # # => + # + # text_area(:application, :notes, cols: 40, rows: 15, class: 'app_input') + # # => + # + # text_area(:entry, :body, size: "20x20", disabled: 'disabled') + # # => + def text_area(object_name, method, options = {}) + Tags::TextArea.new(object_name, method, self, options).render + end + + # Returns a checkbox tag tailored for accessing a specified attribute (identified by +method+) on an object + # assigned to the template (identified by +object+). This object must be an instance object (@object) and not a local object. + # It's intended that +method+ returns an integer and if that integer is above zero, then the checkbox is checked. + # Additional options on the input tag can be passed as a hash with +options+. The +checked_value+ defaults to 1 + # while the default +unchecked_value+ is set to 0 which is convenient for boolean values. + # + # ==== Gotcha + # + # The HTML specification says unchecked check boxes are not successful, and + # thus web browsers do not send them. Unfortunately this introduces a gotcha: + # if an +Invoice+ model has a +paid+ flag, and in the form that edits a paid + # invoice the user unchecks its check box, no +paid+ parameter is sent. So, + # any mass-assignment idiom like + # + # @invoice.update(params[:invoice]) + # + # wouldn't update the flag. + # + # To prevent this the helper generates an auxiliary hidden field before + # the very check box. The hidden field has the same name and its + # attributes mimic an unchecked check box. + # + # This way, the client either sends only the hidden field (representing + # the check box is unchecked), or both fields. Since the HTML specification + # says key/value pairs have to be sent in the same order they appear in the + # form, and parameters extraction gets the last occurrence of any repeated + # key in the query string, that works for ordinary forms. + # + # Unfortunately that workaround does not work when the check box goes + # within an array-like parameter, as in + # + # <%= fields_for "project[invoice_attributes][]", invoice, index: nil do |form| %> + # <%= form.check_box :paid %> + # ... + # <% end %> + # + # because parameter name repetition is precisely what Rails seeks to distinguish + # the elements of the array. For each item with a checked check box you + # get an extra ghost item with only that attribute, assigned to "0". + # + # In that case it is preferable to either use +check_box_tag+ or to use + # hashes instead of arrays. + # + # # Let's say that @post.validated? is 1: + # check_box("post", "validated") + # # => + # # + # + # # Let's say that @puppy.gooddog is "no": + # check_box("puppy", "gooddog", {}, "yes", "no") + # # => + # # + # + # check_box("eula", "accepted", { class: 'eula_check' }, "yes", "no") + # # => + # # + def check_box(object_name, method, options = {}, checked_value = "1", unchecked_value = "0") + Tags::CheckBox.new(object_name, method, self, checked_value, unchecked_value, options).render + end + + # Returns a radio button tag for accessing a specified attribute (identified by +method+) on an object + # assigned to the template (identified by +object+). If the current value of +method+ is +tag_value+ the + # radio button will be checked. + # + # To force the radio button to be checked pass checked: true in the + # +options+ hash. You may pass HTML options there as well. + # + # # Let's say that @post.category returns "rails": + # radio_button("post", "category", "rails") + # radio_button("post", "category", "java") + # # => + # # + # + # radio_button("user", "receive_newsletter", "yes") + # radio_button("user", "receive_newsletter", "no") + # # => + # # + def radio_button(object_name, method, tag_value, options = {}) + Tags::RadioButton.new(object_name, method, self, tag_value, options).render + end + + # Returns a text_field of type "color". + # + # color_field("car", "color") + # # => + def color_field(object_name, method, options = {}) + Tags::ColorField.new(object_name, method, self, options).render + end + + # Returns an input of type "search" for accessing a specified attribute (identified by +method+) on an object + # assigned to the template (identified by +object_name+). Inputs of type "search" may be styled differently by + # some browsers. + # + # search_field(:user, :name) + # # => + # search_field(:user, :name, autosave: false) + # # => + # search_field(:user, :name, results: 3) + # # => + # # Assume request.host returns "www.example.com" + # search_field(:user, :name, autosave: true) + # # => + # search_field(:user, :name, onsearch: true) + # # => + # search_field(:user, :name, autosave: false, onsearch: true) + # # => + # search_field(:user, :name, autosave: true, onsearch: true) + # # => + def search_field(object_name, method, options = {}) + Tags::SearchField.new(object_name, method, self, options).render + end + + # Returns a text_field of type "tel". + # + # telephone_field("user", "phone") + # # => + # + def telephone_field(object_name, method, options = {}) + Tags::TelField.new(object_name, method, self, options).render + end + # aliases telephone_field + alias phone_field telephone_field + + # Returns a text_field of type "date". + # + # date_field("user", "born_on") + # # => + # + # The default value is generated by trying to call "to_date" + # on the object's value, which makes it behave as expected for instances + # of DateTime and ActiveSupport::TimeWithZone. You can still override that + # by passing the "value" option explicitly, e.g. + # + # @user.born_on = Date.new(1984, 1, 27) + # date_field("user", "born_on", value: "1984-05-12") + # # => + # + # You can create values for the "min" and "max" attributes by passing + # instances of Date or Time to the options hash. + # + # date_field("user", "born_on", min: Date.today) + # # => + # + # Alternatively, you can pass a String formatted as an ISO8601 date as the + # values for "min" and "max." + # + # date_field("user", "born_on", min: "2014-05-20") + # # => + # + def date_field(object_name, method, options = {}) + Tags::DateField.new(object_name, method, self, options).render + end + + # Returns a text_field of type "time". + # + # The default value is generated by trying to call +strftime+ with "%T.%L" + # on the objects's value. It is still possible to override that + # by passing the "value" option. + # + # === Options + # * Accepts same options as time_field_tag + # + # === Example + # time_field("task", "started_at") + # # => + # + # You can create values for the "min" and "max" attributes by passing + # instances of Date or Time to the options hash. + # + # time_field("task", "started_at", min: Time.now) + # # => + # + # Alternatively, you can pass a String formatted as an ISO8601 time as the + # values for "min" and "max." + # + # time_field("task", "started_at", min: "01:00:00") + # # => + # + def time_field(object_name, method, options = {}) + Tags::TimeField.new(object_name, method, self, options).render + end + + # Returns a text_field of type "datetime". + # + # datetime_field("user", "born_on") + # # => + # + # The default value is generated by trying to call +strftime+ with "%Y-%m-%dT%T.%L%z" + # on the object's value, which makes it behave as expected for instances + # of DateTime and ActiveSupport::TimeWithZone. + # + # @user.born_on = Date.new(1984, 1, 12) + # datetime_field("user", "born_on") + # # => + # + # You can create values for the "min" and "max" attributes by passing + # instances of Date or Time to the options hash. + # + # datetime_field("user", "born_on", min: Date.today) + # # => + # + # Alternatively, you can pass a String formatted as an ISO8601 datetime + # with UTC offset as the values for "min" and "max." + # + # datetime_field("user", "born_on", min: "2014-05-20T00:00:00+0000") + # # => + # + def datetime_field(object_name, method, options = {}) + Tags::DatetimeField.new(object_name, method, self, options).render + end + + # Returns a text_field of type "datetime-local". + # + # datetime_local_field("user", "born_on") + # # => + # + # The default value is generated by trying to call +strftime+ with "%Y-%m-%dT%T" + # on the object's value, which makes it behave as expected for instances + # of DateTime and ActiveSupport::TimeWithZone. + # + # @user.born_on = Date.new(1984, 1, 12) + # datetime_local_field("user", "born_on") + # # => + # + # You can create values for the "min" and "max" attributes by passing + # instances of Date or Time to the options hash. + # + # datetime_local_field("user", "born_on", min: Date.today) + # # => + # + # Alternatively, you can pass a String formatted as an ISO8601 datetime as + # the values for "min" and "max." + # + # datetime_local_field("user", "born_on", min: "2014-05-20T00:00:00") + # # => + # + def datetime_local_field(object_name, method, options = {}) + Tags::DatetimeLocalField.new(object_name, method, self, options).render + end + + # Returns a text_field of type "month". + # + # month_field("user", "born_on") + # # => + # + # The default value is generated by trying to call +strftime+ with "%Y-%m" + # on the object's value, which makes it behave as expected for instances + # of DateTime and ActiveSupport::TimeWithZone. + # + # @user.born_on = Date.new(1984, 1, 27) + # month_field("user", "born_on") + # # => + # + def month_field(object_name, method, options = {}) + Tags::MonthField.new(object_name, method, self, options).render + end + + # Returns a text_field of type "week". + # + # week_field("user", "born_on") + # # => + # + # The default value is generated by trying to call +strftime+ with "%Y-W%W" + # on the object's value, which makes it behave as expected for instances + # of DateTime and ActiveSupport::TimeWithZone. + # + # @user.born_on = Date.new(1984, 5, 12) + # week_field("user", "born_on") + # # => + # + def week_field(object_name, method, options = {}) + Tags::WeekField.new(object_name, method, self, options).render + end + + # Returns a text_field of type "url". + # + # url_field("user", "homepage") + # # => + # + def url_field(object_name, method, options = {}) + Tags::UrlField.new(object_name, method, self, options).render + end + + # Returns a text_field of type "email". + # + # email_field("user", "address") + # # => + # + def email_field(object_name, method, options = {}) + Tags::EmailField.new(object_name, method, self, options).render + end + + # Returns an input tag of type "number". + # + # ==== Options + # * Accepts same options as number_field_tag + def number_field(object_name, method, options = {}) + Tags::NumberField.new(object_name, method, self, options).render + end + + # Returns an input tag of type "range". + # + # ==== Options + # * Accepts same options as range_field_tag + def range_field(object_name, method, options = {}) + Tags::RangeField.new(object_name, method, self, options).render + end + + private + + def instantiate_builder(record_name, record_object, options) + case record_name + when String, Symbol + object = record_object + object_name = record_name + else + object = record_name + object_name = model_name_from_record_or_class(object).param_key + end + + builder = options[:builder] || default_form_builder_class + builder.new(object_name, object, self, options) + end + + def default_form_builder_class + builder = ActionView::Base.default_form_builder + builder.respond_to?(:constantize) ? builder.constantize : builder + end + end + + # A +FormBuilder+ object is associated with a particular model object and + # allows you to generate fields associated with the model object. The + # +FormBuilder+ object is yielded when using +form_for+ or +fields_for+. + # For example: + # + # <%= form_for @person do |person_form| %> + # Name: <%= person_form.text_field :name %> + # Admin: <%= person_form.check_box :admin %> + # <% end %> + # + # In the above block, a +FormBuilder+ object is yielded as the + # +person_form+ variable. This allows you to generate the +text_field+ + # and +check_box+ fields by specifying their eponymous methods, which + # modify the underlying template and associates the +@person+ model object + # with the form. + # + # The +FormBuilder+ object can be thought of as serving as a proxy for the + # methods in the +FormHelper+ module. This class, however, allows you to + # call methods with the model object you are building the form for. + # + # You can create your own custom FormBuilder templates by subclassing this + # class. For example: + # + # class MyFormBuilder < ActionView::Helpers::FormBuilder + # def div_radio_button(method, tag_value, options = {}) + # @template.content_tag(:div, + # @template.radio_button( + # @object_name, method, tag_value, objectify_options(options) + # ) + # ) + # end + # end + # + # The above code creates a new method +div_radio_button+ which wraps a div + # around the new radio button. Note that when options are passed in, you + # must call +objectify_options+ in order for the model object to get + # correctly passed to the method. If +objectify_options+ is not called, + # then the newly created helper will not be linked back to the model. + # + # The +div_radio_button+ code from above can now be used as follows: + # + # <%= form_for @person, :builder => MyFormBuilder do |f| %> + # I am a child: <%= f.div_radio_button(:admin, "child") %> + # I am an adult: <%= f.div_radio_button(:admin, "adult") %> + # <% end -%> + # + # The standard set of helper methods for form building are located in the + # +field_helpers+ class attribute. + class FormBuilder + include ModelNaming + + # The methods which wrap a form helper call. + class_attribute :field_helpers + self.field_helpers = [:fields_for, :label, :text_field, :password_field, + :hidden_field, :file_field, :text_area, :check_box, + :radio_button, :color_field, :search_field, + :telephone_field, :phone_field, :date_field, + :time_field, :datetime_field, :datetime_local_field, + :month_field, :week_field, :url_field, :email_field, + :number_field, :range_field] + + attr_accessor :object_name, :object, :options + + attr_reader :multipart, :index + alias :multipart? :multipart + + def multipart=(multipart) + @multipart = multipart + + if parent_builder = @options[:parent_builder] + parent_builder.multipart = multipart + end + end + + def self._to_partial_path + @_to_partial_path ||= name.demodulize.underscore.sub!(/_builder$/, '') + end + + def to_partial_path + self.class._to_partial_path + end + + def to_model + self + end + + def initialize(object_name, object, template, options) + @nested_child_index = {} + @object_name, @object, @template, @options = object_name, object, template, options + @default_options = @options ? @options.slice(:index, :namespace) : {} + if @object_name.to_s.match(/\[\]$/) + if object ||= @template.instance_variable_get("@#{Regexp.last_match.pre_match}") and object.respond_to?(:to_param) + @auto_index = object.to_param + else + raise ArgumentError, "object[] naming but object param and @object var don't exist or don't respond to to_param: #{object.inspect}" + end + end + @multipart = nil + @index = options[:index] || options[:child_index] + end + + (field_helpers - [:label, :check_box, :radio_button, :fields_for, :hidden_field, :file_field]).each do |selector| + class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1 + def #{selector}(method, options = {}) # def text_field(method, options = {}) + @template.send( # @template.send( + #{selector.inspect}, # "text_field", + @object_name, # @object_name, + method, # method, + objectify_options(options)) # objectify_options(options)) + end # end + RUBY_EVAL + end + + # Creates a scope around a specific model object like form_for, but + # doesn't create the form tags themselves. This makes fields_for suitable + # for specifying additional model objects in the same form. + # + # Although the usage and purpose of +fields_for+ is similar to +form_for+'s, + # its method signature is slightly different. Like +form_for+, it yields + # a FormBuilder object associated with a particular model object to a block, + # and within the block allows methods to be called on the builder to + # generate fields associated with the model object. Fields may reflect + # a model object in two ways - how they are named (hence how submitted + # values appear within the +params+ hash in the controller) and what + # default values are shown when the form the fields appear in is first + # displayed. In order for both of these features to be specified independently, + # both an object name (represented by either a symbol or string) and the + # object itself can be passed to the method separately - + # + # <%= form_for @person do |person_form| %> + # First name: <%= person_form.text_field :first_name %> + # Last name : <%= person_form.text_field :last_name %> + # + # <%= fields_for :permission, @person.permission do |permission_fields| %> + # Admin? : <%= permission_fields.check_box :admin %> + # <% end %> + # + # <%= person_form.submit %> + # <% end %> + # + # In this case, the checkbox field will be represented by an HTML +input+ + # tag with the +name+ attribute permission[admin], and the submitted + # value will appear in the controller as params[:permission][:admin]. + # If @person.permission is an existing record with an attribute + # +admin+, the initial state of the checkbox when first displayed will + # reflect the value of @person.permission.admin. + # + # Often this can be simplified by passing just the name of the model + # object to +fields_for+ - + # + # <%= fields_for :permission do |permission_fields| %> + # Admin?: <%= permission_fields.check_box :admin %> + # <% end %> + # + # ...in which case, if :permission also happens to be the name of an + # instance variable @permission, the initial state of the input + # field will reflect the value of that variable's attribute @permission.admin. + # + # Alternatively, you can pass just the model object itself (if the first + # argument isn't a string or symbol +fields_for+ will realize that the + # name has been omitted) - + # + # <%= fields_for @person.permission do |permission_fields| %> + # Admin?: <%= permission_fields.check_box :admin %> + # <% end %> + # + # and +fields_for+ will derive the required name of the field from the + # _class_ of the model object, e.g. if @person.permission, is + # of class +Permission+, the field will still be named permission[admin]. + # + # Note: This also works for the methods in FormOptionHelper and + # DateHelper that are designed to work with an object as base, like + # FormOptionHelper#collection_select and DateHelper#datetime_select. + # + # === Nested Attributes Examples + # + # When the object belonging to the current scope has a nested attribute + # writer for a certain attribute, fields_for will yield a new scope + # for that attribute. This allows you to create forms that set or change + # the attributes of a parent object and its associations in one go. + # + # Nested attribute writers are normal setter methods named after an + # association. The most common way of defining these writers is either + # with +accepts_nested_attributes_for+ in a model definition or by + # defining a method with the proper name. For example: the attribute + # writer for the association :address is called + # address_attributes=. + # + # Whether a one-to-one or one-to-many style form builder will be yielded + # depends on whether the normal reader method returns a _single_ object + # or an _array_ of objects. + # + # ==== One-to-one + # + # Consider a Person class which returns a _single_ Address from the + # address reader method and responds to the + # address_attributes= writer method: + # + # class Person + # def address + # @address + # end + # + # def address_attributes=(attributes) + # # Process the attributes hash + # end + # end + # + # This model can now be used with a nested fields_for, like so: + # + # <%= form_for @person do |person_form| %> + # ... + # <%= person_form.fields_for :address do |address_fields| %> + # Street : <%= address_fields.text_field :street %> + # Zip code: <%= address_fields.text_field :zip_code %> + # <% end %> + # ... + # <% end %> + # + # When address is already an association on a Person you can use + # +accepts_nested_attributes_for+ to define the writer method for you: + # + # class Person < ActiveRecord::Base + # has_one :address + # accepts_nested_attributes_for :address + # end + # + # If you want to destroy the associated model through the form, you have + # to enable it first using the :allow_destroy option for + # +accepts_nested_attributes_for+: + # + # class Person < ActiveRecord::Base + # has_one :address + # accepts_nested_attributes_for :address, allow_destroy: true + # end + # + # Now, when you use a form element with the _destroy parameter, + # with a value that evaluates to +true+, you will destroy the associated + # model (eg. 1, '1', true, or 'true'): + # + # <%= form_for @person do |person_form| %> + # ... + # <%= person_form.fields_for :address do |address_fields| %> + # ... + # Delete: <%= address_fields.check_box :_destroy %> + # <% end %> + # ... + # <% end %> + # + # ==== One-to-many + # + # Consider a Person class which returns an _array_ of Project instances + # from the projects reader method and responds to the + # projects_attributes= writer method: + # + # class Person + # def projects + # [@project1, @project2] + # end + # + # def projects_attributes=(attributes) + # # Process the attributes hash + # end + # end + # + # Note that the projects_attributes= writer method is in fact + # required for fields_for to correctly identify :projects as a + # collection, and the correct indices to be set in the form markup. + # + # When projects is already an association on Person you can use + # +accepts_nested_attributes_for+ to define the writer method for you: + # + # class Person < ActiveRecord::Base + # has_many :projects + # accepts_nested_attributes_for :projects + # end + # + # This model can now be used with a nested fields_for. The block given to + # the nested fields_for call will be repeated for each instance in the + # collection: + # + # <%= form_for @person do |person_form| %> + # ... + # <%= person_form.fields_for :projects do |project_fields| %> + # <% if project_fields.object.active? %> + # Name: <%= project_fields.text_field :name %> + # <% end %> + # <% end %> + # ... + # <% end %> + # + # It's also possible to specify the instance to be used: + # + # <%= form_for @person do |person_form| %> + # ... + # <% @person.projects.each do |project| %> + # <% if project.active? %> + # <%= person_form.fields_for :projects, project do |project_fields| %> + # Name: <%= project_fields.text_field :name %> + # <% end %> + # <% end %> + # <% end %> + # ... + # <% end %> + # + # Or a collection to be used: + # + # <%= form_for @person do |person_form| %> + # ... + # <%= person_form.fields_for :projects, @active_projects do |project_fields| %> + # Name: <%= project_fields.text_field :name %> + # <% end %> + # ... + # <% end %> + # + # If you want to destroy any of the associated models through the + # form, you have to enable it first using the :allow_destroy + # option for +accepts_nested_attributes_for+: + # + # class Person < ActiveRecord::Base + # has_many :projects + # accepts_nested_attributes_for :projects, allow_destroy: true + # end + # + # This will allow you to specify which models to destroy in the + # attributes hash by adding a form element for the _destroy + # parameter with a value that evaluates to +true+ + # (eg. 1, '1', true, or 'true'): + # + # <%= form_for @person do |person_form| %> + # ... + # <%= person_form.fields_for :projects do |project_fields| %> + # Delete: <%= project_fields.check_box :_destroy %> + # <% end %> + # ... + # <% end %> + # + # When a collection is used you might want to know the index of each + # object into the array. For this purpose, the index method + # is available in the FormBuilder object. + # + # <%= form_for @person do |person_form| %> + # ... + # <%= person_form.fields_for :projects do |project_fields| %> + # Project #<%= project_fields.index %> + # ... + # <% end %> + # ... + # <% end %> + # + # Note that fields_for will automatically generate a hidden field + # to store the ID of the record. There are circumstances where this + # hidden field is not needed and you can pass include_id: false + # to prevent fields_for from rendering it automatically. + def fields_for(record_name, record_object = nil, fields_options = {}, &block) + fields_options, record_object = record_object, nil if record_object.is_a?(Hash) && record_object.extractable_options? + fields_options[:builder] ||= options[:builder] + fields_options[:namespace] = options[:namespace] + fields_options[:parent_builder] = self + + case record_name + when String, Symbol + if nested_attributes_association?(record_name) + return fields_for_with_nested_attributes(record_name, record_object, fields_options, block) + end + else + record_object = record_name.is_a?(Array) ? record_name.last : record_name + record_name = model_name_from_record_or_class(record_object).param_key + end + + index = if options.has_key?(:index) + options[:index] + elsif defined?(@auto_index) + self.object_name = @object_name.to_s.sub(/\[\]$/,"") + @auto_index + end + + record_name = index ? "#{object_name}[#{index}][#{record_name}]" : "#{object_name}[#{record_name}]" + fields_options[:child_index] = index + + @template.fields_for(record_name, record_object, fields_options, &block) + end + + # Returns a label tag tailored for labelling an input field for a specified attribute (identified by +method+) on an object + # assigned to the template (identified by +object+). The text of label will default to the attribute name unless a translation + # is found in the current I18n locale (through helpers.label..) or you specify it explicitly. + # Additional options on the label tag can be passed as a hash with +options+. These options will be tagged + # onto the HTML as an HTML element attribute as in the example shown, except for the :value option, which is designed to + # target labels for radio_button tags (where the value is used in the ID of the input tag). + # + # ==== Examples + # label(:post, :title) + # # => + # + # You can localize your labels based on model and attribute names. + # For example you can define the following in your locale (e.g. en.yml) + # + # helpers: + # label: + # post: + # body: "Write your entire text here" + # + # Which then will result in + # + # label(:post, :body) + # # => + # + # Localization can also be based purely on the translation of the attribute-name + # (if you are using ActiveRecord): + # + # activerecord: + # attributes: + # post: + # cost: "Total cost" + # + # label(:post, :cost) + # # => + # + # label(:post, :title, "A short title") + # # => + # + # label(:post, :title, "A short title", class: "title_label") + # # => + # + # label(:post, :privacy, "Public Post", value: "public") + # # => + # + # label(:post, :terms) do + # 'Accept Terms.'.html_safe + # end + def label(method, text = nil, options = {}, &block) + @template.label(@object_name, method, text, objectify_options(options), &block) + end + + # Returns a checkbox tag tailored for accessing a specified attribute (identified by +method+) on an object + # assigned to the template (identified by +object+). This object must be an instance object (@object) and not a local object. + # It's intended that +method+ returns an integer and if that integer is above zero, then the checkbox is checked. + # Additional options on the input tag can be passed as a hash with +options+. The +checked_value+ defaults to 1 + # while the default +unchecked_value+ is set to 0 which is convenient for boolean values. + # + # ==== Gotcha + # + # The HTML specification says unchecked check boxes are not successful, and + # thus web browsers do not send them. Unfortunately this introduces a gotcha: + # if an +Invoice+ model has a +paid+ flag, and in the form that edits a paid + # invoice the user unchecks its check box, no +paid+ parameter is sent. So, + # any mass-assignment idiom like + # + # @invoice.update(params[:invoice]) + # + # wouldn't update the flag. + # + # To prevent this the helper generates an auxiliary hidden field before + # the very check box. The hidden field has the same name and its + # attributes mimic an unchecked check box. + # + # This way, the client either sends only the hidden field (representing + # the check box is unchecked), or both fields. Since the HTML specification + # says key/value pairs have to be sent in the same order they appear in the + # form, and parameters extraction gets the last occurrence of any repeated + # key in the query string, that works for ordinary forms. + # + # Unfortunately that workaround does not work when the check box goes + # within an array-like parameter, as in + # + # <%= fields_for "project[invoice_attributes][]", invoice, index: nil do |form| %> + # <%= form.check_box :paid %> + # ... + # <% end %> + # + # because parameter name repetition is precisely what Rails seeks to distinguish + # the elements of the array. For each item with a checked check box you + # get an extra ghost item with only that attribute, assigned to "0". + # + # In that case it is preferable to either use +check_box_tag+ or to use + # hashes instead of arrays. + # + # # Let's say that @post.validated? is 1: + # check_box("post", "validated") + # # => + # # + # + # # Let's say that @puppy.gooddog is "no": + # check_box("puppy", "gooddog", {}, "yes", "no") + # # => + # # + # + # check_box("eula", "accepted", { class: 'eula_check' }, "yes", "no") + # # => + # # + def check_box(method, options = {}, checked_value = "1", unchecked_value = "0") + @template.check_box(@object_name, method, objectify_options(options), checked_value, unchecked_value) + end + + # Returns a radio button tag for accessing a specified attribute (identified by +method+) on an object + # assigned to the template (identified by +object+). If the current value of +method+ is +tag_value+ the + # radio button will be checked. + # + # To force the radio button to be checked pass checked: true in the + # +options+ hash. You may pass HTML options there as well. + # + # # Let's say that @post.category returns "rails": + # radio_button("post", "category", "rails") + # radio_button("post", "category", "java") + # # => + # # + # + # radio_button("user", "receive_newsletter", "yes") + # radio_button("user", "receive_newsletter", "no") + # # => + # # + def radio_button(method, tag_value, options = {}) + @template.radio_button(@object_name, method, tag_value, objectify_options(options)) + end + + # Returns a hidden input tag tailored for accessing a specified attribute (identified by +method+) on an object + # assigned to the template (identified by +object+). Additional options on the input tag can be passed as a + # hash with +options+. These options will be tagged onto the HTML as an HTML element attribute as in the example + # shown. + # + # ==== Examples + # hidden_field(:signup, :pass_confirm) + # # => + # + # hidden_field(:post, :tag_list) + # # => + # + # hidden_field(:user, :token) + # # => + # + def hidden_field(method, options = {}) + @emitted_hidden_id = true if method == :id + @template.hidden_field(@object_name, method, objectify_options(options)) + end + + # Returns a file upload input tag tailored for accessing a specified attribute (identified by +method+) on an object + # assigned to the template (identified by +object+). Additional options on the input tag can be passed as a + # hash with +options+. These options will be tagged onto the HTML as an HTML element attribute as in the example + # shown. + # + # Using this method inside a +form_for+ block will set the enclosing form's encoding to multipart/form-data. + # + # ==== Options + # * Creates standard HTML attributes for the tag. + # * :disabled - If set to true, the user will not be able to use this input. + # * :multiple - If set to true, *in most updated browsers* the user will be allowed to select multiple files. + # * :accept - If set to one or multiple mime-types, the user will be suggested a filter when choosing a file. You still need to set up model validations. + # + # ==== Examples + # file_field(:user, :avatar) + # # => + # + # file_field(:post, :image, :multiple => true) + # # => + # + # file_field(:post, :attached, accept: 'text/html') + # # => + # + # file_field(:post, :image, accept: 'image/png,image/gif,image/jpeg') + # # => + # + # file_field(:attachment, :file, class: 'file_input') + # # => + def file_field(method, options = {}) + self.multipart = true + @template.file_field(@object_name, method, objectify_options(options)) + end + + # Add the submit button for the given form. When no value is given, it checks + # if the object is a new resource or not to create the proper label: + # + # <%= form_for @post do |f| %> + # <%= f.submit %> + # <% end %> + # + # In the example above, if @post is a new record, it will use "Create Post" as + # submit button label, otherwise, it uses "Update Post". + # + # Those labels can be customized using I18n, under the helpers.submit key and accept + # the %{model} as translation interpolation: + # + # en: + # helpers: + # submit: + # create: "Create a %{model}" + # update: "Confirm changes to %{model}" + # + # It also searches for a key specific for the given object: + # + # en: + # helpers: + # submit: + # post: + # create: "Add %{model}" + # + def submit(value=nil, options={}) + value, options = nil, value if value.is_a?(Hash) + value ||= submit_default_value + @template.submit_tag(value, options) + end + + # Add the submit button for the given form. When no value is given, it checks + # if the object is a new resource or not to create the proper label: + # + # <%= form_for @post do |f| %> + # <%= f.button %> + # <% end %> + # + # In the example above, if @post is a new record, it will use "Create Post" as + # button label, otherwise, it uses "Update Post". + # + # Those labels can be customized using I18n, under the helpers.submit key + # (the same as submit helper) and accept the %{model} as translation interpolation: + # + # en: + # helpers: + # submit: + # create: "Create a %{model}" + # update: "Confirm changes to %{model}" + # + # It also searches for a key specific for the given object: + # + # en: + # helpers: + # submit: + # post: + # create: "Add %{model}" + # + # ==== Examples + # button("Create a post") + # # => + # + # button do + # content_tag(:strong, 'Ask me!') + # end + # # => + # + def button(value = nil, options = {}, &block) + value, options = nil, value if value.is_a?(Hash) + value ||= submit_default_value + @template.button_tag(value, options, &block) + end + + def emitted_hidden_id? + @emitted_hidden_id ||= nil + end + + private + def objectify_options(options) + @default_options.merge(options.merge(object: @object)) + end + + def submit_default_value + object = convert_to_model(@object) + key = object ? (object.persisted? ? :update : :create) : :submit + + model = if object.respond_to?(:model_name) + object.model_name.human + else + @object_name.to_s.humanize + end + + defaults = [] + defaults << :"helpers.submit.#{object_name}.#{key}" + defaults << :"helpers.submit.#{key}" + defaults << "#{key.to_s.humanize} #{model}" + + I18n.t(defaults.shift, model: model, default: defaults) + end + + def nested_attributes_association?(association_name) + @object.respond_to?("#{association_name}_attributes=") + end + + def fields_for_with_nested_attributes(association_name, association, options, block) + name = "#{object_name}[#{association_name}_attributes]" + association = convert_to_model(association) + + if association.respond_to?(:persisted?) + association = [association] if @object.send(association_name).respond_to?(:to_ary) + elsif !association.respond_to?(:to_ary) + association = @object.send(association_name) + end + + if association.respond_to?(:to_ary) + explicit_child_index = options[:child_index] + output = ActiveSupport::SafeBuffer.new + association.each do |child| + options[:child_index] = nested_child_index(name) unless explicit_child_index + output << fields_for_nested_model("#{name}[#{options[:child_index]}]", child, options, block) + end + output + elsif association + fields_for_nested_model(name, association, options, block) + end + end + + def fields_for_nested_model(name, object, fields_options, block) + object = convert_to_model(object) + emit_hidden_id = object.persisted? && fields_options.fetch(:include_id) { + options.fetch(:include_id, true) + } + + @template.fields_for(name, object, fields_options) do |f| + output = @template.capture(f, &block) + output.concat f.hidden_field(:id) if output && emit_hidden_id && !f.emitted_hidden_id? + output + end + end + + def nested_child_index(name) + @nested_child_index[name] ||= -1 + @nested_child_index[name] += 1 + end + end + end + + ActiveSupport.on_load(:action_view) do + cattr_accessor(:default_form_builder, instance_writer: false, instance_reader: false) do + ::ActionView::Helpers::FormBuilder + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/form_options_helper.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/form_options_helper.rb new file mode 100644 index 0000000..98d4ae7 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/form_options_helper.rb @@ -0,0 +1,841 @@ +require 'cgi' +require 'erb' +require 'action_view/helpers/form_helper' +require 'active_support/core_ext/string/output_safety' +require 'active_support/core_ext/array/extract_options' +require 'active_support/core_ext/array/wrap' + +module ActionView + # = Action View Form Option Helpers + module Helpers + # Provides a number of methods for turning different kinds of containers into a set of option tags. + # + # The collection_select, select and time_zone_select methods take an options parameter, a hash: + # + # * :include_blank - set to true or a prompt string if the first option element of the select element is a blank. Useful if there is not a default value required for the select element. + # + # select("post", "category", Post::CATEGORIES, {include_blank: true}) + # + # could become: + # + # + # + # Another common case is a select tag for a belongs_to-associated object. + # + # Example with @post.person_id => 2: + # + # select("post", "person_id", Person.all.collect {|p| [ p.name, p.id ] }, {include_blank: 'None'}) + # + # could become: + # + # + # + # * :prompt - set to true or a prompt string. When the select element doesn't have a value yet, this prepends an option with a generic prompt -- "Please select" -- or the given prompt string. + # + # select("post", "person_id", Person.all.collect {|p| [ p.name, p.id ] }, {prompt: 'Select Person'}) + # + # could become: + # + # + # + # * :index - like the other form helpers, +select+ can accept an :index option to manually set the ID used in the resulting output. Unlike other helpers, +select+ expects this + # option to be in the +html_options+ parameter. + # + # select("album[]", "genre", %w[rap rock country], {}, { index: nil }) + # + # becomes: + # + # + # + # * :disabled - can be a single value or an array of values that will be disabled options in the final output. + # + # select("post", "category", Post::CATEGORIES, {disabled: 'restricted'}) + # + # could become: + # + # + # + # When used with the collection_select helper, :disabled can also be a Proc that identifies those options that should be disabled. + # + # collection_select(:post, :category_id, Category.all, :id, :name, {disabled: lambda{|category| category.archived? }}) + # + # If the categories "2008 stuff" and "Christmas" return true when the method archived? is called, this would return: + # + # + module FormOptionsHelper + # ERB::Util can mask some helpers like textilize. Make sure to include them. + include TextHelper + + # Create a select tag and a series of contained option tags for the provided object and method. + # The option currently held by the object will be selected, provided that the object is available. + # + # There are two possible formats for the +choices+ parameter, corresponding to other helpers' output: + # + # * A flat collection (see +options_for_select+). + # + # * A nested collection (see +grouped_options_for_select+). + # + # For example: + # + # select("post", "person_id", Person.all.collect {|p| [ p.name, p.id ] }, { include_blank: true }) + # + # would become: + # + # + # + # assuming the associated person has ID 1. + # + # This can be used to provide a default set of options in the standard way: before rendering the create form, a + # new model instance is assigned the default options and bound to @model_name. Usually this model is not saved + # to the database. Instead, a second model object is created when the create request is received. + # This allows the user to submit a form page more than once with the expected results of creating multiple records. + # In addition, this allows a single partial to be used to generate form inputs for both edit and create forms. + # + # By default, post.person_id is the selected option. Specify selected: value to use a different selection + # or selected: nil to leave all options unselected. Similarly, you can specify values to be disabled in the option + # tags by specifying the :disabled option. This can either be a single value or an array of values to be disabled. + # + # A block can be passed to +select+ to customize how the options tags will be rendered. This + # is useful when the options tag has complex attributes. + # + # select(report, "campaign_ids") do + # available_campaigns.each do |c| + # content_tag(:option, c.name, value: c.id, data: { tags: c.tags.to_json }) + # end + # end + # + # ==== Gotcha + # + # The HTML specification says when +multiple+ parameter passed to select and all options got deselected + # web browsers do not send any value to server. Unfortunately this introduces a gotcha: + # if an +User+ model has many +roles+ and have +role_ids+ accessor, and in the form that edits roles of the user + # the user deselects all roles from +role_ids+ multiple select box, no +role_ids+ parameter is sent. So, + # any mass-assignment idiom like + # + # @user.update(params[:user]) + # + # wouldn't update roles. + # + # To prevent this the helper generates an auxiliary hidden field before + # every multiple select. The hidden field has the same name as multiple select and blank value. + # + # Note: The client either sends only the hidden field (representing + # the deselected multiple select box), or both fields. This means that the resulting array + # always contains a blank string. + # + # In case if you don't want the helper to generate this hidden field you can specify + # include_hidden: false option. + # + def select(object, method, choices = nil, options = {}, html_options = {}, &block) + Tags::Select.new(object, method, self, choices, options, html_options, &block).render + end + + # Returns + # + # + # + # + # + def collection_select(object, method, collection, value_method, text_method, options = {}, html_options = {}) + Tags::CollectionSelect.new(object, method, self, collection, value_method, text_method, options, html_options).render + end + + # Returns + # + # + # + # + # + # + # + # + # + # + def grouped_collection_select(object, method, collection, group_method, group_label_method, option_key_method, option_value_method, options = {}, html_options = {}) + Tags::GroupedCollectionSelect.new(object, method, self, collection, group_method, group_label_method, option_key_method, option_value_method, options, html_options).render + end + + # Returns select and option tags for the given object and method, using + # #time_zone_options_for_select to generate the list of option tags. + # + # In addition to the :include_blank option documented above, + # this method also supports a :model option, which defaults + # to ActiveSupport::TimeZone. This may be used by users to specify a + # different time zone model object. (See +time_zone_options_for_select+ + # for more information.) + # + # You can also supply an array of ActiveSupport::TimeZone objects + # as +priority_zones+, so that they will be listed above the rest of the + # (long) list. (You can use ActiveSupport::TimeZone.us_zones as a convenience + # for obtaining a list of the US time zones, or a Regexp to select the zones + # of your choice) + # + # Finally, this method supports a :default option, which selects + # a default ActiveSupport::TimeZone if the object's time zone is +nil+. + # + # time_zone_select( "user", "time_zone", nil, include_blank: true) + # + # time_zone_select( "user", "time_zone", nil, default: "Pacific Time (US & Canada)" ) + # + # time_zone_select( "user", 'time_zone', ActiveSupport::TimeZone.us_zones, default: "Pacific Time (US & Canada)") + # + # time_zone_select( "user", 'time_zone', [ ActiveSupport::TimeZone['Alaska'], ActiveSupport::TimeZone['Hawaii'] ]) + # + # time_zone_select( "user", 'time_zone', /Australia/) + # + # time_zone_select( "user", "time_zone", ActiveSupport::TimeZone.all.sort, model: ActiveSupport::TimeZone) + def time_zone_select(object, method, priority_zones = nil, options = {}, html_options = {}) + Tags::TimeZoneSelect.new(object, method, self, priority_zones, options, html_options).render + end + + # Accepts a container (hash, array, enumerable, your type) and returns a string of option tags. Given a container + # where the elements respond to first and last (such as a two-element array), the "lasts" serve as option values and + # the "firsts" as option text. Hashes are turned into this form automatically, so the keys become "firsts" and values + # become lasts. If +selected+ is specified, the matching "last" or element will get the selected option-tag. +selected+ + # may also be an array of values to be selected when using a multiple select. + # + # options_for_select([["Dollar", "$"], ["Kroner", "DKK"]]) + # # => + # # => + # + # options_for_select([ "VISA", "MasterCard" ], "MasterCard") + # # => + # # => + # + # options_for_select({ "Basic" => "$20", "Plus" => "$40" }, "$40") + # # => + # # => + # + # options_for_select([ "VISA", "MasterCard", "Discover" ], ["VISA", "Discover"]) + # # => + # # => + # # => + # + # You can optionally provide HTML attributes as the last element of the array. + # + # options_for_select([ "Denmark", ["USA", {class: 'bold'}], "Sweden" ], ["USA", "Sweden"]) + # # => + # # => + # # => + # + # options_for_select([["Dollar", "$", {class: "bold"}], ["Kroner", "DKK", {onclick: "alert('HI');"}]]) + # # => + # # => + # + # If you wish to specify disabled option tags, set +selected+ to be a hash, with :disabled being either a value + # or array of values to be disabled. In this case, you can use :selected to specify selected option tags. + # + # options_for_select(["Free", "Basic", "Advanced", "Super Platinum"], disabled: "Super Platinum") + # # => + # # => + # # => + # # => + # + # options_for_select(["Free", "Basic", "Advanced", "Super Platinum"], disabled: ["Advanced", "Super Platinum"]) + # # => + # # => + # # => + # # => + # + # options_for_select(["Free", "Basic", "Advanced", "Super Platinum"], selected: "Free", disabled: "Super Platinum") + # # => + # # => + # # => + # # => + # + # NOTE: Only the option tags are returned, you have to wrap this call in a regular HTML select tag. + def options_for_select(container, selected = nil) + return container if String === container + + selected, disabled = extract_selected_and_disabled(selected).map do |r| + Array(r).map { |item| item.to_s } + end + + container.map do |element| + html_attributes = option_html_attributes(element) + text, value = option_text_and_value(element).map { |item| item.to_s } + + html_attributes[:selected] ||= option_value_selected?(value, selected) + html_attributes[:disabled] ||= disabled && option_value_selected?(value, disabled) + html_attributes[:value] = value + + content_tag_string(:option, text, html_attributes) + end.join("\n").html_safe + end + + # Returns a string of option tags that have been compiled by iterating over the +collection+ and assigning + # the result of a call to the +value_method+ as the option value and the +text_method+ as the option text. + # + # options_from_collection_for_select(@people, 'id', 'name') + # # => + # + # This is more often than not used inside a #select_tag like this example: + # + # select_tag 'person', options_from_collection_for_select(@people, 'id', 'name') + # + # If +selected+ is specified as a value or array of values, the element(s) returning a match on +value_method+ + # will be selected option tag(s). + # + # If +selected+ is specified as a Proc, those members of the collection that return true for the anonymous + # function are the selected values. + # + # +selected+ can also be a hash, specifying both :selected and/or :disabled values as required. + # + # Be sure to specify the same class as the +value_method+ when specifying selected or disabled options. + # Failure to do this will produce undesired results. Example: + # options_from_collection_for_select(@people, 'id', 'name', '1') + # Will not select a person with the id of 1 because 1 (an Integer) is not the same as '1' (a string) + # options_from_collection_for_select(@people, 'id', 'name', 1) + # should produce the desired results. + def options_from_collection_for_select(collection, value_method, text_method, selected = nil) + options = collection.map do |element| + [value_for_collection(element, text_method), value_for_collection(element, value_method), option_html_attributes(element)] + end + selected, disabled = extract_selected_and_disabled(selected) + select_deselect = { + selected: extract_values_from_collection(collection, value_method, selected), + disabled: extract_values_from_collection(collection, value_method, disabled) + } + + options_for_select(options, select_deselect) + end + + # Returns a string of tags, like options_from_collection_for_select, but + # groups them by tags based on the object relationships of the arguments. + # + # Parameters: + # * +collection+ - An array of objects representing the tags. + # * +group_method+ - The name of a method which, when called on a member of +collection+, returns an + # array of child objects representing the tags. + # * +group_label_method+ - The name of a method which, when called on a member of +collection+, returns a + # string to be used as the +label+ attribute for its tag. + # * +option_key_method+ - The name of a method which, when called on a child object of a member of + # +collection+, returns a value to be used as the +value+ attribute for its tag. + # * +option_value_method+ - The name of a method which, when called on a child object of a member of + # +collection+, returns a value to be used as the contents of its tag. + # * +selected_key+ - A value equal to the +value+ attribute for one of the tags, + # which will have the +selected+ attribute set. Corresponds to the return value of one of the calls + # to +option_key_method+. If +nil+, no selection is made. Can also be a hash if disabled values are + # to be specified. + # + # Example object structure for use with this method: + # + # class Continent < ActiveRecord::Base + # has_many :countries + # # attribs: id, name + # end + # + # class Country < ActiveRecord::Base + # belongs_to :continent + # # attribs: id, name, continent_id + # end + # + # Sample usage: + # option_groups_from_collection_for_select(@continents, :countries, :name, :id, :name, 3) + # + # Possible output: + # + # + # + # ... + # + # + # + # + # + # ... + # + # + # Note: Only the and tags are returned, so you still have to + # wrap the output in an appropriate tag. + def grouped_options_for_select(grouped_options, selected_key = nil, options = {}) + prompt = options[:prompt] + divider = options[:divider] + + body = "".html_safe + + if prompt + body.safe_concat content_tag(:option, prompt_text(prompt), value: "") + end + + grouped_options.each do |container| + html_attributes = option_html_attributes(container) + + if divider + label = divider + else + label, container = container + end + + html_attributes = { label: label }.merge!(html_attributes) + body.safe_concat content_tag(:optgroup, options_for_select(container, selected_key), html_attributes) + end + + body + end + + # Returns a string of option tags for pretty much any time zone in the + # world. Supply a ActiveSupport::TimeZone name as +selected+ to have it + # marked as the selected option tag. You can also supply an array of + # ActiveSupport::TimeZone objects as +priority_zones+, so that they will + # be listed above the rest of the (long) list. (You can use + # ActiveSupport::TimeZone.us_zones as a convenience for obtaining a list + # of the US time zones, or a Regexp to select the zones of your choice) + # + # The +selected+ parameter must be either +nil+, or a string that names + # a ActiveSupport::TimeZone. + # + # By default, +model+ is the ActiveSupport::TimeZone constant (which can + # be obtained in Active Record as a value object). The only requirement + # is that the +model+ parameter be an object that responds to +all+, and + # returns an array of objects that represent time zones. + # + # NOTE: Only the option tags are returned, you have to wrap this call in + # a regular HTML select tag. + def time_zone_options_for_select(selected = nil, priority_zones = nil, model = ::ActiveSupport::TimeZone) + zone_options = "".html_safe + + zones = model.all + convert_zones = lambda { |list| list.map { |z| [ z.to_s, z.name ] } } + + if priority_zones + if priority_zones.is_a?(Regexp) + priority_zones = zones.select { |z| z =~ priority_zones } + end + + zone_options.safe_concat options_for_select(convert_zones[priority_zones], selected) + zone_options.safe_concat content_tag(:option, '-------------', value: '', disabled: true) + zone_options.safe_concat "\n" + + zones = zones - priority_zones + end + + zone_options.safe_concat options_for_select(convert_zones[zones], selected) + end + + # Returns radio button tags for the collection of existing return values + # of +method+ for +object+'s class. The value returned from calling + # +method+ on the instance +object+ will be selected. If calling +method+ + # returns +nil+, no selection is made. + # + # The :value_method and :text_method parameters are + # methods to be called on each member of +collection+. The return values + # are used as the +value+ attribute and contents of each radio button tag, + # respectively. They can also be any object that responds to +call+, such + # as a +proc+, that will be called for each member of the +collection+ to + # retrieve the value/text. + # + # Example object structure for use with this method: + # class Post < ActiveRecord::Base + # belongs_to :author + # end + # class Author < ActiveRecord::Base + # has_many :posts + # def name_with_initial + # "#{first_name.first}. #{last_name}" + # end + # end + # + # Sample usage (selecting the associated Author for an instance of Post, @post): + # collection_radio_buttons(:post, :author_id, Author.all, :id, :name_with_initial) + # + # If @post.author_id is already 1, this would return: + # + # + # + # + # + # + # + # It is also possible to customize the way the elements will be shown by + # giving a block to the method: + # collection_radio_buttons(:post, :author_id, Author.all, :id, :name_with_initial) do |b| + # b.label { b.radio_button } + # end + # + # The argument passed to the block is a special kind of builder for this + # collection, which has the ability to generate the label and radio button + # for the current item in the collection, with proper text and value. + # Using it, you can change the label and radio button display order or + # even use the label as wrapper, as in the example above. + # + # The builder methods label and radio_button also accept + # extra HTML options: + # collection_radio_buttons(:post, :author_id, Author.all, :id, :name_with_initial) do |b| + # b.label(class: "radio_button") { b.radio_button(class: "radio_button") } + # end + # + # There are also three special methods available: object, text and + # value, which are the current item being rendered, its text and value methods, + # respectively. You can use them like this: + # collection_radio_buttons(:post, :author_id, Author.all, :id, :name_with_initial) do |b| + # b.label(:"data-value" => b.value) { b.radio_button + b.text } + # end + def collection_radio_buttons(object, method, collection, value_method, text_method, options = {}, html_options = {}, &block) + Tags::CollectionRadioButtons.new(object, method, self, collection, value_method, text_method, options, html_options).render(&block) + end + + # Returns check box tags for the collection of existing return values of + # +method+ for +object+'s class. The value returned from calling +method+ + # on the instance +object+ will be selected. If calling +method+ returns + # +nil+, no selection is made. + # + # The :value_method and :text_method parameters are + # methods to be called on each member of +collection+. The return values + # are used as the +value+ attribute and contents of each check box tag, + # respectively. They can also be any object that responds to +call+, such + # as a +proc+, that will be called for each member of the +collection+ to + # retrieve the value/text. + # + # Example object structure for use with this method: + # class Post < ActiveRecord::Base + # has_and_belongs_to_many :authors + # end + # class Author < ActiveRecord::Base + # has_and_belongs_to_many :posts + # def name_with_initial + # "#{first_name.first}. #{last_name}" + # end + # end + # + # Sample usage (selecting the associated Author for an instance of Post, @post): + # collection_check_boxes(:post, :author_ids, Author.all, :id, :name_with_initial) + # + # If @post.author_ids is already [1], this would return: + # + # + # + # + # + # + # + # + # It is also possible to customize the way the elements will be shown by + # giving a block to the method: + # collection_check_boxes(:post, :author_ids, Author.all, :id, :name_with_initial) do |b| + # b.label { b.check_box } + # end + # + # The argument passed to the block is a special kind of builder for this + # collection, which has the ability to generate the label and check box + # for the current item in the collection, with proper text and value. + # Using it, you can change the label and check box display order or even + # use the label as wrapper, as in the example above. + # + # The builder methods label and check_box also accept + # extra HTML options: + # collection_check_boxes(:post, :author_ids, Author.all, :id, :name_with_initial) do |b| + # b.label(class: "check_box") { b.check_box(class: "check_box") } + # end + # + # There are also three special methods available: object, text and + # value, which are the current item being rendered, its text and value methods, + # respectively. You can use them like this: + # collection_check_boxes(:post, :author_ids, Author.all, :id, :name_with_initial) do |b| + # b.label(:"data-value" => b.value) { b.check_box + b.text } + # end + def collection_check_boxes(object, method, collection, value_method, text_method, options = {}, html_options = {}, &block) + Tags::CollectionCheckBoxes.new(object, method, self, collection, value_method, text_method, options, html_options).render(&block) + end + + private + def option_html_attributes(element) + if Array === element + element.select { |e| Hash === e }.reduce({}, :merge!) + else + {} + end + end + + def option_text_and_value(option) + # Options are [text, value] pairs or strings used for both. + if !option.is_a?(String) && option.respond_to?(:first) && option.respond_to?(:last) + option = option.reject { |e| Hash === e } if Array === option + [option.first, option.last] + else + [option, option] + end + end + + def option_value_selected?(value, selected) + Array(selected).include? value + end + + def extract_selected_and_disabled(selected) + if selected.is_a?(Proc) + [selected, nil] + else + selected = Array.wrap(selected) + options = selected.extract_options!.symbolize_keys + selected_items = options.fetch(:selected, selected) + [selected_items, options[:disabled]] + end + end + + def extract_values_from_collection(collection, value_method, selected) + if selected.is_a?(Proc) + collection.map do |element| + element.send(value_method) if selected.call(element) + end.compact + else + selected + end + end + + def value_for_collection(item, value) + value.respond_to?(:call) ? value.call(item) : item.send(value) + end + + def prompt_text(prompt) + prompt.kind_of?(String) ? prompt : I18n.translate('helpers.select.prompt', default: 'Please select') + end + end + + class FormBuilder + # Wraps ActionView::Helpers::FormOptionsHelper#select for form builders: + # + # <%= form_for @post do |f| %> + # <%= f.select :person_id, Person.all.collect { |p| [ p.name, p.id ] }, include_blank: true %> + # <%= f.submit %> + # <% end %> + # + # Please refer to the documentation of the base helper for details. + def select(method, choices = nil, options = {}, html_options = {}, &block) + @template.select(@object_name, method, choices, objectify_options(options), @default_options.merge(html_options), &block) + end + + # Wraps ActionView::Helpers::FormOptionsHelper#collection_select for form builders: + # + # <%= form_for @post do |f| %> + # <%= f.collection_select :person_id, Author.all, :id, :name_with_initial, prompt: true %> + # <%= f.submit %> + # <% end %> + # + # Please refer to the documentation of the base helper for details. + def collection_select(method, collection, value_method, text_method, options = {}, html_options = {}) + @template.collection_select(@object_name, method, collection, value_method, text_method, objectify_options(options), @default_options.merge(html_options)) + end + + # Wraps ActionView::Helpers::FormOptionsHelper#grouped_collection_select for form builders: + # + # <%= form_for @city do |f| %> + # <%= f.grouped_collection_select :country_id, @continents, :countries, :name, :id, :name %> + # <%= f.submit %> + # <% end %> + # + # Please refer to the documentation of the base helper for details. + def grouped_collection_select(method, collection, group_method, group_label_method, option_key_method, option_value_method, options = {}, html_options = {}) + @template.grouped_collection_select(@object_name, method, collection, group_method, group_label_method, option_key_method, option_value_method, objectify_options(options), @default_options.merge(html_options)) + end + + # Wraps ActionView::Helpers::FormOptionsHelper#time_zone_select for form builders: + # + # <%= form_for @user do |f| %> + # <%= f.time_zone_select :time_zone, nil, include_blank: true %> + # <%= f.submit %> + # <% end %> + # + # Please refer to the documentation of the base helper for details. + def time_zone_select(method, priority_zones = nil, options = {}, html_options = {}) + @template.time_zone_select(@object_name, method, priority_zones, objectify_options(options), @default_options.merge(html_options)) + end + + # Wraps ActionView::Helpers::FormOptionsHelper#collection_check_boxes for form builders: + # + # <%= form_for @post do |f| %> + # <%= f.collection_check_boxes :author_ids, Author.all, :id, :name_with_initial %> + # <%= f.submit %> + # <% end %> + # + # Please refer to the documentation of the base helper for details. + def collection_check_boxes(method, collection, value_method, text_method, options = {}, html_options = {}, &block) + @template.collection_check_boxes(@object_name, method, collection, value_method, text_method, objectify_options(options), @default_options.merge(html_options), &block) + end + + # Wraps ActionView::Helpers::FormOptionsHelper#collection_radio_buttons for form builders: + # + # <%= form_for @post do |f| %> + # <%= f.collection_radio_buttons :author_id, Author.all, :id, :name_with_initial %> + # <%= f.submit %> + # <% end %> + # + # Please refer to the documentation of the base helper for details. + def collection_radio_buttons(method, collection, value_method, text_method, options = {}, html_options = {}, &block) + @template.collection_radio_buttons(@object_name, method, collection, value_method, text_method, objectify_options(options), @default_options.merge(html_options), &block) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/form_tag_helper.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/form_tag_helper.rb new file mode 100644 index 0000000..b0b74cb --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/form_tag_helper.rb @@ -0,0 +1,876 @@ +require 'cgi' +require 'action_view/helpers/tag_helper' +require 'active_support/core_ext/string/output_safety' +require 'active_support/core_ext/module/attribute_accessors' + +module ActionView + # = Action View Form Tag Helpers + module Helpers + # Provides a number of methods for creating form tags that don't rely on an Active Record object assigned to the template like + # FormHelper does. Instead, you provide the names and values manually. + # + # NOTE: The HTML options disabled, readonly, and multiple can all be treated as booleans. So specifying + # disabled: true will give disabled="disabled". + module FormTagHelper + extend ActiveSupport::Concern + + include UrlHelper + include TextHelper + + mattr_accessor :embed_authenticity_token_in_remote_forms + self.embed_authenticity_token_in_remote_forms = false + + # Starts a form tag that points the action to an url configured with url_for_options just like + # ActionController::Base#url_for. The method for the form defaults to POST. + # + # ==== Options + # * :multipart - If set to true, the enctype is set to "multipart/form-data". + # * :method - The method to use when submitting the form, usually either "get" or "post". + # If "patch", "put", "delete", or another verb is used, a hidden input with name _method + # is added to simulate the verb over post. + # * :authenticity_token - Authenticity token to use in the form. Use only if you need to + # pass custom authenticity token string, or to not add authenticity_token field at all + # (by passing false). Remote forms may omit the embedded authenticity token + # by setting config.action_view.embed_authenticity_token_in_remote_forms = false. + # This is helpful when you're fragment-caching the form. Remote forms get the + # authenticity token from the meta tag, so embedding is unnecessary unless you + # support browsers without JavaScript. + # * :remote - If set to true, will allow the Unobtrusive JavaScript drivers to control the + # submit behavior. By default this behavior is an ajax submit. + # * :enforce_utf8 - If set to false, a hidden input with name utf8 is not output. + # * Any other key creates standard HTML attributes for the tag. + # + # ==== Examples + # form_tag('/posts') + # # =>
    + # + # form_tag('/posts/1', method: :put) + # # => ... ... + # + # form_tag('/upload', multipart: true) + # # => + # + # <%= form_tag('/posts') do -%> + #
    <%= submit_tag 'Save' %>
    + # <% end -%> + # # =>
    + # + # <%= form_tag('/posts', remote: true) %> + # # =>
    + # + # form_tag('http://far.away.com/form', authenticity_token: false) + # # form without authenticity token + # + # form_tag('http://far.away.com/form', authenticity_token: "cf50faa3fe97702ca1ae") + # # form with custom authenticity token + # + def form_tag(url_for_options = {}, options = {}, &block) + html_options = html_options_for_form(url_for_options, options) + if block_given? + form_tag_with_body(html_options, capture(&block)) + else + form_tag_html(html_options) + end + end + + # Creates a dropdown selection box, or if the :multiple option is set to true, a multiple + # choice selection box. + # + # Helpers::FormOptions can be used to create common select boxes such as countries, time zones, or + # associated records. option_tags is a string containing the option tags for the select box. + # + # ==== Options + # * :multiple - If set to true the selection will allow multiple choices. + # * :disabled - If set to true, the user will not be able to use this input. + # * :include_blank - If set to true, an empty option will be created. If set to a string, the string will be used as the option's content and the value will be empty. + # * :prompt - Create a prompt option with blank value and the text asking user to select something. + # * Any other key creates standard HTML attributes for the tag. + # + # ==== Examples + # select_tag "people", options_from_collection_for_select(@people, "id", "name") + # # + # + # select_tag "people", options_from_collection_for_select(@people, "id", "name", "1") + # # + # + # select_tag "people", "".html_safe + # # => + # + # select_tag "count", "".html_safe + # # => + # + # select_tag "colors", "".html_safe, multiple: true + # # => + # + # select_tag "locations", "".html_safe + # # => + # + # select_tag "access", "".html_safe, multiple: true, class: 'form_input', id: 'unique_id' + # # => + # + # select_tag "people", options_from_collection_for_select(@people, "id", "name"), include_blank: true + # # => + # + # select_tag "people", options_from_collection_for_select(@people, "id", "name"), include_blank: "All" + # # => + # + # select_tag "people", options_from_collection_for_select(@people, "id", "name"), prompt: "Select something" + # # => + # + # select_tag "destination", "".html_safe, disabled: true + # # => + # + # select_tag "credit_card", options_for_select([ "VISA", "MasterCard" ], "MasterCard") + # # => + def select_tag(name, option_tags = nil, options = {}) + option_tags ||= "" + html_name = (options[:multiple] == true && !name.to_s.ends_with?("[]")) ? "#{name}[]" : name + + if options.include?(:include_blank) + include_blank = options.delete(:include_blank) + + if include_blank == true + include_blank = '' + end + + if include_blank + option_tags = content_tag(:option, include_blank, value: '').safe_concat(option_tags) + end + end + + if prompt = options.delete(:prompt) + option_tags = content_tag(:option, prompt, value: '').safe_concat(option_tags) + end + + content_tag :select, option_tags, { "name" => html_name, "id" => sanitize_to_id(name) }.update(options.stringify_keys) + end + + # Creates a standard text field; use these text fields to input smaller chunks of text like a username + # or a search query. + # + # ==== Options + # * :disabled - If set to true, the user will not be able to use this input. + # * :size - The number of visible characters that will fit in the input. + # * :maxlength - The maximum number of characters that the browser will allow the user to enter. + # * :placeholder - The text contained in the field by default which is removed when the field receives focus. + # * Any other key creates standard HTML attributes for the tag. + # + # ==== Examples + # text_field_tag 'name' + # # => + # + # text_field_tag 'query', 'Enter your search query here' + # # => + # + # text_field_tag 'search', nil, placeholder: 'Enter search term...' + # # => + # + # text_field_tag 'request', nil, class: 'special_input' + # # => + # + # text_field_tag 'address', '', size: 75 + # # => + # + # text_field_tag 'zip', nil, maxlength: 5 + # # => + # + # text_field_tag 'payment_amount', '$0.00', disabled: true + # # => + # + # text_field_tag 'ip', '0.0.0.0', maxlength: 15, size: 20, class: "ip-input" + # # => + def text_field_tag(name, value = nil, options = {}) + tag :input, { "type" => "text", "name" => name, "id" => sanitize_to_id(name), "value" => value }.update(options.stringify_keys) + end + + # Creates a label element. Accepts a block. + # + # ==== Options + # * Creates standard HTML attributes for the tag. + # + # ==== Examples + # label_tag 'name' + # # => + # + # label_tag 'name', 'Your name' + # # => + # + # label_tag 'name', nil, class: 'small_label' + # # => + def label_tag(name = nil, content_or_options = nil, options = nil, &block) + if block_given? && content_or_options.is_a?(Hash) + options = content_or_options = content_or_options.stringify_keys + else + options ||= {} + options = options.stringify_keys + end + options["for"] = sanitize_to_id(name) unless name.blank? || options.has_key?("for") + content_tag :label, content_or_options || name.to_s.humanize, options, &block + end + + # Creates a hidden form input field used to transmit data that would be lost due to HTTP's statelessness or + # data that should be hidden from the user. + # + # ==== Options + # * Creates standard HTML attributes for the tag. + # + # ==== Examples + # hidden_field_tag 'tags_list' + # # => + # + # hidden_field_tag 'token', 'VUBJKB23UIVI1UU1VOBVI@' + # # => + # + # hidden_field_tag 'collected_input', '', onchange: "alert('Input collected!')" + # # => + def hidden_field_tag(name, value = nil, options = {}) + text_field_tag(name, value, options.merge(type: :hidden)) + end + + # Creates a file upload field. If you are using file uploads then you will also need + # to set the multipart option for the form tag: + # + # <%= form_tag '/upload', multipart: true do %> + # <%= file_field_tag "file" %> + # <%= submit_tag %> + # <% end %> + # + # The specified URL will then be passed a File object containing the selected file, or if the field + # was left blank, a StringIO object. + # + # ==== Options + # * Creates standard HTML attributes for the tag. + # * :disabled - If set to true, the user will not be able to use this input. + # * :multiple - If set to true, *in most updated browsers* the user will be allowed to select multiple files. + # * :accept - If set to one or multiple mime-types, the user will be suggested a filter when choosing a file. You still need to set up model validations. + # + # ==== Examples + # file_field_tag 'attachment' + # # => + # + # file_field_tag 'avatar', class: 'profile_input' + # # => + # + # file_field_tag 'picture', disabled: true + # # => + # + # file_field_tag 'resume', value: '~/resume.doc' + # # => + # + # file_field_tag 'user_pic', accept: 'image/png,image/gif,image/jpeg' + # # => + # + # file_field_tag 'file', accept: 'text/html', class: 'upload', value: 'index.html' + # # => + def file_field_tag(name, options = {}) + text_field_tag(name, nil, options.merge(type: :file)) + end + + # Creates a password field, a masked text field that will hide the users input behind a mask character. + # + # ==== Options + # * :disabled - If set to true, the user will not be able to use this input. + # * :size - The number of visible characters that will fit in the input. + # * :maxlength - The maximum number of characters that the browser will allow the user to enter. + # * Any other key creates standard HTML attributes for the tag. + # + # ==== Examples + # password_field_tag 'pass' + # # => + # + # password_field_tag 'secret', 'Your secret here' + # # => + # + # password_field_tag 'masked', nil, class: 'masked_input_field' + # # => + # + # password_field_tag 'token', '', size: 15 + # # => + # + # password_field_tag 'key', nil, maxlength: 16 + # # => + # + # password_field_tag 'confirm_pass', nil, disabled: true + # # => + # + # password_field_tag 'pin', '1234', maxlength: 4, size: 6, class: "pin_input" + # # => + def password_field_tag(name = "password", value = nil, options = {}) + text_field_tag(name, value, options.merge(type: :password)) + end + + # Creates a text input area; use a textarea for longer text inputs such as blog posts or descriptions. + # + # ==== Options + # * :size - A string specifying the dimensions (columns by rows) of the textarea (e.g., "25x10"). + # * :rows - Specify the number of rows in the textarea + # * :cols - Specify the number of columns in the textarea + # * :disabled - If set to true, the user will not be able to use this input. + # * :escape - By default, the contents of the text input are HTML escaped. + # If you need unescaped contents, set this to false. + # * Any other key creates standard HTML attributes for the tag. + # + # ==== Examples + # text_area_tag 'post' + # # => + # + # text_area_tag 'bio', @user.bio + # # => + # + # text_area_tag 'body', nil, rows: 10, cols: 25 + # # => + # + # text_area_tag 'body', nil, size: "25x10" + # # => + # + # text_area_tag 'description', "Description goes here.", disabled: true + # # => + # + # text_area_tag 'comment', nil, class: 'comment_input' + # # => + def text_area_tag(name, content = nil, options = {}) + options = options.stringify_keys + + if size = options.delete("size") + options["cols"], options["rows"] = size.split("x") if size.respond_to?(:split) + end + + escape = options.delete("escape") { true } + content = ERB::Util.html_escape(content) if escape + + content_tag :textarea, content.to_s.html_safe, { "name" => name, "id" => sanitize_to_id(name) }.update(options) + end + + # Creates a check box form input tag. + # + # ==== Options + # * :disabled - If set to true, the user will not be able to use this input. + # * Any other key creates standard HTML options for the tag. + # + # ==== Examples + # check_box_tag 'accept' + # # => + # + # check_box_tag 'rock', 'rock music' + # # => + # + # check_box_tag 'receive_email', 'yes', true + # # => + # + # check_box_tag 'tos', 'yes', false, class: 'accept_tos' + # # => + # + # check_box_tag 'eula', 'accepted', false, disabled: true + # # => + def check_box_tag(name, value = "1", checked = false, options = {}) + html_options = { "type" => "checkbox", "name" => name, "id" => sanitize_to_id(name), "value" => value }.update(options.stringify_keys) + html_options["checked"] = "checked" if checked + tag :input, html_options + end + + # Creates a radio button; use groups of radio buttons named the same to allow users to + # select from a group of options. + # + # ==== Options + # * :disabled - If set to true, the user will not be able to use this input. + # * Any other key creates standard HTML options for the tag. + # + # ==== Examples + # radio_button_tag 'gender', 'male' + # # => + # + # radio_button_tag 'receive_updates', 'no', true + # # => + # + # radio_button_tag 'time_slot', "3:00 p.m.", false, disabled: true + # # => + # + # radio_button_tag 'color', "green", true, class: "color_input" + # # => + def radio_button_tag(name, value, checked = false, options = {}) + html_options = { "type" => "radio", "name" => name, "id" => "#{sanitize_to_id(name)}_#{sanitize_to_id(value)}", "value" => value }.update(options.stringify_keys) + html_options["checked"] = "checked" if checked + tag :input, html_options + end + + # Creates a submit button with the text value as the caption. + # + # ==== Options + # * :data - This option can be used to add custom data attributes. + # * :disabled - If true, the user will not be able to use this input. + # * Any other key creates standard HTML options for the tag. + # + # ==== Data attributes + # + # * confirm: 'question?' - If present the unobtrusive JavaScript + # drivers will provide a prompt with the question specified. If the user accepts, + # the form is processed normally, otherwise no action is taken. + # * :disable_with - Value of this parameter will be used as the value for a + # disabled version of the submit button when the form is submitted. This feature is + # provided by the unobtrusive JavaScript driver. + # + # ==== Examples + # submit_tag + # # => + # + # submit_tag "Edit this article" + # # => + # + # submit_tag "Save edits", disabled: true + # # => + # + # submit_tag "Complete sale", data: { disable_with: "Please wait..." } + # # => + # + # submit_tag nil, class: "form_submit" + # # => + # + # submit_tag "Edit", class: "edit_button" + # # => + # + # submit_tag "Save", data: { confirm: "Are you sure?" } + # # => + # + def submit_tag(value = "Save changes", options = {}) + options = options.stringify_keys + + tag :input, { "type" => "submit", "name" => "commit", "value" => value }.update(options) + end + + # Creates a button element that defines a submit button, + # resetbutton or a generic button which can be used in + # JavaScript, for example. You can use the button tag as a regular + # submit tag but it isn't supported in legacy browsers. However, + # the button tag allows richer labels such as images and emphasis, + # so this helper will also accept a block. + # + # ==== Options + # * :data - This option can be used to add custom data attributes. + # * :disabled - If true, the user will not be able to + # use this input. + # * Any other key creates standard HTML options for the tag. + # + # ==== Data attributes + # + # * confirm: 'question?' - If present, the + # unobtrusive JavaScript drivers will provide a prompt with + # the question specified. If the user accepts, the form is + # processed normally, otherwise no action is taken. + # * :disable_with - Value of this parameter will be + # used as the value for a disabled version of the submit + # button when the form is submitted. This feature is provided + # by the unobtrusive JavaScript driver. + # + # ==== Examples + # button_tag + # # => + # + # button_tag(type: 'button') do + # content_tag(:strong, 'Ask me!') + # end + # # => + # + # button_tag "Checkout", data: { disable_with: "Please wait..." } + # # => + # + def button_tag(content_or_options = nil, options = nil, &block) + if content_or_options.is_a? Hash + options = content_or_options + else + options ||= {} + end + + options = { 'name' => 'button', 'type' => 'submit' }.merge!(options.stringify_keys) + + if block_given? + content_tag :button, options, &block + else + content_tag :button, content_or_options || 'Button', options + end + end + + # Displays an image which when clicked will submit the form. + # + # source is passed to AssetTagHelper#path_to_image + # + # ==== Options + # * :data - This option can be used to add custom data attributes. + # * :disabled - If set to true, the user will not be able to use this input. + # * Any other key creates standard HTML options for the tag. + # + # ==== Data attributes + # + # * confirm: 'question?' - This will add a JavaScript confirm + # prompt with the question specified. If the user accepts, the form is + # processed normally, otherwise no action is taken. + # + # ==== Examples + # image_submit_tag("login.png") + # # => + # + # image_submit_tag("purchase.png", disabled: true) + # # => + # + # image_submit_tag("search.png", class: 'search_button', alt: 'Find') + # # => + # + # image_submit_tag("agree.png", disabled: true, class: "agree_disagree_button") + # # => + # + # image_submit_tag("save.png", data: { confirm: "Are you sure?" }) + # # => + def image_submit_tag(source, options = {}) + options = options.stringify_keys + tag :input, { "alt" => image_alt(source), "type" => "image", "src" => path_to_image(source) }.update(options) + end + + # Creates a field set for grouping HTML form elements. + # + # legend will become the fieldset's title (optional as per W3C). + # options accept the same values as tag. + # + # ==== Examples + # <%= field_set_tag do %> + #

    <%= text_field_tag 'name' %>

    + # <% end %> + # # =>

    + # + # <%= field_set_tag 'Your details' do %> + #

    <%= text_field_tag 'name' %>

    + # <% end %> + # # =>
    Your details

    + # + # <%= field_set_tag nil, class: 'format' do %> + #

    <%= text_field_tag 'name' %>

    + # <% end %> + # # =>

    + def field_set_tag(legend = nil, options = nil, &block) + output = tag(:fieldset, options, true) + output.safe_concat(content_tag(:legend, legend)) unless legend.blank? + output.concat(capture(&block)) if block_given? + output.safe_concat("") + end + + # Creates a text field of type "color". + # + # ==== Options + # * Accepts the same options as text_field_tag. + # + # ==== Examples + # color_field_tag 'name' + # # => + # + # color_field_tag 'color', '#DEF726' + # # => + # + # color_field_tag 'color', nil, class: 'special_input' + # # => + # + # color_field_tag 'color', '#DEF726', class: 'special_input', disabled: true + # # => + def color_field_tag(name, value = nil, options = {}) + text_field_tag(name, value, options.merge(type: :color)) + end + + # Creates a text field of type "search". + # + # ==== Options + # * Accepts the same options as text_field_tag. + # + # ==== Examples + # search_field_tag 'name' + # # => + # + # search_field_tag 'search', 'Enter your search query here' + # # => + # + # search_field_tag 'search', nil, class: 'special_input' + # # => + # + # search_field_tag 'search', 'Enter your search query here', class: 'special_input', disabled: true + # # => + def search_field_tag(name, value = nil, options = {}) + text_field_tag(name, value, options.merge(type: :search)) + end + + # Creates a text field of type "tel". + # + # ==== Options + # * Accepts the same options as text_field_tag. + # + # ==== Examples + # telephone_field_tag 'name' + # # => + # + # telephone_field_tag 'tel', '0123456789' + # # => + # + # telephone_field_tag 'tel', nil, class: 'special_input' + # # => + # + # telephone_field_tag 'tel', '0123456789', class: 'special_input', disabled: true + # # => + def telephone_field_tag(name, value = nil, options = {}) + text_field_tag(name, value, options.merge(type: :tel)) + end + alias phone_field_tag telephone_field_tag + + # Creates a text field of type "date". + # + # ==== Options + # * Accepts the same options as text_field_tag. + # + # ==== Examples + # date_field_tag 'name' + # # => + # + # date_field_tag 'date', '01/01/2014' + # # => + # + # date_field_tag 'date', nil, class: 'special_input' + # # => + # + # date_field_tag 'date', '01/01/2014', class: 'special_input', disabled: true + # # => + def date_field_tag(name, value = nil, options = {}) + text_field_tag(name, value, options.merge(type: :date)) + end + + # Creates a text field of type "time". + # + # === Options + # * :min - The minimum acceptable value. + # * :max - The maximum acceptable value. + # * :step - The acceptable value granularity. + # * Otherwise accepts the same options as text_field_tag. + def time_field_tag(name, value = nil, options = {}) + text_field_tag(name, value, options.merge(type: :time)) + end + + # Creates a text field of type "datetime". + # + # === Options + # * :min - The minimum acceptable value. + # * :max - The maximum acceptable value. + # * :step - The acceptable value granularity. + # * Otherwise accepts the same options as text_field_tag. + def datetime_field_tag(name, value = nil, options = {}) + text_field_tag(name, value, options.merge(type: :datetime)) + end + + # Creates a text field of type "datetime-local". + # + # === Options + # * :min - The minimum acceptable value. + # * :max - The maximum acceptable value. + # * :step - The acceptable value granularity. + # * Otherwise accepts the same options as text_field_tag. + def datetime_local_field_tag(name, value = nil, options = {}) + text_field_tag(name, value, options.merge(type: 'datetime-local')) + end + + # Creates a text field of type "month". + # + # === Options + # * :min - The minimum acceptable value. + # * :max - The maximum acceptable value. + # * :step - The acceptable value granularity. + # * Otherwise accepts the same options as text_field_tag. + def month_field_tag(name, value = nil, options = {}) + text_field_tag(name, value, options.merge(type: :month)) + end + + # Creates a text field of type "week". + # + # === Options + # * :min - The minimum acceptable value. + # * :max - The maximum acceptable value. + # * :step - The acceptable value granularity. + # * Otherwise accepts the same options as text_field_tag. + def week_field_tag(name, value = nil, options = {}) + text_field_tag(name, value, options.merge(type: :week)) + end + + # Creates a text field of type "url". + # + # ==== Options + # * Accepts the same options as text_field_tag. + # + # ==== Examples + # url_field_tag 'name' + # # => + # + # url_field_tag 'url', 'http://rubyonrails.org' + # # => + # + # url_field_tag 'url', nil, class: 'special_input' + # # => + # + # url_field_tag 'url', 'http://rubyonrails.org', class: 'special_input', disabled: true + # # => + def url_field_tag(name, value = nil, options = {}) + text_field_tag(name, value, options.merge(type: :url)) + end + + # Creates a text field of type "email". + # + # ==== Options + # * Accepts the same options as text_field_tag. + # + # ==== Examples + # email_field_tag 'name' + # # => + # + # email_field_tag 'email', 'email@example.com' + # # => + # + # email_field_tag 'email', nil, class: 'special_input' + # # => + # + # email_field_tag 'email', 'email@example.com', class: 'special_input', disabled: true + # # => + def email_field_tag(name, value = nil, options = {}) + text_field_tag(name, value, options.merge(type: :email)) + end + + # Creates a number field. + # + # ==== Options + # * :min - The minimum acceptable value. + # * :max - The maximum acceptable value. + # * :in - A range specifying the :min and + # :max values. + # * :within - Same as :in. + # * :step - The acceptable value granularity. + # * Otherwise accepts the same options as text_field_tag. + # + # ==== Examples + # number_field_tag 'quantity' + # # => + # + # number_field_tag 'quantity', '1' + # # => + # + # number_field_tag 'quantity', nil, class: 'special_input' + # # => + # + # number_field_tag 'quantity', nil, min: 1 + # # => + # + # number_field_tag 'quantity', nil, max: 9 + # # => + # + # number_field_tag 'quantity', nil, in: 1...10 + # # => + # + # number_field_tag 'quantity', nil, within: 1...10 + # # => + # + # number_field_tag 'quantity', nil, min: 1, max: 10 + # # => + # + # number_field_tag 'quantity', nil, min: 1, max: 10, step: 2 + # # => + # + # number_field_tag 'quantity', '1', class: 'special_input', disabled: true + # # => + def number_field_tag(name, value = nil, options = {}) + options = options.stringify_keys + options["type"] ||= "number" + if range = options.delete("in") || options.delete("within") + options.update("min" => range.min, "max" => range.max) + end + text_field_tag(name, value, options) + end + + # Creates a range form element. + # + # ==== Options + # * Accepts the same options as number_field_tag. + def range_field_tag(name, value = nil, options = {}) + number_field_tag(name, value, options.merge(type: :range)) + end + + # Creates the hidden UTF8 enforcer tag. Override this method in a helper + # to customize the tag. + def utf8_enforcer_tag + # Use raw HTML to ensure the value is written as an HTML entity; it + # needs to be the right character regardless of which encoding the + # browser infers. + ''.html_safe + end + + private + def html_options_for_form(url_for_options, options) + options.stringify_keys.tap do |html_options| + html_options["enctype"] = "multipart/form-data" if html_options.delete("multipart") + # The following URL is unescaped, this is just a hash of options, and it is the + # responsibility of the caller to escape all the values. + html_options["action"] = url_for(url_for_options) + html_options["accept-charset"] = "UTF-8" + + html_options["data-remote"] = true if html_options.delete("remote") + + if html_options["data-remote"] && + !embed_authenticity_token_in_remote_forms && + html_options["authenticity_token"].blank? + # The authenticity token is taken from the meta tag in this case + html_options["authenticity_token"] = false + elsif html_options["authenticity_token"] == true + # Include the default authenticity_token, which is only generated when its set to nil, + # but we needed the true value to override the default of no authenticity_token on data-remote. + html_options["authenticity_token"] = nil + end + end + end + + def extra_tags_for_form(html_options) + authenticity_token = html_options.delete("authenticity_token") + method = html_options.delete("method").to_s + + method_tag = case method + when /^get$/i # must be case-insensitive, but can't use downcase as might be nil + html_options["method"] = "get" + '' + when /^post$/i, "", nil + html_options["method"] = "post" + token_tag(authenticity_token) + else + html_options["method"] = "post" + method_tag(method) + token_tag(authenticity_token) + end + + if html_options.delete("enforce_utf8") { true } + utf8_enforcer_tag + method_tag + else + method_tag + end + end + + def form_tag_html(html_options) + extra_tags = extra_tags_for_form(html_options) + tag(:form, html_options, true) + extra_tags + end + + def form_tag_with_body(html_options, content) + output = form_tag_html(html_options) + output << content + output.safe_concat("
    ") + end + + # see http://www.w3.org/TR/html4/types.html#type-name + def sanitize_to_id(name) + name.to_s.delete(']').tr('^-a-zA-Z0-9:.', "_") + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/javascript_helper.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/javascript_helper.rb new file mode 100644 index 0000000..629c447 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/javascript_helper.rb @@ -0,0 +1,81 @@ +require 'action_view/helpers/tag_helper' + +module ActionView + module Helpers + module JavaScriptHelper + JS_ESCAPE_MAP = { + '\\' => '\\\\', + ' '<\/', + "\r\n" => '\n', + "\n" => '\n', + "\r" => '\n', + '"' => '\\"', + "'" => "\\'" + } + + JS_ESCAPE_MAP["\342\200\250".force_encoding(Encoding::UTF_8).encode!] = '
' + JS_ESCAPE_MAP["\342\200\251".force_encoding(Encoding::UTF_8).encode!] = '
' + + # Escapes carriage returns and single and double quotes for JavaScript segments. + # + # Also available through the alias j(). This is particularly helpful in JavaScript + # responses, like: + # + # $('some_element').replaceWith('<%=j render 'some/element_template' %>'); + def escape_javascript(javascript) + if javascript + result = javascript.gsub(/(\\|<\/|\r\n|\342\200\250|\342\200\251|[\n\r"'])/u) {|match| JS_ESCAPE_MAP[match] } + javascript.html_safe? ? result.html_safe : result + else + '' + end + end + + alias_method :j, :escape_javascript + + # Returns a JavaScript tag with the +content+ inside. Example: + # javascript_tag "alert('All is good')" + # + # Returns: + # + # + # +html_options+ may be a hash of attributes for the \ + # + # Instead of passing the content as an argument, you can also use a block + # in which case, you pass your +html_options+ as the first parameter. + # + # <%= javascript_tag defer: 'defer' do -%> + # alert('All is good') + # <% end -%> + def javascript_tag(content_or_options_with_block = nil, html_options = {}, &block) + content = + if block_given? + html_options = content_or_options_with_block if content_or_options_with_block.is_a?(Hash) + capture(&block) + else + content_or_options_with_block + end + + content_tag(:script, javascript_cdata_section(content), html_options) + end + + def javascript_cdata_section(content) #:nodoc: + "\n//#{cdata_section("\n#{content}\n//")}\n".html_safe + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/number_helper.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/number_helper.rb new file mode 100644 index 0000000..f66dbfe --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/number_helper.rb @@ -0,0 +1,432 @@ +# encoding: utf-8 + +require 'active_support/core_ext/hash/keys' +require 'active_support/core_ext/string/output_safety' +require 'active_support/number_helper' + +module ActionView + # = Action View Number Helpers + module Helpers #:nodoc: + + # Provides methods for converting numbers into formatted strings. + # Methods are provided for phone numbers, currency, percentage, + # precision, positional notation, file size and pretty printing. + # + # Most methods expect a +number+ argument, and will return it + # unchanged if can't be converted into a valid number. + module NumberHelper + + # Raised when argument +number+ param given to the helpers is invalid and + # the option :raise is set to +true+. + class InvalidNumberError < StandardError + attr_accessor :number + def initialize(number) + @number = number + end + end + + # Formats a +number+ into a US phone number (e.g., (555) + # 123-9876). You can customize the format in the +options+ hash. + # + # ==== Options + # + # * :area_code - Adds parentheses around the area code. + # * :delimiter - Specifies the delimiter to use + # (defaults to "-"). + # * :extension - Specifies an extension to add to the + # end of the generated number. + # * :country_code - Sets the country code for the phone + # number. + # * :raise - If true, raises +InvalidNumberError+ when + # the argument is invalid. + # + # ==== Examples + # + # number_to_phone(5551234) # => 555-1234 + # number_to_phone("5551234") # => 555-1234 + # number_to_phone(1235551234) # => 123-555-1234 + # number_to_phone(1235551234, area_code: true) # => (123) 555-1234 + # number_to_phone(1235551234, delimiter: " ") # => 123 555 1234 + # number_to_phone(1235551234, area_code: true, extension: 555) # => (123) 555-1234 x 555 + # number_to_phone(1235551234, country_code: 1) # => +1-123-555-1234 + # number_to_phone("123a456") # => 123a456 + # number_to_phone("1234a567", raise: true) # => InvalidNumberError + # + # number_to_phone(1235551234, country_code: 1, extension: 1343, delimiter: ".") + # # => +1.123.555.1234 x 1343 + def number_to_phone(number, options = {}) + return unless number + options = options.symbolize_keys + + parse_float(number, true) if options.delete(:raise) + ERB::Util.html_escape(ActiveSupport::NumberHelper.number_to_phone(number, options)) + end + + # Formats a +number+ into a currency string (e.g., $13.65). You + # can customize the format in the +options+ hash. + # + # ==== Options + # + # * :locale - Sets the locale to be used for formatting + # (defaults to current locale). + # * :precision - Sets the level of precision (defaults + # to 2). + # * :unit - Sets the denomination of the currency + # (defaults to "$"). + # * :separator - Sets the separator between the units + # (defaults to "."). + # * :delimiter - Sets the thousands delimiter (defaults + # to ","). + # * :format - Sets the format for non-negative numbers + # (defaults to "%u%n"). Fields are %u for the + # currency, and %n for the number. + # * :negative_format - Sets the format for negative + # numbers (defaults to prepending an hyphen to the formatted + # number given by :format). Accepts the same fields + # than :format, except %n is here the + # absolute value of the number. + # * :raise - If true, raises +InvalidNumberError+ when + # the argument is invalid. + # + # ==== Examples + # + # number_to_currency(1234567890.50) # => $1,234,567,890.50 + # number_to_currency(1234567890.506) # => $1,234,567,890.51 + # number_to_currency(1234567890.506, precision: 3) # => $1,234,567,890.506 + # number_to_currency(1234567890.506, locale: :fr) # => 1 234 567 890,51 € + # number_to_currency("123a456") # => $123a456 + # + # number_to_currency("123a456", raise: true) # => InvalidNumberError + # + # number_to_currency(-1234567890.50, negative_format: "(%u%n)") + # # => ($1,234,567,890.50) + # number_to_currency(1234567890.50, unit: "R$", separator: ",", delimiter: "") + # # => R$1234567890,50 + # number_to_currency(1234567890.50, unit: "R$", separator: ",", delimiter: "", format: "%n %u") + # # => 1234567890,50 R$ + def number_to_currency(number, options = {}) + delegate_number_helper_method(:number_to_currency, number, options) + end + + # Formats a +number+ as a percentage string (e.g., 65%). You can + # customize the format in the +options+ hash. + # + # ==== Options + # + # * :locale - Sets the locale to be used for formatting + # (defaults to current locale). + # * :precision - Sets the precision of the number + # (defaults to 3). + # * :significant - If +true+, precision will be the # + # of significant_digits. If +false+, the # of fractional + # digits (defaults to +false+). + # * :separator - Sets the separator between the + # fractional and integer digits (defaults to "."). + # * :delimiter - Sets the thousands delimiter (defaults + # to ""). + # * :strip_insignificant_zeros - If +true+ removes + # insignificant zeros after the decimal separator (defaults to + # +false+). + # * :format - Specifies the format of the percentage + # string The number field is %n (defaults to "%n%"). + # * :raise - If true, raises +InvalidNumberError+ when + # the argument is invalid. + # + # ==== Examples + # + # number_to_percentage(100) # => 100.000% + # number_to_percentage("98") # => 98.000% + # number_to_percentage(100, precision: 0) # => 100% + # number_to_percentage(1000, delimiter: '.', separator: ',') # => 1.000,000% + # number_to_percentage(302.24398923423, precision: 5) # => 302.24399% + # number_to_percentage(1000, locale: :fr) # => 1 000,000% + # number_to_percentage("98a") # => 98a% + # number_to_percentage(100, format: "%n %") # => 100 % + # + # number_to_percentage("98a", raise: true) # => InvalidNumberError + def number_to_percentage(number, options = {}) + delegate_number_helper_method(:number_to_percentage, number, options) + end + + # Formats a +number+ with grouped thousands using +delimiter+ + # (e.g., 12,324). You can customize the format in the +options+ + # hash. + # + # ==== Options + # + # * :locale - Sets the locale to be used for formatting + # (defaults to current locale). + # * :delimiter - Sets the thousands delimiter (defaults + # to ","). + # * :separator - Sets the separator between the + # fractional and integer digits (defaults to "."). + # * :raise - If true, raises +InvalidNumberError+ when + # the argument is invalid. + # + # ==== Examples + # + # number_with_delimiter(12345678) # => 12,345,678 + # number_with_delimiter("123456") # => 123,456 + # number_with_delimiter(12345678.05) # => 12,345,678.05 + # number_with_delimiter(12345678, delimiter: ".") # => 12.345.678 + # number_with_delimiter(12345678, delimiter: ",") # => 12,345,678 + # number_with_delimiter(12345678.05, separator: " ") # => 12,345,678 05 + # number_with_delimiter(12345678.05, locale: :fr) # => 12 345 678,05 + # number_with_delimiter("112a") # => 112a + # number_with_delimiter(98765432.98, delimiter: " ", separator: ",") + # # => 98 765 432,98 + # + # number_with_delimiter("112a", raise: true) # => raise InvalidNumberError + def number_with_delimiter(number, options = {}) + delegate_number_helper_method(:number_to_delimited, number, options) + end + + # Formats a +number+ with the specified level of + # :precision (e.g., 112.32 has a precision of 2 if + # +:significant+ is +false+, and 5 if +:significant+ is +true+). + # You can customize the format in the +options+ hash. + # + # ==== Options + # + # * :locale - Sets the locale to be used for formatting + # (defaults to current locale). + # * :precision - Sets the precision of the number + # (defaults to 3). + # * :significant - If +true+, precision will be the # + # of significant_digits. If +false+, the # of fractional + # digits (defaults to +false+). + # * :separator - Sets the separator between the + # fractional and integer digits (defaults to "."). + # * :delimiter - Sets the thousands delimiter (defaults + # to ""). + # * :strip_insignificant_zeros - If +true+ removes + # insignificant zeros after the decimal separator (defaults to + # +false+). + # * :raise - If true, raises +InvalidNumberError+ when + # the argument is invalid. + # + # ==== Examples + # + # number_with_precision(111.2345) # => 111.235 + # number_with_precision(111.2345, precision: 2) # => 111.23 + # number_with_precision(13, precision: 5) # => 13.00000 + # number_with_precision(389.32314, precision: 0) # => 389 + # number_with_precision(111.2345, significant: true) # => 111 + # number_with_precision(111.2345, precision: 1, significant: true) # => 100 + # number_with_precision(13, precision: 5, significant: true) # => 13.000 + # number_with_precision(111.234, locale: :fr) # => 111,234 + # + # number_with_precision(13, precision: 5, significant: true, strip_insignificant_zeros: true) + # # => 13 + # + # number_with_precision(389.32314, precision: 4, significant: true) # => 389.3 + # number_with_precision(1111.2345, precision: 2, separator: ',', delimiter: '.') + # # => 1.111,23 + def number_with_precision(number, options = {}) + delegate_number_helper_method(:number_to_rounded, number, options) + end + + # Formats the bytes in +number+ into a more understandable + # representation (e.g., giving it 1500 yields 1.5 KB). This + # method is useful for reporting file sizes to users. You can + # customize the format in the +options+ hash. + # + # See number_to_human if you want to pretty-print a + # generic number. + # + # ==== Options + # + # * :locale - Sets the locale to be used for formatting + # (defaults to current locale). + # * :precision - Sets the precision of the number + # (defaults to 3). + # * :significant - If +true+, precision will be the # + # of significant_digits. If +false+, the # of fractional + # digits (defaults to +true+) + # * :separator - Sets the separator between the + # fractional and integer digits (defaults to "."). + # * :delimiter - Sets the thousands delimiter (defaults + # to ""). + # * :strip_insignificant_zeros - If +true+ removes + # insignificant zeros after the decimal separator (defaults to + # +true+) + # * :prefix - If +:si+ formats the number using the SI + # prefix (defaults to :binary) + # * :raise - If true, raises +InvalidNumberError+ when + # the argument is invalid. + # + # ==== Examples + # + # number_to_human_size(123) # => 123 Bytes + # number_to_human_size(1234) # => 1.21 KB + # number_to_human_size(12345) # => 12.1 KB + # number_to_human_size(1234567) # => 1.18 MB + # number_to_human_size(1234567890) # => 1.15 GB + # number_to_human_size(1234567890123) # => 1.12 TB + # number_to_human_size(1234567, precision: 2) # => 1.2 MB + # number_to_human_size(483989, precision: 2) # => 470 KB + # number_to_human_size(1234567, precision: 2, separator: ',') # => 1,2 MB + # number_to_human_size(1234567890123, precision: 5) # => "1.1228 TB" + # number_to_human_size(524288000, precision: 5) # => "500 MB" + def number_to_human_size(number, options = {}) + delegate_number_helper_method(:number_to_human_size, number, options) + end + + # Pretty prints (formats and approximates) a number in a way it + # is more readable by humans (eg.: 1200000000 becomes "1.2 + # Billion"). This is useful for numbers that can get very large + # (and too hard to read). + # + # See number_to_human_size if you want to print a file + # size. + # + # You can also define you own unit-quantifier names if you want + # to use other decimal units (eg.: 1500 becomes "1.5 + # kilometers", 0.150 becomes "150 milliliters", etc). You may + # define a wide range of unit quantifiers, even fractional ones + # (centi, deci, mili, etc). + # + # ==== Options + # + # * :locale - Sets the locale to be used for formatting + # (defaults to current locale). + # * :precision - Sets the precision of the number + # (defaults to 3). + # * :significant - If +true+, precision will be the # + # of significant_digits. If +false+, the # of fractional + # digits (defaults to +true+) + # * :separator - Sets the separator between the + # fractional and integer digits (defaults to "."). + # * :delimiter - Sets the thousands delimiter (defaults + # to ""). + # * :strip_insignificant_zeros - If +true+ removes + # insignificant zeros after the decimal separator (defaults to + # +true+) + # * :units - A Hash of unit quantifier names. Or a + # string containing an i18n scope where to find this hash. It + # might have the following keys: + # * *integers*: :unit, :ten, + # :hundred, :thousand, :million, + # :billion, :trillion, + # :quadrillion + # * *fractionals*: :deci, :centi, + # :mili, :micro, :nano, + # :pico, :femto + # * :format - Sets the format of the output string + # (defaults to "%n %u"). The field types are: + # * %u - The quantifier (ex.: 'thousand') + # * %n - The number + # * :raise - If true, raises +InvalidNumberError+ when + # the argument is invalid. + # + # ==== Examples + # + # number_to_human(123) # => "123" + # number_to_human(1234) # => "1.23 Thousand" + # number_to_human(12345) # => "12.3 Thousand" + # number_to_human(1234567) # => "1.23 Million" + # number_to_human(1234567890) # => "1.23 Billion" + # number_to_human(1234567890123) # => "1.23 Trillion" + # number_to_human(1234567890123456) # => "1.23 Quadrillion" + # number_to_human(1234567890123456789) # => "1230 Quadrillion" + # number_to_human(489939, precision: 2) # => "490 Thousand" + # number_to_human(489939, precision: 4) # => "489.9 Thousand" + # number_to_human(1234567, precision: 4, + # significant: false) # => "1.2346 Million" + # number_to_human(1234567, precision: 1, + # separator: ',', + # significant: false) # => "1,2 Million" + # + # number_to_human(500000000, precision: 5) # => "500 Million" + # number_to_human(12345012345, significant: false) # => "12.345 Billion" + # + # Non-significant zeros after the decimal separator are stripped + # out by default (set :strip_insignificant_zeros to + # +false+ to change that): + # + # number_to_human(12.00001) # => "12" + # number_to_human(12.00001, strip_insignificant_zeros: false) # => "12.0" + # + # ==== Custom Unit Quantifiers + # + # You can also use your own custom unit quantifiers: + # number_to_human(500000, units: {unit: "ml", thousand: "lt"}) # => "500 lt" + # + # If in your I18n locale you have: + # distance: + # centi: + # one: "centimeter" + # other: "centimeters" + # unit: + # one: "meter" + # other: "meters" + # thousand: + # one: "kilometer" + # other: "kilometers" + # billion: "gazillion-distance" + # + # Then you could do: + # + # number_to_human(543934, units: :distance) # => "544 kilometers" + # number_to_human(54393498, units: :distance) # => "54400 kilometers" + # number_to_human(54393498000, units: :distance) # => "54.4 gazillion-distance" + # number_to_human(343, units: :distance, precision: 1) # => "300 meters" + # number_to_human(1, units: :distance) # => "1 meter" + # number_to_human(0.34, units: :distance) # => "34 centimeters" + # + def number_to_human(number, options = {}) + delegate_number_helper_method(:number_to_human, number, options) + end + + private + + def delegate_number_helper_method(method, number, options) + return unless number + options = escape_unsafe_options(options.symbolize_keys) + + wrap_with_output_safety_handling(number, options.delete(:raise)) { + ActiveSupport::NumberHelper.public_send(method, number, options) + } + end + + def escape_unsafe_options(options) + options[:format] = ERB::Util.html_escape(options[:format]) if options[:format] + options[:negative_format] = ERB::Util.html_escape(options[:negative_format]) if options[:negative_format] + options[:separator] = ERB::Util.html_escape(options[:separator]) if options[:separator] + options[:delimiter] = ERB::Util.html_escape(options[:delimiter]) if options[:delimiter] + options[:unit] = ERB::Util.html_escape(options[:unit]) if options[:unit] && !options[:unit].html_safe? + options[:units] = escape_units(options[:units]) if options[:units] && Hash === options[:units] + options + end + + def escape_units(units) + Hash[units.map do |k, v| + [k, ERB::Util.html_escape(v)] + end] + end + + def wrap_with_output_safety_handling(number, raise_on_invalid, &block) + valid_float = valid_float?(number) + raise InvalidNumberError, number if raise_on_invalid && !valid_float + + formatted_number = yield + + if valid_float || number.html_safe? + formatted_number.html_safe + else + formatted_number + end + end + + def valid_float?(number) + !parse_float(number, false).nil? + end + + def parse_float(number, raise_error) + Float(number) + rescue ArgumentError, TypeError + raise InvalidNumberError, number if raise_error + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/output_safety_helper.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/output_safety_helper.rb new file mode 100644 index 0000000..1c2a400 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/output_safety_helper.rb @@ -0,0 +1,38 @@ +require 'active_support/core_ext/string/output_safety' + +module ActionView #:nodoc: + # = Action View Raw Output Helper + module Helpers #:nodoc: + module OutputSafetyHelper + # This method outputs without escaping a string. Since escaping tags is + # now default, this can be used when you don't want Rails to automatically + # escape tags. This is not recommended if the data is coming from the user's + # input. + # + # For example: + # + # raw @user.name + # # => 'Jimmy Tables' + def raw(stringish) + stringish.to_s.html_safe + end + + # This method returns an HTML safe string similar to what Array#join + # would return. The array is flattened, and all items, including + # the supplied separator, are HTML escaped unless they are HTML + # safe, and the returned string is marked as HTML safe. + # + # safe_join(["

    foo

    ".html_safe, "

    bar

    "], "
    ") + # # => "

    foo

    <br /><p>bar</p>" + # + # safe_join(["

    foo

    ".html_safe, "

    bar

    ".html_safe], "
    ".html_safe) + # # => "

    foo


    bar

    " + # + def safe_join(array, sep=$,) + sep = ERB::Util.unwrapped_html_escape(sep) + + array.flatten.map! { |i| ERB::Util.unwrapped_html_escape(i) }.join(sep).html_safe + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/record_tag_helper.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/record_tag_helper.rb new file mode 100644 index 0000000..77c3e6d --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/record_tag_helper.rb @@ -0,0 +1,108 @@ +require 'action_view/record_identifier' + +module ActionView + # = Action View Record Tag Helpers + module Helpers + module RecordTagHelper + include ActionView::RecordIdentifier + + # Produces a wrapper DIV element with id and class parameters that + # relate to the specified Active Record object. Usage example: + # + # <%= div_for(@person, class: "foo") do %> + # <%= @person.name %> + # <% end %> + # + # produces: + # + #
    Joe Bloggs
    + # + # You can also pass an array of Active Record objects, which will then + # get iterated over and yield each record as an argument for the block. + # For example: + # + # <%= div_for(@people, class: "foo") do |person| %> + # <%= person.name %> + # <% end %> + # + # produces: + # + #
    Joe Bloggs
    + #
    Jane Bloggs
    + # + def div_for(record, *args, &block) + content_tag_for(:div, record, *args, &block) + end + + # content_tag_for creates an HTML element with id and class parameters + # that relate to the specified Active Record object. For example: + # + # <%= content_tag_for(:tr, @person) do %> + # <%= @person.first_name %> + # <%= @person.last_name %> + # <% end %> + # + # would produce the following HTML (assuming @person is an instance of + # a Person object, with an id value of 123): + # + # .... + # + # If you require the HTML id attribute to have a prefix, you can specify it: + # + # <%= content_tag_for(:tr, @person, :foo) do %> ... + # + # produces: + # + # ... + # + # You can also pass an array of objects which this method will loop through + # and yield the current object to the supplied block, reducing the need for + # having to iterate through the object (using each) beforehand. + # For example (assuming @people is an array of Person objects): + # + # <%= content_tag_for(:tr, @people) do |person| %> + # <%= person.first_name %> + # <%= person.last_name %> + # <% end %> + # + # produces: + # + # ... + # ... + # + # content_tag_for also accepts a hash of options, which will be converted to + # additional HTML attributes. If you specify a :class value, it will be combined + # with the default class name for your object. For example: + # + # <%= content_tag_for(:li, @person, class: "bar") %>... + # + # produces: + # + #
  • ... + # + def content_tag_for(tag_name, single_or_multiple_records, prefix = nil, options = nil, &block) + options, prefix = prefix, nil if prefix.is_a?(Hash) + + Array(single_or_multiple_records).map do |single_record| + content_tag_for_single_record(tag_name, single_record, prefix, options, &block) + end.join("\n").html_safe + end + + private + + # Called by content_tag_for internally to render a content tag + # for each record. + def content_tag_for_single_record(tag_name, record, prefix, options, &block) + options = options ? options.dup : {} + options[:class] = [ dom_class(record, prefix), options[:class] ].compact + options[:id] = dom_id(record, prefix) + + if block_given? + content_tag(tag_name, capture(record, &block), options) + else + content_tag(tag_name, "", options) + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/rendering_helper.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/rendering_helper.rb new file mode 100644 index 0000000..e11670e --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/rendering_helper.rb @@ -0,0 +1,98 @@ +module ActionView + module Helpers + # = Action View Rendering + # + # Implements methods that allow rendering from a view context. + # In order to use this module, all you need is to implement + # view_renderer that returns an ActionView::Renderer object. + module RenderingHelper + # Returns the result of a render that's dictated by the options hash. The primary options are: + # + # * :partial - See ActionView::PartialRenderer. + # * :file - Renders an explicit template file (this used to be the old default), add :locals to pass in those. + # * :inline - Renders an inline template similar to how it's done in the controller. + # * :text - Renders the text passed in out. + # * :plain - Renders the text passed in out. Setting the content + # type as text/plain. + # * :html - Renders the HTML safe string passed in out, otherwise + # performs HTML escape on the string first. Setting the content type as + # text/html. + # * :body - Renders the text passed in, and inherits the content + # type of text/html from ActionDispatch::Response + # object. + # + # If no options hash is passed or :update specified, the default is to render a partial and use the second parameter + # as the locals hash. + def render(options = {}, locals = {}, &block) + case options + when Hash + if block_given? + view_renderer.render_partial(self, options.merge(:partial => options[:layout]), &block) + else + view_renderer.render(self, options) + end + else + view_renderer.render_partial(self, :partial => options, :locals => locals) + end + end + + # Overwrites _layout_for in the context object so it supports the case a block is + # passed to a partial. Returns the contents that are yielded to a layout, given a + # name or a block. + # + # You can think of a layout as a method that is called with a block. If the user calls + # yield :some_name, the block, by default, returns content_for(:some_name). + # If the user calls simply +yield+, the default block returns content_for(:layout). + # + # The user can override this default by passing a block to the layout: + # + # # The template + # <%= render layout: "my_layout" do %> + # Content + # <% end %> + # + # # The layout + # + # <%= yield %> + # + # + # In this case, instead of the default block, which would return content_for(:layout), + # this method returns the block that was passed in to render :layout, and the response + # would be + # + # + # Content + # + # + # Finally, the block can take block arguments, which can be passed in by +yield+: + # + # # The template + # <%= render layout: "my_layout" do |customer| %> + # Hello <%= customer.name %> + # <% end %> + # + # # The layout + # + # <%= yield Struct.new(:name).new("David") %> + # + # + # In this case, the layout would receive the block passed into render :layout, + # and the struct specified would be passed into the block as an argument. The result + # would be + # + # + # Hello David + # + # + def _layout_for(*args, &block) + name = args.first + + if block && !name.is_a?(Symbol) + capture(*args, &block) + else + super + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/sanitize_helper.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/sanitize_helper.rb new file mode 100644 index 0000000..ccd88be --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/sanitize_helper.rb @@ -0,0 +1,172 @@ +require 'active_support/core_ext/object/try' +require 'active_support/deprecation' +require 'rails-html-sanitizer' + +module ActionView + # = Action View Sanitize Helpers + module Helpers + # The SanitizeHelper module provides a set of methods for scrubbing text of undesired HTML elements. + # These helper methods extend Action View making them callable within your template files. + module SanitizeHelper + extend ActiveSupport::Concern + # Sanitizes HTML input, stripping all tags and attributes that aren't whitelisted. + # + # It also strips href/src attributes with unsafe protocols like + # javascript:, while also protecting against attempts to use Unicode, + # ASCII, and hex character references to work around these protocol filters. + # + # The default sanitizer is Rails::Html::WhiteListSanitizer. See {Rails HTML + # Sanitizers}[https://github.com/rails/rails-html-sanitizer] for more information. + # + # Custom sanitization rules can also be provided. + # + # Please note that sanitizing user-provided text does not guarantee that the + # resulting markup is valid or even well-formed. For example, the output may still + # contain unescaped characters like <, >, or &. + # + # ==== Options + # + # * :tags - An array of allowed tags. + # * :attributes - An array of allowed attributes. + # * :scrubber - A {Rails::Html scrubber}[https://github.com/rails/rails-html-sanitizer] + # or {Loofah::Scrubber}[https://github.com/flavorjones/loofah] object that + # defines custom sanitization rules. A custom scrubber takes precedence over + # custom tags and attributes. + # + # ==== Examples + # + # Normal use: + # + # <%= sanitize @comment.body %> + # + # Providing custom whitelisted tags and attributes: + # + # <%= sanitize @comment.body, tags: %w(strong em a), attributes: %w(href) %> + # + # Providing a custom Rails::Html scrubber: + # + # class CommentScrubber < Rails::Html::PermitScrubber + # def allowed_node?(node) + # !%w(form script comment blockquote).include?(node.name) + # end + # + # def skip_node?(node) + # node.text? + # end + # + # def scrub_attribute?(name) + # name == 'style' + # end + # end + # + # <%= sanitize @comment.body, scrubber: CommentScrubber.new %> + # + # See {Rails HTML Sanitizer}[https://github.com/rails/rails-html-sanitizer] for + # documentation about Rails::Html scrubbers. + # + # Providing a custom Loofah::Scrubber: + # + # scrubber = Loofah::Scrubber.new do |node| + # node.remove if node.name == 'script' + # end + # + # <%= sanitize @comment.body, scrubber: scrubber %> + # + # See {Loofah's documentation}[https://github.com/flavorjones/loofah] for more + # information about defining custom Loofah::Scrubber objects. + # + # To set the default allowed tags or attributes across your application: + # + # # In config/application.rb + # config.action_view.sanitized_allowed_tags = ['strong', 'em', 'a'] + # config.action_view.sanitized_allowed_attributes = ['href', 'title'] + def sanitize(html, options = {}) + self.class.white_list_sanitizer.sanitize(html, options).try(:html_safe) + end + + # Sanitizes a block of CSS code. Used by +sanitize+ when it comes across a style attribute. + def sanitize_css(style) + self.class.white_list_sanitizer.sanitize_css(style) + end + + # Strips all HTML tags from +html+, including comments. + # + # strip_tags("Strip these tags!") + # # => Strip these tags! + # + # strip_tags("Bold no more! See more here...") + # # => Bold no more! See more here... + # + # strip_tags("
    Welcome to my website!
    ") + # # => Welcome to my website! + def strip_tags(html) + self.class.full_sanitizer.sanitize(html, encode_special_chars: false) + end + + # Strips all link tags from +html+ leaving just the link text. + # + # strip_links('Ruby on Rails') + # # => Ruby on Rails + # + # strip_links('Please e-mail me at me@email.com.') + # # => Please e-mail me at me@email.com. + # + # strip_links('Blog: Visit.') + # # => Blog: Visit. + def strip_links(html) + self.class.link_sanitizer.sanitize(html) + end + + module ClassMethods #:nodoc: + attr_writer :full_sanitizer, :link_sanitizer, :white_list_sanitizer + + # Vendors the full, link and white list sanitizers. + # Provided strictly for compabitility and can be removed in Rails 5. + def sanitizer_vendor + Rails::Html::Sanitizer + end + + def sanitized_allowed_tags + sanitizer_vendor.white_list_sanitizer.allowed_tags + end + + def sanitized_allowed_attributes + sanitizer_vendor.white_list_sanitizer.allowed_attributes + end + + # Gets the Rails::Html::FullSanitizer instance used by +strip_tags+. Replace with + # any object that responds to +sanitize+. + # + # class Application < Rails::Application + # config.action_view.full_sanitizer = MySpecialSanitizer.new + # end + # + def full_sanitizer + @full_sanitizer ||= sanitizer_vendor.full_sanitizer.new + end + + # Gets the Rails::Html::LinkSanitizer instance used by +strip_links+. + # Replace with any object that responds to +sanitize+. + # + # class Application < Rails::Application + # config.action_view.link_sanitizer = MySpecialSanitizer.new + # end + # + def link_sanitizer + @link_sanitizer ||= sanitizer_vendor.link_sanitizer.new + end + + # Gets the Rails::Html::WhiteListSanitizer instance used by sanitize and +sanitize_css+. + # Replace with any object that responds to +sanitize+. + # + # class Application < Rails::Application + # config.action_view.white_list_sanitizer = MySpecialSanitizer.new + # end + # + def white_list_sanitizer + @white_list_sanitizer ||= sanitizer_vendor.white_list_sanitizer.new + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tag_helper.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tag_helper.rb new file mode 100644 index 0000000..b203857 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tag_helper.rb @@ -0,0 +1,188 @@ +require 'active_support/core_ext/string/output_safety' +require 'set' + +module ActionView + # = Action View Tag Helpers + module Helpers #:nodoc: + # Provides methods to generate HTML tags programmatically when you can't use + # a Builder. By default, they output XHTML compliant tags. + module TagHelper + extend ActiveSupport::Concern + include CaptureHelper + include OutputSafetyHelper + + BOOLEAN_ATTRIBUTES = %w(disabled readonly multiple checked autobuffer + autoplay controls loop selected hidden scoped async + defer reversed ismap seamless muted required + autofocus novalidate formnovalidate open pubdate + itemscope allowfullscreen default inert sortable + truespeed typemustmatch).to_set + + BOOLEAN_ATTRIBUTES.merge(BOOLEAN_ATTRIBUTES.map {|attribute| attribute.to_sym }) + + TAG_PREFIXES = ['aria', 'data', :aria, :data].to_set + + PRE_CONTENT_STRINGS = { + :textarea => "\n" + } + + # Returns an empty HTML tag of type +name+ which by default is XHTML + # compliant. Set +open+ to true to create an open tag compatible + # with HTML 4.0 and below. Add HTML attributes by passing an attributes + # hash to +options+. Set +escape+ to false to disable attribute value + # escaping. + # + # ==== Options + # You can use symbols or strings for the attribute names. + # + # Use +true+ with boolean attributes that can render with no value, like + # +disabled+ and +readonly+. + # + # HTML5 data-* attributes can be set with a single +data+ key + # pointing to a hash of sub-attributes. + # + # To play nicely with JavaScript conventions sub-attributes are dasherized. + # For example, a key +user_id+ would render as data-user-id and + # thus accessed as dataset.userId. + # + # Values are encoded to JSON, with the exception of strings, symbols and + # BigDecimals. + # This may come in handy when using jQuery's HTML5-aware .data() + # from 1.4.3. + # + # ==== Examples + # tag("br") + # # =>
    + # + # tag("br", nil, true) + # # =>
    + # + # tag("input", type: 'text', disabled: true) + # # => + # + # tag("input", type: 'text', class: ["strong", "highlight"]) + # # => + # + # tag("img", src: "open & shut.png") + # # => + # + # tag("img", {src: "open & shut.png"}, false, false) + # # => + # + # tag("div", data: {name: 'Stephen', city_state: %w(Chicago IL)}) + # # =>
    + def tag(name, options = nil, open = false, escape = true) + "<#{name}#{tag_options(options, escape) if options}#{open ? ">" : " />"}".html_safe + end + + # Returns an HTML block tag of type +name+ surrounding the +content+. Add + # HTML attributes by passing an attributes hash to +options+. + # Instead of passing the content as an argument, you can also use a block + # in which case, you pass your +options+ as the second parameter. + # Set escape to false to disable attribute value escaping. + # + # ==== Options + # The +options+ hash can be used with attributes with no value like (disabled and + # readonly), which you can give a value of true in the +options+ hash. You can use + # symbols or strings for the attribute names. + # + # ==== Examples + # content_tag(:p, "Hello world!") + # # =>

    Hello world!

    + # content_tag(:div, content_tag(:p, "Hello world!"), class: "strong") + # # =>

    Hello world!

    + # content_tag(:div, "Hello world!", class: ["strong", "highlight"]) + # # =>
    Hello world!
    + # content_tag("select", options, multiple: true) + # # => + # + # <%= content_tag :div, class: "strong" do -%> + # Hello world! + # <% end -%> + # # =>
    Hello world!
    + def content_tag(name, content_or_options_with_block = nil, options = nil, escape = true, &block) + if block_given? + options = content_or_options_with_block if content_or_options_with_block.is_a?(Hash) + content_tag_string(name, capture(&block), options, escape) + else + content_tag_string(name, content_or_options_with_block, options, escape) + end + end + + # Returns a CDATA section with the given +content+. CDATA sections + # are used to escape blocks of text containing characters which would + # otherwise be recognized as markup. CDATA sections begin with the string + # and end with (and may not contain) the string ]]>. + # + # cdata_section("") + # # => ]]> + # + # cdata_section(File.read("hello_world.txt")) + # # => + # + # cdata_section("hello]]>world") + # # => world]]> + def cdata_section(content) + splitted = content.to_s.gsub(/\]\]\>/, ']]]]>') + "".html_safe + end + + # Returns an escaped version of +html+ without affecting existing escaped entities. + # + # escape_once("1 < 2 & 3") + # # => "1 < 2 & 3" + # + # escape_once("<< Accept & Checkout") + # # => "<< Accept & Checkout" + def escape_once(html) + ERB::Util.html_escape_once(html) + end + + private + + def content_tag_string(name, content, options, escape = true) + tag_options = tag_options(options, escape) if options + content = ERB::Util.unwrapped_html_escape(content) if escape + "<#{name}#{tag_options}>#{PRE_CONTENT_STRINGS[name.to_sym]}#{content}".html_safe + end + + def tag_options(options, escape = true) + return if options.blank? + attrs = [] + options.each_pair do |key, value| + if TAG_PREFIXES.include?(key) && value.is_a?(Hash) + value.each_pair do |k, v| + attrs << prefix_tag_option(key, k, v, escape) + end + elsif BOOLEAN_ATTRIBUTES.include?(key) + attrs << boolean_tag_option(key) if value + elsif !value.nil? + attrs << tag_option(key, value, escape) + end + end + " #{attrs * ' '}" unless attrs.empty? + end + + def prefix_tag_option(prefix, key, value, escape) + key = "#{prefix}-#{key.to_s.dasherize}" + unless value.is_a?(String) || value.is_a?(Symbol) || value.is_a?(BigDecimal) + value = value.to_json + end + tag_option(key, value, escape) + end + + def boolean_tag_option(key) + %(#{key}="#{key}") + end + + def tag_option(key, value, escape) + if value.is_a?(Array) + value = escape ? safe_join(value, " ") : value.join(" ") + else + value = escape ? ERB::Util.unwrapped_html_escape(value) : value + end + %(#{key}="#{value}") + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags.rb new file mode 100644 index 0000000..a4f6eb0 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags.rb @@ -0,0 +1,42 @@ +module ActionView + module Helpers + module Tags #:nodoc: + extend ActiveSupport::Autoload + + eager_autoload do + autoload :Base + autoload :Translator + autoload :CheckBox + autoload :CollectionCheckBoxes + autoload :CollectionRadioButtons + autoload :CollectionSelect + autoload :ColorField + autoload :DateField + autoload :DateSelect + autoload :DatetimeField + autoload :DatetimeLocalField + autoload :DatetimeSelect + autoload :EmailField + autoload :FileField + autoload :GroupedCollectionSelect + autoload :HiddenField + autoload :Label + autoload :MonthField + autoload :NumberField + autoload :PasswordField + autoload :RadioButton + autoload :RangeField + autoload :SearchField + autoload :Select + autoload :TelField + autoload :TextArea + autoload :TextField + autoload :TimeField + autoload :TimeSelect + autoload :TimeZoneSelect + autoload :UrlField + autoload :WeekField + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/base.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/base.rb new file mode 100644 index 0000000..7740c60 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/base.rb @@ -0,0 +1,155 @@ +module ActionView + module Helpers + module Tags # :nodoc: + class Base # :nodoc: + include Helpers::ActiveModelInstanceTag, Helpers::TagHelper, Helpers::FormTagHelper + include FormOptionsHelper + + attr_reader :object + + def initialize(object_name, method_name, template_object, options = {}) + @object_name, @method_name = object_name.to_s.dup, method_name.to_s.dup + @template_object = template_object + + @object_name.sub!(/\[\]$/,"") || @object_name.sub!(/\[\]\]$/,"]") + @object = retrieve_object(options.delete(:object)) + @options = options + @auto_index = retrieve_autoindex(Regexp.last_match.pre_match) if Regexp.last_match + end + + # This is what child classes implement. + def render + raise NotImplementedError, "Subclasses must implement a render method" + end + + private + + def value(object) + object.public_send @method_name if object + end + + def value_before_type_cast(object) + unless object.nil? + method_before_type_cast = @method_name + "_before_type_cast" + + if value_came_from_user?(object) && object.respond_to?(method_before_type_cast) + object.public_send(method_before_type_cast) + else + value(object) + end + end + end + + def value_came_from_user?(object) + method_name = "#{@method_name}_came_from_user?" + !object.respond_to?(method_name) || object.public_send(method_name) + end + + def retrieve_object(object) + if object + object + elsif @template_object.instance_variable_defined?("@#{@object_name}") + @template_object.instance_variable_get("@#{@object_name}") + end + rescue NameError + # As @object_name may contain the nested syntax (item[subobject]) we need to fallback to nil. + nil + end + + def retrieve_autoindex(pre_match) + object = self.object || @template_object.instance_variable_get("@#{pre_match}") + if object && object.respond_to?(:to_param) + object.to_param + else + raise ArgumentError, "object[] naming but object param and @object var don't exist or don't respond to to_param: #{object.inspect}" + end + end + + def add_default_name_and_id_for_value(tag_value, options) + if tag_value.nil? + add_default_name_and_id(options) + else + specified_id = options["id"] + add_default_name_and_id(options) + + if specified_id.blank? && options["id"].present? + options["id"] += "_#{sanitized_value(tag_value)}" + end + end + end + + def add_default_name_and_id(options) + if options.has_key?("index") + options["name"] ||= options.fetch("name"){ tag_name_with_index(options["index"], options["multiple"]) } + options["id"] = options.fetch("id"){ tag_id_with_index(options["index"]) } + options.delete("index") + elsif defined?(@auto_index) + options["name"] ||= options.fetch("name"){ tag_name_with_index(@auto_index, options["multiple"]) } + options["id"] = options.fetch("id"){ tag_id_with_index(@auto_index) } + else + options["name"] ||= options.fetch("name"){ tag_name(options["multiple"]) } + options["id"] = options.fetch("id"){ tag_id } + end + + options["id"] = [options.delete('namespace'), options["id"]].compact.join("_").presence + end + + def tag_name(multiple = false) + "#{@object_name}[#{sanitized_method_name}]#{"[]" if multiple}" + end + + def tag_name_with_index(index, multiple = false) + "#{@object_name}[#{index}][#{sanitized_method_name}]#{"[]" if multiple}" + end + + def tag_id + "#{sanitized_object_name}_#{sanitized_method_name}" + end + + def tag_id_with_index(index) + "#{sanitized_object_name}_#{index}_#{sanitized_method_name}" + end + + def sanitized_object_name + @sanitized_object_name ||= @object_name.gsub(/\]\[|[^-a-zA-Z0-9:.]/, "_").sub(/_$/, "") + end + + def sanitized_method_name + @sanitized_method_name ||= @method_name.sub(/\?$/,"") + end + + def sanitized_value(value) + value.to_s.gsub(/\s/, "_").gsub(/[^-\w]/, "").downcase + end + + def select_content_tag(option_tags, options, html_options) + html_options = html_options.stringify_keys + add_default_name_and_id(html_options) + options[:include_blank] ||= true unless options[:prompt] || select_not_required?(html_options) + value = options.fetch(:selected) { value(object) } + select = content_tag("select", add_options(option_tags, options, value), html_options) + + if html_options["multiple"] && options.fetch(:include_hidden, true) + tag("input", :disabled => html_options["disabled"], :name => html_options["name"], :type => "hidden", :value => "") + select + else + select + end + end + + def select_not_required?(html_options) + !html_options["required"] || html_options["multiple"] || html_options["size"].to_i > 1 + end + + def add_options(option_tags, options, value = nil) + if options[:include_blank] + option_tags = content_tag_string('option', options[:include_blank].kind_of?(String) ? options[:include_blank] : nil, :value => '') + "\n" + option_tags + end + if value.blank? && options[:prompt] + option_tags = content_tag_string('option', prompt_text(options[:prompt]), :value => '') + "\n" + option_tags + end + option_tags + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/check_box.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/check_box.rb new file mode 100644 index 0000000..6d51f26 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/check_box.rb @@ -0,0 +1,64 @@ +require 'action_view/helpers/tags/checkable' + +module ActionView + module Helpers + module Tags # :nodoc: + class CheckBox < Base #:nodoc: + include Checkable + + def initialize(object_name, method_name, template_object, checked_value, unchecked_value, options) + @checked_value = checked_value + @unchecked_value = unchecked_value + super(object_name, method_name, template_object, options) + end + + def render + options = @options.stringify_keys + options["type"] = "checkbox" + options["value"] = @checked_value + options["checked"] = "checked" if input_checked?(object, options) + + if options["multiple"] + add_default_name_and_id_for_value(@checked_value, options) + options.delete("multiple") + else + add_default_name_and_id(options) + end + + include_hidden = options.delete("include_hidden") { true } + checkbox = tag("input", options) + + if include_hidden + hidden = hidden_field_for_checkbox(options) + hidden + checkbox + else + checkbox + end + end + + private + + def checked?(value) + case value + when TrueClass, FalseClass + value == !!@checked_value + when NilClass + false + when String + value == @checked_value + else + if value.respond_to?(:include?) + value.include?(@checked_value) + else + value.to_i == @checked_value.to_i + end + end + end + + def hidden_field_for_checkbox(options) + @unchecked_value ? tag("input", options.slice("name", "disabled", "form").merge!("type" => "hidden", "value" => @unchecked_value)) : "".html_safe + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/checkable.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/checkable.rb new file mode 100644 index 0000000..052e9df --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/checkable.rb @@ -0,0 +1,16 @@ +module ActionView + module Helpers + module Tags # :nodoc: + module Checkable # :nodoc: + def input_checked?(object, options) + if options.has_key?("checked") + checked = options.delete "checked" + checked == true || checked == "checked" + else + checked?(value(object)) + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/collection_check_boxes.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/collection_check_boxes.rb new file mode 100644 index 0000000..6242a2a --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/collection_check_boxes.rb @@ -0,0 +1,57 @@ +require 'action_view/helpers/tags/collection_helpers' + +module ActionView + module Helpers + module Tags # :nodoc: + class CollectionCheckBoxes < Base # :nodoc: + include CollectionHelpers + + class CheckBoxBuilder < Builder # :nodoc: + def check_box(extra_html_options={}) + html_options = extra_html_options.merge(@input_html_options) + @template_object.check_box(@object_name, @method_name, html_options, @value, nil) + end + end + + def render(&block) + rendered_collection = render_collection do |item, value, text, default_html_options| + default_html_options[:multiple] = true + builder = instantiate_builder(CheckBoxBuilder, item, value, text, default_html_options) + + if block_given? + @template_object.capture(builder, &block) + else + render_component(builder) + end + end + + # Append a hidden field to make sure something will be sent back to the + # server if all check boxes are unchecked. + if @options.fetch(:include_hidden, true) + rendered_collection + hidden_field + else + rendered_collection + end + end + + private + + def render_component(builder) + builder.check_box + builder.label + end + + def hidden_field + hidden_name = @html_options[:name] + + hidden_name ||= if @options.has_key?(:index) + "#{tag_name_with_index(@options[:index])}[]" + else + "#{tag_name}[]" + end + + @template_object.hidden_field_tag(hidden_name, "", id: nil) + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/collection_helpers.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/collection_helpers.rb new file mode 100644 index 0000000..8050638 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/collection_helpers.rb @@ -0,0 +1,85 @@ +module ActionView + module Helpers + module Tags # :nodoc: + module CollectionHelpers # :nodoc: + class Builder # :nodoc: + attr_reader :object, :text, :value + + def initialize(template_object, object_name, method_name, object, + sanitized_attribute_name, text, value, input_html_options) + @template_object = template_object + @object_name = object_name + @method_name = method_name + @object = object + @sanitized_attribute_name = sanitized_attribute_name + @text = text + @value = value + @input_html_options = input_html_options + end + + def label(label_html_options={}, &block) + html_options = @input_html_options.slice(:index, :namespace).merge(label_html_options) + @template_object.label(@object_name, @sanitized_attribute_name, @text, html_options, &block) + end + end + + def initialize(object_name, method_name, template_object, collection, value_method, text_method, options, html_options) + @collection = collection + @value_method = value_method + @text_method = text_method + @html_options = html_options + + super(object_name, method_name, template_object, options) + end + + private + + def instantiate_builder(builder_class, item, value, text, html_options) + builder_class.new(@template_object, @object_name, @method_name, item, + sanitize_attribute_name(value), text, value, html_options) + end + + # Generate default options for collection helpers, such as :checked and + # :disabled. + def default_html_options_for_collection(item, value) #:nodoc: + html_options = @html_options.dup + + [:checked, :selected, :disabled, :readonly].each do |option| + current_value = @options[option] + next if current_value.nil? + + accept = if current_value.respond_to?(:call) + current_value.call(item) + else + Array(current_value).map(&:to_s).include?(value.to_s) + end + + if accept + html_options[option] = true + elsif option == :checked + html_options[option] = false + end + end + + html_options[:object] = @object + html_options + end + + def sanitize_attribute_name(value) #:nodoc: + "#{sanitized_method_name}_#{sanitized_value(value)}" + end + + def render_collection #:nodoc: + @collection.map do |item| + value = value_for_collection(item, @value_method) + text = value_for_collection(item, @text_method) + default_html_options = default_html_options_for_collection(item, value) + additional_html_options = option_html_attributes(item) + + yield item, value, text, default_html_options.merge(additional_html_options) + end.join.html_safe + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/collection_radio_buttons.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/collection_radio_buttons.rb new file mode 100644 index 0000000..20be34c --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/collection_radio_buttons.rb @@ -0,0 +1,36 @@ +require 'action_view/helpers/tags/collection_helpers' + +module ActionView + module Helpers + module Tags # :nodoc: + class CollectionRadioButtons < Base # :nodoc: + include CollectionHelpers + + class RadioButtonBuilder < Builder # :nodoc: + def radio_button(extra_html_options={}) + html_options = extra_html_options.merge(@input_html_options) + @template_object.radio_button(@object_name, @method_name, @value, html_options) + end + end + + def render(&block) + render_collection do |item, value, text, default_html_options| + builder = instantiate_builder(RadioButtonBuilder, item, value, text, default_html_options) + + if block_given? + @template_object.capture(builder, &block) + else + render_component(builder) + end + end + end + + private + + def render_component(builder) + builder.radio_button + builder.label + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/collection_select.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/collection_select.rb new file mode 100644 index 0000000..6cb2b2e --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/collection_select.rb @@ -0,0 +1,28 @@ +module ActionView + module Helpers + module Tags # :nodoc: + class CollectionSelect < Base #:nodoc: + def initialize(object_name, method_name, template_object, collection, value_method, text_method, options, html_options) + @collection = collection + @value_method = value_method + @text_method = text_method + @html_options = html_options + + super(object_name, method_name, template_object, options) + end + + def render + option_tags_options = { + :selected => @options.fetch(:selected) { value(@object) }, + :disabled => @options[:disabled] + } + + select_content_tag( + options_from_collection_for_select(@collection, @value_method, @text_method, option_tags_options), + @options, @html_options + ) + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/color_field.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/color_field.rb new file mode 100644 index 0000000..b4bbe92 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/color_field.rb @@ -0,0 +1,25 @@ +module ActionView + module Helpers + module Tags # :nodoc: + class ColorField < TextField # :nodoc: + def render + options = @options.stringify_keys + options["value"] ||= validate_color_string(value(object)) + @options = options + super + end + + private + + def validate_color_string(string) + regex = /#[0-9a-fA-F]{6}/ + if regex.match(string) + string.downcase + else + "#000000" + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/date_field.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/date_field.rb new file mode 100644 index 0000000..c22be0d --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/date_field.rb @@ -0,0 +1,13 @@ +module ActionView + module Helpers + module Tags # :nodoc: + class DateField < DatetimeField # :nodoc: + private + + def format_date(value) + value.try(:strftime, "%Y-%m-%d") + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/date_select.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/date_select.rb new file mode 100644 index 0000000..0c4ac40 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/date_select.rb @@ -0,0 +1,72 @@ +require 'active_support/core_ext/time/calculations' + +module ActionView + module Helpers + module Tags # :nodoc: + class DateSelect < Base # :nodoc: + def initialize(object_name, method_name, template_object, options, html_options) + @html_options = html_options + + super(object_name, method_name, template_object, options) + end + + def render + error_wrapping(datetime_selector(@options, @html_options).send("select_#{select_type}").html_safe) + end + + class << self + def select_type + @select_type ||= self.name.split("::").last.sub("Select", "").downcase + end + end + + private + + def select_type + self.class.select_type + end + + def datetime_selector(options, html_options) + datetime = options.fetch(:selected) { value(object) || default_datetime(options) } + @auto_index ||= nil + + options = options.dup + options[:field_name] = @method_name + options[:include_position] = true + options[:prefix] ||= @object_name + options[:index] = @auto_index if @auto_index && !options.has_key?(:index) + + DateTimeSelector.new(datetime, options, html_options) + end + + def default_datetime(options) + return if options[:include_blank] || options[:prompt] + + case options[:default] + when nil + Time.current + when Date, Time + options[:default] + else + default = options[:default].dup + + # Rename :minute and :second to :min and :sec + default[:min] ||= default[:minute] + default[:sec] ||= default[:second] + + time = Time.current + + [:year, :month, :day, :hour, :min, :sec].each do |key| + default[key] ||= time.send(key) + end + + Time.utc( + default[:year], default[:month], default[:day], + default[:hour], default[:min], default[:sec] + ) + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/datetime_field.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/datetime_field.rb new file mode 100644 index 0000000..b2cee9d --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/datetime_field.rb @@ -0,0 +1,30 @@ +module ActionView + module Helpers + module Tags # :nodoc: + class DatetimeField < TextField # :nodoc: + def render + options = @options.stringify_keys + options["value"] ||= format_date(value(object)) + options["min"] = format_date(datetime_value(options["min"])) + options["max"] = format_date(datetime_value(options["max"])) + @options = options + super + end + + private + + def format_date(value) + value.try(:strftime, "%Y-%m-%dT%T.%L%z") + end + + def datetime_value(value) + if value.is_a? String + DateTime.parse(value) rescue nil + else + value + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/datetime_local_field.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/datetime_local_field.rb new file mode 100644 index 0000000..b4a7418 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/datetime_local_field.rb @@ -0,0 +1,19 @@ +module ActionView + module Helpers + module Tags # :nodoc: + class DatetimeLocalField < DatetimeField # :nodoc: + class << self + def field_type + @field_type ||= "datetime-local" + end + end + + private + + def format_date(value) + value.try(:strftime, "%Y-%m-%dT%T") + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/datetime_select.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/datetime_select.rb new file mode 100644 index 0000000..563de18 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/datetime_select.rb @@ -0,0 +1,8 @@ +module ActionView + module Helpers + module Tags # :nodoc: + class DatetimeSelect < DateSelect # :nodoc: + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/email_field.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/email_field.rb new file mode 100644 index 0000000..7ce3ccb --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/email_field.rb @@ -0,0 +1,8 @@ +module ActionView + module Helpers + module Tags # :nodoc: + class EmailField < TextField # :nodoc: + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/file_field.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/file_field.rb new file mode 100644 index 0000000..476b820 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/file_field.rb @@ -0,0 +1,8 @@ +module ActionView + module Helpers + module Tags # :nodoc: + class FileField < TextField # :nodoc: + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/grouped_collection_select.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/grouped_collection_select.rb new file mode 100644 index 0000000..2ed4712 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/grouped_collection_select.rb @@ -0,0 +1,29 @@ +module ActionView + module Helpers + module Tags # :nodoc: + class GroupedCollectionSelect < Base # :nodoc: + def initialize(object_name, method_name, template_object, collection, group_method, group_label_method, option_key_method, option_value_method, options, html_options) + @collection = collection + @group_method = group_method + @group_label_method = group_label_method + @option_key_method = option_key_method + @option_value_method = option_value_method + @html_options = html_options + + super(object_name, method_name, template_object, options) + end + + def render + option_tags_options = { + :selected => @options.fetch(:selected) { value(@object) }, + :disabled => @options[:disabled] + } + + select_content_tag( + option_groups_from_collection_for_select(@collection, @group_method, @group_label_method, @option_key_method, @option_value_method, option_tags_options), @options, @html_options + ) + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/hidden_field.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/hidden_field.rb new file mode 100644 index 0000000..c3757c2 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/hidden_field.rb @@ -0,0 +1,8 @@ +module ActionView + module Helpers + module Tags # :nodoc: + class HiddenField < TextField # :nodoc: + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/label.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/label.rb new file mode 100644 index 0000000..6476534 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/label.rb @@ -0,0 +1,79 @@ +module ActionView + module Helpers + module Tags # :nodoc: + class Label < Base # :nodoc: + class LabelBuilder # :nodoc: + attr_reader :object + + def initialize(template_object, object_name, method_name, object, tag_value) + @template_object = template_object + @object_name = object_name + @method_name = method_name + @object = object + @tag_value = tag_value + end + + def translation + method_and_value = @tag_value.present? ? "#{@method_name}.#{@tag_value}" : @method_name + + content ||= Translator + .new(object, @object_name, method_and_value, "helpers.label") + .translate + content ||= @method_name.humanize + + content + end + end + + def initialize(object_name, method_name, template_object, content_or_options = nil, options = nil) + options ||= {} + + content_is_options = content_or_options.is_a?(Hash) + if content_is_options + options.merge! content_or_options + @content = nil + else + @content = content_or_options + end + + super(object_name, method_name, template_object, options) + end + + def render(&block) + options = @options.stringify_keys + tag_value = options.delete("value") + name_and_id = options.dup + + if name_and_id["for"] + name_and_id["id"] = name_and_id["for"] + else + name_and_id.delete("id") + end + + add_default_name_and_id_for_value(tag_value, name_and_id) + options.delete("index") + options.delete("namespace") + options["for"] = name_and_id["id"] unless options.key?("for") + + builder = LabelBuilder.new(@template_object, @object_name, @method_name, @object, tag_value) + + content = if block_given? + @template_object.capture(builder, &block) + elsif @content.present? + @content.to_s + else + render_component(builder) + end + + label_tag(name_and_id["id"], content, options) + end + + private + + def render_component(builder) + builder.translation + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/month_field.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/month_field.rb new file mode 100644 index 0000000..4c0fb84 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/month_field.rb @@ -0,0 +1,13 @@ +module ActionView + module Helpers + module Tags # :nodoc: + class MonthField < DatetimeField # :nodoc: + private + + def format_date(value) + value.try(:strftime, "%Y-%m") + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/number_field.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/number_field.rb new file mode 100644 index 0000000..4f95b1b --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/number_field.rb @@ -0,0 +1,18 @@ +module ActionView + module Helpers + module Tags # :nodoc: + class NumberField < TextField # :nodoc: + def render + options = @options.stringify_keys + + if range = options.delete("in") || options.delete("within") + options.update("min" => range.min, "max" => range.max) + end + + @options = options + super + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/password_field.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/password_field.rb new file mode 100644 index 0000000..6099fa6 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/password_field.rb @@ -0,0 +1,12 @@ +module ActionView + module Helpers + module Tags # :nodoc: + class PasswordField < TextField # :nodoc: + def render + @options = {:value => nil}.merge!(@options) + super + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/placeholderable.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/placeholderable.rb new file mode 100644 index 0000000..04684fe --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/placeholderable.rb @@ -0,0 +1,22 @@ +module ActionView + module Helpers + module Tags # :nodoc: + module Placeholderable # :nodoc: + def initialize(*) + super + + if tag_value = @options[:placeholder] + placeholder = tag_value if tag_value.is_a?(String) + method_and_value = tag_value.is_a?(TrueClass) ? @method_name : "#{@method_name}.#{tag_value}" + + placeholder ||= Tags::Translator + .new(object, @object_name, method_and_value, "helpers.placeholder") + .translate + placeholder ||= @method_name.humanize + @options[:placeholder] = placeholder + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/radio_button.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/radio_button.rb new file mode 100644 index 0000000..4849c53 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/radio_button.rb @@ -0,0 +1,31 @@ +require 'action_view/helpers/tags/checkable' + +module ActionView + module Helpers + module Tags # :nodoc: + class RadioButton < Base # :nodoc: + include Checkable + + def initialize(object_name, method_name, template_object, tag_value, options) + @tag_value = tag_value + super(object_name, method_name, template_object, options) + end + + def render + options = @options.stringify_keys + options["type"] = "radio" + options["value"] = @tag_value + options["checked"] = "checked" if input_checked?(object, options) + add_default_name_and_id_for_value(@tag_value, options) + tag("input", options) + end + + private + + def checked?(value) + value.to_s == @tag_value.to_s + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/range_field.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/range_field.rb new file mode 100644 index 0000000..f98ae88 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/range_field.rb @@ -0,0 +1,8 @@ +module ActionView + module Helpers + module Tags # :nodoc: + class RangeField < NumberField # :nodoc: + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/search_field.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/search_field.rb new file mode 100644 index 0000000..4597cec --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/search_field.rb @@ -0,0 +1,22 @@ +module ActionView + module Helpers + module Tags # :nodoc: + class SearchField < TextField # :nodoc: + def render + super do |options| + if options["autosave"] + if options["autosave"] == true + options["autosave"] = request.host.split(".").reverse.join(".") + end + options["results"] ||= 10 + end + + if options["onsearch"] + options["incremental"] = true unless options.has_key?("incremental") + end + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/select.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/select.rb new file mode 100644 index 0000000..180900c --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/select.rb @@ -0,0 +1,41 @@ +module ActionView + module Helpers + module Tags # :nodoc: + class Select < Base # :nodoc: + def initialize(object_name, method_name, template_object, choices, options, html_options) + @choices = block_given? ? template_object.capture { yield || "" } : choices + @choices = @choices.to_a if @choices.is_a?(Range) + + @html_options = html_options + + super(object_name, method_name, template_object, options) + end + + def render + option_tags_options = { + :selected => @options.fetch(:selected) { value(@object) }, + :disabled => @options[:disabled] + } + + option_tags = if grouped_choices? + grouped_options_for_select(@choices, option_tags_options) + else + options_for_select(@choices, option_tags_options) + end + + select_content_tag(option_tags, @options, @html_options) + end + + private + + # Grouped choices look like this: + # + # [nil, []] + # { nil => [] } + def grouped_choices? + !@choices.empty? && @choices.first.respond_to?(:last) && Array === @choices.first.last + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/tel_field.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/tel_field.rb new file mode 100644 index 0000000..987bb9e --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/tel_field.rb @@ -0,0 +1,8 @@ +module ActionView + module Helpers + module Tags # :nodoc: + class TelField < TextField # :nodoc: + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/text_area.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/text_area.rb new file mode 100644 index 0000000..69038c1 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/text_area.rb @@ -0,0 +1,22 @@ +require 'action_view/helpers/tags/placeholderable' + +module ActionView + module Helpers + module Tags # :nodoc: + class TextArea < Base # :nodoc: + include Placeholderable + + def render + options = @options.stringify_keys + add_default_name_and_id(options) + + if size = options.delete("size") + options["cols"], options["rows"] = size.split("x") if size.respond_to?(:split) + end + + content_tag("textarea", options.delete("value") { value_before_type_cast(object) }, options) + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/text_field.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/text_field.rb new file mode 100644 index 0000000..49fc81e --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/text_field.rb @@ -0,0 +1,33 @@ +require 'action_view/helpers/tags/placeholderable' + +module ActionView + module Helpers + module Tags # :nodoc: + class TextField < Base # :nodoc: + include Placeholderable + + def render + options = @options.stringify_keys + options["size"] = options["maxlength"] unless options.key?("size") + options["type"] ||= field_type + options["value"] = options.fetch("value") { value_before_type_cast(object) } unless field_type == "file" + yield options if block_given? + add_default_name_and_id(options) + tag("input", options) + end + + class << self + def field_type + @field_type ||= self.name.split("::").last.sub("Field", "").downcase + end + end + + private + + def field_type + self.class.field_type + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/time_field.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/time_field.rb new file mode 100644 index 0000000..0e90a3a --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/time_field.rb @@ -0,0 +1,13 @@ +module ActionView + module Helpers + module Tags # :nodoc: + class TimeField < DatetimeField # :nodoc: + private + + def format_date(value) + value.try(:strftime, "%T.%L") + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/time_select.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/time_select.rb new file mode 100644 index 0000000..0b06311 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/time_select.rb @@ -0,0 +1,8 @@ +module ActionView + module Helpers + module Tags # :nodoc: + class TimeSelect < DateSelect # :nodoc: + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/time_zone_select.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/time_zone_select.rb new file mode 100644 index 0000000..80d165e --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/time_zone_select.rb @@ -0,0 +1,20 @@ +module ActionView + module Helpers + module Tags # :nodoc: + class TimeZoneSelect < Base # :nodoc: + def initialize(object_name, method_name, template_object, priority_zones, options, html_options) + @priority_zones = priority_zones + @html_options = html_options + + super(object_name, method_name, template_object, options) + end + + def render + select_content_tag( + time_zone_options_for_select(value(@object) || @options[:default], @priority_zones, @options[:model] || ActiveSupport::TimeZone), @options, @html_options + ) + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/translator.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/translator.rb new file mode 100644 index 0000000..1af4c73 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/translator.rb @@ -0,0 +1,40 @@ +module ActionView + module Helpers + module Tags # :nodoc: + class Translator # :nodoc: + def initialize(object, object_name, method_and_value, scope) + @object_name = object_name.gsub(/\[(.*)_attributes\]\[\d+\]/, '.\1') + @method_and_value = method_and_value + @scope = scope + @model = object.respond_to?(:to_model) ? object.to_model : nil + end + + def translate + translated_attribute = I18n.t("#{object_name}.#{method_and_value}", default: i18n_default, scope: scope).presence + translated_attribute || human_attribute_name + end + + protected + + attr_reader :object_name, :method_and_value, :scope, :model + + private + + def i18n_default + if model + key = model.model_name.i18n_key + ["#{key}.#{method_and_value}".to_sym, ""] + else + "" + end + end + + def human_attribute_name + if model && model.class.respond_to?(:human_attribute_name) + model.class.human_attribute_name(method_and_value) + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/url_field.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/url_field.rb new file mode 100644 index 0000000..d763401 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/url_field.rb @@ -0,0 +1,8 @@ +module ActionView + module Helpers + module Tags # :nodoc: + class UrlField < TextField # :nodoc: + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/week_field.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/week_field.rb new file mode 100644 index 0000000..835d166 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/tags/week_field.rb @@ -0,0 +1,13 @@ +module ActionView + module Helpers + module Tags # :nodoc: + class WeekField < DatetimeField # :nodoc: + private + + def format_date(value) + value.try(:strftime, "%Y-W%V") + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/text_helper.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/text_helper.rb new file mode 100644 index 0000000..a9f1631 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/text_helper.rb @@ -0,0 +1,467 @@ +require 'active_support/core_ext/string/filters' +require 'active_support/core_ext/array/extract_options' + +module ActionView + # = Action View Text Helpers + module Helpers #:nodoc: + # The TextHelper module provides a set of methods for filtering, formatting + # and transforming strings, which can reduce the amount of inline Ruby code in + # your views. These helper methods extend Action View making them callable + # within your template files. + # + # ==== Sanitization + # + # Most text helpers by default sanitize the given content, but do not escape it. + # This means HTML tags will appear in the page but all malicious code will be removed. + # Let's look at some examples using the +simple_format+ method: + # + # simple_format('Example') + # # => "

    Example

    " + # + # simple_format('Example') + # # => "

    Example

    " + # + # If you want to escape all content, you should invoke the +h+ method before + # calling the text helper. + # + # simple_format h('Example') + # # => "

    <a href=\"http://example.com/\">Example</a>

    " + module TextHelper + extend ActiveSupport::Concern + + include SanitizeHelper + include TagHelper + include OutputSafetyHelper + + # The preferred method of outputting text in your views is to use the + # <%= "text" %> eRuby syntax. The regular _puts_ and _print_ methods + # do not operate as expected in an eRuby code block. If you absolutely must + # output text within a non-output code block (i.e., <% %>), you can use the concat method. + # + # <% + # concat "hello" + # # is the equivalent of <%= "hello" %> + # + # if logged_in + # concat "Logged in!" + # else + # concat link_to('login', action: :login) + # end + # # will either display "Logged in!" or a login link + # %> + def concat(string) + output_buffer << string + end + + def safe_concat(string) + output_buffer.respond_to?(:safe_concat) ? output_buffer.safe_concat(string) : concat(string) + end + + # Truncates a given +text+ after a given :length if +text+ is longer than :length + # (defaults to 30). The last characters will be replaced with the :omission (defaults to "...") + # for a total length not exceeding :length. + # + # Pass a :separator to truncate +text+ at a natural break. + # + # Pass a block if you want to show extra content when the text is truncated. + # + # The result is marked as HTML-safe, but it is escaped by default, unless :escape is + # +false+. Care should be taken if +text+ contains HTML tags or entities, because truncation + # may produce invalid HTML (such as unbalanced or incomplete tags). + # + # truncate("Once upon a time in a world far far away") + # # => "Once upon a time in a world..." + # + # truncate("Once upon a time in a world far far away", length: 17) + # # => "Once upon a ti..." + # + # truncate("Once upon a time in a world far far away", length: 17, separator: ' ') + # # => "Once upon a..." + # + # truncate("And they found that many people were sleeping better.", length: 25, omission: '... (continued)') + # # => "And they f... (continued)" + # + # truncate("

    Once upon a time in a world far far away

    ") + # # => "<p>Once upon a time in a wo..." + # + # truncate("

    Once upon a time in a world far far away

    ", escape: false) + # # => "

    Once upon a time in a wo..." + # + # truncate("Once upon a time in a world far far away") { link_to "Continue", "#" } + # # => "Once upon a time in a wo...Continue" + def truncate(text, options = {}, &block) + if text + length = options.fetch(:length, 30) + + content = text.truncate(length, options) + content = options[:escape] == false ? content.html_safe : ERB::Util.html_escape(content) + content << capture(&block) if block_given? && text.length > length + content + end + end + + # Highlights one or more +phrases+ everywhere in +text+ by inserting it into + # a :highlighter string. The highlighter can be specialized by passing :highlighter + # as a single-quoted string with \1 where the phrase is to be inserted (defaults to + # '\1') or passing a block that receives each matched term. + # + # highlight('You searched for: rails', 'rails') + # # => You searched for: rails + # + # highlight('You searched for: rails', /for|rails/) + # # => You searched for: rails + # + # highlight('You searched for: ruby, rails, dhh', 'actionpack') + # # => You searched for: ruby, rails, dhh + # + # highlight('You searched for: rails', ['for', 'rails'], highlighter: '\1') + # # => You searched for: rails + # + # highlight('You searched for: rails', 'rails', highlighter: '\1') + # # => You searched for: rails + # + # highlight('You searched for: rails', 'rails') { |match| link_to(search_path(q: match, match)) } + # # => You searched for: rails + def highlight(text, phrases, options = {}) + text = sanitize(text) if options.fetch(:sanitize, true) + + if text.blank? || phrases.blank? + text || "" + else + match = Array(phrases).map do |p| + Regexp === p ? p.to_s : Regexp.escape(p) + end.join('|') + + if block_given? + text.gsub(/(#{match})(?![^<]*?>)/i) { |found| yield found } + else + highlighter = options.fetch(:highlighter, '\1') + text.gsub(/(#{match})(?![^<]*?>)/i, highlighter) + end + end.html_safe + end + + # Extracts an excerpt from +text+ that matches the first instance of +phrase+. + # The :radius option expands the excerpt on each side of the first occurrence of +phrase+ by the number of characters + # defined in :radius (which defaults to 100). If the excerpt radius overflows the beginning or end of the +text+, + # then the :omission option (which defaults to "...") will be prepended/appended accordingly. Use the + # :separator option to choose the delimitation. The resulting string will be stripped in any case. If the +phrase+ + # isn't found, nil is returned. + # + # excerpt('This is an example', 'an', radius: 5) + # # => ...s is an exam... + # + # excerpt('This is an example', 'is', radius: 5) + # # => This is a... + # + # excerpt('This is an example', 'is') + # # => This is an example + # + # excerpt('This next thing is an example', 'ex', radius: 2) + # # => ...next... + # + # excerpt('This is also an example', 'an', radius: 8, omission: ' ') + # # => is also an example + # + # excerpt('This is a very beautiful morning', 'very', separator: ' ', radius: 1) + # # => ...a very beautiful... + def excerpt(text, phrase, options = {}) + return unless text && phrase + + separator = options.fetch(:separator, nil) || "" + case phrase + when Regexp + regex = phrase + else + regex = /#{Regexp.escape(phrase)}/i + end + + return unless matches = text.match(regex) + phrase = matches[0] + + unless separator.empty? + text.split(separator).each do |value| + if value.match(regex) + regex = phrase = value + break + end + end + end + + first_part, second_part = text.split(phrase, 2) + + prefix, first_part = cut_excerpt_part(:first, first_part, separator, options) + postfix, second_part = cut_excerpt_part(:second, second_part, separator, options) + + affix = [first_part, separator, phrase, separator, second_part].join.strip + [prefix, affix, postfix].join + end + + # Attempts to pluralize the +singular+ word unless +count+ is 1. If + # +plural+ is supplied, it will use that when count is > 1, otherwise + # it will use the Inflector to determine the plural form. + # + # pluralize(1, 'person') + # # => 1 person + # + # pluralize(2, 'person') + # # => 2 people + # + # pluralize(3, 'person', 'users') + # # => 3 users + # + # pluralize(0, 'person') + # # => 0 people + def pluralize(count, singular, plural = nil) + word = if (count == 1 || count =~ /^1(\.0+)?$/) + singular + else + plural || singular.pluralize + end + + "#{count || 0} #{word}" + end + + # Wraps the +text+ into lines no longer than +line_width+ width. This method + # breaks on the first whitespace character that does not exceed +line_width+ + # (which is 80 by default). + # + # word_wrap('Once upon a time') + # # => Once upon a time + # + # word_wrap('Once upon a time, in a kingdom called Far Far Away, a king fell ill, and finding a successor to the throne turned out to be more trouble than anyone could have imagined...') + # # => Once upon a time, in a kingdom called Far Far Away, a king fell ill, and finding\na successor to the throne turned out to be more trouble than anyone could have\nimagined... + # + # word_wrap('Once upon a time', line_width: 8) + # # => Once\nupon a\ntime + # + # word_wrap('Once upon a time', line_width: 1) + # # => Once\nupon\na\ntime + def word_wrap(text, options = {}) + line_width = options.fetch(:line_width, 80) + + text.split("\n").collect! do |line| + line.length > line_width ? line.gsub(/(.{1,#{line_width}})(\s+|$)/, "\\1\n").strip : line + end * "\n" + end + + # Returns +text+ transformed into HTML using simple formatting rules. + # Two or more consecutive newlines(\n\n) are considered as a + # paragraph and wrapped in

    tags. One newline (\n) is + # considered as a linebreak and a
    tag is appended. This + # method does not remove the newlines from the +text+. + # + # You can pass any HTML attributes into html_options. These + # will be added to all created paragraphs. + # + # ==== Options + # * :sanitize - If +false+, does not sanitize +text+. + # * :wrapper_tag - String representing the wrapper tag, defaults to "p" + # + # ==== Examples + # my_text = "Here is some basic text...\n...with a line break." + # + # simple_format(my_text) + # # => "

    Here is some basic text...\n
    ...with a line break.

    " + # + # simple_format(my_text, {}, wrapper_tag: "div") + # # => "
    Here is some basic text...\n
    ...with a line break.
    " + # + # more_text = "We want to put a paragraph...\n\n...right there." + # + # simple_format(more_text) + # # => "

    We want to put a paragraph...

    \n\n

    ...right there.

    " + # + # simple_format("Look ma! A class!", class: 'description') + # # => "

    Look ma! A class!

    " + # + # simple_format("Unblinkable.") + # # => "

    Unblinkable.

    " + # + # simple_format("Blinkable! It's true.", {}, sanitize: false) + # # => "

    Blinkable! It's true.

    " + def simple_format(text, html_options = {}, options = {}) + wrapper_tag = options.fetch(:wrapper_tag, :p) + + text = sanitize(text) if options.fetch(:sanitize, true) + paragraphs = split_paragraphs(text) + + if paragraphs.empty? + content_tag(wrapper_tag, nil, html_options) + else + paragraphs.map! { |paragraph| + content_tag(wrapper_tag, raw(paragraph), html_options) + }.join("\n\n").html_safe + end + end + + # Creates a Cycle object whose _to_s_ method cycles through elements of an + # array every time it is called. This can be used for example, to alternate + # classes for table rows. You can use named cycles to allow nesting in loops. + # Passing a Hash as the last parameter with a :name key will create a + # named cycle. The default name for a cycle without a +:name+ key is + # "default". You can manually reset a cycle by calling reset_cycle + # and passing the name of the cycle. The current cycle string can be obtained + # anytime using the current_cycle method. + # + # # Alternate CSS classes for even and odd numbers... + # @items = [1,2,3,4] + # + # <% @items.each do |item| %> + # "> + # + # + # <% end %> + #
    item
    + # + # + # # Cycle CSS classes for rows, and text colors for values within each row + # @items = x = [{first: 'Robert', middle: 'Daniel', last: 'James'}, + # {first: 'Emily', middle: 'Shannon', maiden: 'Pike', last: 'Hicks'}, + # {first: 'June', middle: 'Dae', last: 'Jones'}] + # <% @items.each do |item| %> + # "> + # + # <% item.values.each do |value| %> + # <%# Create a named cycle "colors" %> + # "> + # <%= value %> + # + # <% end %> + # <% reset_cycle("colors") %> + # + # + # <% end %> + def cycle(first_value, *values) + options = values.extract_options! + name = options.fetch(:name, 'default') + + values.unshift(*first_value) + + cycle = get_cycle(name) + unless cycle && cycle.values == values + cycle = set_cycle(name, Cycle.new(*values)) + end + cycle.to_s + end + + # Returns the current cycle string after a cycle has been started. Useful + # for complex table highlighting or any other design need which requires + # the current cycle string in more than one place. + # + # # Alternate background colors + # @items = [1,2,3,4] + # <% @items.each do |item| %> + #
    "> + # <%= item %> + #
    + # <% end %> + def current_cycle(name = "default") + cycle = get_cycle(name) + cycle.current_value if cycle + end + + # Resets a cycle so that it starts from the first element the next time + # it is called. Pass in +name+ to reset a named cycle. + # + # # Alternate CSS classes for even and odd numbers... + # @items = [[1,2,3,4], [5,6,3], [3,4,5,6,7,4]] + # + # <% @items.each do |item| %> + # "> + # <% item.each do |value| %> + # "> + # <%= value %> + # + # <% end %> + # + # <% reset_cycle("colors") %> + # + # <% end %> + #
    + def reset_cycle(name = "default") + cycle = get_cycle(name) + cycle.reset if cycle + end + + class Cycle #:nodoc: + attr_reader :values + + def initialize(first_value, *values) + @values = values.unshift(first_value) + reset + end + + def reset + @index = 0 + end + + def current_value + @values[previous_index].to_s + end + + def to_s + value = @values[@index].to_s + @index = next_index + return value + end + + private + + def next_index + step_index(1) + end + + def previous_index + step_index(-1) + end + + def step_index(n) + (@index + n) % @values.size + end + end + + private + # The cycle helpers need to store the cycles in a place that is + # guaranteed to be reset every time a page is rendered, so it + # uses an instance variable of ActionView::Base. + def get_cycle(name) + @_cycles = Hash.new unless defined?(@_cycles) + return @_cycles[name] + end + + def set_cycle(name, cycle_object) + @_cycles = Hash.new unless defined?(@_cycles) + @_cycles[name] = cycle_object + end + + def split_paragraphs(text) + return [] if text.blank? + + text.to_str.gsub(/\r\n?/, "\n").split(/\n\n+/).map! do |t| + t.gsub!(/([^\n]\n)(?=[^\n])/, '\1
    ') || t + end + end + + def cut_excerpt_part(part_position, part, separator, options) + return "", "" unless part + + radius = options.fetch(:radius, 100) + omission = options.fetch(:omission, "...") + + part = part.split(separator) + part.delete("") + affix = part.size > radius ? omission : "" + + part = if part_position == :first + drop_index = [part.length - radius, 0].max + part.drop(drop_index) + else + part.first(radius) + end + + return affix, part.join(separator) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/translation_helper.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/translation_helper.rb new file mode 100644 index 0000000..49b6649 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/translation_helper.rb @@ -0,0 +1,110 @@ +require 'action_view/helpers/tag_helper' +require 'active_support/core_ext/string/access' +require 'i18n/exceptions' + +module ActionView + # = Action View Translation Helpers + module Helpers + module TranslationHelper + include TagHelper + # Delegates to I18n#translate but also performs three additional functions. + # + # First, it will ensure that any thrown +MissingTranslation+ messages will be turned + # into inline spans that: + # + # * have a "translation-missing" class set, + # * contain the missing key as a title attribute and + # * a titleized version of the last key segment as a text. + # + # E.g. the value returned for a missing translation key :"blog.post.title" will be + # Title. + # This way your views will display rather reasonable strings but it will still + # be easy to spot missing translations. + # + # Second, it'll scope the key by the current partial if the key starts + # with a period. So if you call translate(".foo") from the + # people/index.html.erb template, you'll actually be calling + # I18n.translate("people.index.foo"). This makes it less repetitive + # to translate many keys within the same partials and gives you a simple framework + # for scoping them consistently. If you don't prepend the key with a period, + # nothing is converted. + # + # Third, it'll mark the translation as safe HTML if the key has the suffix + # "_html" or the last element of the key is the word "html". For example, + # calling translate("footer_html") or translate("footer.html") will return + # a safe HTML string that won't be escaped by other HTML helper methods. This + # naming convention helps to identify translations that include HTML tags so that + # you know what kind of output to expect when you call translate in a template. + def translate(key, options = {}) + options = options.dup + has_default = options.has_key?(:default) + remaining_defaults = Array(options.delete(:default)).compact + + if has_default && !remaining_defaults.first.kind_of?(Symbol) + options[:default] = remaining_defaults + end + + # If the user has explicitly decided to NOT raise errors, pass that option to I18n. + # Otherwise, tell I18n to raise an exception, which we rescue further in this method. + # Note: `raise_error` refers to us re-raising the error in this method. I18n is forced to raise by default. + if options[:raise] == false || (options.key?(:rescue_format) && options[:rescue_format].nil?) + raise_error = false + i18n_raise = false + else + raise_error = options[:raise] || options[:rescue_format] || ActionView::Base.raise_on_missing_translations + i18n_raise = true + end + + if html_safe_translation_key?(key) + html_safe_options = options.dup + options.except(*I18n::RESERVED_KEYS).each do |name, value| + unless name == :count && value.is_a?(Numeric) + html_safe_options[name] = ERB::Util.html_escape(value.to_s) + end + end + translation = I18n.translate(scope_key_by_partial(key), html_safe_options.merge(raise: i18n_raise)) + + translation.respond_to?(:html_safe) ? translation.html_safe : translation + else + I18n.translate(scope_key_by_partial(key), options.merge(raise: i18n_raise)) + end + rescue I18n::MissingTranslationData => e + if remaining_defaults.present? + translate remaining_defaults.shift, options.merge(default: remaining_defaults) + else + raise e if raise_error + + keys = I18n.normalize_keys(e.locale, e.key, e.options[:scope]) + content_tag('span', keys.last.to_s.titleize, :class => 'translation_missing', :title => "translation missing: #{keys.join('.')}") + end + end + alias :t :translate + + # Delegates to I18n.localize with no additional functionality. + # + # See http://rubydoc.info/github/svenfuchs/i18n/master/I18n/Backend/Base:localize + # for more information. + def localize(*args) + I18n.localize(*args) + end + alias :l :localize + + private + def scope_key_by_partial(key) + if key.to_s.first == "." + if @virtual_path + @virtual_path.gsub(%r{/_?}, ".") + key.to_s + else + raise "Cannot use t(#{key.inspect}) shortcut because path is not available" + end + else + key + end + end + + def html_safe_translation_key?(key) + key.to_s =~ /(\b|_|\.)html$/ + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/url_helper.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/url_helper.rb new file mode 100644 index 0000000..23a5100 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/helpers/url_helper.rb @@ -0,0 +1,621 @@ +require 'action_view/helpers/javascript_helper' +require 'active_support/core_ext/array/access' +require 'active_support/core_ext/hash/keys' +require 'active_support/core_ext/string/output_safety' + +module ActionView + # = Action View URL Helpers + module Helpers #:nodoc: + # Provides a set of methods for making links and getting URLs that + # depend on the routing subsystem (see ActionDispatch::Routing). + # This allows you to use the same format for links in views + # and controllers. + module UrlHelper + # This helper may be included in any class that includes the + # URL helpers of a routes (routes.url_helpers). Some methods + # provided here will only work in the context of a request + # (link_to_unless_current, for instance), which must be provided + # as a method called #request on the context. + BUTTON_TAG_METHOD_VERBS = %w{patch put delete} + extend ActiveSupport::Concern + + include TagHelper + + module ClassMethods + def _url_for_modules + ActionView::RoutingUrlFor + end + end + + # Basic implementation of url_for to allow use helpers without routes existence + def url_for(options = nil) # :nodoc: + case options + when String + options + when :back + _back_url + else + raise ArgumentError, "arguments passed to url_for can't be handled. Please require " + + "routes or provide your own implementation" + end + end + + def _back_url # :nodoc: + referrer = controller.respond_to?(:request) && controller.request.env["HTTP_REFERER"] + referrer || 'javascript:history.back()' + end + protected :_back_url + + # Creates a link tag of the given +name+ using a URL created by the set of +options+. + # See the valid options in the documentation for +url_for+. It's also possible to + # pass a String instead of an options hash, which generates a link tag that uses the + # value of the String as the href for the link. Using a :back Symbol instead + # of an options hash will generate a link to the referrer (a JavaScript back link + # will be used in place of a referrer if none exists). If +nil+ is passed as the name + # the value of the link itself will become the name. + # + # ==== Signatures + # + # link_to(body, url, html_options = {}) + # # url is a String; you can use URL helpers like + # # posts_path + # + # link_to(body, url_options = {}, html_options = {}) + # # url_options, except :method, is passed to url_for + # + # link_to(options = {}, html_options = {}) do + # # name + # end + # + # link_to(url, html_options = {}) do + # # name + # end + # + # ==== Options + # * :data - This option can be used to add custom data attributes. + # * method: symbol of HTTP verb - This modifier will dynamically + # create an HTML form and immediately submit the form for processing using + # the HTTP verb specified. Useful for having links perform a POST operation + # in dangerous actions like deleting a record (which search bots can follow + # while spidering your site). Supported verbs are :post, :delete, :patch, and :put. + # Note that if the user has JavaScript disabled, the request will fall back + # to using GET. If href: '#' is used and the user has JavaScript + # disabled clicking the link will have no effect. If you are relying on the + # POST behavior, you should check for it in your controller's action by using + # the request object's methods for post?, delete?, patch?, or put?. + # * remote: true - This will allow the unobtrusive JavaScript + # driver to make an Ajax request to the URL in question instead of following + # the link. The drivers each provide mechanisms for listening for the + # completion of the Ajax request and performing JavaScript operations once + # they're complete + # + # ==== Data attributes + # + # * confirm: 'question?' - This will allow the unobtrusive JavaScript + # driver to prompt with the question specified (in this case, the + # resulting text would be question?. If the user accepts, the + # link is processed normally, otherwise no action is taken. + # * :disable_with - Value of this parameter will be + # used as the value for a disabled version of the submit + # button when the form is submitted. This feature is provided + # by the unobtrusive JavaScript driver. + # + # ==== Examples + # Because it relies on +url_for+, +link_to+ supports both older-style controller/action/id arguments + # and newer RESTful routes. Current Rails style favors RESTful routes whenever possible, so base + # your application on resources and use + # + # link_to "Profile", profile_path(@profile) + # # => Profile + # + # or the even pithier + # + # link_to "Profile", @profile + # # => Profile + # + # in place of the older more verbose, non-resource-oriented + # + # link_to "Profile", controller: "profiles", action: "show", id: @profile + # # => Profile + # + # Similarly, + # + # link_to "Profiles", profiles_path + # # => Profiles + # + # is better than + # + # link_to "Profiles", controller: "profiles" + # # => Profiles + # + # You can use a block as well if your link target is hard to fit into the name parameter. ERB example: + # + # <%= link_to(@profile) do %> + # <%= @profile.name %> -- Check it out! + # <% end %> + # # => + # David -- Check it out! + # + # + # Classes and ids for CSS are easy to produce: + # + # link_to "Articles", articles_path, id: "news", class: "article" + # # => Articles + # + # Be careful when using the older argument style, as an extra literal hash is needed: + # + # link_to "Articles", { controller: "articles" }, id: "news", class: "article" + # # => Articles + # + # Leaving the hash off gives the wrong link: + # + # link_to "WRONG!", controller: "articles", id: "news", class: "article" + # # => WRONG! + # + # +link_to+ can also produce links with anchors or query strings: + # + # link_to "Comment wall", profile_path(@profile, anchor: "wall") + # # => Comment wall + # + # link_to "Ruby on Rails search", controller: "searches", query: "ruby on rails" + # # => Ruby on Rails search + # + # link_to "Nonsense search", searches_path(foo: "bar", baz: "quux") + # # => Nonsense search + # + # The only option specific to +link_to+ (:method) is used as follows: + # + # link_to("Destroy", "http://www.example.com", method: :delete) + # # => Destroy + # + # You can also use custom data attributes using the :data option: + # + # link_to "Visit Other Site", "http://www.rubyonrails.org/", data: { confirm: "Are you sure?" } + # # => Visit Other Site + def link_to(name = nil, options = nil, html_options = nil, &block) + html_options, options, name = options, name, block if block_given? + options ||= {} + + html_options = convert_options_to_data_attributes(options, html_options) + + url = url_for(options) + html_options['href'] ||= url + + content_tag(:a, name || url, html_options, &block) + end + + # Generates a form containing a single button that submits to the URL created + # by the set of +options+. This is the safest method to ensure links that + # cause changes to your data are not triggered by search bots or accelerators. + # If the HTML button does not work with your layout, you can also consider + # using the +link_to+ method with the :method modifier as described in + # the +link_to+ documentation. + # + # By default, the generated form element has a class name of button_to + # to allow styling of the form itself and its children. This can be changed + # using the :form_class modifier within +html_options+. You can control + # the form submission and input element behavior using +html_options+. + # This method accepts the :method modifier described in the +link_to+ documentation. + # If no :method modifier is given, it will default to performing a POST operation. + # You can also disable the button by passing disabled: true in +html_options+. + # If you are using RESTful routes, you can pass the :method + # to change the HTTP verb used to submit the form. + # + # ==== Options + # The +options+ hash accepts the same options as +url_for+. + # + # There are a few special +html_options+: + # * :method - Symbol of HTTP verb. Supported verbs are :post, :get, + # :delete, :patch, and :put. By default it will be :post. + # * :disabled - If set to true, it will generate a disabled button. + # * :data - This option can be used to add custom data attributes. + # * :remote - If set to true, will allow the Unobtrusive JavaScript drivers to control the + # submit behavior. By default this behavior is an ajax submit. + # * :form - This hash will be form attributes + # * :form_class - This controls the class of the form within which the submit button will + # be placed + # * :params - Hash of parameters to be rendered as hidden fields within the form. + # + # ==== Data attributes + # + # * :confirm - This will use the unobtrusive JavaScript driver to + # prompt with the question specified. If the user accepts, the link is + # processed normally, otherwise no action is taken. + # * :disable_with - Value of this parameter will be + # used as the value for a disabled version of the submit + # button when the form is submitted. This feature is provided + # by the unobtrusive JavaScript driver. + # + # ==== Examples + # <%= button_to "New", action: "new" %> + # # => "
    + # # + # #
    " + # + # <%= button_to "New", new_articles_path %> + # # => "
    + # # + # #
    " + # + # <%= button_to [:make_happy, @user] do %> + # Make happy <%= @user.name %> + # <% end %> + # # => "
    + # # + # #
    " + # + # <%= button_to "New", { action: "new" }, form_class: "new-thing" %> + # # => "
    + # # + # #
    " + # + # + # <%= button_to "Create", { action: "create" }, remote: true, form: { "data-type" => "json" } %> + # # => "
    + # # + # # + # #
    " + # + # + # <%= button_to "Delete Image", { action: "delete", id: @image.id }, + # method: :delete, data: { confirm: "Are you sure?" } %> + # # => "
    + # # + # # + # # + # #
    " + # + # + # <%= button_to('Destroy', 'http://www.example.com', + # method: "delete", remote: true, data: { confirm: 'Are you sure?', disable_with: 'loading...' }) %> + # # => "
    + # # + # # + # # + # #
    " + # # + def button_to(name = nil, options = nil, html_options = nil, &block) + html_options, options = options, name if block_given? + options ||= {} + html_options ||= {} + + html_options = html_options.stringify_keys + convert_boolean_attributes!(html_options, %w(disabled)) + + url = options.is_a?(String) ? options : url_for(options) + remote = html_options.delete('remote') + params = html_options.delete('params') + + method = html_options.delete('method').to_s + method_tag = BUTTON_TAG_METHOD_VERBS.include?(method) ? method_tag(method) : ''.html_safe + + form_method = method == 'get' ? 'get' : 'post' + form_options = html_options.delete('form') || {} + form_options[:class] ||= html_options.delete('form_class') || 'button_to' + form_options.merge!(method: form_method, action: url) + form_options.merge!("data-remote" => "true") if remote + + request_token_tag = form_method == 'post' ? token_tag : '' + + html_options = convert_options_to_data_attributes(options, html_options) + html_options['type'] = 'submit' + + button = if block_given? + content_tag('button', html_options, &block) + else + html_options['value'] = name || url + tag('input', html_options) + end + + inner_tags = method_tag.safe_concat(button).safe_concat(request_token_tag) + if params + params.each do |param_name, value| + inner_tags.safe_concat tag(:input, type: "hidden", name: param_name, value: value.to_param) + end + end + content_tag('form', inner_tags, form_options) + end + + # Creates a link tag of the given +name+ using a URL created by the set of + # +options+ unless the current request URI is the same as the links, in + # which case only the name is returned (or the given block is yielded, if + # one exists). You can give +link_to_unless_current+ a block which will + # specialize the default behavior (e.g., show a "Start Here" link rather + # than the link's text). + # + # ==== Examples + # Let's say you have a navigation menu... + # + # + # + # If in the "about" action, it will render... + # + # + # + # ...but if in the "index" action, it will render: + # + # + # + # The implicit block given to +link_to_unless_current+ is evaluated if the current + # action is the action given. So, if we had a comments page and wanted to render a + # "Go Back" link instead of a link to the comments page, we could do something like this... + # + # <%= + # link_to_unless_current("Comment", { controller: "comments", action: "new" }) do + # link_to("Go back", { controller: "posts", action: "index" }) + # end + # %> + def link_to_unless_current(name, options = {}, html_options = {}, &block) + link_to_unless current_page?(options), name, options, html_options, &block + end + + # Creates a link tag of the given +name+ using a URL created by the set of + # +options+ unless +condition+ is true, in which case only the name is + # returned. To specialize the default behavior (i.e., show a login link rather + # than just the plaintext link text), you can pass a block that + # accepts the name or the full argument list for +link_to_unless+. + # + # ==== Examples + # <%= link_to_unless(@current_user.nil?, "Reply", { action: "reply" }) %> + # # If the user is logged in... + # # => Reply + # + # <%= + # link_to_unless(@current_user.nil?, "Reply", { action: "reply" }) do |name| + # link_to(name, { controller: "accounts", action: "signup" }) + # end + # %> + # # If the user is logged in... + # # => Reply + # # If not... + # # => Reply + def link_to_unless(condition, name, options = {}, html_options = {}, &block) + link_to_if !condition, name, options, html_options, &block + end + + # Creates a link tag of the given +name+ using a URL created by the set of + # +options+ if +condition+ is true, otherwise only the name is + # returned. To specialize the default behavior, you can pass a block that + # accepts the name or the full argument list for +link_to_unless+ (see the examples + # in +link_to_unless+). + # + # ==== Examples + # <%= link_to_if(@current_user.nil?, "Login", { controller: "sessions", action: "new" }) %> + # # If the user isn't logged in... + # # => Login + # + # <%= + # link_to_if(@current_user.nil?, "Login", { controller: "sessions", action: "new" }) do + # link_to(@current_user.login, { controller: "accounts", action: "show", id: @current_user }) + # end + # %> + # # If the user isn't logged in... + # # => Login + # # If they are logged in... + # # => my_username + def link_to_if(condition, name, options = {}, html_options = {}, &block) + if condition + link_to(name, options, html_options) + else + if block_given? + block.arity <= 1 ? capture(name, &block) : capture(name, options, html_options, &block) + else + ERB::Util.html_escape(name) + end + end + end + + # Creates a mailto link tag to the specified +email_address+, which is + # also used as the name of the link unless +name+ is specified. Additional + # HTML attributes for the link can be passed in +html_options+. + # + # +mail_to+ has several methods for customizing the email itself by + # passing special keys to +html_options+. + # + # ==== Options + # * :subject - Preset the subject line of the email. + # * :body - Preset the body of the email. + # * :cc - Carbon Copy additional recipients on the email. + # * :bcc - Blind Carbon Copy additional recipients on the email. + # + # ==== Obfuscation + # Prior to Rails 4.0, +mail_to+ provided options for encoding the address + # in order to hinder email harvesters. To take advantage of these options, + # install the +actionview-encoded_mail_to+ gem. + # + # ==== Examples + # mail_to "me@domain.com" + # # => me@domain.com + # + # mail_to "me@domain.com", "My email" + # # => My email + # + # mail_to "me@domain.com", "My email", cc: "ccaddress@domain.com", + # subject: "This is an example email" + # # => My email + # + # You can use a block as well if your link target is hard to fit into the name parameter. ERB example: + # + # <%= mail_to "me@domain.com" do %> + # Email me: me@domain.com + # <% end %> + # # => + # Email me: me@domain.com + # + def mail_to(email_address, name = nil, html_options = {}, &block) + html_options, name = name, nil if block_given? + html_options = (html_options || {}).stringify_keys + + extras = %w{ cc bcc body subject }.map! { |item| + option = html_options.delete(item) || next + "#{item}=#{Rack::Utils.escape_path(option)}" + }.compact + extras = extras.empty? ? '' : '?' + extras.join('&') + + encoded_email_address = ERB::Util.url_encode(email_address ? email_address.to_str : '').gsub("%40", "@") + html_options["href"] = "mailto:#{encoded_email_address}#{extras}" + + content_tag(:a, name || email_address, html_options, &block) + end + + # True if the current request URI was generated by the given +options+. + # + # ==== Examples + # Let's say we're in the http://www.example.com/shop/checkout?order=desc action. + # + # current_page?(action: 'process') + # # => false + # + # current_page?(controller: 'shop', action: 'checkout') + # # => true + # + # current_page?(controller: 'shop', action: 'checkout', order: 'asc') + # # => false + # + # current_page?(action: 'checkout') + # # => true + # + # current_page?(controller: 'library', action: 'checkout') + # # => false + # + # current_page?('http://www.example.com/shop/checkout') + # # => true + # + # current_page?('/shop/checkout') + # # => true + # + # Let's say we're in the http://www.example.com/shop/checkout?order=desc&page=1 action. + # + # current_page?(action: 'process') + # # => false + # + # current_page?(controller: 'shop', action: 'checkout') + # # => true + # + # current_page?(controller: 'shop', action: 'checkout', order: 'desc', page: '1') + # # => true + # + # current_page?(controller: 'shop', action: 'checkout', order: 'desc', page: '2') + # # => false + # + # current_page?(controller: 'shop', action: 'checkout', order: 'desc') + # # => false + # + # current_page?(action: 'checkout') + # # => true + # + # current_page?(controller: 'library', action: 'checkout') + # # => false + # + # Let's say we're in the http://www.example.com/products action with method POST in case of invalid product. + # + # current_page?(controller: 'product', action: 'index') + # # => false + # + def current_page?(options) + unless request + raise "You cannot use helpers that need to determine the current " \ + "page unless your view context provides a Request object " \ + "in a #request method" + end + + return false unless request.get? || request.head? + + url_string = URI.parser.unescape(url_for(options)).force_encoding(Encoding::BINARY) + + # We ignore any extra parameters in the request_uri if the + # submitted url doesn't have any either. This lets the function + # work with things like ?order=asc + request_uri = url_string.index("?") ? request.fullpath : request.path + request_uri = URI.parser.unescape(request_uri).force_encoding(Encoding::BINARY) + + if url_string =~ /^\w+:\/\// + url_string == "#{request.protocol}#{request.host_with_port}#{request_uri}" + else + url_string == request_uri + end + end + + private + def convert_options_to_data_attributes(options, html_options) + if html_options + html_options = html_options.stringify_keys + html_options['data-remote'] = 'true' if link_to_remote_options?(options) || link_to_remote_options?(html_options) + + method = html_options.delete('method') + + add_method_to_attributes!(html_options, method) if method + + html_options + else + link_to_remote_options?(options) ? {'data-remote' => 'true'} : {} + end + end + + def link_to_remote_options?(options) + if options.is_a?(Hash) + options.delete('remote') || options.delete(:remote) + end + end + + def add_method_to_attributes!(html_options, method) + if method && method.to_s.downcase != "get" && html_options["rel"] !~ /nofollow/ + html_options["rel"] = "#{html_options["rel"]} nofollow".lstrip + end + html_options["data-method"] = method + end + + # Processes the +html_options+ hash, converting the boolean + # attributes from true/false form into the form required by + # HTML/XHTML. (An attribute is considered to be boolean if + # its name is listed in the given +bool_attrs+ array.) + # + # More specifically, for each boolean attribute in +html_options+ + # given as: + # + # "attr" => bool_value + # + # if the associated +bool_value+ evaluates to true, it is + # replaced with the attribute's name; otherwise the attribute is + # removed from the +html_options+ hash. (See the XHTML 1.0 spec, + # section 4.5 "Attribute Minimization" for more: + # http://www.w3.org/TR/xhtml1/#h-4.5) + # + # Returns the updated +html_options+ hash, which is also modified + # in place. + # + # Example: + # + # convert_boolean_attributes!( html_options, + # %w( checked disabled readonly ) ) + def convert_boolean_attributes!(html_options, bool_attrs) + bool_attrs.each { |x| html_options[x] = x if html_options.delete(x) } + html_options + end + + def token_tag(token=nil) + if token != false && protect_against_forgery? + token ||= form_authenticity_token + tag(:input, type: "hidden", name: request_forgery_protection_token.to_s, value: token) + else + '' + end + end + + def method_tag(method) + tag('input', type: 'hidden', name: '_method', value: method.to_s) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/layouts.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/layouts.rb new file mode 100644 index 0000000..9ee05bd --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/layouts.rb @@ -0,0 +1,426 @@ +require "action_view/rendering" +require "active_support/core_ext/module/remove_method" + +module ActionView + # Layouts reverse the common pattern of including shared headers and footers in many templates to isolate changes in + # repeated setups. The inclusion pattern has pages that look like this: + # + # <%= render "shared/header" %> + # Hello World + # <%= render "shared/footer" %> + # + # This approach is a decent way of keeping common structures isolated from the changing content, but it's verbose + # and if you ever want to change the structure of these two includes, you'll have to change all the templates. + # + # With layouts, you can flip it around and have the common structure know where to insert changing content. This means + # that the header and footer are only mentioned in one place, like this: + # + # // The header part of this layout + # <%= yield %> + # // The footer part of this layout + # + # And then you have content pages that look like this: + # + # hello world + # + # At rendering time, the content page is computed and then inserted in the layout, like this: + # + # // The header part of this layout + # hello world + # // The footer part of this layout + # + # == Accessing shared variables + # + # Layouts have access to variables specified in the content pages and vice versa. This allows you to have layouts with + # references that won't materialize before rendering time: + # + #

    <%= @page_title %>

    + # <%= yield %> + # + # ...and content pages that fulfill these references _at_ rendering time: + # + # <% @page_title = "Welcome" %> + # Off-world colonies offers you a chance to start a new life + # + # The result after rendering is: + # + #

    Welcome

    + # Off-world colonies offers you a chance to start a new life + # + # == Layout assignment + # + # You can either specify a layout declaratively (using the #layout class method) or give + # it the same name as your controller, and place it in app/views/layouts. + # If a subclass does not have a layout specified, it inherits its layout using normal Ruby inheritance. + # + # For instance, if you have PostsController and a template named app/views/layouts/posts.html.erb, + # that template will be used for all actions in PostsController and controllers inheriting + # from PostsController. + # + # If you use a module, for instance Weblog::PostsController, you will need a template named + # app/views/layouts/weblog/posts.html.erb. + # + # Since all your controllers inherit from ApplicationController, they will use + # app/views/layouts/application.html.erb if no other layout is specified + # or provided. + # + # == Inheritance Examples + # + # class BankController < ActionController::Base + # # bank.html.erb exists + # + # class ExchangeController < BankController + # # exchange.html.erb exists + # + # class CurrencyController < BankController + # + # class InformationController < BankController + # layout "information" + # + # class TellerController < InformationController + # # teller.html.erb exists + # + # class EmployeeController < InformationController + # # employee.html.erb exists + # layout nil + # + # class VaultController < BankController + # layout :access_level_layout + # + # class TillController < BankController + # layout false + # + # In these examples, we have three implicit lookup scenarios: + # * The BankController uses the "bank" layout. + # * The ExchangeController uses the "exchange" layout. + # * The CurrencyController inherits the layout from BankController. + # + # However, when a layout is explicitly set, the explicitly set layout wins: + # * The InformationController uses the "information" layout, explicitly set. + # * The TellerController also uses the "information" layout, because the parent explicitly set it. + # * The EmployeeController uses the "employee" layout, because it set the layout to nil, resetting the parent configuration. + # * The VaultController chooses a layout dynamically by calling the access_level_layout method. + # * The TillController does not use a layout at all. + # + # == Types of layouts + # + # Layouts are basically just regular templates, but the name of this template needs not be specified statically. Sometimes + # you want to alternate layouts depending on runtime information, such as whether someone is logged in or not. This can + # be done either by specifying a method reference as a symbol or using an inline method (as a proc). + # + # The method reference is the preferred approach to variable layouts and is used like this: + # + # class WeblogController < ActionController::Base + # layout :writers_and_readers + # + # def index + # # fetching posts + # end + # + # private + # def writers_and_readers + # logged_in? ? "writer_layout" : "reader_layout" + # end + # end + # + # Now when a new request for the index action is processed, the layout will vary depending on whether the person accessing + # is logged in or not. + # + # If you want to use an inline method, such as a proc, do something like this: + # + # class WeblogController < ActionController::Base + # layout proc { |controller| controller.logged_in? ? "writer_layout" : "reader_layout" } + # end + # + # If an argument isn't given to the proc, it's evaluated in the context of + # the current controller anyway. + # + # class WeblogController < ActionController::Base + # layout proc { logged_in? ? "writer_layout" : "reader_layout" } + # end + # + # Of course, the most common way of specifying a layout is still just as a plain template name: + # + # class WeblogController < ActionController::Base + # layout "weblog_standard" + # end + # + # The template will be looked always in app/views/layouts/ folder. But you can point + # layouts folder direct also. layout "layouts/demo" is the same as layout "demo". + # + # Setting the layout to nil forces it to be looked up in the filesystem and fallbacks to the parent behavior if none exists. + # Setting it to nil is useful to re-enable template lookup overriding a previous configuration set in the parent: + # + # class ApplicationController < ActionController::Base + # layout "application" + # end + # + # class PostsController < ApplicationController + # # Will use "application" layout + # end + # + # class CommentsController < ApplicationController + # # Will search for "comments" layout and fallback "application" layout + # layout nil + # end + # + # == Conditional layouts + # + # If you have a layout that by default is applied to all the actions of a controller, you still have the option of rendering + # a given action or set of actions without a layout, or restricting a layout to only a single action or a set of actions. The + # :only and :except options can be passed to the layout call. For example: + # + # class WeblogController < ActionController::Base + # layout "weblog_standard", except: :rss + # + # # ... + # + # end + # + # This will assign "weblog_standard" as the WeblogController's layout for all actions except for the +rss+ action, which will + # be rendered directly, without wrapping a layout around the rendered view. + # + # Both the :only and :except condition can accept an arbitrary number of method references, so + # #except: [ :rss, :text_only ] is valid, as is except: :rss. + # + # == Using a different layout in the action render call + # + # If most of your actions use the same layout, it makes perfect sense to define a controller-wide layout as described above. + # Sometimes you'll have exceptions where one action wants to use a different layout than the rest of the controller. + # You can do this by passing a :layout option to the render call. For example: + # + # class WeblogController < ActionController::Base + # layout "weblog_standard" + # + # def help + # render action: "help", layout: "help" + # end + # end + # + # This will override the controller-wide "weblog_standard" layout, and will render the help action with the "help" layout instead. + module Layouts + extend ActiveSupport::Concern + + include ActionView::Rendering + + included do + class_attribute :_layout, :_layout_conditions, :instance_accessor => false + self._layout = nil + self._layout_conditions = {} + _write_layout_method + end + + delegate :_layout_conditions, to: :class + + module ClassMethods + def inherited(klass) # :nodoc: + super + klass._write_layout_method + end + + # This module is mixed in if layout conditions are provided. This means + # that if no layout conditions are used, this method is not used + module LayoutConditions # :nodoc: + private + + # Determines whether the current action has a layout definition by + # checking the action name against the :only and :except conditions + # set by the layout method. + # + # ==== Returns + # * Boolean - True if the action has a layout definition, false otherwise. + def _conditional_layout? + return unless super + + conditions = _layout_conditions + + if only = conditions[:only] + only.include?(action_name) + elsif except = conditions[:except] + !except.include?(action_name) + else + true + end + end + end + + # Specify the layout to use for this class. + # + # If the specified layout is a: + # String:: the String is the template name + # Symbol:: call the method specified by the symbol, which will return the template name + # false:: There is no layout + # true:: raise an ArgumentError + # nil:: Force default layout behavior with inheritance + # + # ==== Parameters + # * layout - The layout to use. + # + # ==== Options (conditions) + # * :only - A list of actions to apply this layout to. + # * :except - Apply this layout to all actions but this one. + def layout(layout, conditions = {}) + include LayoutConditions unless conditions.empty? + + conditions.each {|k, v| conditions[k] = Array(v).map {|a| a.to_s} } + self._layout_conditions = conditions + + self._layout = layout + _write_layout_method + end + + # Creates a _layout method to be called by _default_layout . + # + # If a layout is not explicitly mentioned then look for a layout with the controller's name. + # if nothing is found then try same procedure to find super class's layout. + def _write_layout_method # :nodoc: + remove_possible_method(:_layout) + + prefixes = _implied_layout_name =~ /\blayouts/ ? [] : ["layouts"] + default_behavior = "lookup_context.find_all('#{_implied_layout_name}', #{prefixes.inspect}).first || super" + name_clause = if name + default_behavior + else + <<-RUBY + super + RUBY + end + + layout_definition = case _layout + when String + _layout.inspect + when Symbol + <<-RUBY + #{_layout}.tap do |layout| + return #{default_behavior} if layout.nil? + unless layout.is_a?(String) || !layout + raise ArgumentError, "Your layout method :#{_layout} returned \#{layout}. It " \ + "should have returned a String, false, or nil" + end + end + RUBY + when Proc + define_method :_layout_from_proc, &_layout + protected :_layout_from_proc + <<-RUBY + result = _layout_from_proc(#{_layout.arity == 0 ? '' : 'self'}) + return #{default_behavior} if result.nil? + result + RUBY + when false + nil + when true + raise ArgumentError, "Layouts must be specified as a String, Symbol, Proc, false, or nil" + when nil + name_clause + end + + self.class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def _layout + if _conditional_layout? + #{layout_definition} + else + #{name_clause} + end + end + private :_layout + RUBY + end + + private + + # If no layout is supplied, look for a template named the return + # value of this method. + # + # ==== Returns + # * String - A template name + def _implied_layout_name # :nodoc: + controller_path + end + end + + def _normalize_options(options) # :nodoc: + super + + if _include_layout?(options) + layout = options.delete(:layout) { :default } + options[:layout] = _layout_for_option(layout) + end + end + + attr_internal_writer :action_has_layout + + def initialize(*) # :nodoc: + @_action_has_layout = true + super + end + + # Controls whether an action should be rendered using a layout. + # If you want to disable any layout settings for the + # current action so that it is rendered without a layout then + # either override this method in your controller to return false + # for that action or set the action_has_layout attribute + # to false before rendering. + def action_has_layout? + @_action_has_layout + end + + private + + def _conditional_layout? + true + end + + # This will be overwritten by _write_layout_method + def _layout; end + + # Determine the layout for a given name, taking into account the name type. + # + # ==== Parameters + # * name - The name of the template + def _layout_for_option(name) + case name + when String then _normalize_layout(name) + when Proc then name + when true then Proc.new { _default_layout(true) } + when :default then Proc.new { _default_layout(false) } + when false, nil then nil + else + raise ArgumentError, + "String, Proc, :default, true, or false, expected for `layout'; you passed #{name.inspect}" + end + end + + def _normalize_layout(value) + value.is_a?(String) && value !~ /\blayouts/ ? "layouts/#{value}" : value + end + + # Returns the default layout for this controller. + # Optionally raises an exception if the layout could not be found. + # + # ==== Parameters + # * require_layout - If set to true and layout is not found, + # an ArgumentError exception is raised (defaults to false) + # + # ==== Returns + # * template - The template object for the default layout (or nil) + def _default_layout(require_layout = false) + begin + value = _layout if action_has_layout? + rescue NameError => e + raise e, "Could not render layout: #{e.message}" + end + + if require_layout && action_has_layout? && !value + raise ArgumentError, + "There was no default layout for #{self.class} in #{view_paths.inspect}" + end + + _normalize_layout(value) + end + + def _include_layout?(options) + (options.keys & [:body, :text, :plain, :html, :inline, :partial]).empty? || options.key?(:layout) + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/locale/en.yml b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/locale/en.yml new file mode 100644 index 0000000..8a56f14 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/locale/en.yml @@ -0,0 +1,56 @@ +"en": + # Used in distance_of_time_in_words(), distance_of_time_in_words_to_now(), time_ago_in_words() + datetime: + distance_in_words: + half_a_minute: "half a minute" + less_than_x_seconds: + one: "less than 1 second" + other: "less than %{count} seconds" + x_seconds: + one: "1 second" + other: "%{count} seconds" + less_than_x_minutes: + one: "less than a minute" + other: "less than %{count} minutes" + x_minutes: + one: "1 minute" + other: "%{count} minutes" + about_x_hours: + one: "about 1 hour" + other: "about %{count} hours" + x_days: + one: "1 day" + other: "%{count} days" + about_x_months: + one: "about 1 month" + other: "about %{count} months" + x_months: + one: "1 month" + other: "%{count} months" + about_x_years: + one: "about 1 year" + other: "about %{count} years" + over_x_years: + one: "over 1 year" + other: "over %{count} years" + almost_x_years: + one: "almost 1 year" + other: "almost %{count} years" + prompts: + year: "Year" + month: "Month" + day: "Day" + hour: "Hour" + minute: "Minute" + second: "Seconds" + + helpers: + select: + # Default value for :prompt => true in FormOptionsHelper + prompt: "Please select" + + # Default translation keys for submit and button FormHelper + submit: + create: 'Create %{model}' + update: 'Update %{model}' + submit: 'Save %{model}' diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/log_subscriber.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/log_subscriber.rb new file mode 100644 index 0000000..9047dbd --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/log_subscriber.rb @@ -0,0 +1,44 @@ +require 'active_support/log_subscriber' + +module ActionView + # = Action View Log Subscriber + # + # Provides functionality so that Rails can output logs from Action View. + class LogSubscriber < ActiveSupport::LogSubscriber + VIEWS_PATTERN = /^app\/views\// + + def initialize + @root = nil + super + end + + def render_template(event) + info do + message = " Rendered #{from_rails_root(event.payload[:identifier])}" + message << " within #{from_rails_root(event.payload[:layout])}" if event.payload[:layout] + message << " (#{event.duration.round(1)}ms)" + end + end + alias :render_partial :render_template + alias :render_collection :render_template + + def logger + ActionView::Base.logger + end + + protected + + EMPTY = '' + def from_rails_root(string) + string = string.sub(rails_root, EMPTY) + string.sub!(VIEWS_PATTERN, EMPTY) + string + end + + def rails_root + @root ||= "#{Rails.root}/" + end + end +end + +ActionView::LogSubscriber.attach_to :action_view diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/lookup_context.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/lookup_context.rb new file mode 100644 index 0000000..cb34391 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/lookup_context.rb @@ -0,0 +1,259 @@ +require 'thread_safe' +require 'active_support/core_ext/module/remove_method' +require 'active_support/core_ext/module/attribute_accessors' +require 'action_view/template/resolver' + +module ActionView + # = Action View Lookup Context + # + # LookupContext is the object responsible to hold all information required to lookup + # templates, i.e. view paths and details. The LookupContext is also responsible to + # generate a key, given to view paths, used in the resolver cache lookup. Since + # this key is generated just once during the request, it speeds up all cache accesses. + class LookupContext #:nodoc: + attr_accessor :prefixes, :rendered_format + + mattr_accessor :fallbacks + @@fallbacks = FallbackFileSystemResolver.instances + + mattr_accessor :registered_details + self.registered_details = [] + + def self.register_detail(name, options = {}, &block) + self.registered_details << name + initialize = registered_details.map { |n| "@details[:#{n}] = details[:#{n}] || default_#{n}" } + + Accessors.send :define_method, :"default_#{name}", &block + Accessors.module_eval <<-METHOD, __FILE__, __LINE__ + 1 + def #{name} + @details.fetch(:#{name}, []) + end + + def #{name}=(value) + value = value.present? ? Array(value) : default_#{name} + _set_detail(:#{name}, value) if value != @details[:#{name}] + end + + remove_possible_method :initialize_details + def initialize_details(details) + #{initialize.join("\n")} + end + METHOD + end + + # Holds accessors for the registered details. + module Accessors #:nodoc: + end + + register_detail(:locale) do + locales = [I18n.locale] + locales.concat(I18n.fallbacks[I18n.locale]) if I18n.respond_to? :fallbacks + locales << I18n.default_locale + locales.uniq! + locales + end + register_detail(:formats) { ActionView::Base.default_formats || [:html, :text, :js, :css, :xml, :json] } + register_detail(:variants) { [] } + register_detail(:handlers){ Template::Handlers.extensions } + + class DetailsKey #:nodoc: + alias :eql? :equal? + alias :object_hash :hash + + attr_reader :hash + @details_keys = ThreadSafe::Cache.new + + def self.get(details) + if details[:formats] + details = details.dup + details[:formats] &= Mime::SET.symbols + end + @details_keys[details] ||= new + end + + def self.clear + @details_keys.clear + end + + def initialize + @hash = object_hash + end + end + + # Add caching behavior on top of Details. + module DetailsCache + attr_accessor :cache + + # Calculate the details key. Remove the handlers from calculation to improve performance + # since the user cannot modify it explicitly. + def details_key #:nodoc: + @details_key ||= DetailsKey.get(@details) if @cache + end + + # Temporary skip passing the details_key forward. + def disable_cache + old_value, @cache = @cache, false + yield + ensure + @cache = old_value + end + + protected + + def _set_detail(key, value) + @details = @details.dup if @details_key + @details_key = nil + @details[key] = value + end + end + + # Helpers related to template lookup using the lookup context information. + module ViewPaths + attr_reader :view_paths, :html_fallback_for_js + + # Whenever setting view paths, makes a copy so that we can manipulate them in + # instance objects as we wish. + def view_paths=(paths) + @view_paths = ActionView::PathSet.new(Array(paths)) + end + + def find(name, prefixes = [], partial = false, keys = [], options = {}) + @view_paths.find(*args_for_lookup(name, prefixes, partial, keys, options)) + end + alias :find_template :find + + def find_file(name, prefixes = [], partial = false, keys = [], options = {}) + @view_paths.find_file(*args_for_lookup(name, prefixes, partial, keys, options)) + end + + def find_all(name, prefixes = [], partial = false, keys = [], options = {}) + @view_paths.find_all(*args_for_lookup(name, prefixes, partial, keys, options)) + end + + def exists?(name, prefixes = [], partial = false, keys = [], options = {}) + @view_paths.exists?(*args_for_lookup(name, prefixes, partial, keys, options)) + end + alias :template_exists? :exists? + + # Adds fallbacks to the view paths. Useful in cases when you are rendering + # a :file. + def with_fallbacks + added_resolvers = 0 + self.class.fallbacks.each do |resolver| + next if view_paths.include?(resolver) + view_paths.push(resolver) + added_resolvers += 1 + end + yield + ensure + added_resolvers.times { view_paths.pop } + end + + protected + + def args_for_lookup(name, prefixes, partial, keys, details_options) #:nodoc: + name, prefixes = normalize_name(name, prefixes) + details, details_key = detail_args_for(details_options) + [name, prefixes, partial || false, details, details_key, keys] + end + + # Compute details hash and key according to user options (e.g. passed from #render). + def detail_args_for(options) + return @details, details_key if options.empty? # most common path. + user_details = @details.merge(options) + + if @cache + details_key = DetailsKey.get(user_details) + else + details_key = nil + end + + [user_details, details_key] + end + + # Support legacy foo.erb names even though we now ignore .erb + # as well as incorrectly putting part of the path in the template + # name instead of the prefix. + def normalize_name(name, prefixes) #:nodoc: + prefixes = prefixes.presence + parts = name.to_s.split('/') + parts.shift if parts.first.empty? + name = parts.pop + + return name, prefixes || [""] if parts.empty? + + parts = parts.join('/') + prefixes = prefixes ? prefixes.map { |p| "#{p}/#{parts}" } : [parts] + + return name, prefixes + end + end + + include Accessors + include DetailsCache + include ViewPaths + + def initialize(view_paths, details = {}, prefixes = []) + @details, @details_key = {}, nil + @skip_default_locale = false + @cache = true + @prefixes = prefixes + @rendered_format = nil + + self.view_paths = view_paths + initialize_details(details) + end + + # Override formats= to expand ["*/*"] values and automatically + # add :html as fallback to :js. + def formats=(values) + if values + values.concat(default_formats) if values.delete "*/*" + if values == [:js] + values << :html + @html_fallback_for_js = true + end + end + super(values) + end + + # Do not use the default locale on template lookup. + def skip_default_locale! + @skip_default_locale = true + self.locale = nil + end + + # Override locale to return a symbol instead of array. + def locale + @details[:locale].first + end + + # Overload locale= to also set the I18n.locale. If the current I18n.config object responds + # to original_config, it means that it has a copy of the original I18n configuration and it's + # acting as proxy, which we need to skip. + def locale=(value) + if value + config = I18n.config.respond_to?(:original_config) ? I18n.config.original_config : I18n.config + config.locale = value + end + + super(@skip_default_locale ? I18n.locale : default_locale) + end + + # Uses the first format in the formats array for layout lookup. + def with_layout_format + if formats.size == 1 + yield + else + old_formats = formats + _set_detail(:formats, formats[0,1]) + + begin + yield + ensure + _set_detail(:formats, old_formats) + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/model_naming.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/model_naming.rb new file mode 100644 index 0000000..d42e436 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/model_naming.rb @@ -0,0 +1,12 @@ +module ActionView + module ModelNaming + # Converts the given object to an ActiveModel compliant one. + def convert_to_model(object) + object.respond_to?(:to_model) ? object.to_model : object + end + + def model_name_from_record_or_class(record_or_class) + convert_to_model(record_or_class).model_name + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/path_set.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/path_set.rb new file mode 100644 index 0000000..8d21913 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/path_set.rb @@ -0,0 +1,89 @@ +module ActionView #:nodoc: + # = Action View PathSet + # + # This class is used to store and access paths in Action View. A number of + # operations are defined so that you can search among the paths in this + # set and also perform operations on other +PathSet+ objects. + # + # A +LookupContext+ will use a +PathSet+ to store the paths in its context. + class PathSet #:nodoc: + include Enumerable + + attr_reader :paths + + delegate :[], :include?, :pop, :size, :each, to: :paths + + def initialize(paths = []) + @paths = typecast paths + end + + def initialize_copy(other) + @paths = other.paths.dup + self + end + + def to_ary + paths.dup + end + + def compact + PathSet.new paths.compact + end + + def +(array) + PathSet.new(paths + array) + end + + %w(<< concat push insert unshift).each do |method| + class_eval <<-METHOD, __FILE__, __LINE__ + 1 + def #{method}(*args) + paths.#{method}(*typecast(args)) + end + METHOD + end + + def find(*args) + find_all(*args).first || raise(MissingTemplate.new(self, *args)) + end + + def find_file(path, prefixes = [], *args) + _find_all(path, prefixes, args, true).first || raise(MissingTemplate.new(self, path, prefixes, *args)) + end + + def find_all(path, prefixes = [], *args) + _find_all path, prefixes, args, false + end + + def exists?(path, prefixes, *args) + find_all(path, prefixes, *args).any? + end + + private + + def _find_all(path, prefixes, args, outside_app) + prefixes = [prefixes] if String === prefixes + prefixes.each do |prefix| + paths.each do |resolver| + if outside_app + templates = resolver.find_all_anywhere(path, prefix, *args) + else + templates = resolver.find_all(path, prefix, *args) + end + return templates unless templates.empty? + end + end + [] + end + + def typecast(paths) + paths.map do |path| + case path + when Pathname, String + OptimizedFileSystemResolver.new path.to_s + else + path + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/railtie.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/railtie.rb new file mode 100644 index 0000000..81f9c40 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/railtie.rb @@ -0,0 +1,49 @@ +require "action_view" +require "rails" + +module ActionView + # = Action View Railtie + class Railtie < Rails::Railtie # :nodoc: + config.action_view = ActiveSupport::OrderedOptions.new + config.action_view.embed_authenticity_token_in_remote_forms = false + + config.eager_load_namespaces << ActionView + + initializer "action_view.embed_authenticity_token_in_remote_forms" do |app| + ActiveSupport.on_load(:action_view) do + ActionView::Helpers::FormTagHelper.embed_authenticity_token_in_remote_forms = + app.config.action_view.delete(:embed_authenticity_token_in_remote_forms) + end + end + + initializer "action_view.logger" do + ActiveSupport.on_load(:action_view) { self.logger ||= Rails.logger } + end + + initializer "action_view.set_configs" do |app| + ActiveSupport.on_load(:action_view) do + app.config.action_view.each do |k,v| + send "#{k}=", v + end + end + end + + initializer "action_view.caching" do |app| + ActiveSupport.on_load(:action_view) do + if app.config.action_view.cache_template_loading.nil? + ActionView::Resolver.caching = app.config.cache_classes + end + end + end + + initializer "action_view.setup_action_pack" do |app| + ActiveSupport.on_load(:action_controller) do + ActionView::RoutingUrlFor.send(:include, ActionDispatch::Routing::UrlFor) + end + end + + rake_tasks do + load "action_view/tasks/dependencies.rake" + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/record_identifier.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/record_identifier.rb new file mode 100644 index 0000000..63f6454 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/record_identifier.rb @@ -0,0 +1,84 @@ +require 'active_support/core_ext/module' +require 'action_view/model_naming' + +module ActionView + # The record identifier encapsulates a number of naming conventions for dealing with records, like Active Records or + # pretty much any other model type that has an id. These patterns are then used to try elevate the view actions to + # a higher logical level. + # + # # routes + # resources :posts + # + # # view + # <%= div_for(post) do %>
    + # <%= post.body %> What a wonderful world! + # <% end %>
    + # + # # controller + # def update + # post = Post.find(params[:id]) + # post.update(params[:post]) + # + # redirect_to(post) # Calls polymorphic_url(post) which in turn calls post_url(post) + # end + # + # As the example above shows, you can stop caring to a large extent what the actual id of the post is. + # You just know that one is being assigned and that the subsequent calls in redirect_to expect that + # same naming convention and allows you to write less code if you follow it. + module RecordIdentifier + extend self + extend ModelNaming + + include ModelNaming + + JOIN = '_'.freeze + NEW = 'new'.freeze + + # The DOM class convention is to use the singular form of an object or class. + # + # dom_class(post) # => "post" + # dom_class(Person) # => "person" + # + # If you need to address multiple instances of the same class in the same view, you can prefix the dom_class: + # + # dom_class(post, :edit) # => "edit_post" + # dom_class(Person, :edit) # => "edit_person" + def dom_class(record_or_class, prefix = nil) + singular = model_name_from_record_or_class(record_or_class).param_key + prefix ? "#{prefix}#{JOIN}#{singular}" : singular + end + + # The DOM id convention is to use the singular form of an object or class with the id following an underscore. + # If no id is found, prefix with "new_" instead. + # + # dom_id(Post.find(45)) # => "post_45" + # dom_id(Post.new) # => "new_post" + # + # If you need to address multiple instances of the same class in the same view, you can prefix the dom_id: + # + # dom_id(Post.find(45), :edit) # => "edit_post_45" + # dom_id(Post.new, :custom) # => "custom_post" + def dom_id(record, prefix = nil) + if record_id = record_key_for_dom_id(record) + "#{dom_class(record, prefix)}#{JOIN}#{record_id}" + else + dom_class(record, prefix || NEW) + end + end + + protected + + # Returns a string representation of the key attribute(s) that is suitable for use in an HTML DOM id. + # This can be overwritten to customize the default generated string representation if desired. + # If you need to read back a key from a dom_id in order to query for the underlying database record, + # you should write a helper like 'person_record_from_dom_id' that will extract the key either based + # on the default implementation (which just joins all key attributes with '_') or on your own + # overwritten version of the method. By default, this implementation passes the key string through a + # method that replaces all characters that are invalid inside DOM ids, with valid ones. You need to + # make sure yourself that your dom ids are valid, in case you overwrite this method. + def record_key_for_dom_id(record) + key = convert_to_model(record).to_key + key ? key.join('_') : key + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/renderer/abstract_renderer.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/renderer/abstract_renderer.rb new file mode 100644 index 0000000..aa77a77 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/renderer/abstract_renderer.rb @@ -0,0 +1,49 @@ +module ActionView + # This class defines the interface for a renderer. Each class that + # subclasses +AbstractRenderer+ is used by the base +Renderer+ class to + # render a specific type of object. + # + # The base +Renderer+ class uses its +render+ method to delegate to the + # renderers. These currently consist of + # + # PartialRenderer - Used for rendering partials + # TemplateRenderer - Used for rendering other types of templates + # StreamingTemplateRenderer - Used for streaming + # + # Whenever the +render+ method is called on the base +Renderer+ class, a new + # renderer object of the correct type is created, and the +render+ method on + # that new object is called in turn. This abstracts the setup and rendering + # into a separate classes for partials and templates. + class AbstractRenderer #:nodoc: + delegate :find_template, :find_file, :template_exists?, :with_fallbacks, :with_layout_format, :formats, :to => :@lookup_context + + def initialize(lookup_context) + @lookup_context = lookup_context + end + + def render + raise NotImplementedError + end + + protected + + def extract_details(options) + @lookup_context.registered_details.each_with_object({}) do |key, details| + value = options[key] + + details[key] = Array(value) if value + end + end + + def instrument(name, options={}) + ActiveSupport::Notifications.instrument("render_#{name}.action_view", options){ yield } + end + + def prepend_formats(formats) + formats = Array(formats) + return if formats.empty? || @lookup_context.html_fallback_for_js + + @lookup_context.formats = formats | @lookup_context.formats + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/renderer/partial_renderer.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/renderer/partial_renderer.rb new file mode 100644 index 0000000..b0924e3 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/renderer/partial_renderer.rb @@ -0,0 +1,548 @@ +require 'thread_safe' + +module ActionView + class PartialIteration + # The number of iterations that will be done by the partial. + attr_reader :size + + # The current iteration of the partial. + attr_reader :index + + def initialize(size) + @size = size + @index = 0 + end + + # Check if this is the first iteration of the partial. + def first? + index == 0 + end + + # Check if this is the last iteration of the partial. + def last? + index == size - 1 + end + + def iterate! # :nodoc: + @index += 1 + end + end + + # = Action View Partials + # + # There's also a convenience method for rendering sub templates within the current controller that depends on a + # single object (we call this kind of sub templates for partials). It relies on the fact that partials should + # follow the naming convention of being prefixed with an underscore -- as to separate them from regular + # templates that could be rendered on their own. + # + # In a template for Advertiser#account: + # + # <%= render partial: "account" %> + # + # This would render "advertiser/_account.html.erb". + # + # In another template for Advertiser#buy, we could have: + # + # <%= render partial: "account", locals: { account: @buyer } %> + # + # <% @advertisements.each do |ad| %> + # <%= render partial: "ad", locals: { ad: ad } %> + # <% end %> + # + # This would first render "advertiser/_account.html.erb" with @buyer passed in as the local variable +account+, then + # render "advertiser/_ad.html.erb" and pass the local variable +ad+ to the template for display. + # + # == The :as and :object options + # + # By default ActionView::PartialRenderer doesn't have any local variables. + # The :object option can be used to pass an object to the partial. For instance: + # + # <%= render partial: "account", object: @buyer %> + # + # would provide the @buyer object to the partial, available under the local variable +account+ and is + # equivalent to: + # + # <%= render partial: "account", locals: { account: @buyer } %> + # + # With the :as option we can specify a different name for said local variable. For example, if we + # wanted it to be +user+ instead of +account+ we'd do: + # + # <%= render partial: "account", object: @buyer, as: 'user' %> + # + # This is equivalent to + # + # <%= render partial: "account", locals: { user: @buyer } %> + # + # == Rendering a collection of partials + # + # The example of partial use describes a familiar pattern where a template needs to iterate over an array and + # render a sub template for each of the elements. This pattern has been implemented as a single method that + # accepts an array and renders a partial by the same name as the elements contained within. So the three-lined + # example in "Using partials" can be rewritten with a single line: + # + # <%= render partial: "ad", collection: @advertisements %> + # + # This will render "advertiser/_ad.html.erb" and pass the local variable +ad+ to the template for display. An + # iteration object will automatically be made available to the template with a name of the form + # +partial_name_iteration+. The iteration object has knowledge about which index the current object has in + # the collection and the total size of the collection. The iteration object also has two convenience methods, + # +first?+ and +last?+. In the case of the example above, the template would be fed +ad_iteration+. + # For backwards compatibility the +partial_name_counter+ is still present and is mapped to the iteration's + # +index+ method. + # + # The :as option may be used when rendering partials. + # + # You can specify a partial to be rendered between elements via the :spacer_template option. + # The following example will render advertiser/_ad_divider.html.erb between each ad partial: + # + # <%= render partial: "ad", collection: @advertisements, spacer_template: "ad_divider" %> + # + # If the given :collection is nil or empty, render will return nil. This will allow you + # to specify a text which will displayed instead by using this form: + # + # <%= render(partial: "ad", collection: @advertisements) || "There's no ad to be displayed" %> + # + # NOTE: Due to backwards compatibility concerns, the collection can't be one of hashes. Normally you'd also + # just keep domain objects, like Active Records, in there. + # + # == Rendering shared partials + # + # Two controllers can share a set of partials and render them like this: + # + # <%= render partial: "advertisement/ad", locals: { ad: @advertisement } %> + # + # This will render the partial "advertisement/_ad.html.erb" regardless of which controller this is being called from. + # + # == Rendering objects that respond to `to_partial_path` + # + # Instead of explicitly naming the location of a partial, you can also let PartialRenderer do the work + # and pick the proper path by checking `to_partial_path` method. + # + # # @account.to_partial_path returns 'accounts/account', so it can be used to replace: + # # <%= render partial: "accounts/account", locals: { account: @account} %> + # <%= render partial: @account %> + # + # # @posts is an array of Post instances, so every post record returns 'posts/post' on `to_partial_path`, + # # that's why we can replace: + # # <%= render partial: "posts/post", collection: @posts %> + # <%= render partial: @posts %> + # + # == Rendering the default case + # + # If you're not going to be using any of the options like collections or layouts, you can also use the short-hand + # defaults of render to render partials. Examples: + # + # # Instead of <%= render partial: "account" %> + # <%= render "account" %> + # + # # Instead of <%= render partial: "account", locals: { account: @buyer } %> + # <%= render "account", account: @buyer %> + # + # # @account.to_partial_path returns 'accounts/account', so it can be used to replace: + # # <%= render partial: "accounts/account", locals: { account: @account} %> + # <%= render @account %> + # + # # @posts is an array of Post instances, so every post record returns 'posts/post' on `to_partial_path`, + # # that's why we can replace: + # # <%= render partial: "posts/post", collection: @posts %> + # <%= render @posts %> + # + # == Rendering partials with layouts + # + # Partials can have their own layouts applied to them. These layouts are different than the ones that are + # specified globally for the entire action, but they work in a similar fashion. Imagine a list with two types + # of users: + # + # <%# app/views/users/index.html.erb &> + # Here's the administrator: + # <%= render partial: "user", layout: "administrator", locals: { user: administrator } %> + # + # Here's the editor: + # <%= render partial: "user", layout: "editor", locals: { user: editor } %> + # + # <%# app/views/users/_user.html.erb &> + # Name: <%= user.name %> + # + # <%# app/views/users/_administrator.html.erb &> + #
    + # Budget: $<%= user.budget %> + # <%= yield %> + #
    + # + # <%# app/views/users/_editor.html.erb &> + #
    + # Deadline: <%= user.deadline %> + # <%= yield %> + #
    + # + # ...this will return: + # + # Here's the administrator: + #
    + # Budget: $<%= user.budget %> + # Name: <%= user.name %> + #
    + # + # Here's the editor: + #
    + # Deadline: <%= user.deadline %> + # Name: <%= user.name %> + #
    + # + # If a collection is given, the layout will be rendered once for each item in + # the collection. For example, these two snippets have the same output: + # + # <%# app/views/users/_user.html.erb %> + # Name: <%= user.name %> + # + # <%# app/views/users/index.html.erb %> + # <%# This does not use layouts %> + #
      + # <% users.each do |user| -%> + #
    • + # <%= render partial: "user", locals: { user: user } %> + #
    • + # <% end -%> + #
    + # + # <%# app/views/users/_li_layout.html.erb %> + #
  • + # <%= yield %> + #
  • + # + # <%# app/views/users/index.html.erb %> + #
      + # <%= render partial: "user", layout: "li_layout", collection: users %> + #
    + # + # Given two users whose names are Alice and Bob, these snippets return: + # + #
      + #
    • + # Name: Alice + #
    • + #
    • + # Name: Bob + #
    • + #
    + # + # The current object being rendered, as well as the object_counter, will be + # available as local variables inside the layout template under the same names + # as available in the partial. + # + # You can also apply a layout to a block within any template: + # + # <%# app/views/users/_chief.html.erb &> + # <%= render(layout: "administrator", locals: { user: chief }) do %> + # Title: <%= chief.title %> + # <% end %> + # + # ...this will return: + # + #
    + # Budget: $<%= user.budget %> + # Title: <%= chief.name %> + #
    + # + # As you can see, the :locals hash is shared between both the partial and its layout. + # + # If you pass arguments to "yield" then this will be passed to the block. One way to use this is to pass + # an array to layout and treat it as an enumerable. + # + # <%# app/views/users/_user.html.erb &> + #
    + # Budget: $<%= user.budget %> + # <%= yield user %> + #
    + # + # <%# app/views/users/index.html.erb &> + # <%= render layout: @users do |user| %> + # Title: <%= user.title %> + # <% end %> + # + # This will render the layout for each user and yield to the block, passing the user, each time. + # + # You can also yield multiple times in one layout and use block arguments to differentiate the sections. + # + # <%# app/views/users/_user.html.erb &> + #
    + # <%= yield user, :header %> + # Budget: $<%= user.budget %> + # <%= yield user, :footer %> + #
    + # + # <%# app/views/users/index.html.erb &> + # <%= render layout: @users do |user, section| %> + # <%- case section when :header -%> + # Title: <%= user.title %> + # <%- when :footer -%> + # Deadline: <%= user.deadline %> + # <%- end -%> + # <% end %> + class PartialRenderer < AbstractRenderer + PREFIXED_PARTIAL_NAMES = ThreadSafe::Cache.new do |h, k| + h[k] = ThreadSafe::Cache.new + end + + def initialize(*) + super + @context_prefix = @lookup_context.prefixes.first + end + + def render(context, options, block) + setup(context, options, block) + identifier = (@template = find_partial) ? @template.identifier : @path + + @lookup_context.rendered_format ||= begin + if @template && @template.formats.present? + @template.formats.first + else + formats.first + end + end + + if @collection + instrument(:collection, :identifier => identifier || "collection", :count => @collection.size) do + render_collection + end + else + instrument(:partial, :identifier => identifier) do + render_partial + end + end + end + + private + + def render_collection + return nil if @collection.blank? + + if @options.key?(:spacer_template) + spacer = find_template(@options[:spacer_template], @locals.keys).render(@view, @locals) + end + + result = @template ? collection_with_template : collection_without_template + result.join(spacer).html_safe + end + + def render_partial + view, locals, block = @view, @locals, @block + object, as = @object, @variable + + if !block && (layout = @options[:layout]) + layout = find_template(layout.to_s, @template_keys) + end + + object = locals[as] if object.nil? # Respect object when object is false + locals[as] = object + + content = @template.render(view, locals) do |*name| + view._layout_for(*name, &block) + end + + content = layout.render(view, locals){ content } if layout + content + end + + private + + # Sets up instance variables needed for rendering a partial. This method + # finds the options and details and extracts them. The method also contains + # logic that handles the type of object passed in as the partial. + # + # If +options[:partial]+ is a string, then the +@path+ instance variable is + # set to that string. Otherwise, the +options[:partial]+ object must + # respond to +to_partial_path+ in order to setup the path. + def setup(context, options, block) + @view = context + @options = options + @block = block + + @locals = options[:locals] || {} + @details = extract_details(options) + + prepend_formats(options[:formats]) + + partial = options[:partial] + + if String === partial + @has_object = options.key?(:object) + @object = options[:object] + @collection = collection_from_options + @path = partial + else + @has_object = true + @object = partial + @collection = collection_from_object || collection_from_options + + if @collection + paths = @collection_data = @collection.map { |o| partial_path(o) } + @path = paths.uniq.one? ? paths.first : nil + else + @path = partial_path + end + end + + if as = options[:as] + raise_invalid_option_as(as) unless as.to_s =~ /\A[a-z_]\w*\z/ + as = as.to_sym + end + + if @path + @variable, @variable_counter, @variable_iteration = retrieve_variable(@path, as) + @template_keys = retrieve_template_keys + else + paths.map! { |path| retrieve_variable(path, as).unshift(path) } + end + + self + end + + def collection_from_options + if @options.key?(:collection) + collection = @options[:collection] + collection.respond_to?(:to_ary) ? collection.to_ary : [] + end + end + + def collection_from_object + @object.to_ary if @object.respond_to?(:to_ary) + end + + def find_partial + find_template(@path, @template_keys) if @path + end + + def find_template(path, locals) + prefixes = path.include?(?/) ? [] : @lookup_context.prefixes + @lookup_context.find_template(path, prefixes, true, locals, @details) + end + + def collection_with_template + view, locals, template = @view, @locals, @template + as, counter, iteration = @variable, @variable_counter, @variable_iteration + + if layout = @options[:layout] + layout = find_template(layout, @template_keys) + end + + partial_iteration = PartialIteration.new(@collection.size) + locals[iteration] = partial_iteration + + @collection.map do |object| + locals[as] = object + locals[counter] = partial_iteration.index + + content = template.render(view, locals) + content = layout.render(view, locals) { content } if layout + partial_iteration.iterate! + content + end + end + + def collection_without_template + view, locals, collection_data = @view, @locals, @collection_data + cache = {} + keys = @locals.keys + + partial_iteration = PartialIteration.new(@collection.size) + + @collection.map do |object| + index = partial_iteration.index + path, as, counter, iteration = collection_data[index] + + locals[as] = object + locals[counter] = index + locals[iteration] = partial_iteration + + template = (cache[path] ||= find_template(path, keys + [as, counter])) + content = template.render(view, locals) + partial_iteration.iterate! + content + end + end + + # Obtains the path to where the object's partial is located. If the object + # responds to +to_partial_path+, then +to_partial_path+ will be called and + # will provide the path. If the object does not respond to +to_partial_path+, + # then an +ArgumentError+ is raised. + # + # If +prefix_partial_path_with_controller_namespace+ is true, then this + # method will prefix the partial paths with a namespace. + def partial_path(object = @object) + object = object.to_model if object.respond_to?(:to_model) + + path = if object.respond_to?(:to_partial_path) + object.to_partial_path + else + raise ArgumentError.new("'#{object.inspect}' is not an ActiveModel-compatible object. It must implement :to_partial_path.") + end + + if @view.prefix_partial_path_with_controller_namespace + prefixed_partial_names[path] ||= merge_prefix_into_object_path(@context_prefix, path.dup) + else + path + end + end + + def prefixed_partial_names + @prefixed_partial_names ||= PREFIXED_PARTIAL_NAMES[@context_prefix] + end + + def merge_prefix_into_object_path(prefix, object_path) + if prefix.include?(?/) && object_path.include?(?/) + prefixes = [] + prefix_array = File.dirname(prefix).split('/') + object_path_array = object_path.split('/')[0..-3] # skip model dir & partial + + prefix_array.each_with_index do |dir, index| + break if dir == object_path_array[index] + prefixes << dir + end + + (prefixes << object_path).join("/") + else + object_path + end + end + + def retrieve_template_keys + keys = @locals.keys + keys << @variable if @has_object || @collection + if @collection + keys << @variable_counter + keys << @variable_iteration + end + keys + end + + def retrieve_variable(path, as) + variable = as || begin + base = path[-1] == "/" ? "" : File.basename(path) + raise_invalid_identifier(path) unless base =~ /\A_?([a-z]\w*)(\.\w+)*\z/ + $1.to_sym + end + if @collection + variable_counter = :"#{variable}_counter" + variable_iteration = :"#{variable}_iteration" + end + [variable, variable_counter, variable_iteration] + end + + IDENTIFIER_ERROR_MESSAGE = "The partial name (%s) is not a valid Ruby identifier; " + + "make sure your partial name starts with underscore, " + + "and is followed by any combination of letters, numbers and underscores." + + OPTION_AS_ERROR_MESSAGE = "The value (%s) of the option `as` is not a valid Ruby identifier; " + + "make sure it starts with lowercase letter, " + + "and is followed by any combination of letters, numbers and underscores." + + def raise_invalid_identifier(path) + raise ArgumentError.new(IDENTIFIER_ERROR_MESSAGE % (path)) + end + + def raise_invalid_option_as(as) + raise ArgumentError.new(OPTION_AS_ERROR_MESSAGE % (as)) + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/renderer/renderer.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/renderer/renderer.rb new file mode 100644 index 0000000..5ba7b2b --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/renderer/renderer.rb @@ -0,0 +1,54 @@ +module ActionView + # This is the main entry point for rendering. It basically delegates + # to other objects like TemplateRenderer and PartialRenderer which + # actually renders the template. + # + # The Renderer will parse the options from the +render+ or +render_body+ + # method and render a partial or a template based on the options. The + # +TemplateRenderer+ and +PartialRenderer+ objects are wrappers which do all + # the setup and logic necessary to render a view and a new object is created + # each time +render+ is called. + class Renderer + attr_accessor :lookup_context + + def initialize(lookup_context) + @lookup_context = lookup_context + end + + # Main render entry point shared by AV and AC. + def render(context, options) + if options.respond_to?(:permitted?) && !options.permitted? + raise ArgumentError, "render parameters are not permitted" + end + + if options.key?(:partial) + render_partial(context, options) + else + render_template(context, options) + end + end + + # Render but returns a valid Rack body. If fibers are defined, we return + # a streaming body that renders the template piece by piece. + # + # Note that partials are not supported to be rendered with streaming, + # so in such cases, we just wrap them in an array. + def render_body(context, options) + if options.key?(:partial) + [render_partial(context, options)] + else + StreamingTemplateRenderer.new(@lookup_context).render(context, options) + end + end + + # Direct accessor to template rendering. + def render_template(context, options) #:nodoc: + TemplateRenderer.new(@lookup_context).render(context, options) + end + + # Direct access to partial rendering. + def render_partial(context, options, &block) #:nodoc: + PartialRenderer.new(@lookup_context).render(context, options, block) + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/renderer/streaming_template_renderer.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/renderer/streaming_template_renderer.rb new file mode 100644 index 0000000..3ab2cd3 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/renderer/streaming_template_renderer.rb @@ -0,0 +1,103 @@ +require 'fiber' + +module ActionView + # == TODO + # + # * Support streaming from child templates, partials and so on. + # * Integrate exceptions with exceptron + # * Rack::Cache needs to support streaming bodies + class StreamingTemplateRenderer < TemplateRenderer #:nodoc: + # A valid Rack::Body (i.e. it responds to each). + # It is initialized with a block that, when called, starts + # rendering the template. + class Body #:nodoc: + def initialize(&start) + @start = start + end + + def each(&block) + begin + @start.call(block) + rescue Exception => exception + log_error(exception) + block.call ActionView::Base.streaming_completion_on_exception + end + self + end + + private + + # This is the same logging logic as in ShowExceptions middleware. + # TODO Once "exceptron" is in, refactor this piece to simply re-use exceptron. + def log_error(exception) #:nodoc: + logger = ActionView::Base.logger + return unless logger + + message = "\n#{exception.class} (#{exception.message}):\n" + message << exception.annoted_source_code.to_s if exception.respond_to?(:annoted_source_code) + message << " " << exception.backtrace.join("\n ") + logger.fatal("#{message}\n\n") + end + end + + # For streaming, instead of rendering a given a template, we return a Body + # object that responds to each. This object is initialized with a block + # that knows how to render the template. + def render_template(template, layout_name = nil, locals = {}) #:nodoc: + return [super] unless layout_name && template.supports_streaming? + + locals ||= {} + layout = layout_name && find_layout(layout_name, locals.keys) + + Body.new do |buffer| + delayed_render(buffer, template, layout, @view, locals) + end + end + + private + + def delayed_render(buffer, template, layout, view, locals) + # Wrap the given buffer in the StreamingBuffer and pass it to the + # underlying template handler. Now, every time something is concatenated + # to the buffer, it is not appended to an array, but streamed straight + # to the client. + output = ActionView::StreamingBuffer.new(buffer) + yielder = lambda { |*name| view._layout_for(*name) } + + instrument(:template, :identifier => template.identifier, :layout => layout.try(:virtual_path)) do + fiber = Fiber.new do + if layout + layout.render(view, locals, output, &yielder) + else + # If you don't have a layout, just render the thing + # and concatenate the final result. This is the same + # as a layout with just <%= yield %> + output.safe_concat view._layout_for + end + end + + # Set the view flow to support streaming. It will be aware + # when to stop rendering the layout because it needs to search + # something in the template and vice-versa. + view.view_flow = StreamingFlow.new(view, fiber) + + # Yo! Start the fiber! + fiber.resume + + # If the fiber is still alive, it means we need something + # from the template, so start rendering it. If not, it means + # the layout exited without requiring anything from the template. + if fiber.alive? + content = template.render(view, locals, &yielder) + + # Once rendering the template is done, sets its content in the :layout key. + view.view_flow.set(:layout, content) + + # In case the layout continues yielding, we need to resume + # the fiber until all yields are handled. + fiber.resume while fiber.alive? + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/renderer/template_renderer.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/renderer/template_renderer.rb new file mode 100644 index 0000000..73b6077 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/renderer/template_renderer.rb @@ -0,0 +1,101 @@ +require 'active_support/core_ext/object/try' + +module ActionView + class TemplateRenderer < AbstractRenderer #:nodoc: + def render(context, options) + @view = context + @details = extract_details(options) + template = determine_template(options) + + prepend_formats(template.formats) + + @lookup_context.rendered_format ||= (template.formats.first || formats.first) + + render_template(template, options[:layout], options[:locals]) + end + + private + + # Determine the template to be rendered using the given options. + def determine_template(options) + keys = options.has_key?(:locals) ? options[:locals].keys : [] + + if options.key?(:body) + Template::Text.new(options[:body]) + elsif options.key?(:text) + Template::Text.new(options[:text], formats.first) + elsif options.key?(:plain) + Template::Text.new(options[:plain]) + elsif options.key?(:html) + Template::HTML.new(options[:html], formats.first) + elsif options.key?(:file) + with_fallbacks { find_file(options[:file], nil, false, keys, @details) } + elsif options.key?(:inline) + handler = Template.handler_for_extension(options[:type] || "erb") + Template.new(options[:inline], "inline template", handler, :locals => keys) + elsif options.key?(:template) + if options[:template].respond_to?(:render) + options[:template] + else + find_template(options[:template], options[:prefixes], false, keys, @details) + end + else + raise ArgumentError, "You invoked render but did not give any of :partial, :template, :inline, :file, :plain, :text or :body option." + end + end + + # Renders the given template. A string representing the layout can be + # supplied as well. + def render_template(template, layout_name = nil, locals = nil) #:nodoc: + view, locals = @view, locals || {} + + render_with_layout(layout_name, locals) do |layout| + instrument(:template, :identifier => template.identifier, :layout => layout.try(:virtual_path)) do + template.render(view, locals) { |*name| view._layout_for(*name) } + end + end + end + + def render_with_layout(path, locals) #:nodoc: + layout = path && find_layout(path, locals.keys) + content = yield(layout) + + if layout + view = @view + view.view_flow.set(:layout, content) + layout.render(view, locals){ |*name| view._layout_for(*name) } + else + content + end + end + + # This is the method which actually finds the layout using details in the lookup + # context object. If no layout is found, it checks if at least a layout with + # the given name exists across all details before raising the error. + def find_layout(layout, keys) + with_layout_format { resolve_layout(layout, keys) } + end + + def resolve_layout(layout, keys) + case layout + when String + begin + if layout =~ /^\// + with_fallbacks { find_template(layout, nil, false, keys, @details) } + else + find_template(layout, nil, false, keys, @details) + end + rescue ActionView::MissingTemplate + all_details = @details.merge(:formats => @lookup_context.default_formats) + raise unless template_exists?(layout, nil, false, keys, all_details) + end + when Proc + resolve_layout(layout.call, keys) + when FalseClass + nil + else + layout + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/rendering.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/rendering.rb new file mode 100644 index 0000000..abd3b77 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/rendering.rb @@ -0,0 +1,146 @@ +require "action_view/view_paths" + +module ActionView + # This is a class to fix I18n global state. Whenever you provide I18n.locale during a request, + # it will trigger the lookup_context and consequently expire the cache. + class I18nProxy < ::I18n::Config #:nodoc: + attr_reader :original_config, :lookup_context + + def initialize(original_config, lookup_context) + original_config = original_config.original_config if original_config.respond_to?(:original_config) + @original_config, @lookup_context = original_config, lookup_context + end + + def locale + @original_config.locale + end + + def locale=(value) + @lookup_context.locale = value + end + end + + module Rendering + extend ActiveSupport::Concern + include ActionView::ViewPaths + + # Overwrite process to setup I18n proxy. + def process(*) #:nodoc: + old_config, I18n.config = I18n.config, I18nProxy.new(I18n.config, lookup_context) + super + ensure + I18n.config = old_config + end + + module ClassMethods + def view_context_class + @view_context_class ||= begin + supports_path = supports_path? + routes = respond_to?(:_routes) && _routes + helpers = respond_to?(:_helpers) && _helpers + + Class.new(ActionView::Base) do + if routes + include routes.url_helpers(supports_path) + include routes.mounted_helpers + end + + if helpers + include helpers + end + end + end + end + end + + attr_internal_writer :view_context_class + + def view_context_class + @_view_context_class ||= self.class.view_context_class + end + + # An instance of a view class. The default view class is ActionView::Base + # + # The view class must have the following methods: + # View.new[lookup_context, assigns, controller] + # Create a new ActionView instance for a controller and we can also pass the arguments. + # View#render(option) + # Returns String with the rendered template + # + # Override this method in a module to change the default behavior. + def view_context + view_context_class.new(view_renderer, view_assigns, self) + end + + # Returns an object that is able to render templates. + # :api: private + def view_renderer + @_view_renderer ||= ActionView::Renderer.new(lookup_context) + end + + def render_to_body(options = {}) + _process_options(options) + _render_template(options) + end + + def rendered_format + Mime[lookup_context.rendered_format] + end + + private + + # Find and render a template based on the options given. + # :api: private + def _render_template(options) #:nodoc: + variant = options[:variant] + + lookup_context.rendered_format = nil if options[:formats] + lookup_context.variants = variant if variant + + view_renderer.render(view_context, options) + end + + # Assign the rendered format to lookup context. + def _process_format(format, options = {}) #:nodoc: + super + lookup_context.formats = [format.to_sym] + lookup_context.rendered_format = lookup_context.formats.first + end + + # Normalize args by converting render "foo" to render :action => "foo" and + # render "foo/bar" to render :template => "foo/bar". + # :api: private + def _normalize_args(action=nil, options={}) + options = super(action, options) + case action + when NilClass + when Hash + options = action + when String, Symbol + action = action.to_s + key = action.include?(?/) ? :template : :action + options[key] = action + else + options[:partial] = action + end + + options + end + + # Normalize options. + # :api: private + def _normalize_options(options) + options = super(options) + if options[:partial] == true + options[:partial] = action_name + end + + if (options.keys & [:partial, :file, :template]).empty? + options[:prefixes] ||= _prefixes + end + + options[:template] ||= (options[:action] || action_name).to_s + options + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/routing_url_for.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/routing_url_for.rb new file mode 100644 index 0000000..7f20e1b --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/routing_url_for.rb @@ -0,0 +1,135 @@ +require 'action_dispatch/routing/polymorphic_routes' + +module ActionView + module RoutingUrlFor + + # Returns the URL for the set of +options+ provided. This takes the + # same options as +url_for+ in Action Controller (see the + # documentation for ActionController::Base#url_for). Note that by default + # :only_path is true so you'll get the relative "/controller/action" + # instead of the fully qualified URL like "http://example.com/controller/action". + # + # ==== Options + # * :anchor - Specifies the anchor name to be appended to the path. + # * :only_path - If true, returns the relative URL (omitting the protocol, host name, and port) (true by default unless :host is specified). + # * :trailing_slash - If true, adds a trailing slash, as in "/archive/2005/". Note that this + # is currently not recommended since it breaks caching. + # * :host - Overrides the default (current) host if provided. + # * :protocol - Overrides the default (current) protocol if provided. + # * :user - Inline HTTP authentication (only plucked out if :password is also present). + # * :password - Inline HTTP authentication (only plucked out if :user is also present). + # + # ==== Relying on named routes + # + # Passing a record (like an Active Record) instead of a hash as the options parameter will + # trigger the named route for that record. The lookup will happen on the name of the class. So passing a + # Workshop object will attempt to use the +workshop_path+ route. If you have a nested route, such as + # +admin_workshop_path+ you'll have to call that explicitly (it's impossible for +url_for+ to guess that route). + # + # ==== Implicit Controller Namespacing + # + # Controllers passed in using the +:controller+ option will retain their namespace unless it is an absolute one. + # + # ==== Examples + # <%= url_for(action: 'index') %> + # # => /blog/ + # + # <%= url_for(action: 'find', controller: 'books') %> + # # => /books/find + # + # <%= url_for(action: 'login', controller: 'members', only_path: false, protocol: 'https') %> + # # => https://www.example.com/members/login/ + # + # <%= url_for(action: 'play', anchor: 'player') %> + # # => /messages/play/#player + # + # <%= url_for(action: 'jump', anchor: 'tax&ship') %> + # # => /testing/jump/#tax&ship + # + # <%= url_for(Workshop.new) %> + # # relies on Workshop answering a persisted? call (and in this case returning false) + # # => /workshops + # + # <%= url_for(@workshop) %> + # # calls @workshop.to_param which by default returns the id + # # => /workshops/5 + # + # # to_param can be re-defined in a model to provide different URL names: + # # => /workshops/1-workshop-name + # + # <%= url_for("http://www.example.com") %> + # # => http://www.example.com + # + # <%= url_for(:back) %> + # # if request.env["HTTP_REFERER"] is set to "http://www.example.com" + # # => http://www.example.com + # + # <%= url_for(:back) %> + # # if request.env["HTTP_REFERER"] is not set or is blank + # # => javascript:history.back() + # + # <%= url_for(action: 'index', controller: 'users') %> + # # Assuming an "admin" namespace + # # => /admin/users + # + # <%= url_for(action: 'index', controller: '/users') %> + # # Specify absolute path with beginning slash + # # => /users + def url_for(options = nil) + case options + when String + options + when nil + super(only_path: _generate_paths_by_default) + when Hash + options = options.symbolize_keys + unless options.key?(:only_path) + if options[:host].nil? + options[:only_path] = _generate_paths_by_default + else + options[:only_path] = false + end + end + + super(options) + when :back + _back_url + when Array + components = options.dup + if _generate_paths_by_default + polymorphic_path(components, components.extract_options!) + else + polymorphic_url(components, components.extract_options!) + end + else + method = _generate_paths_by_default ? :path : :url + builder = ActionDispatch::Routing::PolymorphicRoutes::HelperMethodBuilder.send(method) + + case options + when Symbol + builder.handle_string_call(self, options) + when Class + builder.handle_class_call(self, options) + else + builder.handle_model_call(self, options) + end + end + end + + def url_options #:nodoc: + return super unless controller.respond_to?(:url_options) + controller.url_options + end + + def _routes_context #:nodoc: + controller + end + protected :_routes_context + + def optimize_routes_generation? #:nodoc: + controller.respond_to?(:optimize_routes_generation?, true) ? + controller.optimize_routes_generation? : super + end + protected :optimize_routes_generation? + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/tasks/dependencies.rake b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/tasks/dependencies.rake new file mode 100644 index 0000000..f394c31 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/tasks/dependencies.rake @@ -0,0 +1,23 @@ +namespace :cache_digests do + desc 'Lookup nested dependencies for TEMPLATE (like messages/show or comments/_comment.html)' + task :nested_dependencies => :environment do + abort 'You must provide TEMPLATE for the task to run' unless ENV['TEMPLATE'].present? + puts JSON.pretty_generate ActionView::Digestor.new(name: CacheDigests.template_name, finder: CacheDigests.finder).nested_dependencies + end + + desc 'Lookup first-level dependencies for TEMPLATE (like messages/show or comments/_comment.html)' + task :dependencies => :environment do + abort 'You must provide TEMPLATE for the task to run' unless ENV['TEMPLATE'].present? + puts JSON.pretty_generate ActionView::Digestor.new(name: CacheDigests.template_name, finder: CacheDigests.finder).dependencies + end + + class CacheDigests + def self.template_name + ENV['TEMPLATE'].split('.', 2).first + end + + def self.finder + ApplicationController.new.lookup_context + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/template.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/template.rb new file mode 100644 index 0000000..6b61378 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/template.rb @@ -0,0 +1,336 @@ +require 'active_support/core_ext/object/try' +require 'active_support/core_ext/kernel/singleton_class' +require 'thread' + +module ActionView + # = Action View Template + class Template + extend ActiveSupport::Autoload + + # === Encodings in ActionView::Template + # + # ActionView::Template is one of a few sources of potential + # encoding issues in Rails. This is because the source for + # templates are usually read from disk, and Ruby (like most + # encoding-aware programming languages) assumes that the + # String retrieved through File IO is encoded in the + # default_external encoding. In Rails, the default + # default_external encoding is UTF-8. + # + # As a result, if a user saves their template as ISO-8859-1 + # (for instance, using a non-Unicode-aware text editor), + # and uses characters outside of the ASCII range, their + # users will see diamonds with question marks in them in + # the browser. + # + # For the rest of this documentation, when we say "UTF-8", + # we mean "UTF-8 or whatever the default_internal encoding + # is set to". By default, it will be UTF-8. + # + # To mitigate this problem, we use a few strategies: + # 1. If the source is not valid UTF-8, we raise an exception + # when the template is compiled to alert the user + # to the problem. + # 2. The user can specify the encoding using Ruby-style + # encoding comments in any template engine. If such + # a comment is supplied, Rails will apply that encoding + # to the resulting compiled source returned by the + # template handler. + # 3. In all cases, we transcode the resulting String to + # the UTF-8. + # + # This means that other parts of Rails can always assume + # that templates are encoded in UTF-8, even if the original + # source of the template was not UTF-8. + # + # From a user's perspective, the easiest thing to do is + # to save your templates as UTF-8. If you do this, you + # do not need to do anything else for things to "just work". + # + # === Instructions for template handlers + # + # The easiest thing for you to do is to simply ignore + # encodings. Rails will hand you the template source + # as the default_internal (generally UTF-8), raising + # an exception for the user before sending the template + # to you if it could not determine the original encoding. + # + # For the greatest simplicity, you can support only + # UTF-8 as the default_internal. This means + # that from the perspective of your handler, the + # entire pipeline is just UTF-8. + # + # === Advanced: Handlers with alternate metadata sources + # + # If you want to provide an alternate mechanism for + # specifying encodings (like ERB does via <%# encoding: ... %>), + # you may indicate that you will handle encodings yourself + # by implementing self.handles_encoding? + # on your handler. + # + # If you do, Rails will not try to encode the String + # into the default_internal, passing you the unaltered + # bytes tagged with the assumed encoding (from + # default_external). + # + # In this case, make sure you return a String from + # your handler encoded in the default_internal. Since + # you are handling out-of-band metadata, you are + # also responsible for alerting the user to any + # problems with converting the user's data to + # the default_internal. + # + # To do so, simply raise +WrongEncodingError+ as follows: + # + # raise WrongEncodingError.new( + # problematic_string, + # expected_encoding + # ) + + eager_autoload do + autoload :Error + autoload :Handlers + autoload :HTML + autoload :Text + autoload :Types + end + + extend Template::Handlers + + attr_accessor :locals, :formats, :variants, :virtual_path + + attr_reader :source, :identifier, :handler, :original_encoding, :updated_at + + # This finalizer is needed (and exactly with a proc inside another proc) + # otherwise templates leak in development. + Finalizer = proc do |method_name, mod| + proc do + mod.module_eval do + remove_possible_method method_name + end + end + end + + def initialize(source, identifier, handler, details) + format = details[:format] || (handler.default_format if handler.respond_to?(:default_format)) + + @source = source + @identifier = identifier + @handler = handler + @compiled = false + @original_encoding = nil + @locals = details[:locals] || [] + @virtual_path = details[:virtual_path] + @updated_at = details[:updated_at] || Time.now + @formats = Array(format).map { |f| f.respond_to?(:ref) ? f.ref : f } + @variants = [details[:variant]] + @compile_mutex = Mutex.new + end + + # Returns if the underlying handler supports streaming. If so, + # a streaming buffer *may* be passed when it start rendering. + def supports_streaming? + handler.respond_to?(:supports_streaming?) && handler.supports_streaming? + end + + # Render a template. If the template was not compiled yet, it is done + # exactly before rendering. + # + # This method is instrumented as "!render_template.action_view". Notice that + # we use a bang in this instrumentation because you don't want to + # consume this in production. This is only slow if it's being listened to. + def render(view, locals, buffer=nil, &block) + instrument("!render_template") do + compile!(view) + view.send(method_name, locals, buffer, &block) + end + rescue => e + handle_render_error(view, e) + end + + def type + @type ||= Types[@formats.first] if @formats.first + end + + # Receives a view object and return a template similar to self by using @virtual_path. + # + # This method is useful if you have a template object but it does not contain its source + # anymore since it was already compiled. In such cases, all you need to do is to call + # refresh passing in the view object. + # + # Notice this method raises an error if the template to be refreshed does not have a + # virtual path set (true just for inline templates). + def refresh(view) + raise "A template needs to have a virtual path in order to be refreshed" unless @virtual_path + lookup = view.lookup_context + pieces = @virtual_path.split("/") + name = pieces.pop + partial = !!name.sub!(/^_/, "") + lookup.disable_cache do + lookup.find_template(name, [ pieces.join('/') ], partial, @locals) + end + end + + def inspect + @inspect ||= defined?(Rails.root) ? identifier.sub("#{Rails.root}/", '') : identifier + end + + # This method is responsible for properly setting the encoding of the + # source. Until this point, we assume that the source is BINARY data. + # If no additional information is supplied, we assume the encoding is + # the same as Encoding.default_external. + # + # The user can also specify the encoding via a comment on the first + # line of the template (# encoding: NAME-OF-ENCODING). This will work + # with any template engine, as we process out the encoding comment + # before passing the source on to the template engine, leaving a + # blank line in its stead. + def encode! + return unless source.encoding == Encoding::BINARY + + # Look for # encoding: *. If we find one, we'll encode the + # String in that encoding, otherwise, we'll use the + # default external encoding. + if source.sub!(/\A#{ENCODING_FLAG}/, '') + encoding = magic_encoding = $1 + else + encoding = Encoding.default_external + end + + # Tag the source with the default external encoding + # or the encoding specified in the file + source.force_encoding(encoding) + + # If the user didn't specify an encoding, and the handler + # handles encodings, we simply pass the String as is to + # the handler (with the default_external tag) + if !magic_encoding && @handler.respond_to?(:handles_encoding?) && @handler.handles_encoding? + source + # Otherwise, if the String is valid in the encoding, + # encode immediately to default_internal. This means + # that if a handler doesn't handle encodings, it will + # always get Strings in the default_internal + elsif source.valid_encoding? + source.encode! + # Otherwise, since the String is invalid in the encoding + # specified, raise an exception + else + raise WrongEncodingError.new(source, encoding) + end + end + + protected + + # Compile a template. This method ensures a template is compiled + # just once and removes the source after it is compiled. + def compile!(view) #:nodoc: + return if @compiled + + # Templates can be used concurrently in threaded environments + # so compilation and any instance variable modification must + # be synchronized + @compile_mutex.synchronize do + # Any thread holding this lock will be compiling the template needed + # by the threads waiting. So re-check the @compiled flag to avoid + # re-compilation + return if @compiled + + if view.is_a?(ActionView::CompiledTemplates) + mod = ActionView::CompiledTemplates + else + mod = view.singleton_class + end + + instrument("!compile_template") do + compile(mod) + end + + # Just discard the source if we have a virtual path. This + # means we can get the template back. + @source = nil if @virtual_path + @compiled = true + end + end + + # Among other things, this method is responsible for properly setting + # the encoding of the compiled template. + # + # If the template engine handles encodings, we send the encoded + # String to the engine without further processing. This allows + # the template engine to support additional mechanisms for + # specifying the encoding. For instance, ERB supports <%# encoding: %> + # + # Otherwise, after we figure out the correct encoding, we then + # encode the source into Encoding.default_internal. + # In general, this means that templates will be UTF-8 inside of Rails, + # regardless of the original source encoding. + def compile(mod) #:nodoc: + encode! + method_name = self.method_name + code = @handler.call(self) + + # Make sure that the resulting String to be eval'd is in the + # encoding of the code + source = <<-end_src + def #{method_name}(local_assigns, output_buffer) + _old_virtual_path, @virtual_path = @virtual_path, #{@virtual_path.inspect};_old_output_buffer = @output_buffer;#{locals_code};#{code} + ensure + @virtual_path, @output_buffer = _old_virtual_path, _old_output_buffer + end + end_src + + # Make sure the source is in the encoding of the returned code + source.force_encoding(code.encoding) + + # In case we get back a String from a handler that is not in + # BINARY or the default_internal, encode it to the default_internal + source.encode! + + # Now, validate that the source we got back from the template + # handler is valid in the default_internal. This is for handlers + # that handle encoding but screw up + unless source.valid_encoding? + raise WrongEncodingError.new(@source, Encoding.default_internal) + end + + mod.module_eval(source, identifier, 0) + ObjectSpace.define_finalizer(self, Finalizer[method_name, mod]) + end + + def handle_render_error(view, e) #:nodoc: + if e.is_a?(Template::Error) + e.sub_template_of(self) + raise e + else + template = self + unless template.source + template = refresh(view) + template.encode! + end + raise Template::Error.new(template, e) + end + end + + def locals_code #:nodoc: + # Double assign to suppress the dreaded 'assigned but unused variable' warning + @locals.each_with_object('') { |key, code| code << "#{key} = #{key} = local_assigns[:#{key}];" } + end + + def method_name #:nodoc: + @method_name ||= begin + m = "_#{identifier_method_name}__#{@identifier.hash}_#{__id__}" + m.tr!('-', '_') + m + end + end + + def identifier_method_name #:nodoc: + inspect.tr('^a-z_', '_') + end + + def instrument(action, &block) + payload = { virtual_path: @virtual_path, identifier: @identifier } + ActiveSupport::Notifications.instrument("#{action}.action_view", payload, &block) + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/template/error.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/template/error.rb new file mode 100644 index 0000000..743ef6d --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/template/error.rb @@ -0,0 +1,141 @@ +require "active_support/core_ext/enumerable" + +module ActionView + # = Action View Errors + class ActionViewError < StandardError #:nodoc: + end + + class EncodingError < StandardError #:nodoc: + end + + class MissingRequestError < StandardError #:nodoc: + end + + class WrongEncodingError < EncodingError #:nodoc: + def initialize(string, encoding) + @string, @encoding = string, encoding + end + + def message + @string.force_encoding(Encoding::ASCII_8BIT) + "Your template was not saved as valid #{@encoding}. Please " \ + "either specify #{@encoding} as the encoding for your template " \ + "in your text editor, or mark the template with its " \ + "encoding by inserting the following as the first line " \ + "of the template:\n\n# encoding: .\n\n" \ + "The source of your template was:\n\n#{@string}" + end + end + + class MissingTemplate < ActionViewError #:nodoc: + attr_reader :path + + def initialize(paths, path, prefixes, partial, details, *) + @path = path + prefixes = Array(prefixes) + template_type = if partial + "partial" + elsif path =~ /layouts/i + 'layout' + else + 'template' + end + + if partial && path.present? + path = path.sub(%r{([^/]+)$}, "_\\1") + end + searched_paths = prefixes.map { |prefix| [prefix, path].join("/") } + + out = "Missing #{template_type} #{searched_paths.join(", ")} with #{details.inspect}. Searched in:\n" + out += paths.compact.map { |p| " * #{p.to_s.inspect}\n" }.join + super out + end + end + + class Template + # The Template::Error exception is raised when the compilation or rendering of the template + # fails. This exception then gathers a bunch of intimate details and uses it to report a + # precise exception message. + class Error < ActionViewError #:nodoc: + SOURCE_CODE_RADIUS = 3 + + attr_reader :original_exception + + def initialize(template, original_exception) + super(original_exception.message) + @template, @original_exception = template, original_exception + @sub_templates = nil + set_backtrace(original_exception.backtrace) + end + + def file_name + @template.identifier + end + + def sub_template_message + if @sub_templates + "Trace of template inclusion: " + + @sub_templates.collect { |template| template.inspect }.join(", ") + else + "" + end + end + + def source_extract(indentation = 0, output = :console) + return unless num = line_number + num = num.to_i + + source_code = @template.source.split("\n") + + start_on_line = [ num - SOURCE_CODE_RADIUS - 1, 0 ].max + end_on_line = [ num + SOURCE_CODE_RADIUS - 1, source_code.length].min + + indent = end_on_line.to_s.size + indentation + return unless source_code = source_code[start_on_line..end_on_line] + + formatted_code_for(source_code, start_on_line, indent, output) + end + + def sub_template_of(template_path) + @sub_templates ||= [] + @sub_templates << template_path + end + + def line_number + @line_number ||= + if file_name + regexp = /#{Regexp.escape File.basename(file_name)}:(\d+)/ + $1 if message =~ regexp || backtrace.find { |line| line =~ regexp } + end + end + + def annoted_source_code + source_extract(4) + end + + private + + def source_location + if line_number + "on line ##{line_number} of " + else + 'in ' + end + file_name + end + + def formatted_code_for(source_code, line_counter, indent, output) + start_value = (output == :html) ? {} : "" + source_code.inject(start_value) do |result, line| + line_counter += 1 + if output == :html + result.update(line_counter.to_s => "%#{indent}s %s\n" % ["", line]) + else + result << "%#{indent}s: %s\n" % [line_counter, line] + end + end + end + end + end + + TemplateError = Template::Error +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/template/handlers.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/template/handlers.rb new file mode 100644 index 0000000..ff2feb5 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/template/handlers.rb @@ -0,0 +1,62 @@ +module ActionView #:nodoc: + # = Action View Template Handlers + class Template + module Handlers #:nodoc: + autoload :ERB, 'action_view/template/handlers/erb' + autoload :Builder, 'action_view/template/handlers/builder' + autoload :Raw, 'action_view/template/handlers/raw' + + def self.extended(base) + base.register_default_template_handler :erb, ERB.new + base.register_template_handler :builder, Builder.new + base.register_template_handler :raw, Raw.new + base.register_template_handler :ruby, :source.to_proc + end + + @@template_handlers = {} + @@default_template_handlers = nil + + def self.extensions + @@template_extensions ||= @@template_handlers.keys + end + + # Register an object that knows how to handle template files with the given + # extensions. This can be used to implement new template types. + # The handler must respond to +:call+, which will be passed the template + # and should return the rendered template as a String. + def register_template_handler(*extensions, handler) + raise(ArgumentError, "Extension is required") if extensions.empty? + extensions.each do |extension| + @@template_handlers[extension.to_sym] = handler + end + @@template_extensions = nil + end + + # Opposite to register_template_handler. + def unregister_template_handler(*extensions) + extensions.each do |extension| + handler = @@template_handlers.delete extension.to_sym + @@default_template_handlers = nil if @@default_template_handlers == handler + end + @@template_extensions = nil + end + + def template_handler_extensions + @@template_handlers.keys.map {|key| key.to_s }.sort + end + + def registered_template_handler(extension) + extension && @@template_handlers[extension.to_sym] + end + + def register_default_template_handler(extension, klass) + register_template_handler(extension, klass) + @@default_template_handlers = klass + end + + def handler_for_extension(extension) + registered_template_handler(extension) || @@default_template_handlers + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/template/handlers/builder.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/template/handlers/builder.rb new file mode 100644 index 0000000..d90b0c6 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/template/handlers/builder.rb @@ -0,0 +1,26 @@ +module ActionView + module Template::Handlers + class Builder + # Default format used by Builder. + class_attribute :default_format + self.default_format = :xml + + def call(template) + require_engine + "xml = ::Builder::XmlMarkup.new(:indent => 2);" + + "self.output_buffer = xml.target!;" + + template.source + + ";xml.target!;" + end + + protected + + def require_engine + @required ||= begin + require "builder" + true + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/template/handlers/erb.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/template/handlers/erb.rb new file mode 100644 index 0000000..85a100e --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/template/handlers/erb.rb @@ -0,0 +1,145 @@ +require 'erubis' + +module ActionView + class Template + module Handlers + class Erubis < ::Erubis::Eruby + def add_preamble(src) + @newline_pending = 0 + src << "@output_buffer = output_buffer || ActionView::OutputBuffer.new;" + end + + def add_text(src, text) + return if text.empty? + + if text == "\n" + @newline_pending += 1 + else + src << "@output_buffer.safe_append='" + src << "\n" * @newline_pending if @newline_pending > 0 + src << escape_text(text) + src << "'.freeze;" + + @newline_pending = 0 + end + end + + # Erubis toggles <%= and <%== behavior when escaping is enabled. + # We override to always treat <%== as escaped. + def add_expr(src, code, indicator) + case indicator + when '==' + add_expr_escaped(src, code) + else + super + end + end + + BLOCK_EXPR = /\s*((\s+|\))do|\{)(\s*\|[^|]*\|)?\s*\Z/ + + def add_expr_literal(src, code) + flush_newline_if_pending(src) + if code =~ BLOCK_EXPR + src << '@output_buffer.append= ' << code + else + src << '@output_buffer.append=(' << code << ');' + end + end + + def add_expr_escaped(src, code) + flush_newline_if_pending(src) + if code =~ BLOCK_EXPR + src << "@output_buffer.safe_expr_append= " << code + else + src << "@output_buffer.safe_expr_append=(" << code << ");" + end + end + + def add_stmt(src, code) + flush_newline_if_pending(src) + super + end + + def add_postamble(src) + flush_newline_if_pending(src) + src << '@output_buffer.to_s' + end + + def flush_newline_if_pending(src) + if @newline_pending > 0 + src << "@output_buffer.safe_append='#{"\n" * @newline_pending}'.freeze;" + @newline_pending = 0 + end + end + end + + class ERB + # Specify trim mode for the ERB compiler. Defaults to '-'. + # See ERB documentation for suitable values. + class_attribute :erb_trim_mode + self.erb_trim_mode = '-' + + # Default implementation used. + class_attribute :erb_implementation + self.erb_implementation = Erubis + + # Do not escape templates of these mime types. + class_attribute :escape_whitelist + self.escape_whitelist = ["text/plain"] + + ENCODING_TAG = Regexp.new("\\A(<%#{ENCODING_FLAG}-?%>)[ \\t]*") + + def self.call(template) + new.call(template) + end + + def supports_streaming? + true + end + + def handles_encoding? + true + end + + def call(template) + # First, convert to BINARY, so in case the encoding is + # wrong, we can still find an encoding tag + # (<%# encoding %>) inside the String using a regular + # expression + template_source = template.source.dup.force_encoding(Encoding::ASCII_8BIT) + + erb = template_source.gsub(ENCODING_TAG, '') + encoding = $2 + + erb.force_encoding valid_encoding(template.source.dup, encoding) + + # Always make sure we return a String in the default_internal + erb.encode! + + self.class.erb_implementation.new( + erb, + :escape => (self.class.escape_whitelist.include? template.type), + :trim => (self.class.erb_trim_mode == "-") + ).src + end + + private + + def valid_encoding(string, encoding) + # If a magic encoding comment was found, tag the + # String with this encoding. This is for a case + # where the original String was assumed to be, + # for instance, UTF-8, but a magic comment + # proved otherwise + string.force_encoding(encoding) if encoding + + # If the String is valid, return the encoding we found + return string.encoding if string.valid_encoding? + + # Otherwise, raise an exception + raise WrongEncodingError.new(string, string.encoding) + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/template/handlers/raw.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/template/handlers/raw.rb new file mode 100644 index 0000000..397c860 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/template/handlers/raw.rb @@ -0,0 +1,11 @@ +module ActionView + module Template::Handlers + class Raw + def call(template) + escaped = template.source.gsub(/:/, '\:') + + '%q:' + escaped + ':;' + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/template/html.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/template/html.rb new file mode 100644 index 0000000..0321f81 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/template/html.rb @@ -0,0 +1,34 @@ +module ActionView #:nodoc: + # = Action View HTML Template + class Template + class HTML #:nodoc: + attr_accessor :type + + def initialize(string, type = nil) + @string = string.to_s + @type = Types[type] || type if type + @type ||= Types[:html] + end + + def identifier + 'html template' + end + + def inspect + 'html template' + end + + def to_str + ERB::Util.h(@string) + end + + def render(*args) + to_str + end + + def formats + [@type.respond_to?(:ref) ? @type.ref : @type.to_s] + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/template/resolver.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/template/resolver.rb new file mode 100644 index 0000000..bb8a305 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/template/resolver.rb @@ -0,0 +1,366 @@ +require "pathname" +require "active_support/core_ext/class" +require "active_support/core_ext/module/attribute_accessors" +require 'active_support/core_ext/string/filters' +require "action_view/template" +require "thread" +require "thread_safe" + +module ActionView + # = Action View Resolver + class Resolver + # Keeps all information about view path and builds virtual path. + class Path + attr_reader :name, :prefix, :partial, :virtual + alias_method :partial?, :partial + + def self.build(name, prefix, partial) + virtual = "" + virtual << "#{prefix}/" unless prefix.empty? + virtual << (partial ? "_#{name}" : name) + new name, prefix, partial, virtual + end + + def initialize(name, prefix, partial, virtual) + @name = name + @prefix = prefix + @partial = partial + @virtual = virtual + end + + def to_str + @virtual + end + alias :to_s :to_str + end + + # Threadsafe template cache + class Cache #:nodoc: + class SmallCache < ThreadSafe::Cache + def initialize(options = {}) + super(options.merge(:initial_capacity => 2)) + end + end + + # preallocate all the default blocks for performance/memory consumption reasons + PARTIAL_BLOCK = lambda {|cache, partial| cache[partial] = SmallCache.new} + PREFIX_BLOCK = lambda {|cache, prefix| cache[prefix] = SmallCache.new(&PARTIAL_BLOCK)} + NAME_BLOCK = lambda {|cache, name| cache[name] = SmallCache.new(&PREFIX_BLOCK)} + KEY_BLOCK = lambda {|cache, key| cache[key] = SmallCache.new(&NAME_BLOCK)} + + # usually a majority of template look ups return nothing, use this canonical preallocated array to save memory + NO_TEMPLATES = [].freeze + + def initialize + @data = SmallCache.new(&KEY_BLOCK) + end + + # Cache the templates returned by the block + def cache(key, name, prefix, partial, locals) + if Resolver.caching? + @data[key][name][prefix][partial][locals] ||= canonical_no_templates(yield) + else + fresh_templates = yield + cached_templates = @data[key][name][prefix][partial][locals] + + if templates_have_changed?(cached_templates, fresh_templates) + @data[key][name][prefix][partial][locals] = canonical_no_templates(fresh_templates) + else + cached_templates || NO_TEMPLATES + end + end + end + + def clear + @data.clear + end + + private + + def canonical_no_templates(templates) + templates.empty? ? NO_TEMPLATES : templates + end + + def templates_have_changed?(cached_templates, fresh_templates) + # if either the old or new template list is empty, we don't need to (and can't) + # compare modification times, and instead just check whether the lists are different + if cached_templates.blank? || fresh_templates.blank? + return fresh_templates.blank? != cached_templates.blank? + end + + cached_templates_max_updated_at = cached_templates.map(&:updated_at).max + + # if a template has changed, it will be now be newer than all the cached templates + fresh_templates.any? { |t| t.updated_at > cached_templates_max_updated_at } + end + end + + cattr_accessor :caching + self.caching = true + + class << self + alias :caching? :caching + end + + def initialize + @cache = Cache.new + end + + def clear_cache + @cache.clear + end + + # Normalizes the arguments and passes it on to find_templates. + def find_all(name, prefix=nil, partial=false, details={}, key=nil, locals=[]) + cached(key, [name, prefix, partial], details, locals) do + find_templates(name, prefix, partial, details, false) + end + end + + def find_all_anywhere(name, prefix, partial=false, details={}, key=nil, locals=[]) + cached(key, [name, prefix, partial], details, locals) do + find_templates(name, prefix, partial, details, true) + end + end + + private + + delegate :caching?, to: :class + + # This is what child classes implement. No defaults are needed + # because Resolver guarantees that the arguments are present and + # normalized. + def find_templates(name, prefix, partial, details, outside_app_allowed) + raise NotImplementedError, "Subclasses must implement a find_templates(name, prefix, partial, details, outside_app_allowed) method" + end + + # Helpers that builds a path. Useful for building virtual paths. + def build_path(name, prefix, partial) + Path.build(name, prefix, partial) + end + + # Handles templates caching. If a key is given and caching is on + # always check the cache before hitting the resolver. Otherwise, + # it always hits the resolver but if the key is present, check if the + # resolver is fresher before returning it. + def cached(key, path_info, details, locals) #:nodoc: + name, prefix, partial = path_info + locals = locals.map { |x| x.to_s }.sort! + + if key + @cache.cache(key, name, prefix, partial, locals) do + decorate(yield, path_info, details, locals) + end + else + decorate(yield, path_info, details, locals) + end + end + + # Ensures all the resolver information is set in the template. + def decorate(templates, path_info, details, locals) #:nodoc: + cached = nil + templates.each do |t| + t.locals = locals + t.formats = details[:formats] || [:html] if t.formats.empty? + t.variants = details[:variants] || [] if t.variants.empty? + t.virtual_path ||= (cached ||= build_path(*path_info)) + end + end + end + + # An abstract class that implements a Resolver with path semantics. + class PathResolver < Resolver #:nodoc: + EXTENSIONS = { :locale => ".", :formats => ".", :variants => "+", :handlers => "." } + DEFAULT_PATTERN = ":prefix/:action{.:locale,}{.:formats,}{+:variants,}{.:handlers,}" + + def initialize(pattern=nil) + @pattern = pattern || DEFAULT_PATTERN + super() + end + + private + + def find_templates(name, prefix, partial, details, outside_app_allowed = false) + path = Path.build(name, prefix, partial) + query(path, details, details[:formats], outside_app_allowed) + end + + def query(path, details, formats, outside_app_allowed) + query = build_query(path, details) + + template_paths = find_template_paths query + template_paths = reject_files_external_to_app(template_paths) unless outside_app_allowed + + template_paths.map { |template| + handler, format, variant = extract_handler_and_format_and_variant(template, formats) + contents = File.binread(template) + + Template.new(contents, File.expand_path(template), handler, + :virtual_path => path.virtual, + :format => format, + :variant => variant, + :updated_at => mtime(template) + ) + } + end + + def reject_files_external_to_app(files) + files.reject { |filename| !inside_path?(@path, filename) } + end + + if RUBY_VERSION >= '2.2.0' + def find_template_paths(query) + Dir[query].reject { |filename| + File.directory?(filename) || + # deals with case-insensitive file systems. + !File.fnmatch(query, filename, File::FNM_EXTGLOB) + } + end + else + def find_template_paths(query) + # deals with case-insensitive file systems. + sanitizer = Hash.new { |h,dir| h[dir] = Dir["#{dir}/*"] } + + Dir[query].reject { |filename| + File.directory?(filename) || + !sanitizer[File.dirname(filename)].include?(filename) + } + end + end + + def inside_path?(path, filename) + filename = File.expand_path(filename) + path = File.join(path, '') + filename.start_with?(path) + end + + # Helper for building query glob string based on resolver's pattern. + def build_query(path, details) + query = @pattern.dup + + prefix = path.prefix.empty? ? "" : "#{escape_entry(path.prefix)}\\1" + query.gsub!(/\:prefix(\/)?/, prefix) + + partial = escape_entry(path.partial? ? "_#{path.name}" : path.name) + query.gsub!(/\:action/, partial) + + details.each do |ext, variants| + query.gsub!(/\:#{ext}/, "{#{variants.compact.uniq.join(',')}}") + end + + File.expand_path(query, @path) + end + + def escape_entry(entry) + entry.gsub(/[*?{}\[\]]/, '\\\\\\&') + end + + # Returns the file mtime from the filesystem. + def mtime(p) + File.mtime(p) + end + + # Extract handler, formats and variant from path. If a format cannot be found neither + # from the path, or the handler, we should return the array of formats given + # to the resolver. + def extract_handler_and_format_and_variant(path, default_formats) + pieces = File.basename(path).split(".") + pieces.shift + + extension = pieces.pop + unless extension + ActiveSupport::Deprecation.warn(<<-MSG.squish) + The file #{path} did not specify a template handler. The default is + currently ERB, but will change to RAW in the future. + MSG + end + + handler = Template.handler_for_extension(extension) + format, variant = pieces.last.split(EXTENSIONS[:variants], 2) if pieces.last + format &&= Template::Types[format] + + [handler, format, variant] + end + end + + # A resolver that loads files from the filesystem. It allows setting your own + # resolving pattern. Such pattern can be a glob string supported by some variables. + # + # ==== Examples + # + # Default pattern, loads views the same way as previous versions of rails, eg. when you're + # looking for `users/new` it will produce query glob: `users/new{.{en},}{.{html,js},}{.{erb,haml},}` + # + # FileSystemResolver.new("/path/to/views", ":prefix/:action{.:locale,}{.:formats,}{+:variants,}{.:handlers,}") + # + # This one allows you to keep files with different formats in separate subdirectories, + # eg. `users/new.html` will be loaded from `users/html/new.erb` or `users/new.html.erb`, + # `users/new.js` from `users/js/new.erb` or `users/new.js.erb`, etc. + # + # FileSystemResolver.new("/path/to/views", ":prefix/{:formats/,}:action{.:locale,}{.:formats,}{+:variants,}{.:handlers,}") + # + # If you don't specify a pattern then the default will be used. + # + # In order to use any of the customized resolvers above in a Rails application, you just need + # to configure ActionController::Base.view_paths in an initializer, for example: + # + # ActionController::Base.view_paths = FileSystemResolver.new( + # Rails.root.join("app/views"), + # ":prefix{/:locale}/:action{.:formats,}{+:variants,}{.:handlers,}" + # ) + # + # ==== Pattern format and variables + # + # Pattern has to be a valid glob string, and it allows you to use the + # following variables: + # + # * :prefix - usually the controller path + # * :action - name of the action + # * :locale - possible locale versions + # * :formats - possible request formats (for example html, json, xml...) + # * :variants - possible request variants (for example phone, tablet...) + # * :handlers - possible handlers (for example erb, haml, builder...) + # + class FileSystemResolver < PathResolver + def initialize(path, pattern=nil) + raise ArgumentError, "path already is a Resolver class" if path.is_a?(Resolver) + super(pattern) + @path = File.expand_path(path) + end + + def to_s + @path.to_s + end + alias :to_path :to_s + + def eql?(resolver) + self.class.equal?(resolver.class) && to_path == resolver.to_path + end + alias :== :eql? + end + + # An Optimized resolver for Rails' most common case. + class OptimizedFileSystemResolver < FileSystemResolver #:nodoc: + def build_query(path, details) + query = escape_entry(File.join(@path, path)) + + exts = EXTENSIONS.map do |ext, prefix| + "{#{details[ext].compact.uniq.map { |e| "#{prefix}#{e}," }.join}}" + end.join + + query + exts + end + end + + # The same as FileSystemResolver but does not allow templates to store + # a virtual path since it is invalid for such resolvers. + class FallbackFileSystemResolver < FileSystemResolver #:nodoc: + def self.instances + [new(""), new("/")] + end + + def decorate(*) + super.each { |t| t.virtual_path = nil } + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/template/text.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/template/text.rb new file mode 100644 index 0000000..04f5b8d --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/template/text.rb @@ -0,0 +1,34 @@ +module ActionView #:nodoc: + # = Action View Text Template + class Template + class Text #:nodoc: + attr_accessor :type + + def initialize(string, type = nil) + @string = string.to_s + @type = Types[type] || type if type + @type ||= Types[:text] + end + + def identifier + 'text template' + end + + def inspect + 'text template' + end + + def to_str + @string + end + + def render(*args) + to_str + end + + def formats + [@type.respond_to?(:ref) ? @type.ref : @type.to_s] + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/template/types.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/template/types.rb new file mode 100644 index 0000000..b84e028 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/template/types.rb @@ -0,0 +1,57 @@ +require 'set' +require 'active_support/core_ext/module/attribute_accessors' + +module ActionView + class Template + class Types + class Type + cattr_accessor :types + self.types = Set.new + + def self.register(*t) + types.merge(t.map { |type| type.to_s }) + end + + register :html, :text, :js, :css, :xml, :json + + def self.[](type) + return type if type.is_a?(self) + + if type.is_a?(Symbol) || types.member?(type.to_s) + new(type) + end + end + + attr_reader :symbol + + def initialize(symbol) + @symbol = symbol.to_sym + end + + delegate :to_s, :to_sym, :to => :symbol + alias to_str to_s + + def ref + to_sym || to_s + end + + def ==(type) + return false if type.blank? + symbol.to_sym == type.to_sym + end + end + + cattr_accessor :type_klass + + def self.delegate_to(klass) + self.type_klass = klass + end + + delegate_to Type + + def self.[](type) + type_klass[type] + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/test_case.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/test_case.rb new file mode 100644 index 0000000..1f9428c --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/test_case.rb @@ -0,0 +1,279 @@ +require 'active_support/core_ext/module/remove_method' +require 'action_controller' +require 'action_controller/test_case' +require 'action_view' + +require 'rails-dom-testing' + +module ActionView + # = Action View Test Case + class TestCase < ActiveSupport::TestCase + class TestController < ActionController::Base + include ActionDispatch::TestProcess + + attr_accessor :request, :response, :params + + class << self + attr_writer :controller_path + end + + def controller_path=(path) + self.class.controller_path=(path) + end + + def initialize + super + self.class.controller_path = "" + @request = ActionController::TestRequest.new + @response = ActionController::TestResponse.new + + @request.env.delete('PATH_INFO') + @params = {} + end + end + + module Behavior + extend ActiveSupport::Concern + + include ActionDispatch::Assertions, ActionDispatch::TestProcess + include Rails::Dom::Testing::Assertions + include ActionController::TemplateAssertions + include ActionView::Context + + include ActionDispatch::Routing::PolymorphicRoutes + + include AbstractController::Helpers + include ActionView::Helpers + include ActionView::RecordIdentifier + include ActionView::RoutingUrlFor + + include ActiveSupport::Testing::ConstantLookup + + delegate :lookup_context, :to => :controller + attr_accessor :controller, :output_buffer, :rendered + + module ClassMethods + def tests(helper_class) + case helper_class + when String, Symbol + self.helper_class = "#{helper_class.to_s.underscore}_helper".camelize.safe_constantize + when Module + self.helper_class = helper_class + end + end + + def determine_default_helper_class(name) + determine_constant_from_test_name(name) do |constant| + Module === constant && !(Class === constant) + end + end + + def helper_method(*methods) + # Almost a duplicate from ActionController::Helpers + methods.flatten.each do |method| + _helpers.module_eval <<-end_eval + def #{method}(*args, &block) # def current_user(*args, &block) + _test_case.send(%(#{method}), *args, &block) # _test_case.send(%(current_user), *args, &block) + end # end + end_eval + end + end + + attr_writer :helper_class + + def helper_class + @helper_class ||= determine_default_helper_class(name) + end + + def new(*) + include_helper_modules! + super + end + + private + + def include_helper_modules! + helper(helper_class) if helper_class + include _helpers + end + + end + + def setup_with_controller + @controller = ActionView::TestCase::TestController.new + @request = @controller.request + # empty string ensures buffer has UTF-8 encoding as + # new without arguments returns ASCII-8BIT encoded buffer like String#new + @output_buffer = ActiveSupport::SafeBuffer.new '' + @rendered = '' + + make_test_case_available_to_view! + say_no_to_protect_against_forgery! + end + + def config + @controller.config if @controller.respond_to?(:config) + end + + def render(options = {}, local_assigns = {}, &block) + view.assign(view_assigns) + @rendered << output = view.render(options, local_assigns, &block) + output + end + + def rendered_views + @_rendered_views ||= RenderedViewsCollection.new + end + + # Need to experiment if this priority is the best one: rendered => output_buffer + class RenderedViewsCollection + def initialize + @rendered_views ||= Hash.new { |hash, key| hash[key] = [] } + end + + def add(view, locals) + @rendered_views[view] ||= [] + @rendered_views[view] << locals + end + + def locals_for(view) + @rendered_views[view] + end + + def rendered_views + @rendered_views.keys + end + + def view_rendered?(view, expected_locals) + locals_for(view).any? do |actual_locals| + expected_locals.all? {|key, value| value == actual_locals[key] } + end + end + end + + included do + setup :setup_with_controller + end + + private + + # Need to experiment if this priority is the best one: rendered => output_buffer + def document_root_element + Nokogiri::HTML::Document.parse(@rendered.blank? ? @output_buffer : @rendered).root + end + + def say_no_to_protect_against_forgery! + _helpers.module_eval do + remove_possible_method :protect_against_forgery? + def protect_against_forgery? + false + end + end + end + + def make_test_case_available_to_view! + test_case_instance = self + _helpers.module_eval do + unless private_method_defined?(:_test_case) + define_method(:_test_case) { test_case_instance } + private :_test_case + end + end + end + + module Locals + attr_accessor :rendered_views + + def render(options = {}, local_assigns = {}) + case options + when Hash + if block_given? + rendered_views.add options[:layout], options[:locals] + elsif options.key?(:partial) + rendered_views.add options[:partial], options[:locals] + end + else + rendered_views.add options, local_assigns + end + + super + end + end + + # The instance of ActionView::Base that is used by +render+. + def view + @view ||= begin + view = @controller.view_context + view.singleton_class.send :include, _helpers + view.extend(Locals) + view.rendered_views = self.rendered_views + view.output_buffer = self.output_buffer + view + end + end + + alias_method :_view, :view + + INTERNAL_IVARS = [ + :@NAME, + :@failures, + :@assertions, + :@__io__, + :@_assertion_wrapped, + :@_assertions, + :@_result, + :@_routes, + :@controller, + :@_layouts, + :@_files, + :@_rendered_views, + :@method_name, + :@output_buffer, + :@_partials, + :@passed, + :@rendered, + :@request, + :@routes, + :@tagged_logger, + :@_templates, + :@options, + :@test_passed, + :@view, + :@view_context_class, + :@_subscribers, + :@html_document, + :@html_scanner_document + ] + + def _user_defined_ivars + instance_variables - INTERNAL_IVARS + end + + # Returns a Hash of instance variables and their values, as defined by + # the user in the test case, which are then assigned to the view being + # rendered. This is generally intended for internal use and extension + # frameworks. + def view_assigns + Hash[_user_defined_ivars.map do |ivar| + [ivar[1..-1].to_sym, instance_variable_get(ivar)] + end] + end + + def _routes + @controller._routes if @controller.respond_to?(:_routes) + end + + def method_missing(selector, *args) + if @controller.respond_to?(:_routes) && + ( @controller._routes.named_routes.route_defined?(selector) || + @controller._routes.mounted_helpers.method_defined?(selector) ) + @controller.__send__(selector, *args) + else + super + end + end + end + + include Behavior + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/testing/resolvers.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/testing/resolvers.rb new file mode 100644 index 0000000..e88f425 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/testing/resolvers.rb @@ -0,0 +1,54 @@ +require 'action_view/template/resolver' + +module ActionView #:nodoc: + # Use FixtureResolver in your tests to simulate the presence of files on the + # file system. This is used internally by Rails' own test suite, and is + # useful for testing extensions that have no way of knowing what the file + # system will look like at runtime. + class FixtureResolver < PathResolver + attr_reader :hash + + def initialize(hash = {}, pattern=nil) + super(pattern) + @hash = hash + end + + def to_s + @hash.keys.join(', ') + end + + private + + def query(path, exts, formats, _) + query = "" + EXTENSIONS.each_key do |ext| + query << '(' << exts[ext].map {|e| e && Regexp.escape(".#{e}") }.join('|') << '|)' + end + query = /^(#{Regexp.escape(path)})#{query}$/ + + templates = [] + @hash.each do |_path, array| + source, updated_at = array + next unless _path =~ query + handler, format, variant = extract_handler_and_format_and_variant(_path, formats) + templates << Template.new(source, _path, handler, + :virtual_path => path.virtual, + :format => format, + :variant => variant, + :updated_at => updated_at + ) + end + + templates.sort_by {|t| -t.identifier.match(/^#{query}$/).captures.reject(&:blank?).size } + end + end + + class NullResolver < PathResolver + def query(path, exts, formats, _) + handler, format, variant = extract_handler_and_format_and_variant(path, formats) + [ActionView::Template.new("Template generated by Null Resolver", path, handler, :virtual_path => path, :format => format, :variant => variant)] + end + end + +end + diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/version.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/version.rb new file mode 100644 index 0000000..f55d3fd --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/version.rb @@ -0,0 +1,8 @@ +require_relative 'gem_version' + +module ActionView + # Returns the version of the currently loaded ActionView as a Gem::Version + def self.version + gem_version + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/view_paths.rb b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/view_paths.rb new file mode 100644 index 0000000..2e203a7 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/actionview-4.2.6/lib/action_view/view_paths.rb @@ -0,0 +1,111 @@ +require 'action_view/base' + +module ActionView + module ViewPaths + extend ActiveSupport::Concern + + included do + class_attribute :_view_paths + self._view_paths = ActionView::PathSet.new + self._view_paths.freeze + end + + delegate :template_exists?, :view_paths, :formats, :formats=, + :locale, :locale=, :to => :lookup_context + + module ClassMethods + def _prefixes # :nodoc: + @_prefixes ||= begin + deprecated_prefixes = handle_deprecated_parent_prefixes + if deprecated_prefixes + deprecated_prefixes + else + return local_prefixes if superclass.abstract? + + local_prefixes + superclass._prefixes + end + end + end + + private + + # Override this method in your controller if you want to change paths prefixes for finding views. + # Prefixes defined here will still be added to parents' ._prefixes. + def local_prefixes + [controller_path] + end + + def handle_deprecated_parent_prefixes # TODO: remove in 4.3/5.0. + return unless respond_to?(:parent_prefixes) + + ActiveSupport::Deprecation.warn(<<-MSG.squish) + Overriding `ActionController::Base::parent_prefixes` is deprecated, + override `.local_prefixes` instead. + MSG + + local_prefixes + parent_prefixes + end + end + + # The prefixes used in render "foo" shortcuts. + def _prefixes # :nodoc: + self.class._prefixes + end + + # LookupContext is the object responsible to hold all information required to lookup + # templates, i.e. view paths and details. Check ActionView::LookupContext for more + # information. + def lookup_context + @_lookup_context ||= + ActionView::LookupContext.new(self.class._view_paths, details_for_lookup, _prefixes) + end + + def details_for_lookup + { } + end + + def append_view_path(path) + lookup_context.view_paths.push(*path) + end + + def prepend_view_path(path) + lookup_context.view_paths.unshift(*path) + end + + module ClassMethods + # Append a path to the list of view paths for this controller. + # + # ==== Parameters + # * path - If a String is provided, it gets converted into + # the default view path. You may also provide a custom view path + # (see ActionView::PathSet for more information) + def append_view_path(path) + self._view_paths = view_paths + Array(path) + end + + # Prepend a path to the list of view paths for this controller. + # + # ==== Parameters + # * path - If a String is provided, it gets converted into + # the default view path. You may also provide a custom view path + # (see ActionView::PathSet for more information) + def prepend_view_path(path) + self._view_paths = ActionView::PathSet.new(Array(path) + view_paths) + end + + # A list of all of the default view paths for this controller. + def view_paths + _view_paths + end + + # Set the view paths. + # + # ==== Parameters + # * paths - If a PathSet is provided, use that; + # otherwise, process the parameter into a PathSet. + def view_paths=(paths) + self._view_paths = ActionView::PathSet.new(Array(paths)) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/CHANGELOG.md b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/CHANGELOG.md new file mode 100644 index 0000000..97a061c --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/CHANGELOG.md @@ -0,0 +1,56 @@ +## Rails 4.2.6 (March 07, 2016) ## + +* No changes. + + +## Rails 4.2.5.2 (February 26, 2016) ## + +* No changes. + + +## Rails 4.2.5.1 (January 25, 2015) ## + +* No changes. + + +## Rails 4.2.5 (November 12, 2015) ## + +* No changes. + + +## Rails 4.2.4 (August 24, 2015) ## + +* Include I18n.locale into job serialization/deserialization and use it around + `perform`. + + Fixes #20799. + + *Johannes Opper* + + +## Rails 4.2.3 (June 25, 2015) ## + +* `assert_enqueued_jobs` and `assert_performed_jobs` in block form use the + given number as expected value. This makes the error message much easier to + understand. + + *y-yagi* + + +## Rails 4.2.2 (June 16, 2015) ## + +* No Changes * + + +## Rails 4.2.1 (March 19, 2015) ## + +* Allow keyword arguments to be used with Active Job. + + Fixes #18741. + + *Sean Griffin* + + +## Rails 4.2.0 (December 20, 2014) ## + +* Started project. diff --git a/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/MIT-LICENSE b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/MIT-LICENSE new file mode 100644 index 0000000..8b1e97b --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/MIT-LICENSE @@ -0,0 +1,21 @@ +Copyright (c) 2014 David Heinemeier Hansson + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/README.md b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/README.md new file mode 100644 index 0000000..3aecfd2 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/README.md @@ -0,0 +1,131 @@ +# Active Job -- Make work happen later + +Active Job is a framework for declaring jobs and making them run on a variety +of queueing backends. These jobs can be everything from regularly scheduled +clean-ups, to billing charges, to mailings. Anything that can be chopped up into +small units of work and run in parallel, really. + +It also serves as the backend for Action Mailer's #deliver_later functionality +that makes it easy to turn any mailing into a job for running later. That's +one of the most common jobs in a modern web application: Sending emails outside +of the request-response cycle, so the user doesn't have to wait on it. + +The main point is to ensure that all Rails apps will have a job infrastructure +in place, even if it's in the form of an "immediate runner". We can then have +framework features and other gems build on top of that, without having to worry +about API differences between Delayed Job and Resque. Picking your queuing +backend becomes more of an operational concern, then. And you'll be able to +switch between them without having to rewrite your jobs. + + +## Usage + +Set the queue adapter for Active Job: + +``` ruby +ActiveJob::Base.queue_adapter = :inline # default queue adapter +``` +Note: To learn how to use your preferred queueing backend see its adapter +documentation at +[ActiveJob::QueueAdapters](http://api.rubyonrails.org/classes/ActiveJob/QueueAdapters.html). + +Declare a job like so: + +```ruby +class MyJob < ActiveJob::Base + queue_as :my_jobs + + def perform(record) + record.do_work + end +end +``` + +Enqueue a job like so: + +```ruby +MyJob.perform_later record # Enqueue a job to be performed as soon the queueing system is free. +``` + +```ruby +MyJob.set(wait_until: Date.tomorrow.noon).perform_later(record) # Enqueue a job to be performed tomorrow at noon. +``` + +```ruby +MyJob.set(wait: 1.week).perform_later(record) # Enqueue a job to be performed 1 week from now. +``` + +That's it! + + +## GlobalID support + +Active Job supports [GlobalID serialization](https://github.com/rails/globalid/) for parameters. This makes it possible +to pass live Active Record objects to your job instead of class/id pairs, which +you then have to manually deserialize. Before, jobs would look like this: + +```ruby +class TrashableCleanupJob + def perform(trashable_class, trashable_id, depth) + trashable = trashable_class.constantize.find(trashable_id) + trashable.cleanup(depth) + end +end +``` + +Now you can simply do: + +```ruby +class TrashableCleanupJob + def perform(trashable, depth) + trashable.cleanup(depth) + end +end +``` + +This works with any class that mixes in GlobalID::Identification, which +by default has been mixed into Active Record classes. + + +## Supported queueing systems + +Active Job has built-in adapters for multiple queueing backends (Sidekiq, +Resque, Delayed Job and others). To get an up-to-date list of the adapters +see the API Documentation for [ActiveJob::QueueAdapters](http://api.rubyonrails.org/classes/ActiveJob/QueueAdapters.html). + +## Auxiliary gems + +* [activejob-stats](https://github.com/seuros/activejob-stats) + +## Download and installation + +The latest version of Active Job can be installed with RubyGems: + +``` + % [sudo] gem install activejob +``` + +Source code can be downloaded as part of the Rails project on GitHub + +* https://github.com/rails/rails/tree/4-2-stable/activejob + +## License + +Active Job is released under the MIT license: + +* http://www.opensource.org/licenses/MIT + + +## Support + +API documentation is at + +* http://api.rubyonrails.org + +Bug reports can be filed for the Ruby on Rails project here: + +* https://github.com/rails/rails/issues + +Feature requests should be discussed on the rails-core mailing list here: + +* https://groups.google.com/forum/?fromgroups#!forum/rubyonrails-core diff --git a/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job.rb b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job.rb new file mode 100644 index 0000000..1b582f5 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job.rb @@ -0,0 +1,37 @@ +#-- +# Copyright (c) 2014 David Heinemeier Hansson +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +#++ + +require 'active_support' +require 'active_support/rails' +require 'active_job/version' +require 'global_id' + +module ActiveJob + extend ActiveSupport::Autoload + + autoload :Base + autoload :QueueAdapters + autoload :ConfiguredJob + autoload :TestCase + autoload :TestHelper +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/arguments.rb b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/arguments.rb new file mode 100644 index 0000000..622c370 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/arguments.rb @@ -0,0 +1,144 @@ +require 'active_support/core_ext/hash' + +module ActiveJob + # Raised when an exception is raised during job arguments deserialization. + # + # Wraps the original exception raised as +original_exception+. + class DeserializationError < StandardError + attr_reader :original_exception + + def initialize(e) #:nodoc: + super("Error while trying to deserialize arguments: #{e.message}") + @original_exception = e + set_backtrace e.backtrace + end + end + + # Raised when an unsupported argument type is being set as job argument. We + # currently support NilClass, Fixnum, Float, String, TrueClass, FalseClass, + # Bignum and object that can be represented as GlobalIDs (ex: Active Record). + # Also raised if you set the key for a Hash something else than a string or + # a symbol. + class SerializationError < ArgumentError + end + + module Arguments + extend self + TYPE_WHITELIST = [ NilClass, Fixnum, Float, String, TrueClass, FalseClass, Bignum ] + + # Serializes a set of arguments. Whitelisted types are returned + # as-is. Arrays/Hashes are serialized element by element. + # All other types are serialized using GlobalID. + def serialize(arguments) + arguments.map { |argument| serialize_argument(argument) } + end + + # Deserializes a set of arguments. Whitelisted types are returned + # as-is. Arrays/Hashes are deserialized element by element. + # All other types are deserialized using GlobalID. + def deserialize(arguments) + arguments.map { |argument| deserialize_argument(argument) } + rescue => e + raise DeserializationError.new(e) + end + + private + GLOBALID_KEY = '_aj_globalid'.freeze + SYMBOL_KEYS_KEY = '_aj_symbol_keys'.freeze + WITH_INDIFFERENT_ACCESS_KEY = '_aj_hash_with_indifferent_access'.freeze + private_constant :GLOBALID_KEY, :SYMBOL_KEYS_KEY, :WITH_INDIFFERENT_ACCESS_KEY + + def serialize_argument(argument) + case argument + when *TYPE_WHITELIST + argument + when GlobalID::Identification + { GLOBALID_KEY => argument.to_global_id.to_s } + when Array + argument.map { |arg| serialize_argument(arg) } + when ActiveSupport::HashWithIndifferentAccess + result = serialize_hash(argument) + result[WITH_INDIFFERENT_ACCESS_KEY] = serialize_argument(true) + result + when Hash + symbol_keys = argument.each_key.grep(Symbol).map(&:to_s) + result = serialize_hash(argument) + result[SYMBOL_KEYS_KEY] = symbol_keys + result + else + raise SerializationError.new("Unsupported argument type: #{argument.class.name}") + end + end + + def deserialize_argument(argument) + case argument + when String + GlobalID::Locator.locate(argument) || argument + when *TYPE_WHITELIST + argument + when Array + argument.map { |arg| deserialize_argument(arg) } + when Hash + if serialized_global_id?(argument) + deserialize_global_id argument + else + deserialize_hash(argument) + end + else + raise ArgumentError, "Can only deserialize primitive arguments: #{argument.inspect}" + end + end + + def serialized_global_id?(hash) + hash.size == 1 and hash.include?(GLOBALID_KEY) + end + + def deserialize_global_id(hash) + GlobalID::Locator.locate hash[GLOBALID_KEY] + end + + def serialize_hash(argument) + argument.each_with_object({}) do |(key, value), hash| + hash[serialize_hash_key(key)] = serialize_argument(value) + end + end + + def deserialize_hash(serialized_hash) + result = serialized_hash.transform_values { |v| deserialize_argument(v) } + if result.delete(WITH_INDIFFERENT_ACCESS_KEY) + result = result.with_indifferent_access + elsif symbol_keys = result.delete(SYMBOL_KEYS_KEY) + result = transform_symbol_keys(result, symbol_keys) + end + result + end + + RESERVED_KEYS = [ + GLOBALID_KEY, GLOBALID_KEY.to_sym, + SYMBOL_KEYS_KEY, SYMBOL_KEYS_KEY.to_sym, + WITH_INDIFFERENT_ACCESS_KEY, WITH_INDIFFERENT_ACCESS_KEY.to_sym, + ] + private_constant :RESERVED_KEYS + + def serialize_hash_key(key) + case key + when *RESERVED_KEYS + raise SerializationError.new("Can't serialize a Hash with reserved key #{key.inspect}") + when String, Symbol + key.to_s + else + raise SerializationError.new("Only string and symbol hash keys may be serialized as job arguments, but #{key.inspect} is a #{key.class}") + end + end + + def transform_symbol_keys(hash, symbol_keys) + hash.transform_keys do |key| + if symbol_keys.include?(key) + key.to_sym + else + key + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/base.rb b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/base.rb new file mode 100644 index 0000000..5d7c4cf --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/base.rb @@ -0,0 +1,68 @@ +require 'active_job/core' +require 'active_job/queue_adapter' +require 'active_job/queue_name' +require 'active_job/enqueuing' +require 'active_job/execution' +require 'active_job/callbacks' +require 'active_job/logging' +require 'active_job/translation' + +module ActiveJob #:nodoc: + # = Active Job + # + # Active Job objects can be configured to work with different backend + # queuing frameworks. To specify a queue adapter to use: + # + # ActiveJob::Base.queue_adapter = :inline + # + # A list of supported adapters can be found in QueueAdapters. + # + # Active Job objects can be defined by creating a class that inherits + # from the ActiveJob::Base class. The only necessary method to + # implement is the "perform" method. + # + # To define an Active Job object: + # + # class ProcessPhotoJob < ActiveJob::Base + # def perform(photo) + # photo.watermark!('Rails') + # photo.rotate!(90.degrees) + # photo.resize_to_fit!(300, 300) + # photo.upload! + # end + # end + # + # Records that are passed in are serialized/deserialized using Global + # ID. More information can be found in Arguments. + # + # To enqueue a job to be performed as soon the queueing system is free: + # + # ProcessPhotoJob.perform_later(photo) + # + # To enqueue a job to be processed at some point in the future: + # + # ProcessPhotoJob.set(wait_until: Date.tomorrow.noon).perform_later(photo) + # + # More information can be found in ActiveJob::Core::ClassMethods#set + # + # A job can also be processed immediately without sending to the queue: + # + # ProcessPhotoJob.perform_now(photo) + # + # == Exceptions + # + # * DeserializationError - Error class for deserialization errors. + # * SerializationError - Error class for serialization errors. + class Base + include Core + include QueueAdapter + include QueueName + include Enqueuing + include Execution + include Callbacks + include Logging + include Translation + + ActiveSupport.run_load_hooks(:active_job, self) + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/callbacks.rb b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/callbacks.rb new file mode 100644 index 0000000..c4ceb48 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/callbacks.rb @@ -0,0 +1,146 @@ +require 'active_support/callbacks' + +module ActiveJob + # = Active Job Callbacks + # + # Active Job provides hooks during the lifecycle of a job. Callbacks allow you + # to trigger logic during the lifecycle of a job. Available callbacks are: + # + # * before_enqueue + # * around_enqueue + # * after_enqueue + # * before_perform + # * around_perform + # * after_perform + # + module Callbacks + extend ActiveSupport::Concern + include ActiveSupport::Callbacks + + included do + define_callbacks :perform + define_callbacks :enqueue + end + + # These methods will be included into any Active Job object, adding + # callbacks for +perform+ and +enqueue+ methods. + module ClassMethods + # Defines a callback that will get called right before the + # job's perform method is executed. + # + # class VideoProcessJob < ActiveJob::Base + # queue_as :default + # + # before_perform do |job| + # UserMailer.notify_video_started_processing(job.arguments.first) + # end + # + # def perform(video_id) + # Video.find(video_id).process + # end + # end + # + def before_perform(*filters, &blk) + set_callback(:perform, :before, *filters, &blk) + end + + # Defines a callback that will get called right after the + # job's perform method has finished. + # + # class VideoProcessJob < ActiveJob::Base + # queue_as :default + # + # after_perform do |job| + # UserMailer.notify_video_processed(job.arguments.first) + # end + # + # def perform(video_id) + # Video.find(video_id).process + # end + # end + # + def after_perform(*filters, &blk) + set_callback(:perform, :after, *filters, &blk) + end + + # Defines a callback that will get called around the job's perform method. + # + # class VideoProcessJob < ActiveJob::Base + # queue_as :default + # + # around_perform do |job, block| + # UserMailer.notify_video_started_processing(job.arguments.first) + # block.call + # UserMailer.notify_video_processed(job.arguments.first) + # end + # + # def perform(video_id) + # Video.find(video_id).process + # end + # end + # + def around_perform(*filters, &blk) + set_callback(:perform, :around, *filters, &blk) + end + + # Defines a callback that will get called right before the + # job is enqueued. + # + # class VideoProcessJob < ActiveJob::Base + # queue_as :default + # + # before_enqueue do |job| + # $statsd.increment "enqueue-video-job.try" + # end + # + # def perform(video_id) + # Video.find(video_id).process + # end + # end + # + def before_enqueue(*filters, &blk) + set_callback(:enqueue, :before, *filters, &blk) + end + + # Defines a callback that will get called right after the + # job is enqueued. + # + # class VideoProcessJob < ActiveJob::Base + # queue_as :default + # + # after_enqueue do |job| + # $statsd.increment "enqueue-video-job.success" + # end + # + # def perform(video_id) + # Video.find(video_id).process + # end + # end + # + def after_enqueue(*filters, &blk) + set_callback(:enqueue, :after, *filters, &blk) + end + + # Defines a callback that will get called before and after the + # job is enqueued. + # + # class VideoProcessJob < ActiveJob::Base + # queue_as :default + # + # around_enqueue do |job, block| + # $statsd.time "video-job.process" do + # block.call + # end + # end + # + # def perform(video_id) + # Video.find(video_id).process + # end + # end + # + def around_enqueue(*filters, &blk) + set_callback(:enqueue, :around, *filters, &blk) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/configured_job.rb b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/configured_job.rb new file mode 100644 index 0000000..979280b --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/configured_job.rb @@ -0,0 +1,16 @@ +module ActiveJob + class ConfiguredJob #:nodoc: + def initialize(job_class, options={}) + @options = options + @job_class = job_class + end + + def perform_now(*args) + @job_class.new(*args).perform_now + end + + def perform_later(*args) + @job_class.new(*args).enqueue @options + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/core.rb b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/core.rb new file mode 100644 index 0000000..cb86f14 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/core.rb @@ -0,0 +1,93 @@ +module ActiveJob + module Core + extend ActiveSupport::Concern + + included do + # Job arguments + attr_accessor :arguments + attr_writer :serialized_arguments + + # Timestamp when the job should be performed + attr_accessor :scheduled_at + + # Job Identifier + attr_accessor :job_id + + # Queue in which the job will reside. + attr_writer :queue_name + + # I18n.locale to be used during the job. + attr_accessor :locale + end + + # These methods will be included into any Active Job object, adding + # helpers for de/serialization and creation of job instances. + module ClassMethods + # Creates a new job instance from a hash created with +serialize+ + def deserialize(job_data) + job = job_data['job_class'].constantize.new + job.job_id = job_data['job_id'] + job.queue_name = job_data['queue_name'] + job.serialized_arguments = job_data['arguments'] + job.locale = job_data['locale'] || I18n.locale + job + end + + # Creates a job preconfigured with the given options. You can call + # perform_later with the job arguments to enqueue the job with the + # preconfigured options + # + # ==== Options + # * :wait - Enqueues the job with the specified delay + # * :wait_until - Enqueues the job at the time specified + # * :queue - Enqueues the job on the specified queue + # + # ==== Examples + # + # VideoJob.set(queue: :some_queue).perform_later(Video.last) + # VideoJob.set(wait: 5.minutes).perform_later(Video.last) + # VideoJob.set(wait_until: Time.now.tomorrow).perform_later(Video.last) + # VideoJob.set(queue: :some_queue, wait: 5.minutes).perform_later(Video.last) + # VideoJob.set(queue: :some_queue, wait_until: Time.now.tomorrow).perform_later(Video.last) + def set(options={}) + ConfiguredJob.new(self, options) + end + end + + # Creates a new job instance. Takes the arguments that will be + # passed to the perform method. + def initialize(*arguments) + @arguments = arguments + @job_id = SecureRandom.uuid + @queue_name = self.class.queue_name + end + + # Returns a hash with the job data that can safely be passed to the + # queueing adapter. + def serialize + { + 'job_class' => self.class.name, + 'job_id' => job_id, + 'queue_name' => queue_name, + 'arguments' => serialize_arguments(arguments), + 'locale' => I18n.locale + } + end + + private + def deserialize_arguments_if_needed + if defined?(@serialized_arguments) && @serialized_arguments.present? + @arguments = deserialize_arguments(@serialized_arguments) + @serialized_arguments = nil + end + end + + def serialize_arguments(serialized_args) + Arguments.serialize(serialized_args) + end + + def deserialize_arguments(serialized_args) + Arguments.deserialize(serialized_args) + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/enqueuing.rb b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/enqueuing.rb new file mode 100644 index 0000000..430c17e --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/enqueuing.rb @@ -0,0 +1,77 @@ +require 'active_job/arguments' + +module ActiveJob + module Enqueuing + extend ActiveSupport::Concern + + # Includes the +perform_later+ method for job initialization. + module ClassMethods + # Push a job onto the queue. The arguments must be legal JSON types + # (string, int, float, nil, true, false, hash or array) or + # GlobalID::Identification instances. Arbitrary Ruby objects + # are not supported. + # + # Returns an instance of the job class queued with arguments available in + # Job#arguments. + def perform_later(*args) + job_or_instantiate(*args).enqueue + end + + protected + def job_or_instantiate(*args) + args.first.is_a?(self) ? args.first : new(*args) + end + end + + # Reschedules the job to be re-executed. This is useful in combination + # with the +rescue_from+ option. When you rescue an exception from your job + # you can ask Active Job to retry performing your job. + # + # ==== Options + # * :wait - Enqueues the job with the specified delay + # * :wait_until - Enqueues the job at the time specified + # * :queue - Enqueues the job on the specified queue + # + # ==== Examples + # + # class SiteScrapperJob < ActiveJob::Base + # rescue_from(ErrorLoadingSite) do + # retry_job queue: :low_priority + # end + # + # def perform(*args) + # # raise ErrorLoadingSite if cannot scrape + # end + # end + def retry_job(options={}) + enqueue options + end + + # Enqueues the job to be performed by the queue adapter. + # + # ==== Options + # * :wait - Enqueues the job with the specified delay + # * :wait_until - Enqueues the job at the time specified + # * :queue - Enqueues the job on the specified queue + # + # ==== Examples + # + # my_job_instance.enqueue + # my_job_instance.enqueue wait: 5.minutes + # my_job_instance.enqueue queue: :important + # my_job_instance.enqueue wait_until: Date.tomorrow.midnight + def enqueue(options={}) + self.scheduled_at = options[:wait].seconds.from_now.to_f if options[:wait] + self.scheduled_at = options[:wait_until].to_f if options[:wait_until] + self.queue_name = self.class.queue_name_from_part(options[:queue]) if options[:queue] + run_callbacks :enqueue do + if self.scheduled_at + self.class.queue_adapter.enqueue_at self, self.scheduled_at + else + self.class.queue_adapter.enqueue self + end + end + self + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/execution.rb b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/execution.rb new file mode 100644 index 0000000..79d232d --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/execution.rb @@ -0,0 +1,42 @@ +require 'active_support/rescuable' +require 'active_job/arguments' + +module ActiveJob + module Execution + extend ActiveSupport::Concern + include ActiveSupport::Rescuable + + # Includes methods for executing and performing jobs instantly. + module ClassMethods + # Performs the job immediately. + # + # MyJob.perform_now("mike") + # + def perform_now(*args) + job_or_instantiate(*args).perform_now + end + + def execute(job_data) #:nodoc: + job = deserialize(job_data) + job.perform_now + end + end + + # Performs the job immediately. The job is not sent to the queueing adapter + # but directly executed by blocking the execution of others until it's finished. + # + # MyJob.new(*args).perform_now + def perform_now + deserialize_arguments_if_needed + run_callbacks :perform do + perform(*arguments) + end + rescue => exception + rescue_with_handler(exception) || raise(exception) + end + + def perform(*) + fail NotImplementedError + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/gem_version.rb b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/gem_version.rb new file mode 100644 index 0000000..e70cfa7 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/gem_version.rb @@ -0,0 +1,15 @@ +module ActiveJob + # Returns the version of the currently loaded Active Job as a Gem::Version + def self.gem_version + Gem::Version.new VERSION::STRING + end + + module VERSION + MAJOR = 4 + MINOR = 2 + TINY = 6 + PRE = nil + + STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".") + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/logging.rb b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/logging.rb new file mode 100644 index 0000000..095d600 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/logging.rb @@ -0,0 +1,107 @@ +require 'active_support/core_ext/string/filters' +require 'active_support/tagged_logging' +require 'active_support/logger' + +module ActiveJob + module Logging #:nodoc: + extend ActiveSupport::Concern + + included do + cattr_accessor(:logger) { ActiveSupport::TaggedLogging.new(ActiveSupport::Logger.new(STDOUT)) } + + around_enqueue do |_, block, _| + tag_logger do + block.call + end + end + + around_perform do |job, block, _| + tag_logger(job.class.name, job.job_id) do + payload = {adapter: job.class.queue_adapter, job: job} + ActiveSupport::Notifications.instrument("perform_start.active_job", payload.dup) + ActiveSupport::Notifications.instrument("perform.active_job", payload) do + block.call + end + end + end + + after_enqueue do |job| + if job.scheduled_at + ActiveSupport::Notifications.instrument "enqueue_at.active_job", + adapter: job.class.queue_adapter, job: job + else + ActiveSupport::Notifications.instrument "enqueue.active_job", + adapter: job.class.queue_adapter, job: job + end + end + end + + private + def tag_logger(*tags) + if logger.respond_to?(:tagged) + tags.unshift "ActiveJob" unless logger_tagged_by_active_job? + ActiveJob::Base.logger.tagged(*tags){ yield } + else + yield + end + end + + def logger_tagged_by_active_job? + logger.formatter.current_tags.include?("ActiveJob") + end + + class LogSubscriber < ActiveSupport::LogSubscriber #:nodoc: + def enqueue(event) + info do + job = event.payload[:job] + "Enqueued #{job.class.name} (Job ID: #{job.job_id}) to #{queue_name(event)}" + args_info(job) + end + end + + def enqueue_at(event) + info do + job = event.payload[:job] + "Enqueued #{job.class.name} (Job ID: #{job.job_id}) to #{queue_name(event)} at #{scheduled_at(event)}" + args_info(job) + end + end + + def perform_start(event) + info do + job = event.payload[:job] + "Performing #{job.class.name} from #{queue_name(event)}" + args_info(job) + end + end + + def perform(event) + info do + job = event.payload[:job] + "Performed #{job.class.name} from #{queue_name(event)} in #{event.duration.round(2)}ms" + end + end + + private + def queue_name(event) + event.payload[:adapter].name.demodulize.remove('Adapter') + "(#{event.payload[:job].queue_name})" + end + + def args_info(job) + if job.arguments.any? + ' with arguments: ' + + job.arguments.map { |arg| arg.try(:to_global_id).try(:to_s) || arg.inspect }.join(', ') + else + '' + end + end + + def scheduled_at(event) + Time.at(event.payload[:job].scheduled_at).utc + end + + def logger + ActiveJob::Base.logger + end + end + end +end + +ActiveJob::Logging::LogSubscriber.attach_to :active_job diff --git a/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/queue_adapter.rb b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/queue_adapter.rb new file mode 100644 index 0000000..d48d56e --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/queue_adapter.rb @@ -0,0 +1,35 @@ +require 'active_job/queue_adapters/inline_adapter' +require 'active_support/core_ext/string/inflections' + +module ActiveJob + # The ActionJob::QueueAdapter module is used to load the + # correct adapter. The default queue adapter is the :inline queue. + module QueueAdapter #:nodoc: + extend ActiveSupport::Concern + + # Includes the setter method for changing the active queue adapter. + module ClassMethods + mattr_reader(:queue_adapter) { ActiveJob::QueueAdapters::InlineAdapter } + + # Specify the backend queue provider. The default queue adapter + # is the :inline queue. See QueueAdapters for more + # information. + def queue_adapter=(name_or_adapter) + @@queue_adapter = \ + case name_or_adapter + when :test + ActiveJob::QueueAdapters::TestAdapter.new + when Symbol, String + load_adapter(name_or_adapter) + else + name_or_adapter if name_or_adapter.respond_to?(:enqueue) + end + end + + private + def load_adapter(name) + "ActiveJob::QueueAdapters::#{name.to_s.camelize}Adapter".constantize + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/queue_adapters.rb b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/queue_adapters.rb new file mode 100644 index 0000000..c112bb7 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/queue_adapters.rb @@ -0,0 +1,50 @@ +module ActiveJob + # == Active Job adapters + # + # Active Job has adapters for the following queueing backends: + # + # * {Backburner}[https://github.com/nesquena/backburner] + # * {Delayed Job}[https://github.com/collectiveidea/delayed_job] + # * {Qu}[https://github.com/bkeepers/qu] + # * {Que}[https://github.com/chanks/que] + # * {queue_classic}[https://github.com/QueueClassic/queue_classic] + # * {Resque 1.x}[https://github.com/resque/resque/tree/1-x-stable] + # * {Sidekiq}[http://sidekiq.org] + # * {Sneakers}[https://github.com/jondot/sneakers] + # * {Sucker Punch}[https://github.com/brandonhilkert/sucker_punch] + # + # === Backends Features + # + # | | Async | Queues | Delayed | Priorities | Timeout | Retries | + # |-------------------|-------|--------|------------|------------|---------|---------| + # | Backburner | Yes | Yes | Yes | Yes | Job | Global | + # | Delayed Job | Yes | Yes | Yes | Job | Global | Global | + # | Qu | Yes | Yes | No | No | No | Global | + # | Que | Yes | Yes | Yes | Job | No | Job | + # | queue_classic | Yes | Yes | Yes* | No | No | No | + # | Resque | Yes | Yes | Yes (Gem) | Queue | Global | Yes | + # | Sidekiq | Yes | Yes | Yes | Queue | No | Job | + # | Sneakers | Yes | Yes | No | Queue | Queue | No | + # | Sucker Punch | Yes | Yes | No | No | No | No | + # | Active Job Inline | No | Yes | N/A | N/A | N/A | N/A | + # + # NOTE: + # queue_classic supports job scheduling since version 3.1. + # For older versions you can use the queue_classic-later gem. + # + module QueueAdapters + extend ActiveSupport::Autoload + + autoload :InlineAdapter + autoload :BackburnerAdapter + autoload :DelayedJobAdapter + autoload :QuAdapter + autoload :QueAdapter + autoload :QueueClassicAdapter + autoload :ResqueAdapter + autoload :SidekiqAdapter + autoload :SneakersAdapter + autoload :SuckerPunchAdapter + autoload :TestAdapter + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/queue_adapters/backburner_adapter.rb b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/queue_adapters/backburner_adapter.rb new file mode 100644 index 0000000..2453d06 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/queue_adapters/backburner_adapter.rb @@ -0,0 +1,36 @@ +require 'backburner' + +module ActiveJob + module QueueAdapters + # == Backburner adapter for Active Job + # + # Backburner is a beanstalkd-powered job queue that can handle a very + # high volume of jobs. You create background jobs and place them on + # multiple work queues to be processed later. Read more about + # Backburner {here}[https://github.com/nesquena/backburner]. + # + # To use Backburner set the queue_adapter config to +:backburner+. + # + # Rails.application.config.active_job.queue_adapter = :backburner + class BackburnerAdapter + class << self + def enqueue(job) #:nodoc: + Backburner::Worker.enqueue JobWrapper, [ job.serialize ], queue: job.queue_name + end + + def enqueue_at(job, timestamp) #:nodoc: + delay = timestamp - Time.current.to_f + Backburner::Worker.enqueue JobWrapper, [ job.serialize ], queue: job.queue_name, delay: delay + end + end + + class JobWrapper #:nodoc: + class << self + def perform(job_data) + Base.execute job_data + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/queue_adapters/delayed_job_adapter.rb b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/queue_adapters/delayed_job_adapter.rb new file mode 100644 index 0000000..69d9e70 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/queue_adapters/delayed_job_adapter.rb @@ -0,0 +1,39 @@ +require 'delayed_job' + +module ActiveJob + module QueueAdapters + # == Delayed Job adapter for Active Job + # + # Delayed::Job (or DJ) encapsulates the common pattern of asynchronously + # executing longer tasks in the background. Although DJ can have many + # storage backends, one of the most used is based on Active Record. + # Read more about Delayed Job {here}[https://github.com/collectiveidea/delayed_job]. + # + # To use Delayed Job, set the queue_adapter config to +:delayed_job+. + # + # Rails.application.config.active_job.queue_adapter = :delayed_job + class DelayedJobAdapter + class << self + def enqueue(job) #:nodoc: + Delayed::Job.enqueue(JobWrapper.new(job.serialize), queue: job.queue_name) + end + + def enqueue_at(job, timestamp) #:nodoc: + Delayed::Job.enqueue(JobWrapper.new(job.serialize), queue: job.queue_name, run_at: Time.at(timestamp)) + end + end + + class JobWrapper #:nodoc: + attr_accessor :job_data + + def initialize(job_data) + @job_data = job_data + end + + def perform + Base.execute(job_data) + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/queue_adapters/inline_adapter.rb b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/queue_adapters/inline_adapter.rb new file mode 100644 index 0000000..e25d88e --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/queue_adapters/inline_adapter.rb @@ -0,0 +1,23 @@ +module ActiveJob + module QueueAdapters + # == Active Job Inline adapter + # + # When enqueueing jobs with the Inline adapter the job will be executed + # immediately. + # + # To use the Inline set the queue_adapter config to +:inline+. + # + # Rails.application.config.active_job.queue_adapter = :inline + class InlineAdapter + class << self + def enqueue(job) #:nodoc: + Base.execute(job.serialize) + end + + def enqueue_at(*) #:nodoc: + raise NotImplementedError.new("Use a queueing backend to enqueue jobs in the future. Read more at http://guides.rubyonrails.org/active_job_basics.html") + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/queue_adapters/qu_adapter.rb b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/queue_adapters/qu_adapter.rb new file mode 100644 index 0000000..30aa5a4 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/queue_adapters/qu_adapter.rb @@ -0,0 +1,42 @@ +require 'qu' + +module ActiveJob + module QueueAdapters + # == Qu adapter for Active Job + # + # Qu is a Ruby library for queuing and processing background jobs. It is + # heavily inspired by delayed_job and Resque. Qu was created to overcome + # some shortcomings in the existing queuing libraries. + # The advantages of Qu are: Multiple backends (redis, mongo), jobs are + # requeued when worker is killed, resque-like API. + # + # Read more about Qu {here}[https://github.com/bkeepers/qu]. + # + # To use Qu set the queue_adapter config to +:qu+. + # + # Rails.application.config.active_job.queue_adapter = :qu + class QuAdapter + class << self + def enqueue(job, *args) #:nodoc: + Qu::Payload.new(klass: JobWrapper, args: [job.serialize]).tap do |payload| + payload.instance_variable_set(:@queue, job.queue_name) + end.push + end + + def enqueue_at(job, timestamp, *args) #:nodoc: + raise NotImplementedError + end + end + + class JobWrapper < Qu::Job #:nodoc: + def initialize(job_data) + @job_data = job_data + end + + def perform + Base.execute @job_data + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/queue_adapters/que_adapter.rb b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/queue_adapters/que_adapter.rb new file mode 100644 index 0000000..e501fe0 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/queue_adapters/que_adapter.rb @@ -0,0 +1,35 @@ +require 'que' + +module ActiveJob + module QueueAdapters + # == Que adapter for Active Job + # + # Que is a high-performance alternative to DelayedJob or QueueClassic that + # improves the reliability of your application by protecting your jobs with + # the same ACID guarantees as the rest of your data. Que is a queue for + # Ruby and PostgreSQL that manages jobs using advisory locks. + # + # Read more about Que {here}[https://github.com/chanks/que]. + # + # To use Que set the queue_adapter config to +:que+. + # + # Rails.application.config.active_job.queue_adapter = :que + class QueAdapter + class << self + def enqueue(job) #:nodoc: + JobWrapper.enqueue job.serialize, queue: job.queue_name + end + + def enqueue_at(job, timestamp) #:nodoc: + JobWrapper.enqueue job.serialize, queue: job.queue_name, run_at: Time.at(timestamp) + end + end + + class JobWrapper < Que::Job #:nodoc: + def run(job_data) + Base.execute job_data + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/queue_adapters/queue_classic_adapter.rb b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/queue_adapters/queue_classic_adapter.rb new file mode 100644 index 0000000..34c11a6 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/queue_adapters/queue_classic_adapter.rb @@ -0,0 +1,54 @@ +require 'queue_classic' + +module ActiveJob + module QueueAdapters + # == queue_classic adapter for Active Job + # + # queue_classic provides a simple interface to a PostgreSQL-backed message + # queue. queue_classic specializes in concurrent locking and minimizing + # database load while providing a simple, intuitive developer experience. + # queue_classic assumes that you are already using PostgreSQL in your + # production environment and that adding another dependency (e.g. redis, + # beanstalkd, 0mq) is undesirable. + # + # Read more about queue_classic {here}[https://github.com/QueueClassic/queue_classic]. + # + # To use queue_classic set the queue_adapter config to +:queue_classic+. + # + # Rails.application.config.active_job.queue_adapter = :queue_classic + class QueueClassicAdapter + class << self + def enqueue(job) #:nodoc: + build_queue(job.queue_name).enqueue("#{JobWrapper.name}.perform", job.serialize) + end + + def enqueue_at(job, timestamp) #:nodoc: + queue = build_queue(job.queue_name) + unless queue.respond_to?(:enqueue_at) + raise NotImplementedError, 'To be able to schedule jobs with queue_classic ' \ + 'the QC::Queue needs to respond to `enqueue_at(timestamp, method, *args)`. ' \ + 'You can implement this yourself or you can use the queue_classic-later gem.' + end + queue.enqueue_at(timestamp, "#{JobWrapper.name}.perform", job.serialize) + end + + # Builds a QC::Queue object to schedule jobs on. + # + # If you have a custom QC::Queue subclass you'll need to subclass + # ActiveJob::QueueAdapters::QueueClassicAdapter and override the + # build_queue method. + def build_queue(queue_name) + QC::Queue.new(queue_name) + end + end + + class JobWrapper #:nodoc: + class << self + def perform(job_data) + Base.execute job_data + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/queue_adapters/resque_adapter.rb b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/queue_adapters/resque_adapter.rb new file mode 100644 index 0000000..88c6b48 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/queue_adapters/resque_adapter.rb @@ -0,0 +1,52 @@ +require 'resque' +require 'active_support/core_ext/enumerable' +require 'active_support/core_ext/array/access' + +begin + require 'resque-scheduler' +rescue LoadError + begin + require 'resque_scheduler' + rescue LoadError + false + end +end + +module ActiveJob + module QueueAdapters + # == Resque adapter for Active Job + # + # Resque (pronounced like "rescue") is a Redis-backed library for creating + # background jobs, placing those jobs on multiple queues, and processing + # them later. + # + # Read more about Resque {here}[https://github.com/resque/resque]. + # + # To use Resque set the queue_adapter config to +:resque+. + # + # Rails.application.config.active_job.queue_adapter = :resque + class ResqueAdapter + class << self + def enqueue(job) #:nodoc: + Resque.enqueue_to job.queue_name, JobWrapper, job.serialize + end + + def enqueue_at(job, timestamp) #:nodoc: + unless Resque.respond_to?(:enqueue_at_with_queue) + raise NotImplementedError, "To be able to schedule jobs with Resque you need the " \ + "resque-scheduler gem. Please add it to your Gemfile and run bundle install" + end + Resque.enqueue_at_with_queue job.queue_name, timestamp, JobWrapper, job.serialize + end + end + + class JobWrapper #:nodoc: + class << self + def perform(job_data) + Base.execute job_data + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/queue_adapters/sidekiq_adapter.rb b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/queue_adapters/sidekiq_adapter.rb new file mode 100644 index 0000000..5a6b010 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/queue_adapters/sidekiq_adapter.rb @@ -0,0 +1,47 @@ +require 'sidekiq' + +module ActiveJob + module QueueAdapters + # == Sidekiq adapter for Active Job + # + # Simple, efficient background processing for Ruby. Sidekiq uses threads to + # handle many jobs at the same time in the same process. It does not + # require Rails but will integrate tightly with it to make background + # processing dead simple. + # + # Read more about Sidekiq {here}[http://sidekiq.org]. + # + # To use Sidekiq set the queue_adapter config to +:sidekiq+. + # + # Rails.application.config.active_job.queue_adapter = :sidekiq + class SidekiqAdapter + class << self + def enqueue(job) #:nodoc: + #Sidekiq::Client does not support symbols as keys + Sidekiq::Client.push \ + 'class' => JobWrapper, + 'wrapped' => job.class.to_s, + 'queue' => job.queue_name, + 'args' => [ job.serialize ] + end + + def enqueue_at(job, timestamp) #:nodoc: + Sidekiq::Client.push \ + 'class' => JobWrapper, + 'wrapped' => job.class.to_s, + 'queue' => job.queue_name, + 'args' => [ job.serialize ], + 'at' => timestamp + end + end + + class JobWrapper #:nodoc: + include Sidekiq::Worker + + def perform(job_data) + Base.execute job_data + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/queue_adapters/sneakers_adapter.rb b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/queue_adapters/sneakers_adapter.rb new file mode 100644 index 0000000..6d60a2f --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/queue_adapters/sneakers_adapter.rb @@ -0,0 +1,46 @@ +require 'sneakers' +require 'thread' + +module ActiveJob + module QueueAdapters + # == Sneakers adapter for Active Job + # + # A high-performance RabbitMQ background processing framework for Ruby. + # Sneakers is being used in production for both I/O and CPU intensive + # workloads, and have achieved the goals of high-performance and + # 0-maintenance, as designed. + # + # Read more about Sneakers {here}[https://github.com/jondot/sneakers]. + # + # To use Sneakers set the queue_adapter config to +:sneakers+. + # + # Rails.application.config.active_job.queue_adapter = :sneakers + class SneakersAdapter + @monitor = Monitor.new + + class << self + def enqueue(job) #:nodoc: + @monitor.synchronize do + JobWrapper.from_queue job.queue_name + JobWrapper.enqueue ActiveSupport::JSON.encode(job.serialize) + end + end + + def enqueue_at(job, timestamp) #:nodoc: + raise NotImplementedError + end + end + + class JobWrapper #:nodoc: + include Sneakers::Worker + from_queue 'default' + + def work(msg) + job_data = ActiveSupport::JSON.decode(msg) + Base.execute job_data + ack! + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/queue_adapters/sucker_punch_adapter.rb b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/queue_adapters/sucker_punch_adapter.rb new file mode 100644 index 0000000..be9e7fd --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/queue_adapters/sucker_punch_adapter.rb @@ -0,0 +1,40 @@ +require 'sucker_punch' + +module ActiveJob + module QueueAdapters + # == Sucker Punch adapter for Active Job + # + # Sucker Punch is a single-process Ruby asynchronous processing library. + # It's girl_friday and DSL sugar on top of Celluloid. With Celluloid's + # actor pattern, we can do asynchronous processing within a single process. + # This reduces costs of hosting on a service like Heroku along with the + # memory footprint of having to maintain additional jobs if hosting on + # a dedicated server. All queues can run within a single Rails/Sinatra + # process. + # + # Read more about Sucker Punch {here}[https://github.com/brandonhilkert/sucker_punch]. + # + # To use Sucker Punch set the queue_adapter config to +:sucker_punch+. + # + # Rails.application.config.active_job.queue_adapter = :sucker_punch + class SuckerPunchAdapter + class << self + def enqueue(job) #:nodoc: + JobWrapper.new.async.perform job.serialize + end + + def enqueue_at(job, timestamp) #:nodoc: + raise NotImplementedError + end + end + + class JobWrapper #:nodoc: + include SuckerPunch::Job + + def perform(job_data) + Base.execute job_data + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/queue_adapters/test_adapter.rb b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/queue_adapters/test_adapter.rb new file mode 100644 index 0000000..ea9df9a --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/queue_adapters/test_adapter.rb @@ -0,0 +1,51 @@ +module ActiveJob + module QueueAdapters + # == Test adapter for Active Job + # + # The test adapter should be used only in testing. Along with + # ActiveJob::TestCase and ActiveJob::TestHelper + # it makes a great tool to test your Rails application. + # + # To use the test adapter set queue_adapter config to +:test+. + # + # Rails.application.config.active_job.queue_adapter = :test + class TestAdapter + delegate :name, to: :class + attr_accessor(:perform_enqueued_jobs, :perform_enqueued_at_jobs) + attr_writer(:enqueued_jobs, :performed_jobs) + + def initialize + self.perform_enqueued_jobs = false + self.perform_enqueued_at_jobs = false + end + + # Provides a store of all the enqueued jobs with the TestAdapter so you can check them. + def enqueued_jobs + @enqueued_jobs ||= [] + end + + # Provides a store of all the performed jobs with the TestAdapter so you can check them. + def performed_jobs + @performed_jobs ||= [] + end + + def enqueue(job) #:nodoc: + if perform_enqueued_jobs + performed_jobs << {job: job.class, args: job.serialize['arguments'], queue: job.queue_name} + Base.execute job.serialize + else + enqueued_jobs << {job: job.class, args: job.serialize['arguments'], queue: job.queue_name} + end + end + + def enqueue_at(job, timestamp) #:nodoc: + if perform_enqueued_at_jobs + performed_jobs << {job: job.class, args: job.serialize['arguments'], queue: job.queue_name, at: timestamp} + Base.execute job.serialize + else + enqueued_jobs << {job: job.class, args: job.serialize['arguments'], queue: job.queue_name, at: timestamp} + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/queue_name.rb b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/queue_name.rb new file mode 100644 index 0000000..9ae0345 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/queue_name.rb @@ -0,0 +1,51 @@ +module ActiveJob + module QueueName + extend ActiveSupport::Concern + + # Includes the ability to override the default queue name and prefix. + module ClassMethods + mattr_accessor(:queue_name_prefix) + mattr_accessor(:default_queue_name) { "default" } + + # Specifies the name of the queue to process the job on. + # + # class PublishToFeedJob < ActiveJob::Base + # queue_as :feeds + # + # def perform(post) + # post.to_feed! + # end + # end + def queue_as(part_name=nil, &block) + if block_given? + self.queue_name = block + else + self.queue_name = queue_name_from_part(part_name) + end + end + + def queue_name_from_part(part_name) #:nodoc: + queue_name = part_name || default_queue_name + name_parts = [queue_name_prefix.presence, queue_name] + name_parts.compact.join(queue_name_delimiter) + end + end + + included do + class_attribute :queue_name, instance_accessor: false + class_attribute :queue_name_delimiter, instance_accessor: false + + self.queue_name = default_queue_name + self.queue_name_delimiter = '_' # set default delimiter to '_' + end + + # Returns the name of the queue the job will be run on + def queue_name + if @queue_name.is_a?(Proc) + @queue_name = self.class.queue_name_from_part(instance_exec(&@queue_name)) + end + @queue_name + end + + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/railtie.rb b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/railtie.rb new file mode 100644 index 0000000..6538ac1 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/railtie.rb @@ -0,0 +1,23 @@ +require 'global_id/railtie' +require 'active_job' + +module ActiveJob + # = Active Job Railtie + class Railtie < Rails::Railtie # :nodoc: + config.active_job = ActiveSupport::OrderedOptions.new + + initializer 'active_job.logger' do + ActiveSupport.on_load(:active_job) { self.logger = ::Rails.logger } + end + + initializer "active_job.set_configs" do |app| + options = app.config.active_job + options.queue_adapter ||= :inline + + ActiveSupport.on_load(:active_job) do + options.each { |k,v| send("#{k}=", v) } + end + end + + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/test_case.rb b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/test_case.rb new file mode 100644 index 0000000..d894a7b --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/test_case.rb @@ -0,0 +1,7 @@ +require 'active_support/test_case' + +module ActiveJob + class TestCase < ActiveSupport::TestCase + include ActiveJob::TestHelper + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/test_helper.rb b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/test_helper.rb new file mode 100644 index 0000000..952856a --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/test_helper.rb @@ -0,0 +1,230 @@ +require 'active_support/core_ext/hash/keys' + +module ActiveJob + # Provides helper methods for testing Active Job + module TestHelper + extend ActiveSupport::Concern + + included do + def before_setup + @old_queue_adapter = queue_adapter + ActiveJob::Base.queue_adapter = :test + clear_enqueued_jobs + clear_performed_jobs + super + end + + def after_teardown + super + ActiveJob::Base.queue_adapter = @old_queue_adapter + end + + # Asserts that the number of enqueued jobs matches the given number. + # + # def test_jobs + # assert_enqueued_jobs 0 + # HelloJob.perform_later('david') + # assert_enqueued_jobs 1 + # HelloJob.perform_later('abdelkader') + # assert_enqueued_jobs 2 + # end + # + # If a block is passed, that block should cause the specified number of + # jobs to be enqueued. + # + # def test_jobs_again + # assert_enqueued_jobs 1 do + # HelloJob.perform_later('cristian') + # end + # + # assert_enqueued_jobs 2 do + # HelloJob.perform_later('aaron') + # HelloJob.perform_later('rafael') + # end + # end + def assert_enqueued_jobs(number) + if block_given? + original_count = enqueued_jobs.size + yield + new_count = enqueued_jobs.size + assert_equal number, new_count - original_count, + "#{number} jobs expected, but #{new_count - original_count} were enqueued" + else + enqueued_jobs_size = enqueued_jobs.size + assert_equal number, enqueued_jobs_size, "#{number} jobs expected, but #{enqueued_jobs_size} were enqueued" + end + end + + # Asserts that no jobs have been enqueued. + # + # def test_jobs + # assert_no_enqueued_jobs + # HelloJob.perform_later('jeremy') + # assert_enqueued_jobs 1 + # end + # + # If a block is passed, that block should not cause any job to be enqueued. + # + # def test_jobs_again + # assert_no_enqueued_jobs do + # # No job should be enqueued from this block + # end + # end + # + # Note: This assertion is simply a shortcut for: + # + # assert_enqueued_jobs 0, &block + def assert_no_enqueued_jobs(&block) + assert_enqueued_jobs 0, &block + end + + # Asserts that the number of performed jobs matches the given number. + # If no block is passed, perform_enqueued_jobs + # must be called around the job call. + # + # def test_jobs + # assert_performed_jobs 0 + # + # perform_enqueued_jobs do + # HelloJob.perform_later('xavier') + # end + # assert_performed_jobs 1 + # + # perform_enqueued_jobs do + # HelloJob.perform_later('yves') + # assert_performed_jobs 2 + # end + # end + # + # If a block is passed, that block should cause the specified number of + # jobs to be performed. + # + # def test_jobs_again + # assert_performed_jobs 1 do + # HelloJob.perform_later('robin') + # end + # + # assert_performed_jobs 2 do + # HelloJob.perform_later('carlos') + # HelloJob.perform_later('sean') + # end + # end + def assert_performed_jobs(number) + if block_given? + original_count = performed_jobs.size + perform_enqueued_jobs { yield } + new_count = performed_jobs.size + assert_equal number, new_count - original_count, + "#{number} jobs expected, but #{new_count - original_count} were performed" + else + performed_jobs_size = performed_jobs.size + assert_equal number, performed_jobs_size, "#{number} jobs expected, but #{performed_jobs_size} were performed" + end + end + + # Asserts that no jobs have been performed. + # + # def test_jobs + # assert_no_performed_jobs + # + # perform_enqueued_jobs do + # HelloJob.perform_later('matthew') + # assert_performed_jobs 1 + # end + # end + # + # If a block is passed, that block should not cause any job to be performed. + # + # def test_jobs_again + # assert_no_performed_jobs do + # # No job should be performed from this block + # end + # end + # + # Note: This assertion is simply a shortcut for: + # + # assert_performed_jobs 0, &block + def assert_no_performed_jobs(&block) + assert_performed_jobs 0, &block + end + + # Asserts that the job passed in the block has been enqueued with the given arguments. + # + # def test_assert_enqueued_with + # assert_enqueued_with(job: MyJob, args: [1,2,3], queue: 'low') do + # MyJob.perform_later(1,2,3) + # end + # end + def assert_enqueued_with(args = {}, &_block) + original_enqueued_jobs = enqueued_jobs.dup + clear_enqueued_jobs + args.assert_valid_keys(:job, :args, :at, :queue) + serialized_args = serialize_args_for_assertion(args) + yield + matching_job = enqueued_jobs.any? do |job| + serialized_args.all? { |key, value| value == job[key] } + end + assert matching_job, "No enqueued job found with #{args}" + ensure + queue_adapter.enqueued_jobs = original_enqueued_jobs + enqueued_jobs + end + + # Asserts that the job passed in the block has been performed with the given arguments. + # + # def test_assert_performed_with + # assert_performed_with(job: MyJob, args: [1,2,3], queue: 'high') do + # MyJob.perform_later(1,2,3) + # end + # end + def assert_performed_with(args = {}, &_block) + original_performed_jobs = performed_jobs.dup + clear_performed_jobs + args.assert_valid_keys(:job, :args, :at, :queue) + serialized_args = serialize_args_for_assertion(args) + perform_enqueued_jobs { yield } + matching_job = performed_jobs.any? do |job| + serialized_args.all? { |key, value| value == job[key] } + end + assert matching_job, "No performed job found with #{args}" + ensure + queue_adapter.performed_jobs = original_performed_jobs + performed_jobs + end + + def perform_enqueued_jobs + @old_perform_enqueued_jobs = queue_adapter.perform_enqueued_jobs + @old_perform_enqueued_at_jobs = queue_adapter.perform_enqueued_at_jobs + queue_adapter.perform_enqueued_jobs = true + queue_adapter.perform_enqueued_at_jobs = true + yield + ensure + queue_adapter.perform_enqueued_jobs = @old_perform_enqueued_jobs + queue_adapter.perform_enqueued_at_jobs = @old_perform_enqueued_at_jobs + end + + def queue_adapter + ActiveJob::Base.queue_adapter + end + + delegate :enqueued_jobs, :enqueued_jobs=, + :performed_jobs, :performed_jobs=, + to: :queue_adapter + + private + def clear_enqueued_jobs + enqueued_jobs.clear + end + + def clear_performed_jobs + performed_jobs.clear + end + + def serialize_args_for_assertion(args) + serialized_args = args.dup + if job_args = serialized_args.delete(:args) + serialized_args[:args] = ActiveJob::Arguments.serialize(job_args) + end + serialized_args + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/translation.rb b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/translation.rb new file mode 100644 index 0000000..67e4cf4 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/translation.rb @@ -0,0 +1,11 @@ +module ActiveJob + module Translation #:nodoc: + extend ActiveSupport::Concern + + included do + around_perform do |job, block, _| + I18n.with_locale(job.locale, &block) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/version.rb b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/version.rb new file mode 100644 index 0000000..971ba9f --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/active_job/version.rb @@ -0,0 +1,8 @@ +require_relative 'gem_version' + +module ActiveJob + # Returns the version of the currently loaded Active Job as a Gem::Version + def self.version + gem_version + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/rails/generators/job/job_generator.rb b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/rails/generators/job/job_generator.rb new file mode 100644 index 0000000..979ffcb --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/rails/generators/job/job_generator.rb @@ -0,0 +1,24 @@ +require 'rails/generators/named_base' + +module Rails + module Generators # :nodoc: + class JobGenerator < Rails::Generators::NamedBase # :nodoc: + desc 'This generator creates an active job file at app/jobs' + + class_option :queue, type: :string, default: 'default', desc: 'The queue name for the generated job' + + check_class_collision suffix: 'Job' + + hook_for :test_framework + + def self.default_generator_root + File.dirname(__FILE__) + end + + def create_job_file + template 'job.rb', File.join('app/jobs', class_path, "#{file_name}_job.rb") + end + + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/rails/generators/job/templates/job.rb b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/rails/generators/job/templates/job.rb new file mode 100644 index 0000000..462c71d --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activejob-4.2.6/lib/rails/generators/job/templates/job.rb @@ -0,0 +1,9 @@ +<% module_namespacing do -%> +class <%= class_name %>Job < ActiveJob::Base + queue_as :<%= options[:queue] %> + + def perform(*args) + # Do something later + end +end +<% end -%> diff --git a/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/CHANGELOG.md b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/CHANGELOG.md new file mode 100644 index 0000000..89c10ab --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/CHANGELOG.md @@ -0,0 +1,103 @@ +## Rails 4.2.6 (March 07, 2016) ## + +* No changes. + + +## Rails 4.2.5.2 (February 26, 2016) ## + +* No changes. + + +## Rails 4.2.5.1 (January 25, 2015) ## + +* No changes. + + +## Rails 4.2.5 (November 12, 2015) ## + +* No changes. + + +## Rails 4.2.4 (August 24, 2015) ## + +* No Changes * + + +## Rails 4.2.3 (June 25, 2015) ## + +* No Changes * + + +## Rails 4.2.2 (June 16, 2015) ## + +* No Changes * + + +## Rails 4.2.1 (March 19, 2015) ## + +* No changes. + + +## Rails 4.2.0 (December 20, 2014) ## + +* Passwords with spaces only allowed in `ActiveModel::SecurePassword`. + + Presence validation can be used to restore old behavior. + + *Yevhene Shemet* + +* Validate options passed to `ActiveModel::Validations.validate`. + + Preventing, in many cases, the simple mistake of using `validate` instead of `validates`. + + *Sonny Michaud* + +* Deprecate `reset_#{attribute}` in favor of `restore_#{attribute}`. + + These methods may cause confusion with the `reset_changes`, which has + different behaviour. + + *Rafael Mendonça França* + +* Deprecate `ActiveModel::Dirty#reset_changes` in favor of `#clear_changes_information`. + + Method's name is causing confusion with the `reset_#{attribute}` methods. + While `reset_name` sets the value of the name attribute to previous value + `reset_changes` only discards the changes. + + *Rafael Mendonça França* + +* Added `restore_attributes` method to `ActiveModel::Dirty` API which restores + the value of changed attributes to previous value. + + *Igor G.* + +* Allow proc and symbol as values for `only_integer` of `NumericalityValidator` + + *Robin Mehner* + +* `has_secure_password` now verifies that the given password is less than 72 + characters if validations are enabled. + + Fixes #14591. + + *Akshay Vishnoi* + +* Remove deprecated `Validator#setup` without replacement. + + See #10716. + + *Kuldeep Aggarwal* + +* Add plural and singular form for length validator's default messages. + + *Abd ar-Rahman Hamid* + +* Introduce `validate` as an alias for `valid?`. + + This is more intuitive when you want to run validations but don't care about + the return value. + + *Henrik Nyh* + +Please check [4-1-stable](https://github.com/rails/rails/blob/4-1-stable/activemodel/CHANGELOG.md) for previous changes. diff --git a/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/MIT-LICENSE b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/MIT-LICENSE new file mode 100644 index 0000000..d58dd9e --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/MIT-LICENSE @@ -0,0 +1,21 @@ +Copyright (c) 2004-2014 David Heinemeier Hansson + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/README.rdoc b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/README.rdoc new file mode 100644 index 0000000..79c330e --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/README.rdoc @@ -0,0 +1,272 @@ += Active Model -- model interfaces for Rails + +Active Model provides a known set of interfaces for usage in model classes. +They allow for Action Pack helpers to interact with non-Active Record models, +for example. Active Model also helps with building custom ORMs for use outside of +the Rails framework. + +Prior to Rails 3.0, if a plugin or gem developer wanted to have an object +interact with Action Pack helpers, it was required to either copy chunks of +code from Rails, or monkey patch entire helpers to make them handle objects +that did not exactly conform to the Active Record interface. This would result +in code duplication and fragile applications that broke on upgrades. Active +Model solves this by defining an explicit API. You can read more about the +API in ActiveModel::Lint::Tests. + +Active Model provides a default module that implements the basic API required +to integrate with Action Pack out of the box: ActiveModel::Model. + + class Person + include ActiveModel::Model + + attr_accessor :name, :age + validates_presence_of :name + end + + person = Person.new(name: 'bob', age: '18') + person.name # => 'bob' + person.age # => '18' + person.valid? # => true + +It includes model name introspections, conversions, translations and +validations, resulting in a class suitable to be used with Action Pack. +See ActiveModel::Model for more examples. + +Active Model also provides the following functionality to have ORM-like +behavior out of the box: + +* Add attribute magic to objects + + class Person + include ActiveModel::AttributeMethods + + attribute_method_prefix 'clear_' + define_attribute_methods :name, :age + + attr_accessor :name, :age + + def clear_attribute(attr) + send("#{attr}=", nil) + end + end + + person = Person.new + person.clear_name + person.clear_age + + {Learn more}[link:classes/ActiveModel/AttributeMethods.html] + +* Callbacks for certain operations + + class Person + extend ActiveModel::Callbacks + define_model_callbacks :create + + def create + run_callbacks :create do + # Your create action methods here + end + end + end + + This generates +before_create+, +around_create+ and +after_create+ + class methods that wrap your create method. + + {Learn more}[link:classes/ActiveModel/Callbacks.html] + +* Tracking value changes + + class Person + include ActiveModel::Dirty + + define_attribute_methods :name + + def name + @name + end + + def name=(val) + name_will_change! unless val == @name + @name = val + end + + def save + # do persistence work + changes_applied + end + end + + person = Person.new + person.name # => nil + person.changed? # => false + person.name = 'bob' + person.changed? # => true + person.changed # => ['name'] + person.changes # => { 'name' => [nil, 'bob'] } + person.save + person.name = 'robert' + person.save + person.previous_changes # => {'name' => ['bob, 'robert']} + + {Learn more}[link:classes/ActiveModel/Dirty.html] + +* Adding +errors+ interface to objects + + Exposing error messages allows objects to interact with Action Pack + helpers seamlessly. + + class Person + + def initialize + @errors = ActiveModel::Errors.new(self) + end + + attr_accessor :name + attr_reader :errors + + def validate! + errors.add(:name, "cannot be nil") if name.nil? + end + + def self.human_attribute_name(attr, options = {}) + "Name" + end + end + + person = Person.new + person.name = nil + person.validate! + person.errors.full_messages + # => ["Name cannot be nil"] + + {Learn more}[link:classes/ActiveModel/Errors.html] + +* Model name introspection + + class NamedPerson + extend ActiveModel::Naming + end + + NamedPerson.model_name.name # => "NamedPerson" + NamedPerson.model_name.human # => "Named person" + + {Learn more}[link:classes/ActiveModel/Naming.html] + +* Making objects serializable + + ActiveModel::Serialization provides a standard interface for your object + to provide +to_json+ or +to_xml+ serialization. + + class SerialPerson + include ActiveModel::Serialization + + attr_accessor :name + + def attributes + {'name' => name} + end + end + + s = SerialPerson.new + s.serializable_hash # => {"name"=>nil} + + class SerialPerson + include ActiveModel::Serializers::JSON + end + + s = SerialPerson.new + s.to_json # => "{\"name\":null}" + + class SerialPerson + include ActiveModel::Serializers::Xml + end + + s = SerialPerson.new + s.to_xml # => "\n "My attribute" + + {Learn more}[link:classes/ActiveModel/Translation.html] + +* Validation support + + class Person + include ActiveModel::Validations + + attr_accessor :first_name, :last_name + + validates_each :first_name, :last_name do |record, attr, value| + record.errors.add attr, 'starts with z.' if value.to_s[0] == ?z + end + end + + person = Person.new + person.first_name = 'zoolander' + person.valid? # => false + + {Learn more}[link:classes/ActiveModel/Validations.html] + +* Custom validators + + class HasNameValidator < ActiveModel::Validator + def validate(record) + record.errors[:name] = "must exist" if record.name.blank? + end + end + + class ValidatorPerson + include ActiveModel::Validations + validates_with HasNameValidator + attr_accessor :name + end + + p = ValidatorPerson.new + p.valid? # => false + p.errors.full_messages # => ["Name must exist"] + p.name = "Bob" + p.valid? # => true + + {Learn more}[link:classes/ActiveModel/Validator.html] + + +== Download and installation + +The latest version of Active Model can be installed with RubyGems: + + % [sudo] gem install activemodel + +Source code can be downloaded as part of the Rails project on GitHub + +* https://github.com/rails/rails/tree/4-2-stable/activemodel + + +== License + +Active Model is released under the MIT license: + +* http://www.opensource.org/licenses/MIT + + +== Support + +API documentation is at + +* http://api.rubyonrails.org + +Bug reports can be filed for the Ruby on Rails project here: + +* https://github.com/rails/rails/issues + +Feature requests should be discussed on the rails-core mailing list here: + +* https://groups.google.com/forum/?fromgroups#!forum/rubyonrails-core + diff --git a/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model.rb b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model.rb new file mode 100644 index 0000000..feb3d93 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model.rb @@ -0,0 +1,71 @@ +#-- +# Copyright (c) 2004-2014 David Heinemeier Hansson +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +#++ + +require 'active_support' +require 'active_support/rails' +require 'active_model/version' + +module ActiveModel + extend ActiveSupport::Autoload + + autoload :AttributeMethods + autoload :BlockValidator, 'active_model/validator' + autoload :Callbacks + autoload :Conversion + autoload :Dirty + autoload :EachValidator, 'active_model/validator' + autoload :ForbiddenAttributesProtection + autoload :Lint + autoload :Model + autoload :Name, 'active_model/naming' + autoload :Naming + autoload :SecurePassword + autoload :Serialization + autoload :TestCase + autoload :Translation + autoload :Validations + autoload :Validator + + eager_autoload do + autoload :Errors + autoload :StrictValidationFailed, 'active_model/errors' + end + + module Serializers + extend ActiveSupport::Autoload + + eager_autoload do + autoload :JSON + autoload :Xml + end + end + + def self.eager_load! + super + ActiveModel::Serializers.eager_load! + end +end + +ActiveSupport.on_load(:i18n) do + I18n.load_path << File.dirname(__FILE__) + '/active_model/locale/en.yml' +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/attribute_methods.rb b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/attribute_methods.rb new file mode 100644 index 0000000..96be551 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/attribute_methods.rb @@ -0,0 +1,478 @@ +require 'thread_safe' +require 'mutex_m' + +module ActiveModel + # Raised when an attribute is not defined. + # + # class User < ActiveRecord::Base + # has_many :pets + # end + # + # user = User.first + # user.pets.select(:id).first.user_id + # # => ActiveModel::MissingAttributeError: missing attribute: user_id + class MissingAttributeError < NoMethodError + end + + # == Active \Model \Attribute \Methods + # + # Provides a way to add prefixes and suffixes to your methods as + # well as handling the creation of ActiveRecord::Base-like + # class methods such as +table_name+. + # + # The requirements to implement ActiveModel::AttributeMethods are to: + # + # * include ActiveModel::AttributeMethods in your class. + # * Call each of its method you want to add, such as +attribute_method_suffix+ + # or +attribute_method_prefix+. + # * Call +define_attribute_methods+ after the other methods are called. + # * Define the various generic +_attribute+ methods that you have declared. + # * Define an +attributes+ method which returns a hash with each + # attribute name in your model as hash key and the attribute value as hash value. + # Hash keys must be strings. + # + # A minimal implementation could be: + # + # class Person + # include ActiveModel::AttributeMethods + # + # attribute_method_affix prefix: 'reset_', suffix: '_to_default!' + # attribute_method_suffix '_contrived?' + # attribute_method_prefix 'clear_' + # define_attribute_methods :name + # + # attr_accessor :name + # + # def attributes + # { 'name' => @name } + # end + # + # private + # + # def attribute_contrived?(attr) + # true + # end + # + # def clear_attribute(attr) + # send("#{attr}=", nil) + # end + # + # def reset_attribute_to_default!(attr) + # send("#{attr}=", 'Default Name') + # end + # end + module AttributeMethods + extend ActiveSupport::Concern + + NAME_COMPILABLE_REGEXP = /\A[a-zA-Z_]\w*[!?=]?\z/ + CALL_COMPILABLE_REGEXP = /\A[a-zA-Z_]\w*[!?]?\z/ + + included do + class_attribute :attribute_aliases, :attribute_method_matchers, instance_writer: false + self.attribute_aliases = {} + self.attribute_method_matchers = [ClassMethods::AttributeMethodMatcher.new] + end + + module ClassMethods + # Declares a method available for all attributes with the given prefix. + # Uses +method_missing+ and respond_to? to rewrite the method. + # + # #{prefix}#{attr}(*args, &block) + # + # to + # + # #{prefix}attribute(#{attr}, *args, &block) + # + # An instance method #{prefix}attribute must exist and accept + # at least the +attr+ argument. + # + # class Person + # include ActiveModel::AttributeMethods + # + # attr_accessor :name + # attribute_method_prefix 'clear_' + # define_attribute_methods :name + # + # private + # + # def clear_attribute(attr) + # send("#{attr}=", nil) + # end + # end + # + # person = Person.new + # person.name = 'Bob' + # person.name # => "Bob" + # person.clear_name + # person.name # => nil + def attribute_method_prefix(*prefixes) + self.attribute_method_matchers += prefixes.map! { |prefix| AttributeMethodMatcher.new prefix: prefix } + undefine_attribute_methods + end + + # Declares a method available for all attributes with the given suffix. + # Uses +method_missing+ and respond_to? to rewrite the method. + # + # #{attr}#{suffix}(*args, &block) + # + # to + # + # attribute#{suffix}(#{attr}, *args, &block) + # + # An attribute#{suffix} instance method must exist and accept at + # least the +attr+ argument. + # + # class Person + # include ActiveModel::AttributeMethods + # + # attr_accessor :name + # attribute_method_suffix '_short?' + # define_attribute_methods :name + # + # private + # + # def attribute_short?(attr) + # send(attr).length < 5 + # end + # end + # + # person = Person.new + # person.name = 'Bob' + # person.name # => "Bob" + # person.name_short? # => true + def attribute_method_suffix(*suffixes) + self.attribute_method_matchers += suffixes.map! { |suffix| AttributeMethodMatcher.new suffix: suffix } + undefine_attribute_methods + end + + # Declares a method available for all attributes with the given prefix + # and suffix. Uses +method_missing+ and respond_to? to rewrite + # the method. + # + # #{prefix}#{attr}#{suffix}(*args, &block) + # + # to + # + # #{prefix}attribute#{suffix}(#{attr}, *args, &block) + # + # An #{prefix}attribute#{suffix} instance method must exist and + # accept at least the +attr+ argument. + # + # class Person + # include ActiveModel::AttributeMethods + # + # attr_accessor :name + # attribute_method_affix prefix: 'reset_', suffix: '_to_default!' + # define_attribute_methods :name + # + # private + # + # def reset_attribute_to_default!(attr) + # send("#{attr}=", 'Default Name') + # end + # end + # + # person = Person.new + # person.name # => 'Gem' + # person.reset_name_to_default! + # person.name # => 'Default Name' + def attribute_method_affix(*affixes) + self.attribute_method_matchers += affixes.map! { |affix| AttributeMethodMatcher.new prefix: affix[:prefix], suffix: affix[:suffix] } + undefine_attribute_methods + end + + # Allows you to make aliases for attributes. + # + # class Person + # include ActiveModel::AttributeMethods + # + # attr_accessor :name + # attribute_method_suffix '_short?' + # define_attribute_methods :name + # + # alias_attribute :nickname, :name + # + # private + # + # def attribute_short?(attr) + # send(attr).length < 5 + # end + # end + # + # person = Person.new + # person.name = 'Bob' + # person.name # => "Bob" + # person.nickname # => "Bob" + # person.name_short? # => true + # person.nickname_short? # => true + def alias_attribute(new_name, old_name) + self.attribute_aliases = attribute_aliases.merge(new_name.to_s => old_name.to_s) + attribute_method_matchers.each do |matcher| + matcher_new = matcher.method_name(new_name).to_s + matcher_old = matcher.method_name(old_name).to_s + define_proxy_call false, self, matcher_new, matcher_old + end + end + + # Is +new_name+ an alias? + def attribute_alias?(new_name) + attribute_aliases.key? new_name.to_s + end + + # Returns the original name for the alias +name+ + def attribute_alias(name) + attribute_aliases[name.to_s] + end + + # Declares the attributes that should be prefixed and suffixed by + # ActiveModel::AttributeMethods. + # + # To use, pass attribute names (as strings or symbols), be sure to declare + # +define_attribute_methods+ after you define any prefix, suffix or affix + # methods, or they will not hook in. + # + # class Person + # include ActiveModel::AttributeMethods + # + # attr_accessor :name, :age, :address + # attribute_method_prefix 'clear_' + # + # # Call to define_attribute_methods must appear after the + # # attribute_method_prefix, attribute_method_suffix or + # # attribute_method_affix declares. + # define_attribute_methods :name, :age, :address + # + # private + # + # def clear_attribute(attr) + # send("#{attr}=", nil) + # end + # end + def define_attribute_methods(*attr_names) + attr_names.flatten.each { |attr_name| define_attribute_method(attr_name) } + end + + # Declares an attribute that should be prefixed and suffixed by + # ActiveModel::AttributeMethods. + # + # To use, pass an attribute name (as string or symbol), be sure to declare + # +define_attribute_method+ after you define any prefix, suffix or affix + # method, or they will not hook in. + # + # class Person + # include ActiveModel::AttributeMethods + # + # attr_accessor :name + # attribute_method_suffix '_short?' + # + # # Call to define_attribute_method must appear after the + # # attribute_method_prefix, attribute_method_suffix or + # # attribute_method_affix declares. + # define_attribute_method :name + # + # private + # + # def attribute_short?(attr) + # send(attr).length < 5 + # end + # end + # + # person = Person.new + # person.name = 'Bob' + # person.name # => "Bob" + # person.name_short? # => true + def define_attribute_method(attr_name) + attribute_method_matchers.each do |matcher| + method_name = matcher.method_name(attr_name) + + unless instance_method_already_implemented?(method_name) + generate_method = "define_method_#{matcher.method_missing_target}" + + if respond_to?(generate_method, true) + send(generate_method, attr_name) + else + define_proxy_call true, generated_attribute_methods, method_name, matcher.method_missing_target, attr_name.to_s + end + end + end + attribute_method_matchers_cache.clear + end + + # Removes all the previously dynamically defined methods from the class. + # + # class Person + # include ActiveModel::AttributeMethods + # + # attr_accessor :name + # attribute_method_suffix '_short?' + # define_attribute_method :name + # + # private + # + # def attribute_short?(attr) + # send(attr).length < 5 + # end + # end + # + # person = Person.new + # person.name = 'Bob' + # person.name_short? # => true + # + # Person.undefine_attribute_methods + # + # person.name_short? # => NoMethodError + def undefine_attribute_methods + generated_attribute_methods.module_eval do + instance_methods.each { |m| undef_method(m) } + end + attribute_method_matchers_cache.clear + end + + def generated_attribute_methods #:nodoc: + @generated_attribute_methods ||= Module.new { + extend Mutex_m + }.tap { |mod| include mod } + end + + protected + def instance_method_already_implemented?(method_name) #:nodoc: + generated_attribute_methods.method_defined?(method_name) + end + + private + # The methods +method_missing+ and +respond_to?+ of this module are + # invoked often in a typical rails, both of which invoke the method + # +match_attribute_method?+. The latter method iterates through an + # array doing regular expression matches, which results in a lot of + # object creations. Most of the time it returns a +nil+ match. As the + # match result is always the same given a +method_name+, this cache is + # used to alleviate the GC, which ultimately also speeds up the app + # significantly (in our case our test suite finishes 10% faster with + # this cache). + def attribute_method_matchers_cache #:nodoc: + @attribute_method_matchers_cache ||= ThreadSafe::Cache.new(initial_capacity: 4) + end + + def attribute_method_matchers_matching(method_name) #:nodoc: + attribute_method_matchers_cache.compute_if_absent(method_name) do + # Must try to match prefixes/suffixes first, or else the matcher with no prefix/suffix + # will match every time. + matchers = attribute_method_matchers.partition(&:plain?).reverse.flatten(1) + matchers.map { |method| method.match(method_name) }.compact + end + end + + # Define a method `name` in `mod` that dispatches to `send` + # using the given `extra` args. This fallbacks `define_method` + # and `send` if the given names cannot be compiled. + def define_proxy_call(include_private, mod, name, send, *extra) #:nodoc: + defn = if name =~ NAME_COMPILABLE_REGEXP + "def #{name}(*args)" + else + "define_method(:'#{name}') do |*args|" + end + + extra = (extra.map!(&:inspect) << "*args").join(", ") + + target = if send =~ CALL_COMPILABLE_REGEXP + "#{"self." unless include_private}#{send}(#{extra})" + else + "send(:'#{send}', #{extra})" + end + + mod.module_eval <<-RUBY, __FILE__, __LINE__ + 1 + #{defn} + #{target} + end + RUBY + end + + class AttributeMethodMatcher #:nodoc: + attr_reader :prefix, :suffix, :method_missing_target + + AttributeMethodMatch = Struct.new(:target, :attr_name, :method_name) + + def initialize(options = {}) + @prefix, @suffix = options.fetch(:prefix, ''), options.fetch(:suffix, '') + @regex = /^(?:#{Regexp.escape(@prefix)})(.*)(?:#{Regexp.escape(@suffix)})$/ + @method_missing_target = "#{@prefix}attribute#{@suffix}" + @method_name = "#{prefix}%s#{suffix}" + end + + def match(method_name) + if @regex =~ method_name + AttributeMethodMatch.new(method_missing_target, $1, method_name) + end + end + + def method_name(attr_name) + @method_name % attr_name + end + + def plain? + prefix.empty? && suffix.empty? + end + end + end + + # Allows access to the object attributes, which are held in the hash + # returned by attributes, as though they were first-class + # methods. So a +Person+ class with a +name+ attribute can for example use + # Person#name and Person#name= and never directly use + # the attributes hash -- except for multiple assigns with + # ActiveRecord::Base#attributes=. + # + # It's also possible to instantiate related objects, so a Client + # class belonging to the +clients+ table with a +master_id+ foreign key + # can instantiate master through Client#master. + def method_missing(method, *args, &block) + if respond_to_without_attributes?(method, true) + super + else + match = match_attribute_method?(method.to_s) + match ? attribute_missing(match, *args, &block) : super + end + end + + # +attribute_missing+ is like +method_missing+, but for attributes. When + # +method_missing+ is called we check to see if there is a matching + # attribute method. If so, we tell +attribute_missing+ to dispatch the + # attribute. This method can be overloaded to customize the behavior. + def attribute_missing(match, *args, &block) + __send__(match.target, match.attr_name, *args, &block) + end + + # A +Person+ instance with a +name+ attribute can ask + # person.respond_to?(:name), person.respond_to?(:name=), + # and person.respond_to?(:name?) which will all return +true+. + alias :respond_to_without_attributes? :respond_to? + def respond_to?(method, include_private_methods = false) + if super + true + elsif !include_private_methods && super(method, true) + # If we're here then we haven't found among non-private methods + # but found among all methods. Which means that the given method is private. + false + else + !match_attribute_method?(method.to_s).nil? + end + end + + protected + def attribute_method?(attr_name) #:nodoc: + respond_to_without_attributes?(:attributes) && attributes.include?(attr_name) + end + + private + # Returns a struct representing the matching attribute method. + # The struct's attributes are prefix, base and suffix. + def match_attribute_method?(method_name) + matches = self.class.send(:attribute_method_matchers_matching, method_name) + matches.detect { |match| attribute_method?(match.attr_name) } + end + + def missing_attribute(attr_name, stack) + raise ActiveModel::MissingAttributeError, "missing attribute: #{attr_name}", stack + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/callbacks.rb b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/callbacks.rb new file mode 100644 index 0000000..b3d70dc --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/callbacks.rb @@ -0,0 +1,149 @@ +require 'active_support/core_ext/array/extract_options' + +module ActiveModel + # == Active \Model \Callbacks + # + # Provides an interface for any class to have Active Record like callbacks. + # + # Like the Active Record methods, the callback chain is aborted as soon as + # one of the methods in the chain returns +false+. + # + # First, extend ActiveModel::Callbacks from the class you are creating: + # + # class MyModel + # extend ActiveModel::Callbacks + # end + # + # Then define a list of methods that you want callbacks attached to: + # + # define_model_callbacks :create, :update + # + # This will provide all three standard callbacks (before, around and after) + # for both the :create and :update methods. To implement, + # you need to wrap the methods you want callbacks on in a block so that the + # callbacks get a chance to fire: + # + # def create + # run_callbacks :create do + # # Your create action methods here + # end + # end + # + # Then in your class, you can use the +before_create+, +after_create+ and + # +around_create+ methods, just as you would in an Active Record model. + # + # before_create :action_before_create + # + # def action_before_create + # # Your code here + # end + # + # When defining an around callback remember to yield to the block, otherwise + # it won't be executed: + # + # around_create :log_status + # + # def log_status + # puts 'going to call the block...' + # yield + # puts 'block successfully called.' + # end + # + # You can choose not to have all three callbacks by passing a hash to the + # +define_model_callbacks+ method. + # + # define_model_callbacks :create, only: [:after, :before] + # + # Would only create the +after_create+ and +before_create+ callback methods in + # your class. + module Callbacks + def self.extended(base) #:nodoc: + base.class_eval do + include ActiveSupport::Callbacks + end + end + + # define_model_callbacks accepts the same options +define_callbacks+ does, + # in case you want to overwrite a default. Besides that, it also accepts an + # :only option, where you can choose if you want all types (before, + # around or after) or just some. + # + # define_model_callbacks :initializer, only: :after + # + # Note, the only: hash will apply to all callbacks defined + # on that method call. To get around this you can call the define_model_callbacks + # method as many times as you need. + # + # define_model_callbacks :create, only: :after + # define_model_callbacks :update, only: :before + # define_model_callbacks :destroy, only: :around + # + # Would create +after_create+, +before_update+ and +around_destroy+ methods + # only. + # + # You can pass in a class to before_, after_ and around_, + # in which case the callback will call that class's _ method + # passing the object that the callback is being called on. + # + # class MyModel + # extend ActiveModel::Callbacks + # define_model_callbacks :create + # + # before_create AnotherClass + # end + # + # class AnotherClass + # def self.before_create( obj ) + # # obj is the MyModel instance that the callback is being called on + # end + # end + # + # NOTE: +method_name+ passed to `define_model_callbacks` must not end with + # `!`, `?` or `=`. + def define_model_callbacks(*callbacks) + options = callbacks.extract_options! + options = { + terminator: ->(_,result) { result == false }, + skip_after_callbacks_if_terminated: true, + scope: [:kind, :name], + only: [:before, :around, :after] + }.merge!(options) + + types = Array(options.delete(:only)) + + callbacks.each do |callback| + define_callbacks(callback, options) + + types.each do |type| + send("_define_#{type}_model_callback", self, callback) + end + end + end + + private + + def _define_before_model_callback(klass, callback) #:nodoc: + klass.define_singleton_method("before_#{callback}") do |*args, &block| + set_callback(:"#{callback}", :before, *args, &block) + end + end + + def _define_around_model_callback(klass, callback) #:nodoc: + klass.define_singleton_method("around_#{callback}") do |*args, &block| + set_callback(:"#{callback}", :around, *args, &block) + end + end + + def _define_after_model_callback(klass, callback) #:nodoc: + klass.define_singleton_method("after_#{callback}") do |*args, &block| + options = args.extract_options! + options[:prepend] = true + conditional = ActiveSupport::Callbacks::Conditionals::Value.new { |v| + v != false + } + options[:if] = Array(options[:if]) << conditional + set_callback(:"#{callback}", :after, *(args << options), &block) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/conversion.rb b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/conversion.rb new file mode 100644 index 0000000..9c9b6f4 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/conversion.rb @@ -0,0 +1,100 @@ +module ActiveModel + # == Active \Model \Conversion + # + # Handles default conversions: to_model, to_key, to_param, and to_partial_path. + # + # Let's take for example this non-persisted object. + # + # class ContactMessage + # include ActiveModel::Conversion + # + # # ContactMessage are never persisted in the DB + # def persisted? + # false + # end + # end + # + # cm = ContactMessage.new + # cm.to_model == cm # => true + # cm.to_key # => nil + # cm.to_param # => nil + # cm.to_partial_path # => "contact_messages/contact_message" + module Conversion + extend ActiveSupport::Concern + + # If your object is already designed to implement all of the Active Model + # you can use the default :to_model implementation, which simply + # returns +self+. + # + # class Person + # include ActiveModel::Conversion + # end + # + # person = Person.new + # person.to_model == person # => true + # + # If your model does not act like an Active Model object, then you should + # define :to_model yourself returning a proxy object that wraps + # your object with Active Model compliant methods. + def to_model + self + end + + # Returns an Array of all key attributes if any is set, regardless if + # the object is persisted or not. Returns +nil+ if there are no key attributes. + # + # class Person + # include ActiveModel::Conversion + # attr_accessor :id + # end + # + # person = Person.create(id: 1) + # person.to_key # => [1] + def to_key + key = respond_to?(:id) && id + key ? [key] : nil + end + + # Returns a +string+ representing the object's key suitable for use in URLs, + # or +nil+ if persisted? is +false+. + # + # class Person + # include ActiveModel::Conversion + # attr_accessor :id + # def persisted? + # true + # end + # end + # + # person = Person.create(id: 1) + # person.to_param # => "1" + def to_param + (persisted? && key = to_key) ? key.join('-') : nil + end + + # Returns a +string+ identifying the path associated with the object. + # ActionPack uses this to find a suitable partial to represent the object. + # + # class Person + # include ActiveModel::Conversion + # end + # + # person = Person.new + # person.to_partial_path # => "people/person" + def to_partial_path + self.class._to_partial_path + end + + module ClassMethods #:nodoc: + # Provide a class level cache for #to_partial_path. This is an + # internal method and should not be accessed directly. + def _to_partial_path #:nodoc: + @_to_partial_path ||= begin + element = ActiveSupport::Inflector.underscore(ActiveSupport::Inflector.demodulize(name)) + collection = ActiveSupport::Inflector.tableize(name) + "#{collection}/#{element}".freeze + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/dirty.rb b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/dirty.rb new file mode 100644 index 0000000..d2a7996 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/dirty.rb @@ -0,0 +1,271 @@ +require 'active_support/hash_with_indifferent_access' +require 'active_support/core_ext/object/duplicable' +require 'active_support/core_ext/string/filters' + +module ActiveModel + # == Active \Model \Dirty + # + # Provides a way to track changes in your object in the same way as + # Active Record does. + # + # The requirements for implementing ActiveModel::Dirty are: + # + # * include ActiveModel::Dirty in your object. + # * Call define_attribute_methods passing each method you want to + # track. + # * Call attr_name_will_change! before each change to the tracked + # attribute. + # * Call changes_applied after the changes are persisted. + # * Call clear_changes_information when you want to reset the changes + # information. + # * Call restore_attributes when you want to restore previous data. + # + # A minimal implementation could be: + # + # class Person + # include ActiveModel::Dirty + # + # define_attribute_methods :name + # + # def initialize(name) + # @name = name + # end + # + # def name + # @name + # end + # + # def name=(val) + # name_will_change! unless val == @name + # @name = val + # end + # + # def save + # # do persistence work + # + # changes_applied + # end + # + # def reload! + # # get the values from the persistence layer + # + # clear_changes_information + # end + # + # def rollback! + # restore_attributes + # end + # end + # + # A newly instantiated +Person+ object is unchanged: + # + # person = Person.new("Uncle Bob") + # person.changed? # => false + # + # Change the name: + # + # person.name = 'Bob' + # person.changed? # => true + # person.name_changed? # => true + # person.name_changed?(from: "Uncle Bob", to: "Bob") # => true + # person.name_was # => "Uncle Bob" + # person.name_change # => ["Uncle Bob", "Bob"] + # person.name = 'Bill' + # person.name_change # => ["Uncle Bob", "Bill"] + # + # Save the changes: + # + # person.save + # person.changed? # => false + # person.name_changed? # => false + # + # Reset the changes: + # + # person.previous_changes # => {"name" => ["Uncle Bob", "Bill"]} + # person.reload! + # person.previous_changes # => {} + # + # Rollback the changes: + # + # person.name = "Uncle Bob" + # person.rollback! + # person.name # => "Bill" + # person.name_changed? # => false + # + # Assigning the same value leaves the attribute unchanged: + # + # person.name = 'Bill' + # person.name_changed? # => false + # person.name_change # => nil + # + # Which attributes have changed? + # + # person.name = 'Bob' + # person.changed # => ["name"] + # person.changes # => {"name" => ["Bill", "Bob"]} + # + # If an attribute is modified in-place then make use of + # +[attribute_name]_will_change!+ to mark that the attribute is changing. + # Otherwise Active Model can't track changes to in-place attributes. Note + # that Active Record can detect in-place modifications automatically. You do + # not need to call +[attribute_name]_will_change!+ on Active Record models. + # + # person.name_will_change! + # person.name_change # => ["Bill", "Bill"] + # person.name << 'y' + # person.name_change # => ["Bill", "Billy"] + module Dirty + extend ActiveSupport::Concern + include ActiveModel::AttributeMethods + + included do + attribute_method_suffix '_changed?', '_change', '_will_change!', '_was' + attribute_method_affix prefix: 'reset_', suffix: '!' + attribute_method_affix prefix: 'restore_', suffix: '!' + end + + # Returns +true+ if any attribute have unsaved changes, +false+ otherwise. + # + # person.changed? # => false + # person.name = 'bob' + # person.changed? # => true + def changed? + changed_attributes.present? + end + + # Returns an array with the name of the attributes with unsaved changes. + # + # person.changed # => [] + # person.name = 'bob' + # person.changed # => ["name"] + def changed + changed_attributes.keys + end + + # Returns a hash of changed attributes indicating their original + # and new values like attr => [original value, new value]. + # + # person.changes # => {} + # person.name = 'bob' + # person.changes # => { "name" => ["bill", "bob"] } + def changes + ActiveSupport::HashWithIndifferentAccess[changed.map { |attr| [attr, attribute_change(attr)] }] + end + + # Returns a hash of attributes that were changed before the model was saved. + # + # person.name # => "bob" + # person.name = 'robert' + # person.save + # person.previous_changes # => {"name" => ["bob", "robert"]} + def previous_changes + @previously_changed ||= ActiveSupport::HashWithIndifferentAccess.new + end + + # Returns a hash of the attributes with unsaved changes indicating their original + # values like attr => original value. + # + # person.name # => "bob" + # person.name = 'robert' + # person.changed_attributes # => {"name" => "bob"} + def changed_attributes + @changed_attributes ||= ActiveSupport::HashWithIndifferentAccess.new + end + + # Handle *_changed? for +method_missing+. + def attribute_changed?(attr, options = {}) #:nodoc: + result = changes_include?(attr) + result &&= options[:to] == __send__(attr) if options.key?(:to) + result &&= options[:from] == changed_attributes[attr] if options.key?(:from) + result + end + + # Handle *_was for +method_missing+. + def attribute_was(attr) # :nodoc: + attribute_changed?(attr) ? changed_attributes[attr] : __send__(attr) + end + + # Restore all previous data of the provided attributes. + def restore_attributes(attributes = changed) + attributes.each { |attr| restore_attribute! attr } + end + + private + + def changes_include?(attr_name) + attributes_changed_by_setter.include?(attr_name) + end + alias attribute_changed_by_setter? changes_include? + + # Removes current changes and makes them accessible through +previous_changes+. + def changes_applied # :doc: + @previously_changed = changes + @changed_attributes = ActiveSupport::HashWithIndifferentAccess.new + end + + # Clear all dirty data: current changes and previous changes. + def clear_changes_information # :doc: + @previously_changed = ActiveSupport::HashWithIndifferentAccess.new + @changed_attributes = ActiveSupport::HashWithIndifferentAccess.new + end + + def reset_changes + ActiveSupport::Deprecation.warn(<<-MSG.squish) + `#reset_changes` is deprecated and will be removed on Rails 5. + Please use `#clear_changes_information` instead. + MSG + + clear_changes_information + end + + # Handle *_change for +method_missing+. + def attribute_change(attr) + [changed_attributes[attr], __send__(attr)] if attribute_changed?(attr) + end + + # Handle *_will_change! for +method_missing+. + def attribute_will_change!(attr) + return if attribute_changed?(attr) + + begin + value = __send__(attr) + value = value.duplicable? ? value.clone : value + rescue TypeError, NoMethodError + end + + set_attribute_was(attr, value) + end + + # Handle reset_*! for +method_missing+. + def reset_attribute!(attr) + ActiveSupport::Deprecation.warn(<<-MSG.squish) + `#reset_#{attr}!` is deprecated and will be removed on Rails 5. + Please use `#restore_#{attr}!` instead. + MSG + + restore_attribute!(attr) + end + + # Handle restore_*! for +method_missing+. + def restore_attribute!(attr) + if attribute_changed?(attr) + __send__("#{attr}=", changed_attributes[attr]) + clear_attribute_changes([attr]) + end + end + + # This is necessary because `changed_attributes` might be overridden in + # other implemntations (e.g. in `ActiveRecord`) + alias_method :attributes_changed_by_setter, :changed_attributes # :nodoc: + + # Force an attribute to have a particular "before" value + def set_attribute_was(attr, old_value) + attributes_changed_by_setter[attr] = old_value + end + + # Remove changes information for the provided attributes. + def clear_attribute_changes(attributes) # :doc: + attributes_changed_by_setter.except!(*attributes) + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/errors.rb b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/errors.rb new file mode 100644 index 0000000..9105ef5 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/errors.rb @@ -0,0 +1,475 @@ +# -*- coding: utf-8 -*- + +require 'active_support/core_ext/array/conversions' +require 'active_support/core_ext/string/inflections' + +module ActiveModel + # == Active \Model \Errors + # + # Provides a modified +Hash+ that you can include in your object + # for handling error messages and interacting with Action View helpers. + # + # A minimal implementation could be: + # + # class Person + # # Required dependency for ActiveModel::Errors + # extend ActiveModel::Naming + # + # def initialize + # @errors = ActiveModel::Errors.new(self) + # end + # + # attr_accessor :name + # attr_reader :errors + # + # def validate! + # errors.add(:name, "cannot be nil") if name.nil? + # end + # + # # The following methods are needed to be minimally implemented + # + # def read_attribute_for_validation(attr) + # send(attr) + # end + # + # def Person.human_attribute_name(attr, options = {}) + # attr + # end + # + # def Person.lookup_ancestors + # [self] + # end + # end + # + # The last three methods are required in your object for Errors to be + # able to generate error messages correctly and also handle multiple + # languages. Of course, if you extend your object with ActiveModel::Translation + # you will not need to implement the last two. Likewise, using + # ActiveModel::Validations will handle the validation related methods + # for you. + # + # The above allows you to do: + # + # person = Person.new + # person.validate! # => ["cannot be nil"] + # person.errors.full_messages # => ["name cannot be nil"] + # # etc.. + class Errors + include Enumerable + + CALLBACKS_OPTIONS = [:if, :unless, :on, :allow_nil, :allow_blank, :strict] + + attr_reader :messages + + # Pass in the instance of the object that is using the errors object. + # + # class Person + # def initialize + # @errors = ActiveModel::Errors.new(self) + # end + # end + def initialize(base) + @base = base + @messages = {} + end + + def initialize_dup(other) # :nodoc: + @messages = other.messages.dup + super + end + + # Clear the error messages. + # + # person.errors.full_messages # => ["name cannot be nil"] + # person.errors.clear + # person.errors.full_messages # => [] + def clear + messages.clear + end + + # Returns +true+ if the error messages include an error for the given key + # +attribute+, +false+ otherwise. + # + # person.errors.messages # => {:name=>["cannot be nil"]} + # person.errors.include?(:name) # => true + # person.errors.include?(:age) # => false + def include?(attribute) + messages[attribute].present? + end + # aliases include? + alias :has_key? :include? + # aliases include? + alias :key? :include? + + # Get messages for +key+. + # + # person.errors.messages # => {:name=>["cannot be nil"]} + # person.errors.get(:name) # => ["cannot be nil"] + # person.errors.get(:age) # => nil + def get(key) + messages[key] + end + + # Set messages for +key+ to +value+. + # + # person.errors.get(:name) # => ["cannot be nil"] + # person.errors.set(:name, ["can't be nil"]) + # person.errors.get(:name) # => ["can't be nil"] + def set(key, value) + messages[key] = value + end + + # Delete messages for +key+. Returns the deleted messages. + # + # person.errors.get(:name) # => ["cannot be nil"] + # person.errors.delete(:name) # => ["cannot be nil"] + # person.errors.get(:name) # => nil + def delete(key) + messages.delete(key) + end + + # When passed a symbol or a name of a method, returns an array of errors + # for the method. + # + # person.errors[:name] # => ["cannot be nil"] + # person.errors['name'] # => ["cannot be nil"] + def [](attribute) + get(attribute.to_sym) || set(attribute.to_sym, []) + end + + # Adds to the supplied attribute the supplied error message. + # + # person.errors[:name] = "must be set" + # person.errors[:name] # => ['must be set'] + def []=(attribute, error) + self[attribute] << error + end + + # Iterates through each error key, value pair in the error messages hash. + # Yields the attribute and the error for that attribute. If the attribute + # has more than one error message, yields once for each error message. + # + # person.errors.add(:name, "can't be blank") + # person.errors.each do |attribute, error| + # # Will yield :name and "can't be blank" + # end + # + # person.errors.add(:name, "must be specified") + # person.errors.each do |attribute, error| + # # Will yield :name and "can't be blank" + # # then yield :name and "must be specified" + # end + def each + messages.each_key do |attribute| + self[attribute].each { |error| yield attribute, error } + end + end + + # Returns the number of error messages. + # + # person.errors.add(:name, "can't be blank") + # person.errors.size # => 1 + # person.errors.add(:name, "must be specified") + # person.errors.size # => 2 + def size + values.flatten.size + end + + # Returns all message values. + # + # person.errors.messages # => {:name=>["cannot be nil", "must be specified"]} + # person.errors.values # => [["cannot be nil", "must be specified"]] + def values + messages.values + end + + # Returns all message keys. + # + # person.errors.messages # => {:name=>["cannot be nil", "must be specified"]} + # person.errors.keys # => [:name] + def keys + messages.keys + end + + # Returns an array of error messages, with the attribute name included. + # + # person.errors.add(:name, "can't be blank") + # person.errors.add(:name, "must be specified") + # person.errors.to_a # => ["name can't be blank", "name must be specified"] + def to_a + full_messages + end + + # Returns the number of error messages. + # + # person.errors.add(:name, "can't be blank") + # person.errors.count # => 1 + # person.errors.add(:name, "must be specified") + # person.errors.count # => 2 + def count + to_a.size + end + + # Returns +true+ if no errors are found, +false+ otherwise. + # If the error message is a string it can be empty. + # + # person.errors.full_messages # => ["name cannot be nil"] + # person.errors.empty? # => false + def empty? + all? { |k, v| v && v.empty? && !v.is_a?(String) } + end + # aliases empty? + alias_method :blank?, :empty? + + # Returns an xml formatted representation of the Errors hash. + # + # person.errors.add(:name, "can't be blank") + # person.errors.add(:name, "must be specified") + # person.errors.to_xml + # # => + # # + # # + # # name can't be blank + # # name must be specified + # # + def to_xml(options={}) + to_a.to_xml({ root: "errors", skip_types: true }.merge!(options)) + end + + # Returns a Hash that can be used as the JSON representation for this + # object. You can pass the :full_messages option. This determines + # if the json object should contain full messages or not (false by default). + # + # person.errors.as_json # => {:name=>["cannot be nil"]} + # person.errors.as_json(full_messages: true) # => {:name=>["name cannot be nil"]} + def as_json(options=nil) + to_hash(options && options[:full_messages]) + end + + # Returns a Hash of attributes with their error messages. If +full_messages+ + # is +true+, it will contain full messages (see +full_message+). + # + # person.errors.to_hash # => {:name=>["cannot be nil"]} + # person.errors.to_hash(true) # => {:name=>["name cannot be nil"]} + def to_hash(full_messages = false) + if full_messages + self.messages.each_with_object({}) do |(attribute, array), messages| + messages[attribute] = array.map { |message| full_message(attribute, message) } + end + else + self.messages.dup + end + end + + # Adds +message+ to the error messages on +attribute+. More than one error + # can be added to the same +attribute+. If no +message+ is supplied, + # :invalid is assumed. + # + # person.errors.add(:name) + # # => ["is invalid"] + # person.errors.add(:name, 'must be implemented') + # # => ["is invalid", "must be implemented"] + # + # person.errors.messages + # # => {:name=>["must be implemented", "is invalid"]} + # + # If +message+ is a symbol, it will be translated using the appropriate + # scope (see +generate_message+). + # + # If +message+ is a proc, it will be called, allowing for things like + # Time.now to be used within an error. + # + # If the :strict option is set to +true+, it will raise + # ActiveModel::StrictValidationFailed instead of adding the error. + # :strict option can also be set to any other exception. + # + # person.errors.add(:name, nil, strict: true) + # # => ActiveModel::StrictValidationFailed: name is invalid + # person.errors.add(:name, nil, strict: NameIsInvalid) + # # => NameIsInvalid: name is invalid + # + # person.errors.messages # => {} + # + # +attribute+ should be set to :base if the error is not + # directly associated with a single attribute. + # + # person.errors.add(:base, "either name or email must be present") + # person.errors.messages + # # => {:base=>["either name or email must be present"]} + def add(attribute, message = :invalid, options = {}) + message = normalize_message(attribute, message, options) + if exception = options[:strict] + exception = ActiveModel::StrictValidationFailed if exception == true + raise exception, full_message(attribute, message) + end + + self[attribute] << message + end + + # Will add an error message to each of the attributes in +attributes+ + # that is empty. + # + # person.errors.add_on_empty(:name) + # person.errors.messages + # # => {:name=>["can't be empty"]} + def add_on_empty(attributes, options = {}) + Array(attributes).each do |attribute| + value = @base.send(:read_attribute_for_validation, attribute) + is_empty = value.respond_to?(:empty?) ? value.empty? : false + add(attribute, :empty, options) if value.nil? || is_empty + end + end + + # Will add an error message to each of the attributes in +attributes+ that + # is blank (using Object#blank?). + # + # person.errors.add_on_blank(:name) + # person.errors.messages + # # => {:name=>["can't be blank"]} + def add_on_blank(attributes, options = {}) + Array(attributes).each do |attribute| + value = @base.send(:read_attribute_for_validation, attribute) + add(attribute, :blank, options) if value.blank? + end + end + + # Returns +true+ if an error on the attribute with the given message is + # present, +false+ otherwise. +message+ is treated the same as for +add+. + # + # person.errors.add :name, :blank + # person.errors.added? :name, :blank # => true + def added?(attribute, message = :invalid, options = {}) + message = normalize_message(attribute, message, options) + self[attribute].include? message + end + + # Returns all the full error messages in an array. + # + # class Person + # validates_presence_of :name, :address, :email + # validates_length_of :name, in: 5..30 + # end + # + # person = Person.create(address: '123 First St.') + # person.errors.full_messages + # # => ["Name is too short (minimum is 5 characters)", "Name can't be blank", "Email can't be blank"] + def full_messages + map { |attribute, message| full_message(attribute, message) } + end + + # Returns all the full error messages for a given attribute in an array. + # + # class Person + # validates_presence_of :name, :email + # validates_length_of :name, in: 5..30 + # end + # + # person = Person.create() + # person.errors.full_messages_for(:name) + # # => ["Name is too short (minimum is 5 characters)", "Name can't be blank"] + def full_messages_for(attribute) + (get(attribute) || []).map { |message| full_message(attribute, message) } + end + + # Returns a full message for a given attribute. + # + # person.errors.full_message(:name, 'is invalid') # => "Name is invalid" + def full_message(attribute, message) + return message if attribute == :base + attr_name = attribute.to_s.tr('.', '_').humanize + attr_name = @base.class.human_attribute_name(attribute, default: attr_name) + I18n.t(:"errors.format", { + default: "%{attribute} %{message}", + attribute: attr_name, + message: message + }) + end + + # Translates an error message in its default scope + # (activemodel.errors.messages). + # + # Error messages are first looked up in models.MODEL.attributes.ATTRIBUTE.MESSAGE, + # if it's not there, it's looked up in models.MODEL.MESSAGE and if + # that is not there also, it returns the translation of the default message + # (e.g. activemodel.errors.messages.MESSAGE). The translated model + # name, translated attribute name and the value are available for + # interpolation. + # + # When using inheritance in your models, it will check all the inherited + # models too, but only if the model itself hasn't been found. Say you have + # class Admin < User; end and you wanted the translation for + # the :blank error message for the title attribute, + # it looks for these translations: + # + # * activemodel.errors.models.admin.attributes.title.blank + # * activemodel.errors.models.admin.blank + # * activemodel.errors.models.user.attributes.title.blank + # * activemodel.errors.models.user.blank + # * any default you provided through the +options+ hash (in the activemodel.errors scope) + # * activemodel.errors.messages.blank + # * errors.attributes.title.blank + # * errors.messages.blank + def generate_message(attribute, type = :invalid, options = {}) + type = options.delete(:message) if options[:message].is_a?(Symbol) + + if @base.class.respond_to?(:i18n_scope) + defaults = @base.class.lookup_ancestors.map do |klass| + [ :"#{@base.class.i18n_scope}.errors.models.#{klass.model_name.i18n_key}.attributes.#{attribute}.#{type}", + :"#{@base.class.i18n_scope}.errors.models.#{klass.model_name.i18n_key}.#{type}" ] + end + else + defaults = [] + end + + defaults << options.delete(:message) + defaults << :"#{@base.class.i18n_scope}.errors.messages.#{type}" if @base.class.respond_to?(:i18n_scope) + defaults << :"errors.attributes.#{attribute}.#{type}" + defaults << :"errors.messages.#{type}" + + defaults.compact! + defaults.flatten! + + key = defaults.shift + value = (attribute != :base ? @base.send(:read_attribute_for_validation, attribute) : nil) + + options = { + default: defaults, + model: @base.model_name.human, + attribute: @base.class.human_attribute_name(attribute), + value: value + }.merge!(options) + + I18n.translate(key, options) + end + + private + def normalize_message(attribute, message, options) + case message + when Symbol + generate_message(attribute, message, options.except(*CALLBACKS_OPTIONS)) + when Proc + message.call + else + message + end + end + end + + # Raised when a validation cannot be corrected by end users and are considered + # exceptional. + # + # class Person + # include ActiveModel::Validations + # + # attr_accessor :name + # + # validates_presence_of :name, strict: true + # end + # + # person = Person.new + # person.name = nil + # person.valid? + # # => ActiveModel::StrictValidationFailed: Name can't be blank + class StrictValidationFailed < StandardError + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/forbidden_attributes_protection.rb b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/forbidden_attributes_protection.rb new file mode 100644 index 0000000..b4fa378 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/forbidden_attributes_protection.rb @@ -0,0 +1,28 @@ +module ActiveModel + # Raised when forbidden attributes are used for mass assignment. + # + # class Person < ActiveRecord::Base + # end + # + # params = ActionController::Parameters.new(name: 'Bob') + # Person.new(params) + # # => ActiveModel::ForbiddenAttributesError + # + # params.permit! + # Person.new(params) + # # => # + class ForbiddenAttributesError < StandardError + end + + module ForbiddenAttributesProtection # :nodoc: + protected + def sanitize_for_mass_assignment(attributes) + if attributes.respond_to?(:permitted?) && !attributes.permitted? + raise ActiveModel::ForbiddenAttributesError + else + attributes + end + end + alias :sanitize_forbidden_attributes :sanitize_for_mass_assignment + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/gem_version.rb b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/gem_version.rb new file mode 100644 index 0000000..8f506c4 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/gem_version.rb @@ -0,0 +1,15 @@ +module ActiveModel + # Returns the version of the currently loaded Active Model as a Gem::Version + def self.gem_version + Gem::Version.new VERSION::STRING + end + + module VERSION + MAJOR = 4 + MINOR = 2 + TINY = 6 + PRE = nil + + STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".") + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/lint.rb b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/lint.rb new file mode 100644 index 0000000..3808752 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/lint.rb @@ -0,0 +1,113 @@ +module ActiveModel + module Lint + # == Active \Model \Lint \Tests + # + # You can test whether an object is compliant with the Active \Model API by + # including ActiveModel::Lint::Tests in your TestCase. It will + # include tests that tell you whether your object is fully compliant, + # or if not, which aspects of the API are not implemented. + # + # Note an object is not required to implement all APIs in order to work + # with Action Pack. This module only intends to provide guidance in case + # you want all features out of the box. + # + # These tests do not attempt to determine the semantic correctness of the + # returned values. For instance, you could implement valid? to + # always return +true+, and the tests would pass. It is up to you to ensure + # that the values are semantically meaningful. + # + # Objects you pass in are expected to return a compliant object from a call + # to to_model. It is perfectly fine for to_model to return + # +self+. + module Tests + + # == Responds to to_key + # + # Returns an Enumerable of all (primary) key attributes + # or nil if model.persisted? is false. This is used by + # dom_id to generate unique ids for the object. + def test_to_key + assert model.respond_to?(:to_key), "The model should respond to to_key" + def model.persisted?() false end + assert model.to_key.nil?, "to_key should return nil when `persisted?` returns false" + end + + # == Responds to to_param + # + # Returns a string representing the object's key suitable for use in URLs + # or +nil+ if model.persisted? is +false+. + # + # Implementers can decide to either raise an exception or provide a + # default in case the record uses a composite primary key. There are no + # tests for this behavior in lint because it doesn't make sense to force + # any of the possible implementation strategies on the implementer. + # However, if the resource is not persisted?, then to_param + # should always return +nil+. + def test_to_param + assert model.respond_to?(:to_param), "The model should respond to to_param" + def model.to_key() [1] end + def model.persisted?() false end + assert model.to_param.nil?, "to_param should return nil when `persisted?` returns false" + end + + # == Responds to to_partial_path + # + # Returns a string giving a relative path. This is used for looking up + # partials. For example, a BlogPost model might return "blog_posts/blog_post" + def test_to_partial_path + assert model.respond_to?(:to_partial_path), "The model should respond to to_partial_path" + assert_kind_of String, model.to_partial_path + end + + # == Responds to persisted? + # + # Returns a boolean that specifies whether the object has been persisted + # yet. This is used when calculating the URL for an object. If the object + # is not persisted, a form for that object, for instance, will route to + # the create action. If it is persisted, a form for the object will routes + # to the update action. + def test_persisted? + assert model.respond_to?(:persisted?), "The model should respond to persisted?" + assert_boolean model.persisted?, "persisted?" + end + + # == \Naming + # + # Model.model_name and Model#model_name must return a string with some + # convenience methods: # :human, :singular and + # :plural. Check ActiveModel::Naming for more information. + def test_model_naming + assert model.class.respond_to?(:model_name), "The model class should respond to model_name" + model_name = model.class.model_name + assert model_name.respond_to?(:to_str) + assert model_name.human.respond_to?(:to_str) + assert model_name.singular.respond_to?(:to_str) + assert model_name.plural.respond_to?(:to_str) + + assert model.respond_to?(:model_name), "The model instance should respond to model_name" + assert_equal model.model_name, model.class.model_name + end + + # == \Errors Testing + # + # Returns an object that implements [](attribute) defined which returns an + # Array of Strings that are the errors for the attribute in question. + # If localization is used, the Strings should be localized for the current + # locale. If no error is present, this method should return an empty Array. + def test_errors_aref + assert model.respond_to?(:errors), "The model should respond to errors" + assert model.errors[:hello].is_a?(Array), "errors#[] should return an Array" + end + + private + def model + assert @model.respond_to?(:to_model), "The object should respond to to_model" + @model.to_model + end + + def assert_boolean(result, name) + assert result == true || result == false, "#{name} should be a boolean" + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/locale/en.yml b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/locale/en.yml new file mode 100644 index 0000000..bf07945 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/locale/en.yml @@ -0,0 +1,35 @@ +en: + errors: + # The default format to use in full error messages. + format: "%{attribute} %{message}" + + # The values :model, :attribute and :value are always available for interpolation + # The value :count is available when applicable. Can be used for pluralization. + messages: + inclusion: "is not included in the list" + exclusion: "is reserved" + invalid: "is invalid" + confirmation: "doesn't match %{attribute}" + accepted: "must be accepted" + empty: "can't be empty" + blank: "can't be blank" + present: "must be blank" + too_long: + one: "is too long (maximum is 1 character)" + other: "is too long (maximum is %{count} characters)" + too_short: + one: "is too short (minimum is 1 character)" + other: "is too short (minimum is %{count} characters)" + wrong_length: + one: "is the wrong length (should be 1 character)" + other: "is the wrong length (should be %{count} characters)" + not_a_number: "is not a number" + not_an_integer: "must be an integer" + greater_than: "must be greater than %{count}" + greater_than_or_equal_to: "must be greater than or equal to %{count}" + equal_to: "must be equal to %{count}" + less_than: "must be less than %{count}" + less_than_or_equal_to: "must be less than or equal to %{count}" + other_than: "must be other than %{count}" + odd: "must be odd" + even: "must be even" diff --git a/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/model.rb b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/model.rb new file mode 100644 index 0000000..d51d6dd --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/model.rb @@ -0,0 +1,99 @@ +module ActiveModel + + # == Active \Model \Basic \Model + # + # Includes the required interface for an object to interact with + # ActionPack, using different ActiveModel modules. + # It includes model name introspections, conversions, translations and + # validations. Besides that, it allows you to initialize the object with a + # hash of attributes, pretty much like ActiveRecord does. + # + # A minimal implementation could be: + # + # class Person + # include ActiveModel::Model + # attr_accessor :name, :age + # end + # + # person = Person.new(name: 'bob', age: '18') + # person.name # => "bob" + # person.age # => "18" + # + # Note that, by default, ActiveModel::Model implements persisted? + # to return +false+, which is the most common case. You may want to override + # it in your class to simulate a different scenario: + # + # class Person + # include ActiveModel::Model + # attr_accessor :id, :name + # + # def persisted? + # self.id == 1 + # end + # end + # + # person = Person.new(id: 1, name: 'bob') + # person.persisted? # => true + # + # Also, if for some reason you need to run code on initialize, make + # sure you call +super+ if you want the attributes hash initialization to + # happen. + # + # class Person + # include ActiveModel::Model + # attr_accessor :id, :name, :omg + # + # def initialize(attributes={}) + # super + # @omg ||= true + # end + # end + # + # person = Person.new(id: 1, name: 'bob') + # person.omg # => true + # + # For more detailed information on other functionalities available, please + # refer to the specific modules included in ActiveModel::Model + # (see below). + module Model + extend ActiveSupport::Concern + include ActiveModel::Validations + include ActiveModel::Conversion + + included do + extend ActiveModel::Naming + extend ActiveModel::Translation + end + + # Initializes a new model with the given +params+. + # + # class Person + # include ActiveModel::Model + # attr_accessor :name, :age + # end + # + # person = Person.new(name: 'bob', age: '18') + # person.name # => "bob" + # person.age # => "18" + def initialize(params={}) + params.each do |attr, value| + self.public_send("#{attr}=", value) + end if params + + super() + end + + # Indicates if the model is persisted. Default is +false+. + # + # class Person + # include ActiveModel::Model + # attr_accessor :id, :name + # end + # + # person = Person.new(id: 1, name: 'bob') + # person.persisted? # => false + def persisted? + false + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/naming.rb b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/naming.rb new file mode 100644 index 0000000..62dbafe --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/naming.rb @@ -0,0 +1,316 @@ +require 'active_support/core_ext/hash/except' +require 'active_support/core_ext/module/introspection' +require 'active_support/core_ext/module/remove_method' + +module ActiveModel + class Name + include Comparable + + attr_reader :singular, :plural, :element, :collection, + :singular_route_key, :route_key, :param_key, :i18n_key, + :name + + alias_method :cache_key, :collection + + ## + # :method: == + # + # :call-seq: + # ==(other) + # + # Equivalent to String#==. Returns +true+ if the class name and + # +other+ are equal, otherwise +false+. + # + # class BlogPost + # extend ActiveModel::Naming + # end + # + # BlogPost.model_name == 'BlogPost' # => true + # BlogPost.model_name == 'Blog Post' # => false + + ## + # :method: === + # + # :call-seq: + # ===(other) + # + # Equivalent to #==. + # + # class BlogPost + # extend ActiveModel::Naming + # end + # + # BlogPost.model_name === 'BlogPost' # => true + # BlogPost.model_name === 'Blog Post' # => false + + ## + # :method: <=> + # + # :call-seq: + # ==(other) + # + # Equivalent to String#<=>. + # + # class BlogPost + # extend ActiveModel::Naming + # end + # + # BlogPost.model_name <=> 'BlogPost' # => 0 + # BlogPost.model_name <=> 'Blog' # => 1 + # BlogPost.model_name <=> 'BlogPosts' # => -1 + + ## + # :method: =~ + # + # :call-seq: + # =~(regexp) + # + # Equivalent to String#=~. Match the class name against the given + # regexp. Returns the position where the match starts or +nil+ if there is + # no match. + # + # class BlogPost + # extend ActiveModel::Naming + # end + # + # BlogPost.model_name =~ /Post/ # => 4 + # BlogPost.model_name =~ /\d/ # => nil + + ## + # :method: !~ + # + # :call-seq: + # !~(regexp) + # + # Equivalent to String#!~. Match the class name against the given + # regexp. Returns +true+ if there is no match, otherwise +false+. + # + # class BlogPost + # extend ActiveModel::Naming + # end + # + # BlogPost.model_name !~ /Post/ # => false + # BlogPost.model_name !~ /\d/ # => true + + ## + # :method: eql? + # + # :call-seq: + # eql?(other) + # + # Equivalent to String#eql?. Returns +true+ if the class name and + # +other+ have the same length and content, otherwise +false+. + # + # class BlogPost + # extend ActiveModel::Naming + # end + # + # BlogPost.model_name.eql?('BlogPost') # => true + # BlogPost.model_name.eql?('Blog Post') # => false + + ## + # :method: to_s + # + # :call-seq: + # to_s() + # + # Returns the class name. + # + # class BlogPost + # extend ActiveModel::Naming + # end + # + # BlogPost.model_name.to_s # => "BlogPost" + + ## + # :method: to_str + # + # :call-seq: + # to_str() + # + # Equivalent to +to_s+. + delegate :==, :===, :<=>, :=~, :"!~", :eql?, :to_s, + :to_str, :as_json, to: :name + + # Returns a new ActiveModel::Name instance. By default, the +namespace+ + # and +name+ option will take the namespace and name of the given class + # respectively. + # + # module Foo + # class Bar + # end + # end + # + # ActiveModel::Name.new(Foo::Bar).to_s + # # => "Foo::Bar" + def initialize(klass, namespace = nil, name = nil) + @name = name || klass.name + + raise ArgumentError, "Class name cannot be blank. You need to supply a name argument when anonymous class given" if @name.blank? + + @unnamespaced = @name.sub(/^#{namespace.name}::/, '') if namespace + @klass = klass + @singular = _singularize(@name) + @plural = ActiveSupport::Inflector.pluralize(@singular) + @element = ActiveSupport::Inflector.underscore(ActiveSupport::Inflector.demodulize(@name)) + @human = ActiveSupport::Inflector.humanize(@element) + @collection = ActiveSupport::Inflector.tableize(@name) + @param_key = (namespace ? _singularize(@unnamespaced) : @singular) + @i18n_key = @name.underscore.to_sym + + @route_key = (namespace ? ActiveSupport::Inflector.pluralize(@param_key) : @plural.dup) + @singular_route_key = ActiveSupport::Inflector.singularize(@route_key) + @route_key << "_index" if @plural == @singular + end + + # Transform the model name into a more humane format, using I18n. By default, + # it will underscore then humanize the class name. + # + # class BlogPost + # extend ActiveModel::Naming + # end + # + # BlogPost.model_name.human # => "Blog post" + # + # Specify +options+ with additional translating options. + def human(options={}) + return @human unless @klass.respond_to?(:lookup_ancestors) && + @klass.respond_to?(:i18n_scope) + + defaults = @klass.lookup_ancestors.map do |klass| + klass.model_name.i18n_key + end + + defaults << options[:default] if options[:default] + defaults << @human + + options = { scope: [@klass.i18n_scope, :models], count: 1, default: defaults }.merge!(options.except(:default)) + I18n.translate(defaults.shift, options) + end + + private + + def _singularize(string, replacement='_') + ActiveSupport::Inflector.underscore(string).tr('/', replacement) + end + end + + # == Active \Model \Naming + # + # Creates a +model_name+ method on your object. + # + # To implement, just extend ActiveModel::Naming in your object: + # + # class BookCover + # extend ActiveModel::Naming + # end + # + # BookCover.model_name.name # => "BookCover" + # BookCover.model_name.human # => "Book cover" + # + # BookCover.model_name.i18n_key # => :book_cover + # BookModule::BookCover.model_name.i18n_key # => :"book_module/book_cover" + # + # Providing the functionality that ActiveModel::Naming provides in your object + # is required to pass the Active Model Lint test. So either extending the + # provided method below, or rolling your own is required. + module Naming + def self.extended(base) #:nodoc: + base.remove_possible_method :model_name + base.delegate :model_name, to: :class + end + + # Returns an ActiveModel::Name object for module. It can be + # used to retrieve all kinds of naming-related information + # (See ActiveModel::Name for more information). + # + # class Person + # extend ActiveModel::Naming + # end + # + # Person.model_name.name # => "Person" + # Person.model_name.class # => ActiveModel::Name + # Person.model_name.singular # => "person" + # Person.model_name.plural # => "people" + def model_name + @_model_name ||= begin + namespace = self.parents.detect do |n| + n.respond_to?(:use_relative_model_naming?) && n.use_relative_model_naming? + end + ActiveModel::Name.new(self, namespace) + end + end + + # Returns the plural class name of a record or class. + # + # ActiveModel::Naming.plural(post) # => "posts" + # ActiveModel::Naming.plural(Highrise::Person) # => "highrise_people" + def self.plural(record_or_class) + model_name_from_record_or_class(record_or_class).plural + end + + # Returns the singular class name of a record or class. + # + # ActiveModel::Naming.singular(post) # => "post" + # ActiveModel::Naming.singular(Highrise::Person) # => "highrise_person" + def self.singular(record_or_class) + model_name_from_record_or_class(record_or_class).singular + end + + # Identifies whether the class name of a record or class is uncountable. + # + # ActiveModel::Naming.uncountable?(Sheep) # => true + # ActiveModel::Naming.uncountable?(Post) # => false + def self.uncountable?(record_or_class) + plural(record_or_class) == singular(record_or_class) + end + + # Returns string to use while generating route names. It differs for + # namespaced models regarding whether it's inside isolated engine. + # + # # For isolated engine: + # ActiveModel::Naming.singular_route_key(Blog::Post) # => "post" + # + # # For shared engine: + # ActiveModel::Naming.singular_route_key(Blog::Post) # => "blog_post" + def self.singular_route_key(record_or_class) + model_name_from_record_or_class(record_or_class).singular_route_key + end + + # Returns string to use while generating route names. It differs for + # namespaced models regarding whether it's inside isolated engine. + # + # # For isolated engine: + # ActiveModel::Naming.route_key(Blog::Post) # => "posts" + # + # # For shared engine: + # ActiveModel::Naming.route_key(Blog::Post) # => "blog_posts" + # + # The route key also considers if the noun is uncountable and, in + # such cases, automatically appends _index. + def self.route_key(record_or_class) + model_name_from_record_or_class(record_or_class).route_key + end + + # Returns string to use for params names. It differs for + # namespaced models regarding whether it's inside isolated engine. + # + # # For isolated engine: + # ActiveModel::Naming.param_key(Blog::Post) # => "post" + # + # # For shared engine: + # ActiveModel::Naming.param_key(Blog::Post) # => "blog_post" + def self.param_key(record_or_class) + model_name_from_record_or_class(record_or_class).param_key + end + + def self.model_name_from_record_or_class(record_or_class) #:nodoc: + if record_or_class.respond_to?(:to_model) + record_or_class.to_model.model_name + else + record_or_class.model_name + end + end + private_class_method :model_name_from_record_or_class + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/railtie.rb b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/railtie.rb new file mode 100644 index 0000000..1671eb7 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/railtie.rb @@ -0,0 +1,12 @@ +require "active_model" +require "rails" + +module ActiveModel + class Railtie < Rails::Railtie # :nodoc: + config.eager_load_namespaces << ActiveModel + + initializer "active_model.secure_password" do + ActiveModel::SecurePassword.min_cost = Rails.env.test? + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/secure_password.rb b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/secure_password.rb new file mode 100644 index 0000000..8f2a069 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/secure_password.rb @@ -0,0 +1,134 @@ +module ActiveModel + module SecurePassword + extend ActiveSupport::Concern + + # BCrypt hash function can handle maximum 72 characters, and if we pass + # password of length more than 72 characters it ignores extra characters. + # Hence need to put a restriction on password length. + MAX_PASSWORD_LENGTH_ALLOWED = 72 + + class << self + attr_accessor :min_cost # :nodoc: + end + self.min_cost = false + + module ClassMethods + # Adds methods to set and authenticate against a BCrypt password. + # This mechanism requires you to have a +password_digest+ attribute. + # + # The following validations are added automatically: + # * Password must be present on creation + # * Password length should be less than or equal to 72 characters + # * Confirmation of password (using a +password_confirmation+ attribute) + # + # If password confirmation validation is not needed, simply leave out the + # value for +password_confirmation+ (i.e. don't provide a form field for + # it). When this attribute has a +nil+ value, the validation will not be + # triggered. + # + # For further customizability, it is possible to supress the default + # validations by passing validations: false as an argument. + # + # Add bcrypt (~> 3.1.7) to Gemfile to use #has_secure_password: + # + # gem 'bcrypt', '~> 3.1.7' + # + # Example using Active Record (which automatically includes ActiveModel::SecurePassword): + # + # # Schema: User(name:string, password_digest:string) + # class User < ActiveRecord::Base + # has_secure_password + # end + # + # user = User.new(name: 'david', password: '', password_confirmation: 'nomatch') + # user.save # => false, password required + # user.password = 'mUc3m00RsqyRe' + # user.save # => false, confirmation doesn't match + # user.password_confirmation = 'mUc3m00RsqyRe' + # user.save # => true + # user.authenticate('notright') # => false + # user.authenticate('mUc3m00RsqyRe') # => user + # User.find_by(name: 'david').try(:authenticate, 'notright') # => false + # User.find_by(name: 'david').try(:authenticate, 'mUc3m00RsqyRe') # => user + def has_secure_password(options = {}) + # Load bcrypt gem only when has_secure_password is used. + # This is to avoid ActiveModel (and by extension the entire framework) + # being dependent on a binary library. + begin + require 'bcrypt' + rescue LoadError + $stderr.puts "You don't have bcrypt installed in your application. Please add it to your Gemfile and run bundle install" + raise + end + + include InstanceMethodsOnActivation + + if options.fetch(:validations, true) + include ActiveModel::Validations + + # This ensures the model has a password by checking whether the password_digest + # is present, so that this works with both new and existing records. However, + # when there is an error, the message is added to the password attribute instead + # so that the error message will make sense to the end-user. + validate do |record| + record.errors.add(:password, :blank) unless record.password_digest.present? + end + + validates_length_of :password, maximum: ActiveModel::SecurePassword::MAX_PASSWORD_LENGTH_ALLOWED + validates_confirmation_of :password, allow_blank: true + end + + # This code is necessary as long as the protected_attributes gem is supported. + if respond_to?(:attributes_protected_by_default) + def self.attributes_protected_by_default #:nodoc: + super + ['password_digest'] + end + end + end + end + + module InstanceMethodsOnActivation + # Returns +self+ if the password is correct, otherwise +false+. + # + # class User < ActiveRecord::Base + # has_secure_password validations: false + # end + # + # user = User.new(name: 'david', password: 'mUc3m00RsqyRe') + # user.save + # user.authenticate('notright') # => false + # user.authenticate('mUc3m00RsqyRe') # => user + def authenticate(unencrypted_password) + BCrypt::Password.new(password_digest) == unencrypted_password && self + end + + attr_reader :password + + # Encrypts the password into the +password_digest+ attribute, only if the + # new password is not empty. + # + # class User < ActiveRecord::Base + # has_secure_password validations: false + # end + # + # user = User.new + # user.password = nil + # user.password_digest # => nil + # user.password = 'mUc3m00RsqyRe' + # user.password_digest # => "$2a$10$4LEA7r4YmNHtvlAvHhsYAeZmk/xeUVtMTYqwIvYY76EW5GUqDiP4." + def password=(unencrypted_password) + if unencrypted_password.nil? + self.password_digest = nil + elsif !unencrypted_password.empty? + @password = unencrypted_password + cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST : BCrypt::Engine.cost + self.password_digest = BCrypt::Password.create(unencrypted_password, cost: cost) + end + end + + def password_confirmation=(unencrypted_password) + @password_confirmation = unencrypted_password + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/serialization.rb b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/serialization.rb new file mode 100644 index 0000000..976f50b --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/serialization.rb @@ -0,0 +1,163 @@ +require 'active_support/core_ext/hash/except' +require 'active_support/core_ext/hash/slice' + +module ActiveModel + # == Active \Model \Serialization + # + # Provides a basic serialization to a serializable_hash for your objects. + # + # A minimal implementation could be: + # + # class Person + # include ActiveModel::Serialization + # + # attr_accessor :name + # + # def attributes + # {'name' => nil} + # end + # end + # + # Which would provide you with: + # + # person = Person.new + # person.serializable_hash # => {"name"=>nil} + # person.name = "Bob" + # person.serializable_hash # => {"name"=>"Bob"} + # + # An +attributes+ hash must be defined and should contain any attributes you + # need to be serialized. Attributes must be strings, not symbols. + # When called, serializable hash will use instance methods that match the name + # of the attributes hash's keys. In order to override this behavior, take a look + # at the private method +read_attribute_for_serialization+. + # + # Most of the time though, either the JSON or XML serializations are needed. + # Both of these modules automatically include the + # ActiveModel::Serialization module, so there is no need to + # explicitly include it. + # + # A minimal implementation including XML and JSON would be: + # + # class Person + # include ActiveModel::Serializers::JSON + # include ActiveModel::Serializers::Xml + # + # attr_accessor :name + # + # def attributes + # {'name' => nil} + # end + # end + # + # Which would provide you with: + # + # person = Person.new + # person.serializable_hash # => {"name"=>nil} + # person.as_json # => {"name"=>nil} + # person.to_json # => "{\"name\":null}" + # person.to_xml # => "\n {"name"=>"Bob"} + # person.as_json # => {"name"=>"Bob"} + # person.to_json # => "{\"name\":\"Bob\"}" + # person.to_xml # => "\n:only
    , :except, :methods and + # :include. The following are all valid examples: + # + # person.serializable_hash(only: 'name') + # person.serializable_hash(include: :address) + # person.serializable_hash(include: { address: { only: 'city' }}) + module Serialization + # Returns a serialized hash of your object. + # + # class Person + # include ActiveModel::Serialization + # + # attr_accessor :name, :age + # + # def attributes + # {'name' => nil, 'age' => nil} + # end + # + # def capitalized_name + # name.capitalize + # end + # end + # + # person = Person.new + # person.name = 'bob' + # person.age = 22 + # person.serializable_hash # => {"name"=>"bob", "age"=>22} + # person.serializable_hash(only: :name) # => {"name"=>"bob"} + # person.serializable_hash(except: :name) # => {"age"=>22} + # person.serializable_hash(methods: :capitalized_name) + # # => {"name"=>"bob", "age"=>22, "capitalized_name"=>"Bob"} + def serializable_hash(options = nil) + options ||= {} + + attribute_names = attributes.keys + if only = options[:only] + attribute_names &= Array(only).map(&:to_s) + elsif except = options[:except] + attribute_names -= Array(except).map(&:to_s) + end + + hash = {} + attribute_names.each { |n| hash[n] = read_attribute_for_serialization(n) } + + Array(options[:methods]).each { |m| hash[m.to_s] = send(m) if respond_to?(m) } + + serializable_add_includes(options) do |association, records, opts| + hash[association.to_s] = if records.respond_to?(:to_ary) + records.to_ary.map { |a| a.serializable_hash(opts) } + else + records.serializable_hash(opts) + end + end + + hash + end + + private + + # Hook method defining how an attribute value should be retrieved for + # serialization. By default this is assumed to be an instance named after + # the attribute. Override this method in subclasses should you need to + # retrieve the value for a given attribute differently: + # + # class MyClass + # include ActiveModel::Serialization + # + # def initialize(data = {}) + # @data = data + # end + # + # def read_attribute_for_serialization(key) + # @data[key] + # end + # end + alias :read_attribute_for_serialization :send + + # Add associations specified via the :include option. + # + # Expects a block that takes as arguments: + # +association+ - name of the association + # +records+ - the association record(s) to be serialized + # +opts+ - options for the association records + def serializable_add_includes(options = {}) #:nodoc: + return unless includes = options[:include] + + unless includes.is_a?(Hash) + includes = Hash[Array(includes).map { |n| n.is_a?(Hash) ? n.to_a.first : [n, {}] }] + end + + includes.each do |association, opts| + if records = send(association) + yield association, records, opts + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/serializers/json.rb b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/serializers/json.rb new file mode 100644 index 0000000..b64a829 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/serializers/json.rb @@ -0,0 +1,145 @@ +require 'active_support/json' + +module ActiveModel + module Serializers + # == Active \Model \JSON \Serializer + module JSON + extend ActiveSupport::Concern + include ActiveModel::Serialization + + included do + extend ActiveModel::Naming + + class_attribute :include_root_in_json, instance_writer: false + self.include_root_in_json = false + end + + # Returns a hash representing the model. Some configuration can be + # passed through +options+. + # + # The option include_root_in_json controls the top-level behavior + # of +as_json+. If +true+, +as_json+ will emit a single root node named + # after the object's type. The default value for include_root_in_json + # option is +false+. + # + # user = User.find(1) + # user.as_json + # # => { "id" => 1, "name" => "Konata Izumi", "age" => 16, + # # "created_at" => "2006/08/01", "awesome" => true} + # + # ActiveRecord::Base.include_root_in_json = true + # + # user.as_json + # # => { "user" => { "id" => 1, "name" => "Konata Izumi", "age" => 16, + # # "created_at" => "2006/08/01", "awesome" => true } } + # + # This behavior can also be achieved by setting the :root option + # to +true+ as in: + # + # user = User.find(1) + # user.as_json(root: true) + # # => { "user" => { "id" => 1, "name" => "Konata Izumi", "age" => 16, + # # "created_at" => "2006/08/01", "awesome" => true } } + # + # Without any +options+, the returned Hash will include all the model's + # attributes. + # + # user = User.find(1) + # user.as_json + # # => { "id" => 1, "name" => "Konata Izumi", "age" => 16, + # # "created_at" => "2006/08/01", "awesome" => true} + # + # The :only and :except options can be used to limit + # the attributes included, and work similar to the +attributes+ method. + # + # user.as_json(only: [:id, :name]) + # # => { "id" => 1, "name" => "Konata Izumi" } + # + # user.as_json(except: [:id, :created_at, :age]) + # # => { "name" => "Konata Izumi", "awesome" => true } + # + # To include the result of some method calls on the model use :methods: + # + # user.as_json(methods: :permalink) + # # => { "id" => 1, "name" => "Konata Izumi", "age" => 16, + # # "created_at" => "2006/08/01", "awesome" => true, + # # "permalink" => "1-konata-izumi" } + # + # To include associations use :include: + # + # user.as_json(include: :posts) + # # => { "id" => 1, "name" => "Konata Izumi", "age" => 16, + # # "created_at" => "2006/08/01", "awesome" => true, + # # "posts" => [ { "id" => 1, "author_id" => 1, "title" => "Welcome to the weblog" }, + # # { "id" => 2, "author_id" => 1, "title" => "So I was thinking" } ] } + # + # Second level and higher order associations work as well: + # + # user.as_json(include: { posts: { + # include: { comments: { + # only: :body } }, + # only: :title } }) + # # => { "id" => 1, "name" => "Konata Izumi", "age" => 16, + # # "created_at" => "2006/08/01", "awesome" => true, + # # "posts" => [ { "comments" => [ { "body" => "1st post!" }, { "body" => "Second!" } ], + # # "title" => "Welcome to the weblog" }, + # # { "comments" => [ { "body" => "Don't think too hard" } ], + # # "title" => "So I was thinking" } ] } + def as_json(options = nil) + root = if options && options.key?(:root) + options[:root] + else + include_root_in_json + end + + if root + root = model_name.element if root == true + { root => serializable_hash(options) } + else + serializable_hash(options) + end + end + + # Sets the model +attributes+ from a JSON string. Returns +self+. + # + # class Person + # include ActiveModel::Serializers::JSON + # + # attr_accessor :name, :age, :awesome + # + # def attributes=(hash) + # hash.each do |key, value| + # send("#{key}=", value) + # end + # end + # + # def attributes + # instance_values + # end + # end + # + # json = { name: 'bob', age: 22, awesome:true }.to_json + # person = Person.new + # person.from_json(json) # => # + # person.name # => "bob" + # person.age # => 22 + # person.awesome # => true + # + # The default value for +include_root+ is +false+. You can change it to + # +true+ if the given JSON string includes a single root node. + # + # json = { person: { name: 'bob', age: 22, awesome:true } }.to_json + # person = Person.new + # person.from_json(json, true) # => # + # person.name # => "bob" + # person.age # => 22 + # person.awesome # => true + def from_json(json, include_root=include_root_in_json) + hash = ActiveSupport::JSON.decode(json) + hash = hash.values.first if include_root + self.attributes = hash + self + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/serializers/xml.rb b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/serializers/xml.rb new file mode 100644 index 0000000..3ad3bf3 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/serializers/xml.rb @@ -0,0 +1,238 @@ +require 'active_support/core_ext/module/attribute_accessors' +require 'active_support/core_ext/array/conversions' +require 'active_support/core_ext/hash/conversions' +require 'active_support/core_ext/hash/slice' +require 'active_support/core_ext/time/acts_like' + +module ActiveModel + module Serializers + # == Active Model XML Serializer + module Xml + extend ActiveSupport::Concern + include ActiveModel::Serialization + + included do + extend ActiveModel::Naming + end + + class Serializer #:nodoc: + class Attribute #:nodoc: + attr_reader :name, :value, :type + + def initialize(name, serializable, value) + @name, @serializable = name, serializable + + if value.acts_like?(:time) && value.respond_to?(:in_time_zone) + value = value.in_time_zone + end + + @value = value + @type = compute_type + end + + def decorations + decorations = {} + decorations[:encoding] = 'base64' if type == :binary + decorations[:type] = (type == :string) ? nil : type + decorations[:nil] = true if value.nil? + decorations + end + + protected + + def compute_type + return if value.nil? + type = ActiveSupport::XmlMini::TYPE_NAMES[value.class.name] + type ||= :string if value.respond_to?(:to_str) + type ||= :yaml + type + end + end + + class MethodAttribute < Attribute #:nodoc: + end + + attr_reader :options + + def initialize(serializable, options = nil) + @serializable = serializable + @options = options ? options.dup : {} + end + + def serializable_hash + @serializable.serializable_hash(@options.except(:include)) + end + + def serializable_collection + methods = Array(options[:methods]).map(&:to_s) + serializable_hash.map do |name, value| + name = name.to_s + if methods.include?(name) + self.class::MethodAttribute.new(name, @serializable, value) + else + self.class::Attribute.new(name, @serializable, value) + end + end + end + + def serialize + require 'builder' unless defined? ::Builder + + options[:indent] ||= 2 + options[:builder] ||= ::Builder::XmlMarkup.new(indent: options[:indent]) + + @builder = options[:builder] + @builder.instruct! unless options[:skip_instruct] + + root = (options[:root] || @serializable.model_name.element).to_s + root = ActiveSupport::XmlMini.rename_key(root, options) + + args = [root] + args << { xmlns: options[:namespace] } if options[:namespace] + args << { type: options[:type] } if options[:type] && !options[:skip_types] + + @builder.tag!(*args) do + add_attributes_and_methods + add_includes + add_extra_behavior + add_procs + yield @builder if block_given? + end + end + + private + + def add_extra_behavior + end + + def add_attributes_and_methods + serializable_collection.each do |attribute| + key = ActiveSupport::XmlMini.rename_key(attribute.name, options) + ActiveSupport::XmlMini.to_tag(key, attribute.value, + options.merge(attribute.decorations)) + end + end + + def add_includes + @serializable.send(:serializable_add_includes, options) do |association, records, opts| + add_associations(association, records, opts) + end + end + + # TODO: This can likely be cleaned up to simple use ActiveSupport::XmlMini.to_tag as well. + def add_associations(association, records, opts) + merged_options = opts.merge(options.slice(:builder, :indent)) + merged_options[:skip_instruct] = true + + [:skip_types, :dasherize, :camelize].each do |key| + merged_options[key] = options[key] if merged_options[key].nil? && !options[key].nil? + end + + if records.respond_to?(:to_ary) + records = records.to_ary + + tag = ActiveSupport::XmlMini.rename_key(association.to_s, options) + type = options[:skip_types] ? { } : { type: "array" } + association_name = association.to_s.singularize + merged_options[:root] = association_name + + if records.empty? + @builder.tag!(tag, type) + else + @builder.tag!(tag, type) do + records.each do |record| + if options[:skip_types] + record_type = {} + else + record_class = (record.class.to_s.underscore == association_name) ? nil : record.class.name + record_type = { type: record_class } + end + + record.to_xml merged_options.merge(record_type) + end + end + end + else + merged_options[:root] = association.to_s + + unless records.class.to_s.underscore == association.to_s + merged_options[:type] = records.class.name + end + + records.to_xml merged_options + end + end + + def add_procs + if procs = options.delete(:procs) + Array(procs).each do |proc| + if proc.arity == 1 + proc.call(options) + else + proc.call(options, @serializable) + end + end + end + end + end + + # Returns XML representing the model. Configuration can be + # passed through +options+. + # + # Without any +options+, the returned XML string will include all the + # model's attributes. + # + # user = User.find(1) + # user.to_xml + # + # + # + # 1 + # David + # 16 + # 2011-01-30T22:29:23Z + # + # + # The :only and :except options can be used to limit the + # attributes included, and work similar to the +attributes+ method. + # + # To include the result of some method calls on the model use :methods. + # + # To include associations use :include. + # + # For further documentation, see ActiveRecord::Serialization#to_xml + def to_xml(options = {}, &block) + Serializer.new(self, options).serialize(&block) + end + + # Sets the model +attributes+ from an XML string. Returns +self+. + # + # class Person + # include ActiveModel::Serializers::Xml + # + # attr_accessor :name, :age, :awesome + # + # def attributes=(hash) + # hash.each do |key, value| + # instance_variable_set("@#{key}", value) + # end + # end + # + # def attributes + # instance_values + # end + # end + # + # xml = { name: 'bob', age: 22, awesome:true }.to_xml + # person = Person.new + # person.from_xml(xml) # => # + # person.name # => "bob" + # person.age # => 22 + # person.awesome # => true + def from_xml(xml) + self.attributes = Hash.from_xml(xml).values.first + self + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/test_case.rb b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/test_case.rb new file mode 100644 index 0000000..5004855 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/test_case.rb @@ -0,0 +1,4 @@ +module ActiveModel #:nodoc: + class TestCase < ActiveSupport::TestCase #:nodoc: + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/translation.rb b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/translation.rb new file mode 100644 index 0000000..8470915 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/translation.rb @@ -0,0 +1,69 @@ +module ActiveModel + + # == Active \Model \Translation + # + # Provides integration between your object and the Rails internationalization + # (i18n) framework. + # + # A minimal implementation could be: + # + # class TranslatedPerson + # extend ActiveModel::Translation + # end + # + # TranslatedPerson.human_attribute_name('my_attribute') + # # => "My attribute" + # + # This also provides the required class methods for hooking into the + # Rails internationalization API, including being able to define a + # class based +i18n_scope+ and +lookup_ancestors+ to find translations in + # parent classes. + module Translation + include ActiveModel::Naming + + # Returns the +i18n_scope+ for the class. Overwrite if you want custom lookup. + def i18n_scope + :activemodel + end + + # When localizing a string, it goes through the lookup returned by this + # method, which is used in ActiveModel::Name#human, + # ActiveModel::Errors#full_messages and + # ActiveModel::Translation#human_attribute_name. + def lookup_ancestors + self.ancestors.select { |x| x.respond_to?(:model_name) } + end + + # Transforms attribute names into a more human format, such as "First name" + # instead of "first_name". + # + # Person.human_attribute_name("first_name") # => "First name" + # + # Specify +options+ with additional translating options. + def human_attribute_name(attribute, options = {}) + options = { count: 1 }.merge!(options) + parts = attribute.to_s.split(".") + attribute = parts.pop + namespace = parts.join("/") unless parts.empty? + attributes_scope = "#{self.i18n_scope}.attributes" + + if namespace + defaults = lookup_ancestors.map do |klass| + :"#{attributes_scope}.#{klass.model_name.i18n_key}/#{namespace}.#{attribute}" + end + defaults << :"#{attributes_scope}.#{namespace}.#{attribute}" + else + defaults = lookup_ancestors.map do |klass| + :"#{attributes_scope}.#{klass.model_name.i18n_key}.#{attribute}" + end + end + + defaults << :"attributes.#{attribute}" + defaults << options.delete(:default) if options[:default] + defaults << attribute.humanize + + options[:default] = defaults + I18n.translate(defaults.shift, options) + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/validations.rb b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/validations.rb new file mode 100644 index 0000000..8185154 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/validations.rb @@ -0,0 +1,405 @@ +require 'active_support/core_ext/array/extract_options' +require 'active_support/core_ext/hash/keys' +require 'active_support/core_ext/hash/except' + +module ActiveModel + + # == Active \Model \Validations + # + # Provides a full validation framework to your objects. + # + # A minimal implementation could be: + # + # class Person + # include ActiveModel::Validations + # + # attr_accessor :first_name, :last_name + # + # validates_each :first_name, :last_name do |record, attr, value| + # record.errors.add attr, 'starts with z.' if value.to_s[0] == ?z + # end + # end + # + # Which provides you with the full standard validation stack that you + # know from Active Record: + # + # person = Person.new + # person.valid? # => true + # person.invalid? # => false + # + # person.first_name = 'zoolander' + # person.valid? # => false + # person.invalid? # => true + # person.errors.messages # => {first_name:["starts with z."]} + # + # Note that ActiveModel::Validations automatically adds an +errors+ + # method to your instances initialized with a new ActiveModel::Errors + # object, so there is no need for you to do this manually. + module Validations + extend ActiveSupport::Concern + + included do + extend ActiveModel::Naming + extend ActiveModel::Callbacks + extend ActiveModel::Translation + + extend HelperMethods + include HelperMethods + + attr_accessor :validation_context + private :validation_context= + define_callbacks :validate, scope: :name + + class_attribute :_validators, instance_writer: false + self._validators = Hash.new { |h,k| h[k] = [] } + end + + module ClassMethods + # Validates each attribute against a block. + # + # class Person + # include ActiveModel::Validations + # + # attr_accessor :first_name, :last_name + # + # validates_each :first_name, :last_name, allow_blank: true do |record, attr, value| + # record.errors.add attr, 'starts with z.' if value.to_s[0] == ?z + # end + # end + # + # Options: + # * :on - Specifies the contexts where this validation is active. + # Runs in all validation contexts by default (nil). You can pass a symbol + # or an array of symbols. (e.g. on: :create or + # on: :custom_validation_context or + # on: [:create, :custom_validation_context]) + # * :allow_nil - Skip validation if attribute is +nil+. + # * :allow_blank - Skip validation if attribute is blank. + # * :if - Specifies a method, proc or string to call to determine + # if the validation should occur (e.g. if: :allow_validation, + # or if: Proc.new { |user| user.signup_step > 2 }). The method, + # proc or string should return or evaluate to a +true+ or +false+ value. + # * :unless - Specifies a method, proc or string to call to + # determine if the validation should not occur (e.g. unless: :skip_validation, + # or unless: Proc.new { |user| user.signup_step <= 2 }). The + # method, proc or string should return or evaluate to a +true+ or +false+ + # value. + def validates_each(*attr_names, &block) + validates_with BlockValidator, _merge_attributes(attr_names), &block + end + + VALID_OPTIONS_FOR_VALIDATE = [:on, :if, :unless, :prepend].freeze # :nodoc: + + # Adds a validation method or block to the class. This is useful when + # overriding the +validate+ instance method becomes too unwieldy and + # you're looking for more descriptive declaration of your validations. + # + # This can be done with a symbol pointing to a method: + # + # class Comment + # include ActiveModel::Validations + # + # validate :must_be_friends + # + # def must_be_friends + # errors.add(:base, 'Must be friends to leave a comment') unless commenter.friend_of?(commentee) + # end + # end + # + # With a block which is passed with the current record to be validated: + # + # class Comment + # include ActiveModel::Validations + # + # validate do |comment| + # comment.must_be_friends + # end + # + # def must_be_friends + # errors.add(:base, 'Must be friends to leave a comment') unless commenter.friend_of?(commentee) + # end + # end + # + # Or with a block where self points to the current record to be validated: + # + # class Comment + # include ActiveModel::Validations + # + # validate do + # errors.add(:base, 'Must be friends to leave a comment') unless commenter.friend_of?(commentee) + # end + # end + # + # Note that the return value of validation methods is not relevant. + # It's not possible to halt the validate callback chain. + # + # Options: + # * :on - Specifies the contexts where this validation is active. + # Runs in all validation contexts by default (nil). You can pass a symbol + # or an array of symbols. (e.g. on: :create or + # on: :custom_validation_context or + # on: [:create, :custom_validation_context]) + # * :if - Specifies a method, proc or string to call to determine + # if the validation should occur (e.g. if: :allow_validation, + # or if: Proc.new { |user| user.signup_step > 2 }). The method, + # proc or string should return or evaluate to a +true+ or +false+ value. + # * :unless - Specifies a method, proc or string to call to + # determine if the validation should not occur (e.g. unless: :skip_validation, + # or unless: Proc.new { |user| user.signup_step <= 2 }). The + # method, proc or string should return or evaluate to a +true+ or +false+ + # value. + def validate(*args, &block) + options = args.extract_options! + + if args.all? { |arg| arg.is_a?(Symbol) } + options.each_key do |k| + unless VALID_OPTIONS_FOR_VALIDATE.include?(k) + raise ArgumentError.new("Unknown key: #{k.inspect}. Valid keys are: #{VALID_OPTIONS_FOR_VALIDATE.map(&:inspect).join(', ')}. Perhaps you meant to call `validates` instead of `validate`?") + end + end + end + + if options.key?(:on) + options = options.dup + options[:if] = Array(options[:if]) + options[:if].unshift ->(o) { + Array(options[:on]).include?(o.validation_context) + } + end + + args << options + set_callback(:validate, *args, &block) + end + + # List all validators that are being used to validate the model using + # +validates_with+ method. + # + # class Person + # include ActiveModel::Validations + # + # validates_with MyValidator + # validates_with OtherValidator, on: :create + # validates_with StrictValidator, strict: true + # end + # + # Person.validators + # # => [ + # # #, + # # #, + # # # + # # ] + def validators + _validators.values.flatten.uniq + end + + # Clears all of the validators and validations. + # + # Note that this will clear anything that is being used to validate + # the model for both the +validates_with+ and +validate+ methods. + # It clears the validators that are created with an invocation of + # +validates_with+ and the callbacks that are set by an invocation + # of +validate+. + # + # class Person + # include ActiveModel::Validations + # + # validates_with MyValidator + # validates_with OtherValidator, on: :create + # validates_with StrictValidator, strict: true + # validate :cannot_be_robot + # + # def cannot_be_robot + # errors.add(:base, 'A person cannot be a robot') if person_is_robot + # end + # end + # + # Person.validators + # # => [ + # # #, + # # #, + # # # + # # ] + # + # If one runs Person.clear_validators! and then checks to see what + # validators this class has, you would obtain: + # + # Person.validators # => [] + # + # Also, the callback set by validate :cannot_be_robot will be erased + # so that: + # + # Person._validate_callbacks.empty? # => true + # + def clear_validators! + reset_callbacks(:validate) + _validators.clear + end + + # List all validators that are being used to validate a specific attribute. + # + # class Person + # include ActiveModel::Validations + # + # attr_accessor :name , :age + # + # validates_presence_of :name + # validates_inclusion_of :age, in: 0..99 + # end + # + # Person.validators_on(:name) + # # => [ + # # #, + # # ] + def validators_on(*attributes) + attributes.flat_map do |attribute| + _validators[attribute.to_sym] + end + end + + # Returns +true+ if +attribute+ is an attribute method, +false+ otherwise. + # + # class Person + # include ActiveModel::Validations + # + # attr_accessor :name + # end + # + # User.attribute_method?(:name) # => true + # User.attribute_method?(:age) # => false + def attribute_method?(attribute) + method_defined?(attribute) + end + + # Copy validators on inheritance. + def inherited(base) #:nodoc: + dup = _validators.dup + base._validators = dup.each { |k, v| dup[k] = v.dup } + super + end + end + + # Clean the +Errors+ object if instance is duped. + def initialize_dup(other) #:nodoc: + @errors = nil + super + end + + # Returns the +Errors+ object that holds all information about attribute + # error messages. + # + # class Person + # include ActiveModel::Validations + # + # attr_accessor :name + # validates_presence_of :name + # end + # + # person = Person.new + # person.valid? # => false + # person.errors # => # + def errors + @errors ||= Errors.new(self) + end + + # Runs all the specified validations and returns +true+ if no errors were + # added otherwise +false+. + # + # Aliased as validate. + # + # class Person + # include ActiveModel::Validations + # + # attr_accessor :name + # validates_presence_of :name + # end + # + # person = Person.new + # person.name = '' + # person.valid? # => false + # person.name = 'david' + # person.valid? # => true + # + # Context can optionally be supplied to define which callbacks to test + # against (the context is defined on the validations using :on). + # + # class Person + # include ActiveModel::Validations + # + # attr_accessor :name + # validates_presence_of :name, on: :new + # end + # + # person = Person.new + # person.valid? # => true + # person.valid?(:new) # => false + def valid?(context = nil) + current_context, self.validation_context = validation_context, context + errors.clear + run_validations! + ensure + self.validation_context = current_context + end + + alias_method :validate, :valid? + + # Performs the opposite of valid?. Returns +true+ if errors were + # added, +false+ otherwise. + # + # class Person + # include ActiveModel::Validations + # + # attr_accessor :name + # validates_presence_of :name + # end + # + # person = Person.new + # person.name = '' + # person.invalid? # => true + # person.name = 'david' + # person.invalid? # => false + # + # Context can optionally be supplied to define which callbacks to test + # against (the context is defined on the validations using :on). + # + # class Person + # include ActiveModel::Validations + # + # attr_accessor :name + # validates_presence_of :name, on: :new + # end + # + # person = Person.new + # person.invalid? # => false + # person.invalid?(:new) # => true + def invalid?(context = nil) + !valid?(context) + end + + # Hook method defining how an attribute value should be retrieved. By default + # this is assumed to be an instance named after the attribute. Override this + # method in subclasses should you need to retrieve the value for a given + # attribute differently: + # + # class MyClass + # include ActiveModel::Validations + # + # def initialize(data = {}) + # @data = data + # end + # + # def read_attribute_for_validation(key) + # @data[key] + # end + # end + alias :read_attribute_for_validation :send + + protected + + def run_validations! #:nodoc: + _run_validate_callbacks + errors.empty? + end + end +end + +Dir[File.dirname(__FILE__) + "/validations/*.rb"].each { |file| require file } diff --git a/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/validations/absence.rb b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/validations/absence.rb new file mode 100644 index 0000000..9b5416f --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/validations/absence.rb @@ -0,0 +1,31 @@ +module ActiveModel + module Validations + # == Active Model Absence Validator + class AbsenceValidator < EachValidator #:nodoc: + def validate_each(record, attr_name, value) + record.errors.add(attr_name, :present, options) if value.present? + end + end + + module HelperMethods + # Validates that the specified attributes are blank (as defined by + # Object#blank?). Happens by default on save. + # + # class Person < ActiveRecord::Base + # validates_absence_of :first_name + # end + # + # The first_name attribute must be in the object and it must be blank. + # + # Configuration options: + # * :message - A custom error message (default is: "must be blank"). + # + # There is also a list of default options supported by every validator: + # +:if+, +:unless+, +:on+, +:allow_nil+, +:allow_blank+, and +:strict+. + # See ActiveModel::Validation#validates for more information + def validates_absence_of(*attr_names) + validates_with AbsenceValidator, _merge_attributes(attr_names) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/validations/acceptance.rb b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/validations/acceptance.rb new file mode 100644 index 0000000..ac5e798 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/validations/acceptance.rb @@ -0,0 +1,55 @@ +module ActiveModel + + module Validations + class AcceptanceValidator < EachValidator # :nodoc: + def initialize(options) + super({ allow_nil: true, accept: "1" }.merge!(options)) + setup!(options[:class]) + end + + def validate_each(record, attribute, value) + unless value == options[:accept] + record.errors.add(attribute, :accepted, options.except(:accept, :allow_nil)) + end + end + + private + def setup!(klass) + attr_readers = attributes.reject { |name| klass.attribute_method?(name) } + attr_writers = attributes.reject { |name| klass.attribute_method?("#{name}=") } + klass.send(:attr_reader, *attr_readers) + klass.send(:attr_writer, *attr_writers) + end + end + + module HelperMethods + # Encapsulates the pattern of wanting to validate the acceptance of a + # terms of service check box (or similar agreement). + # + # class Person < ActiveRecord::Base + # validates_acceptance_of :terms_of_service + # validates_acceptance_of :eula, message: 'must be abided' + # end + # + # If the database column does not exist, the +terms_of_service+ attribute + # is entirely virtual. This check is performed only if +terms_of_service+ + # is not +nil+ and by default on save. + # + # Configuration options: + # * :message - A custom error message (default is: "must be + # accepted"). + # * :accept - Specifies value that is considered accepted. + # The default value is a string "1", which makes it easy to relate to + # an HTML checkbox. This should be set to +true+ if you are validating + # a database column, since the attribute is typecast from "1" to +true+ + # before validation. + # + # There is also a list of default options supported by every validator: + # +:if+, +:unless+, +:on+, +:allow_nil+, +:allow_blank+, and +:strict+. + # See ActiveModel::Validation#validates for more information. + def validates_acceptance_of(*attr_names) + validates_with AcceptanceValidator, _merge_attributes(attr_names) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/validations/callbacks.rb b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/validations/callbacks.rb new file mode 100644 index 0000000..25ccabd --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/validations/callbacks.rb @@ -0,0 +1,117 @@ +module ActiveModel + module Validations + # == Active \Model \Validation \Callbacks + # + # Provides an interface for any class to have +before_validation+ and + # +after_validation+ callbacks. + # + # First, include ActiveModel::Validations::Callbacks from the class you are + # creating: + # + # class MyModel + # include ActiveModel::Validations::Callbacks + # + # before_validation :do_stuff_before_validation + # after_validation :do_stuff_after_validation + # end + # + # Like other before_* callbacks if +before_validation+ returns + # +false+ then valid? will not be called. + module Callbacks + extend ActiveSupport::Concern + + included do + include ActiveSupport::Callbacks + define_callbacks :validation, + terminator: ->(_,result) { result == false }, + skip_after_callbacks_if_terminated: true, + scope: [:kind, :name] + end + + module ClassMethods + # Defines a callback that will get called right before validation + # happens. + # + # class Person + # include ActiveModel::Validations + # include ActiveModel::Validations::Callbacks + # + # attr_accessor :name + # + # validates_length_of :name, maximum: 6 + # + # before_validation :remove_whitespaces + # + # private + # + # def remove_whitespaces + # name.strip! + # end + # end + # + # person = Person.new + # person.name = ' bob ' + # person.valid? # => true + # person.name # => "bob" + def before_validation(*args, &block) + options = args.last + if options.is_a?(Hash) && options[:on] + options[:if] = Array(options[:if]) + options[:on] = Array(options[:on]) + options[:if].unshift ->(o) { + options[:on].include? o.validation_context + } + end + set_callback(:validation, :before, *args, &block) + end + + # Defines a callback that will get called right after validation + # happens. + # + # class Person + # include ActiveModel::Validations + # include ActiveModel::Validations::Callbacks + # + # attr_accessor :name, :status + # + # validates_presence_of :name + # + # after_validation :set_status + # + # private + # + # def set_status + # self.status = errors.empty? + # end + # end + # + # person = Person.new + # person.name = '' + # person.valid? # => false + # person.status # => false + # person.name = 'bob' + # person.valid? # => true + # person.status # => true + def after_validation(*args, &block) + options = args.extract_options! + options[:prepend] = true + options[:if] = Array(options[:if]) + if options[:on] + options[:on] = Array(options[:on]) + options[:if].unshift ->(o) { + options[:on].include? o.validation_context + } + end + set_callback(:validation, :after, *(args << options), &block) + end + end + + protected + + # Overwrite run validations to include callbacks. + def run_validations! #:nodoc: + _run_validation_callbacks { super } + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/validations/clusivity.rb b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/validations/clusivity.rb new file mode 100644 index 0000000..bad9e4f --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/validations/clusivity.rb @@ -0,0 +1,51 @@ +require 'active_support/core_ext/range' + +module ActiveModel + module Validations + module Clusivity #:nodoc: + ERROR_MESSAGE = "An object with the method #include? or a proc, lambda or symbol is required, " \ + "and must be supplied as the :in (or :within) option of the configuration hash" + + def check_validity! + unless delimiter.respond_to?(:include?) || delimiter.respond_to?(:call) || delimiter.respond_to?(:to_sym) + raise ArgumentError, ERROR_MESSAGE + end + end + + private + + def include?(record, value) + members = if delimiter.respond_to?(:call) + delimiter.call(record) + elsif delimiter.respond_to?(:to_sym) + record.send(delimiter) + else + delimiter + end + + members.send(inclusion_method(members), value) + end + + def delimiter + @delimiter ||= options[:in] || options[:within] + end + + # In Ruby 1.9 Range#include? on non-number-or-time-ish ranges checks all + # possible values in the range for equality, which is slower but more accurate. + # Range#cover? uses the previous logic of comparing a value with the range + # endpoints, which is fast but is only accurate on Numeric, Time, or DateTime ranges. + def inclusion_method(enumerable) + if enumerable.is_a? Range + case enumerable.first + when Numeric, Time, DateTime + :cover? + else + :include? + end + else + :include? + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/validations/confirmation.rb b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/validations/confirmation.rb new file mode 100644 index 0000000..1b11c28 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/validations/confirmation.rb @@ -0,0 +1,67 @@ +module ActiveModel + + module Validations + class ConfirmationValidator < EachValidator # :nodoc: + def initialize(options) + super + setup!(options[:class]) + end + + def validate_each(record, attribute, value) + if (confirmed = record.send("#{attribute}_confirmation")) && (value != confirmed) + human_attribute_name = record.class.human_attribute_name(attribute) + record.errors.add(:"#{attribute}_confirmation", :confirmation, options.merge(attribute: human_attribute_name)) + end + end + + private + def setup!(klass) + klass.send(:attr_reader, *attributes.map do |attribute| + :"#{attribute}_confirmation" unless klass.method_defined?(:"#{attribute}_confirmation") + end.compact) + + klass.send(:attr_writer, *attributes.map do |attribute| + :"#{attribute}_confirmation" unless klass.method_defined?(:"#{attribute}_confirmation=") + end.compact) + end + end + + module HelperMethods + # Encapsulates the pattern of wanting to validate a password or email + # address field with a confirmation. + # + # Model: + # class Person < ActiveRecord::Base + # validates_confirmation_of :user_name, :password + # validates_confirmation_of :email_address, + # message: 'should match confirmation' + # end + # + # View: + # <%= password_field "person", "password" %> + # <%= password_field "person", "password_confirmation" %> + # + # The added +password_confirmation+ attribute is virtual; it exists only + # as an in-memory attribute for validating the password. To achieve this, + # the validation adds accessors to the model for the confirmation + # attribute. + # + # NOTE: This check is performed only if +password_confirmation+ is not + # +nil+. To require confirmation, make sure to add a presence check for + # the confirmation attribute: + # + # validates_presence_of :password_confirmation, if: :password_changed? + # + # Configuration options: + # * :message - A custom error message (default is: "doesn't match + # %{translated_attribute_name}"). + # + # There is also a list of default options supported by every validator: + # +:if+, +:unless+, +:on+, +:allow_nil+, +:allow_blank+, and +:strict+. + # See ActiveModel::Validation#validates for more information + def validates_confirmation_of(*attr_names) + validates_with ConfirmationValidator, _merge_attributes(attr_names) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/validations/exclusion.rb b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/validations/exclusion.rb new file mode 100644 index 0000000..f342d27 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/validations/exclusion.rb @@ -0,0 +1,46 @@ +require "active_model/validations/clusivity" + +module ActiveModel + + module Validations + class ExclusionValidator < EachValidator # :nodoc: + include Clusivity + + def validate_each(record, attribute, value) + if include?(record, value) + record.errors.add(attribute, :exclusion, options.except(:in, :within).merge!(value: value)) + end + end + end + + module HelperMethods + # Validates that the value of the specified attribute is not in a + # particular enumerable object. + # + # class Person < ActiveRecord::Base + # validates_exclusion_of :username, in: %w( admin superuser ), message: "You don't belong here" + # validates_exclusion_of :age, in: 30..60, message: 'This site is only for under 30 and over 60' + # validates_exclusion_of :format, in: %w( mov avi ), message: "extension %{value} is not allowed" + # validates_exclusion_of :password, in: ->(person) { [person.username, person.first_name] }, + # message: 'should not be the same as your username or first name' + # validates_exclusion_of :karma, in: :reserved_karmas + # end + # + # Configuration options: + # * :in - An enumerable object of items that the value shouldn't + # be part of. This can be supplied as a proc, lambda or symbol which returns an + # enumerable. If the enumerable is a range the test is performed with + # * :within - A synonym(or alias) for :in + # Range#cover?, otherwise with include?. + # * :message - Specifies a custom error message (default is: "is + # reserved"). + # + # There is also a list of default options supported by every validator: + # +:if+, +:unless+, +:on+, +:allow_nil+, +:allow_blank+, and +:strict+. + # See ActiveModel::Validation#validates for more information + def validates_exclusion_of(*attr_names) + validates_with ExclusionValidator, _merge_attributes(attr_names) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/validations/format.rb b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/validations/format.rb new file mode 100644 index 0000000..02478dd --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/validations/format.rb @@ -0,0 +1,113 @@ +module ActiveModel + + module Validations + class FormatValidator < EachValidator # :nodoc: + def validate_each(record, attribute, value) + if options[:with] + regexp = option_call(record, :with) + record_error(record, attribute, :with, value) if value.to_s !~ regexp + elsif options[:without] + regexp = option_call(record, :without) + record_error(record, attribute, :without, value) if value.to_s =~ regexp + end + end + + def check_validity! + unless options.include?(:with) ^ options.include?(:without) # ^ == xor, or "exclusive or" + raise ArgumentError, "Either :with or :without must be supplied (but not both)" + end + + check_options_validity :with + check_options_validity :without + end + + private + + def option_call(record, name) + option = options[name] + option.respond_to?(:call) ? option.call(record) : option + end + + def record_error(record, attribute, name, value) + record.errors.add(attribute, :invalid, options.except(name).merge!(value: value)) + end + + def check_options_validity(name) + if option = options[name] + if option.is_a?(Regexp) + if options[:multiline] != true && regexp_using_multiline_anchors?(option) + raise ArgumentError, "The provided regular expression is using multiline anchors (^ or $), " \ + "which may present a security risk. Did you mean to use \\A and \\z, or forgot to add the " \ + ":multiline => true option?" + end + elsif !option.respond_to?(:call) + raise ArgumentError, "A regular expression or a proc or lambda must be supplied as :#{name}" + end + end + end + + def regexp_using_multiline_anchors?(regexp) + source = regexp.source + source.start_with?("^") || (source.end_with?("$") && !source.end_with?("\\$")) + end + end + + module HelperMethods + # Validates whether the value of the specified attribute is of the correct + # form, going by the regular expression provided. You can require that the + # attribute matches the regular expression: + # + # class Person < ActiveRecord::Base + # validates_format_of :email, with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i, on: :create + # end + # + # Alternatively, you can require that the specified attribute does _not_ + # match the regular expression: + # + # class Person < ActiveRecord::Base + # validates_format_of :email, without: /NOSPAM/ + # end + # + # You can also provide a proc or lambda which will determine the regular + # expression that will be used to validate the attribute. + # + # class Person < ActiveRecord::Base + # # Admin can have number as a first letter in their screen name + # validates_format_of :screen_name, + # with: ->(person) { person.admin? ? /\A[a-z0-9][a-z0-9_\-]*\z/i : /\A[a-z][a-z0-9_\-]*\z/i } + # end + # + # Note: use \A and \Z to match the start and end of the + # string, ^ and $ match the start/end of a line. + # + # Due to frequent misuse of ^ and $, you need to pass + # the multiline: true option in case you use any of these two + # anchors in the provided regular expression. In most cases, you should be + # using \A and \z. + # + # You must pass either :with or :without as an option. + # In addition, both must be a regular expression or a proc or lambda, or + # else an exception will be raised. + # + # Configuration options: + # * :message - A custom error message (default is: "is invalid"). + # * :with - Regular expression that if the attribute matches will + # result in a successful validation. This can be provided as a proc or + # lambda returning regular expression which will be called at runtime. + # * :without - Regular expression that if the attribute does not + # match will result in a successful validation. This can be provided as + # a proc or lambda returning regular expression which will be called at + # runtime. + # * :multiline - Set to true if your regular expression contains + # anchors that match the beginning or end of lines as opposed to the + # beginning or end of the string. These anchors are ^ and $. + # + # There is also a list of default options supported by every validator: + # +:if+, +:unless+, +:on+, +:allow_nil+, +:allow_blank+, and +:strict+. + # See ActiveModel::Validation#validates for more information + def validates_format_of(*attr_names) + validates_with FormatValidator, _merge_attributes(attr_names) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/validations/inclusion.rb b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/validations/inclusion.rb new file mode 100644 index 0000000..c84025f --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/validations/inclusion.rb @@ -0,0 +1,46 @@ +require "active_model/validations/clusivity" + +module ActiveModel + + module Validations + class InclusionValidator < EachValidator # :nodoc: + include Clusivity + + def validate_each(record, attribute, value) + unless include?(record, value) + record.errors.add(attribute, :inclusion, options.except(:in, :within).merge!(value: value)) + end + end + end + + module HelperMethods + # Validates whether the value of the specified attribute is available in a + # particular enumerable object. + # + # class Person < ActiveRecord::Base + # validates_inclusion_of :gender, in: %w( m f ) + # validates_inclusion_of :age, in: 0..99 + # validates_inclusion_of :format, in: %w( jpg gif png ), message: "extension %{value} is not included in the list" + # validates_inclusion_of :states, in: ->(person) { STATES[person.country] } + # validates_inclusion_of :karma, in: :available_karmas + # end + # + # Configuration options: + # * :in - An enumerable object of available items. This can be + # supplied as a proc, lambda or symbol which returns an enumerable. If the + # enumerable is a numerical range the test is performed with Range#cover?, + # otherwise with include?. When using a proc or lambda the instance + # under validation is passed as an argument. + # * :within - A synonym(or alias) for :in + # * :message - Specifies a custom error message (default is: "is + # not included in the list"). + # + # There is also a list of default options supported by every validator: + # +:if+, +:unless+, +:on+, +:allow_nil+, +:allow_blank+, and +:strict+. + # See ActiveModel::Validation#validates for more information + def validates_inclusion_of(*attr_names) + validates_with InclusionValidator, _merge_attributes(attr_names) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/validations/length.rb b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/validations/length.rb new file mode 100644 index 0000000..a96b30c --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/validations/length.rb @@ -0,0 +1,126 @@ +module ActiveModel + + # == Active \Model Length Validator + module Validations + class LengthValidator < EachValidator # :nodoc: + MESSAGES = { is: :wrong_length, minimum: :too_short, maximum: :too_long }.freeze + CHECKS = { is: :==, minimum: :>=, maximum: :<= }.freeze + + RESERVED_OPTIONS = [:minimum, :maximum, :within, :is, :tokenizer, :too_short, :too_long] + + def initialize(options) + if range = (options.delete(:in) || options.delete(:within)) + raise ArgumentError, ":in and :within must be a Range" unless range.is_a?(Range) + options[:minimum], options[:maximum] = range.min, range.max + end + + if options[:allow_blank] == false && options[:minimum].nil? && options[:is].nil? + options[:minimum] = 1 + end + + super + end + + def check_validity! + keys = CHECKS.keys & options.keys + + if keys.empty? + raise ArgumentError, 'Range unspecified. Specify the :in, :within, :maximum, :minimum, or :is option.' + end + + keys.each do |key| + value = options[key] + + unless (value.is_a?(Integer) && value >= 0) || value == Float::INFINITY + raise ArgumentError, ":#{key} must be a nonnegative Integer or Infinity" + end + end + end + + def validate_each(record, attribute, value) + value = tokenize(value) + value_length = value.respond_to?(:length) ? value.length : value.to_s.length + errors_options = options.except(*RESERVED_OPTIONS) + + CHECKS.each do |key, validity_check| + next unless check_value = options[key] + + if !value.nil? || skip_nil_check?(key) + next if value_length.send(validity_check, check_value) + end + + errors_options[:count] = check_value + + default_message = options[MESSAGES[key]] + errors_options[:message] ||= default_message if default_message + + record.errors.add(attribute, MESSAGES[key], errors_options) + end + end + + private + + def tokenize(value) + if options[:tokenizer] && value.kind_of?(String) + options[:tokenizer].call(value) + end || value + end + + def skip_nil_check?(key) + key == :maximum && options[:allow_nil].nil? && options[:allow_blank].nil? + end + end + + module HelperMethods + + # Validates that the specified attribute matches the length restrictions + # supplied. Only one option can be used at a time: + # + # class Person < ActiveRecord::Base + # validates_length_of :first_name, maximum: 30 + # validates_length_of :last_name, maximum: 30, message: "less than 30 if you don't mind" + # validates_length_of :fax, in: 7..32, allow_nil: true + # validates_length_of :phone, in: 7..32, allow_blank: true + # validates_length_of :user_name, within: 6..20, too_long: 'pick a shorter name', too_short: 'pick a longer name' + # validates_length_of :zip_code, minimum: 5, too_short: 'please enter at least 5 characters' + # validates_length_of :smurf_leader, is: 4, message: "papa is spelled with 4 characters... don't play me." + # validates_length_of :essay, minimum: 100, too_short: 'Your essay must be at least 100 words.', + # tokenizer: ->(str) { str.scan(/\w+/) } + # end + # + # Configuration options: + # * :minimum - The minimum size of the attribute. + # * :maximum - The maximum size of the attribute. Allows +nil+ by + # default if not used with :minimum. + # * :is - The exact size of the attribute. + # * :within - A range specifying the minimum and maximum size of + # the attribute. + # * :in - A synonym (or alias) for :within. + # * :allow_nil - Attribute may be +nil+; skip validation. + # * :allow_blank - Attribute may be blank; skip validation. + # * :too_long - The error message if the attribute goes over the + # maximum (default is: "is too long (maximum is %{count} characters)"). + # * :too_short - The error message if the attribute goes under the + # minimum (default is: "is too short (min is %{count} characters)"). + # * :wrong_length - The error message if using the :is + # method and the attribute is the wrong size (default is: "is the wrong + # length (should be %{count} characters)"). + # * :message - The error message to use for a :minimum, + # :maximum, or :is violation. An alias of the appropriate + # too_long/too_short/wrong_length message. + # * :tokenizer - Specifies how to split up the attribute string. + # (e.g. tokenizer: ->(str) { str.scan(/\w+/) } to count words + # as in above example). Defaults to ->(value) { value.split(//) } + # which counts individual characters. + # + # There is also a list of default options supported by every validator: + # +:if+, +:unless+, +:on+ and +:strict+. + # See ActiveModel::Validation#validates for more information + def validates_length_of(*attr_names) + validates_with LengthValidator, _merge_attributes(attr_names) + end + + alias_method :validates_size_of, :validates_length_of + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/validations/numericality.rb b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/validations/numericality.rb new file mode 100644 index 0000000..4ba4e3e --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/validations/numericality.rb @@ -0,0 +1,159 @@ +module ActiveModel + + module Validations + class NumericalityValidator < EachValidator # :nodoc: + CHECKS = { greater_than: :>, greater_than_or_equal_to: :>=, + equal_to: :==, less_than: :<, less_than_or_equal_to: :<=, + odd: :odd?, even: :even?, other_than: :!= }.freeze + + RESERVED_OPTIONS = CHECKS.keys + [:only_integer] + + def check_validity! + keys = CHECKS.keys - [:odd, :even] + options.slice(*keys).each do |option, value| + unless value.is_a?(Numeric) || value.is_a?(Proc) || value.is_a?(Symbol) + raise ArgumentError, ":#{option} must be a number, a symbol or a proc" + end + end + end + + def validate_each(record, attr_name, value) + before_type_cast = :"#{attr_name}_before_type_cast" + + raw_value = record.send(before_type_cast) if record.respond_to?(before_type_cast) + raw_value ||= value + + if record_attribute_changed_in_place?(record, attr_name) + raw_value = value + end + + return if options[:allow_nil] && raw_value.nil? + + unless value = parse_raw_value_as_a_number(raw_value) + record.errors.add(attr_name, :not_a_number, filtered_options(raw_value)) + return + end + + if allow_only_integer?(record) + unless value = parse_raw_value_as_an_integer(raw_value) + record.errors.add(attr_name, :not_an_integer, filtered_options(raw_value)) + return + end + end + + options.slice(*CHECKS.keys).each do |option, option_value| + case option + when :odd, :even + unless value.to_i.send(CHECKS[option]) + record.errors.add(attr_name, option, filtered_options(value)) + end + else + case option_value + when Proc + option_value = option_value.call(record) + when Symbol + option_value = record.send(option_value) + end + + unless value.send(CHECKS[option], option_value) + record.errors.add(attr_name, option, filtered_options(value).merge!(count: option_value)) + end + end + end + end + + protected + + def parse_raw_value_as_a_number(raw_value) + Kernel.Float(raw_value) if raw_value !~ /\A0[xX]/ + rescue ArgumentError, TypeError + nil + end + + def parse_raw_value_as_an_integer(raw_value) + raw_value.to_i if raw_value.to_s =~ /\A[+-]?\d+\z/ + end + + def filtered_options(value) + filtered = options.except(*RESERVED_OPTIONS) + filtered[:value] = value + filtered + end + + def allow_only_integer?(record) + case options[:only_integer] + when Symbol + record.send(options[:only_integer]) + when Proc + options[:only_integer].call(record) + else + options[:only_integer] + end + end + + private + + def record_attribute_changed_in_place?(record, attr_name) + record.respond_to?(:attribute_changed_in_place?) && + record.attribute_changed_in_place?(attr_name.to_s) + end + end + + module HelperMethods + # Validates whether the value of the specified attribute is numeric by + # trying to convert it to a float with Kernel.Float (if only_integer + # is +false+) or applying it to the regular expression /\A[\+\-]?\d+\Z/ + # (if only_integer is set to +true+). + # + # class Person < ActiveRecord::Base + # validates_numericality_of :value, on: :create + # end + # + # Configuration options: + # * :message - A custom error message (default is: "is not a number"). + # * :only_integer - Specifies whether the value has to be an + # integer, e.g. an integral value (default is +false+). + # * :allow_nil - Skip validation if attribute is +nil+ (default is + # +false+). Notice that for fixnum and float columns empty strings are + # converted to +nil+. + # * :greater_than - Specifies the value must be greater than the + # supplied value. + # * :greater_than_or_equal_to - Specifies the value must be + # greater than or equal the supplied value. + # * :equal_to - Specifies the value must be equal to the supplied + # value. + # * :less_than - Specifies the value must be less than the + # supplied value. + # * :less_than_or_equal_to - Specifies the value must be less + # than or equal the supplied value. + # * :other_than - Specifies the value must be other than the + # supplied value. + # * :odd - Specifies the value must be an odd number. + # * :even - Specifies the value must be an even number. + # + # There is also a list of default options supported by every validator: + # +:if+, +:unless+, +:on+, +:allow_nil+, +:allow_blank+, and +:strict+ . + # See ActiveModel::Validation#validates for more information + # + # The following checks can also be supplied with a proc or a symbol which + # corresponds to a method: + # + # * :greater_than + # * :greater_than_or_equal_to + # * :equal_to + # * :less_than + # * :less_than_or_equal_to + # * :only_integer + # + # For example: + # + # class Person < ActiveRecord::Base + # validates_numericality_of :width, less_than: ->(person) { person.height } + # validates_numericality_of :width, greater_than: :minimum_weight + # end + def validates_numericality_of(*attr_names) + validates_with NumericalityValidator, _merge_attributes(attr_names) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/validations/presence.rb b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/validations/presence.rb new file mode 100644 index 0000000..5d59327 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/validations/presence.rb @@ -0,0 +1,39 @@ + +module ActiveModel + + module Validations + class PresenceValidator < EachValidator # :nodoc: + def validate_each(record, attr_name, value) + record.errors.add(attr_name, :blank, options) if value.blank? + end + end + + module HelperMethods + # Validates that the specified attributes are not blank (as defined by + # Object#blank?). Happens by default on save. + # + # class Person < ActiveRecord::Base + # validates_presence_of :first_name + # end + # + # The first_name attribute must be in the object and it cannot be blank. + # + # If you want to validate the presence of a boolean field (where the real + # values are +true+ and +false+), you will want to use + # validates_inclusion_of :field_name, in: [true, false]. + # + # This is due to the way Object#blank? handles boolean values: + # false.blank? # => true. + # + # Configuration options: + # * :message - A custom error message (default is: "can't be blank"). + # + # There is also a list of default options supported by every validator: + # +:if+, +:unless+, +:on+, +:allow_nil+, +:allow_blank+, and +:strict+. + # See ActiveModel::Validation#validates for more information + def validates_presence_of(*attr_names) + validates_with PresenceValidator, _merge_attributes(attr_names) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/validations/validates.rb b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/validations/validates.rb new file mode 100644 index 0000000..bda436d --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/validations/validates.rb @@ -0,0 +1,173 @@ +require 'active_support/core_ext/hash/slice' + +module ActiveModel + module Validations + module ClassMethods + # This method is a shortcut to all default validators and any custom + # validator classes ending in 'Validator'. Note that Rails default + # validators can be overridden inside specific classes by creating + # custom validator classes in their place such as PresenceValidator. + # + # Examples of using the default rails validators: + # + # validates :terms, acceptance: true + # validates :password, confirmation: true + # validates :username, exclusion: { in: %w(admin superuser) } + # validates :email, format: { with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i, on: :create } + # validates :age, inclusion: { in: 0..9 } + # validates :first_name, length: { maximum: 30 } + # validates :age, numericality: true + # validates :username, presence: true + # validates :username, uniqueness: true + # + # The power of the +validates+ method comes when using custom validators + # and default validators in one call for a given attribute. + # + # class EmailValidator < ActiveModel::EachValidator + # def validate_each(record, attribute, value) + # record.errors.add attribute, (options[:message] || "is not an email") unless + # value =~ /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i + # end + # end + # + # class Person + # include ActiveModel::Validations + # attr_accessor :name, :email + # + # validates :name, presence: true, uniqueness: true, length: { maximum: 100 } + # validates :email, presence: true, email: true + # end + # + # Validator classes may also exist within the class being validated + # allowing custom modules of validators to be included as needed. + # + # class Film + # include ActiveModel::Validations + # + # class TitleValidator < ActiveModel::EachValidator + # def validate_each(record, attribute, value) + # record.errors.add attribute, "must start with 'the'" unless value =~ /\Athe/i + # end + # end + # + # validates :name, title: true + # end + # + # Additionally validator classes may be in another namespace and still + # used within any class. + # + # validates :name, :'film/title' => true + # + # The validators hash can also handle regular expressions, ranges, arrays + # and strings in shortcut form. + # + # validates :email, format: /@/ + # validates :gender, inclusion: %w(male female) + # validates :password, length: 6..20 + # + # When using shortcut form, ranges and arrays are passed to your + # validator's initializer as options[:in] while other types + # including regular expressions and strings are passed as options[:with]. + # + # There is also a list of options that could be used along with validators: + # + # * :on - Specifies the contexts where this validation is active. + # Runs in all validation contexts by default (nil). You can pass a symbol + # or an array of symbols. (e.g. on: :create or + # on: :custom_validation_context or + # on: [:create, :custom_validation_context]) + # * :if - Specifies a method, proc or string to call to determine + # if the validation should occur (e.g. if: :allow_validation, + # or if: Proc.new { |user| user.signup_step > 2 }). The method, + # proc or string should return or evaluate to a +true+ or +false+ value. + # * :unless - Specifies a method, proc or string to call to determine + # if the validation should not occur (e.g. unless: :skip_validation, + # or unless: Proc.new { |user| user.signup_step <= 2 }). The + # method, proc or string should return or evaluate to a +true+ or + # +false+ value. + # * :allow_nil - Skip validation if the attribute is +nil+. + # * :allow_blank - Skip validation if the attribute is blank. + # * :strict - If the :strict option is set to true + # will raise ActiveModel::StrictValidationFailed instead of adding the error. + # :strict option can also be set to any other exception. + # + # Example: + # + # validates :password, presence: true, confirmation: true, if: :password_required? + # validates :token, uniqueness: true, strict: TokenGenerationException + # + # + # Finally, the options +:if+, +:unless+, +:on+, +:allow_blank+, +:allow_nil+, +:strict+ + # and +:message+ can be given to one specific validator, as a hash: + # + # validates :password, presence: { if: :password_required?, message: 'is forgotten.' }, confirmation: true + def validates(*attributes) + defaults = attributes.extract_options!.dup + validations = defaults.slice!(*_validates_default_keys) + + raise ArgumentError, "You need to supply at least one attribute" if attributes.empty? + raise ArgumentError, "You need to supply at least one validation" if validations.empty? + + defaults[:attributes] = attributes + + validations.each do |key, options| + next unless options + key = "#{key.to_s.camelize}Validator" + + begin + validator = key.include?('::') ? key.constantize : const_get(key) + rescue NameError + raise ArgumentError, "Unknown validator: '#{key}'" + end + + validates_with(validator, defaults.merge(_parse_validates_options(options))) + end + end + + # This method is used to define validations that cannot be corrected by end + # users and are considered exceptional. So each validator defined with bang + # or :strict option set to true will always raise + # ActiveModel::StrictValidationFailed instead of adding error + # when validation fails. See validates for more information about + # the validation itself. + # + # class Person + # include ActiveModel::Validations + # + # attr_accessor :name + # validates! :name, presence: true + # end + # + # person = Person.new + # person.name = '' + # person.valid? + # # => ActiveModel::StrictValidationFailed: Name can't be blank + def validates!(*attributes) + options = attributes.extract_options! + options[:strict] = true + validates(*(attributes << options)) + end + + protected + + # When creating custom validators, it might be useful to be able to specify + # additional default keys. This can be done by overwriting this method. + def _validates_default_keys # :nodoc: + [:if, :unless, :on, :allow_blank, :allow_nil , :strict] + end + + def _parse_validates_options(options) # :nodoc: + case options + when TrueClass + {} + when Hash + options + when Range, Array + { in: options } + else + { with: options } + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/validations/with.rb b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/validations/with.rb new file mode 100644 index 0000000..a253132 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/validations/with.rb @@ -0,0 +1,153 @@ +module ActiveModel + module Validations + module HelperMethods + private + def _merge_attributes(attr_names) + options = attr_names.extract_options!.symbolize_keys + attr_names.flatten! + options[:attributes] = attr_names + options + end + end + + class WithValidator < EachValidator # :nodoc: + def validate_each(record, attr, val) + method_name = options[:with] + + if record.method(method_name).arity == 0 + record.send method_name + else + record.send method_name, attr + end + end + end + + module ClassMethods + # Passes the record off to the class or classes specified and allows them + # to add errors based on more complex conditions. + # + # class Person + # include ActiveModel::Validations + # validates_with MyValidator + # end + # + # class MyValidator < ActiveModel::Validator + # def validate(record) + # if some_complex_logic + # record.errors.add :base, 'This record is invalid' + # end + # end + # + # private + # def some_complex_logic + # # ... + # end + # end + # + # You may also pass it multiple classes, like so: + # + # class Person + # include ActiveModel::Validations + # validates_with MyValidator, MyOtherValidator, on: :create + # end + # + # Configuration options: + # * :on - Specifies the contexts where this validation is active. + # Runs in all validation contexts by default (nil). You can pass a symbol + # or an array of symbols. (e.g. on: :create or + # on: :custom_validation_context or + # on: [:create, :custom_validation_context]) + # * :if - Specifies a method, proc or string to call to determine + # if the validation should occur (e.g. if: :allow_validation, + # or if: Proc.new { |user| user.signup_step > 2 }). + # The method, proc or string should return or evaluate to a +true+ or + # +false+ value. + # * :unless - Specifies a method, proc or string to call to + # determine if the validation should not occur + # (e.g. unless: :skip_validation, or + # unless: Proc.new { |user| user.signup_step <= 2 }). + # The method, proc or string should return or evaluate to a +true+ or + # +false+ value. + # * :strict - Specifies whether validation should be strict. + # See ActiveModel::Validation#validates! for more information. + # + # If you pass any additional configuration options, they will be passed + # to the class and available as +options+: + # + # class Person + # include ActiveModel::Validations + # validates_with MyValidator, my_custom_key: 'my custom value' + # end + # + # class MyValidator < ActiveModel::Validator + # def validate(record) + # options[:my_custom_key] # => "my custom value" + # end + # end + def validates_with(*args, &block) + options = args.extract_options! + options[:class] = self + + args.each do |klass| + validator = klass.new(options, &block) + + if validator.respond_to?(:attributes) && !validator.attributes.empty? + validator.attributes.each do |attribute| + _validators[attribute.to_sym] << validator + end + else + _validators[nil] << validator + end + + validate(validator, options) + end + end + end + + # Passes the record off to the class or classes specified and allows them + # to add errors based on more complex conditions. + # + # class Person + # include ActiveModel::Validations + # + # validate :instance_validations + # + # def instance_validations + # validates_with MyValidator + # end + # end + # + # Please consult the class method documentation for more information on + # creating your own validator. + # + # You may also pass it multiple classes, like so: + # + # class Person + # include ActiveModel::Validations + # + # validate :instance_validations, on: :create + # + # def instance_validations + # validates_with MyValidator, MyOtherValidator + # end + # end + # + # Standard configuration options (:on, :if and + # :unless), which are available on the class version of + # +validates_with+, should instead be placed on the +validates+ method + # as these are applied and tested in the callback. + # + # If you pass any additional configuration options, they will be passed + # to the class and available as +options+, please refer to the + # class version of this method for more information. + def validates_with(*args, &block) + options = args.extract_options! + options[:class] = self.class + + args.each do |klass| + validator = klass.new(options, &block) + validator.validate(self) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/validator.rb b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/validator.rb new file mode 100644 index 0000000..0116de6 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/validator.rb @@ -0,0 +1,182 @@ +require "active_support/core_ext/module/anonymous" + +module ActiveModel + + # == Active \Model \Validator + # + # A simple base class that can be used along with + # ActiveModel::Validations::ClassMethods.validates_with + # + # class Person + # include ActiveModel::Validations + # validates_with MyValidator + # end + # + # class MyValidator < ActiveModel::Validator + # def validate(record) + # if some_complex_logic + # record.errors[:base] = "This record is invalid" + # end + # end + # + # private + # def some_complex_logic + # # ... + # end + # end + # + # Any class that inherits from ActiveModel::Validator must implement a method + # called +validate+ which accepts a +record+. + # + # class Person + # include ActiveModel::Validations + # validates_with MyValidator + # end + # + # class MyValidator < ActiveModel::Validator + # def validate(record) + # record # => The person instance being validated + # options # => Any non-standard options passed to validates_with + # end + # end + # + # To cause a validation error, you must add to the +record+'s errors directly + # from within the validators message. + # + # class MyValidator < ActiveModel::Validator + # def validate(record) + # record.errors.add :base, "This is some custom error message" + # record.errors.add :first_name, "This is some complex validation" + # # etc... + # end + # end + # + # To add behavior to the initialize method, use the following signature: + # + # class MyValidator < ActiveModel::Validator + # def initialize(options) + # super + # @my_custom_field = options[:field_name] || :first_name + # end + # end + # + # Note that the validator is initialized only once for the whole application + # life cycle, and not on each validation run. + # + # The easiest way to add custom validators for validating individual attributes + # is with the convenient ActiveModel::EachValidator. + # + # class TitleValidator < ActiveModel::EachValidator + # def validate_each(record, attribute, value) + # record.errors.add attribute, 'must be Mr., Mrs., or Dr.' unless %w(Mr. Mrs. Dr.).include?(value) + # end + # end + # + # This can now be used in combination with the +validates+ method + # (see ActiveModel::Validations::ClassMethods.validates for more on this). + # + # class Person + # include ActiveModel::Validations + # attr_accessor :title + # + # validates :title, presence: true, title: true + # end + # + # It can be useful to access the class that is using that validator when there are prerequisites such + # as an +attr_accessor+ being present. This class is accessible via +options[:class]+ in the constructor. + # To setup your validator override the constructor. + # + # class MyValidator < ActiveModel::Validator + # def initialize(options={}) + # super + # options[:class].send :attr_accessor, :custom_attribute + # end + # end + class Validator + attr_reader :options + + # Returns the kind of the validator. + # + # PresenceValidator.kind # => :presence + # UniquenessValidator.kind # => :uniqueness + def self.kind + @kind ||= name.split('::').last.underscore.sub(/_validator$/, '').to_sym unless anonymous? + end + + # Accepts options that will be made available through the +options+ reader. + def initialize(options = {}) + @options = options.except(:class).freeze + end + + # Returns the kind for this validator. + # + # PresenceValidator.new.kind # => :presence + # UniquenessValidator.new.kind # => :uniqueness + def kind + self.class.kind + end + + # Override this method in subclasses with validation logic, adding errors + # to the records +errors+ array where necessary. + def validate(record) + raise NotImplementedError, "Subclasses must implement a validate(record) method." + end + end + + # +EachValidator+ is a validator which iterates through the attributes given + # in the options hash invoking the validate_each method passing in the + # record, attribute and value. + # + # All Active Model validations are built on top of this validator. + class EachValidator < Validator #:nodoc: + attr_reader :attributes + + # Returns a new validator instance. All options will be available via the + # +options+ reader, however the :attributes option will be removed + # and instead be made available through the +attributes+ reader. + def initialize(options) + @attributes = Array(options.delete(:attributes)) + raise ArgumentError, ":attributes cannot be blank" if @attributes.empty? + super + check_validity! + end + + # Performs validation on the supplied record. By default this will call + # +validates_each+ to determine validity therefore subclasses should + # override +validates_each+ with validation logic. + def validate(record) + attributes.each do |attribute| + value = record.read_attribute_for_validation(attribute) + next if (value.nil? && options[:allow_nil]) || (value.blank? && options[:allow_blank]) + validate_each(record, attribute, value) + end + end + + # Override this method in subclasses with the validation logic, adding + # errors to the records +errors+ array where necessary. + def validate_each(record, attribute, value) + raise NotImplementedError, "Subclasses must implement a validate_each(record, attribute, value) method" + end + + # Hook method that gets called by the initializer allowing verification + # that the arguments supplied are valid. You could for example raise an + # +ArgumentError+ when invalid options are supplied. + def check_validity! + end + end + + # +BlockValidator+ is a special +EachValidator+ which receives a block on initialization + # and call this block for each attribute being validated. +validates_each+ uses this validator. + class BlockValidator < EachValidator #:nodoc: + def initialize(options, &block) + @block = block + super + end + + private + + def validate_each(record, attribute, value) + @block.call(record, attribute, value) + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/version.rb b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/version.rb new file mode 100644 index 0000000..b1f9082 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activemodel-4.2.6/lib/active_model/version.rb @@ -0,0 +1,8 @@ +require_relative 'gem_version' + +module ActiveModel + # Returns the version of the currently loaded ActiveModel as a Gem::Version + def self.version + gem_version + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/CHANGELOG.md b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/CHANGELOG.md new file mode 100644 index 0000000..8fa151c --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/CHANGELOG.md @@ -0,0 +1,1918 @@ +## Rails 4.2.6 (March 07, 2016) ## + +* Fix a bug where using `t.foreign_key` twice with the same `to_table` within + the same table definition would only create one foreign key. + + *George Millo* + +* Fix regression in dirty attribute tracking after #dup. Changes to the + clone no longer show as changed attributes in the original object. + + *Dominic Cleal* + +* Fix regression when loading fixture files with symbol keys. + + Closes #22584. + + *Yves Senn* + +* Fix `rake db:structure:dump` on Postgres when multiple schemas are used. + + Fixes #22346. + + *Nick Muerdter*, *ckoenig* + +* Introduce `connection.data_sources` and `connection.data_source_exists?`. + These methods determine what relations can be used to back Active Record + models (usually tables and views). + + *Yves Senn*, *Matthew Draper* + + +## Rails 4.2.5.2 (February 26, 2016) ## + +* No changes. + + +## Rails 4.2.5.1 (January 25, 2015) ## + +* No changes. + + +## Rails 4.2.5 (November 12, 2015) ## + +* No longer pass deprecated option `-i` to `pg_dump`. + + *Paul Sadauskas* + +* Set `scope.reordering_value` to `true` if :reordering values are specified. + + Fixes #21886. + + *Hiroaki Izu* + +* Avoid disabling errors on the PostgreSQL connection when enabling the + standard_conforming_strings setting. Errors were previously disabled because + the setting wasn't writable in Postgres 8.1 and didn't exist in earlier + versions. Now Rails only supports Postgres 8.2+ we're fine to assume the + setting exists. Disabling errors caused problems when using a connection + pooling tool like PgBouncer because it's not guaranteed to have the same + connection between calls to `execute` and it could leave the connection + with errors disabled. + + Fixes #22101. + + *Harry Marr* + +* Includes HABTM returns correct size now. It's caused by the join dependency + only instantiates one HABTM object because the join table hasn't a primary key. + + Fixes #16032. + + Examples: + + before: + + Project.first.salaried_developers.size # => 3 + Project.includes(:salaried_developers).first.salaried_developers.size # => 1 + + after: + + Project.first.salaried_developers.size # => 3 + Project.includes(:salaried_developers).first.salaried_developers.size # => 3 + + *Bigxiang* + +* Descriptive error message when fixtures contain a missing column. + + Closes #21201. + + *Yves Senn* + +* `bin/rake db:migrate` uses + `ActiveRecord::Tasks::DatabaseTasks.migrations_paths` instead of + `Migrator.migrations_paths`. + + *Tobias Bielohlawek* + +* Fix `rewhere` in a `has_many` association. + + Fixes #21955. + + *Josh Branchaud*, *Kal* + +* Added run_cmd class method to ActiveRecord::Tasks::DatabaseTasks for + drying up Kernel.system() calls within this namespace and to avoid + shell expansion by using a paramter list instead of string as arguments + for Kernel.system(). Thanks to Nate Berkopec for supply patch to get + test units passing. + + *Bryan Paxton* + +* Avoid leaking the first relation we call `first` on, per model. + + Fixes #21921. + + *Matthew Draper*, *Jean Boussier* + +* Allow deserialization of Active Record models that were YAML encoded prior + to Rails 4.2 + + *Sean Griffin* + +* Correctly apply `unscope` when preloading through associations. + + *Jimmy Bourassa* + +* Ensure `select` quotes aliased attributes, even when using `from`. + + Fixes #21488 + + *Sean Griffin & @johanlunds* + +* Correct query for PostgreSQL 8.2 compatibility. + + *Ben Murphy*, *Matthew Draper* + +* Uniqueness validator raises descriptive error when running on a persisted + record without primary key. + + Closes #21304. + + *Yves Senn* + + +## Rails 4.2.4 (August 24, 2015) ## + +* Skip statement cache on through association reader. + + If the through class has default scopes we should skip the statement + cache. + + Closes #20745. + + *Rafael Mendonça França* + +* Fixes #19420. When generating schema.rb using Postgres BigInt[] data type + the limit: 8 was not coming through. This caused it to become Int[] data type + after doing a rebuild off of schema.rb. + + *Jake Waller* + +* Fix state being carried over from previous transaction. + + Considering the following example where `name` is a required attribute. + Before we had `new_record?` returning `true` for a persisted record: + + author = Author.create! name: 'foo' + author.name = nil + author.save # => false + author.new_record? # => true + + Fixes #20824. + + *Roque Pinel* + +* Correctly ignore `mark_for_destruction` when `autosave` isn't set to `true` + when validating associations. + + Fixes #20882. + + *Sean Griffin* + +* Fix through associations using scopes having the scope merged multiple + times. + + Fixes #20721. + Fixes #20727. + + *Sean Griffin* + +* `ActiveRecord::Base.dump_schema_after_migration` applies migration tasks + other than `db:migrate`. (eg. `db:rollback`, `db:migrate:dup`, ...) + + Fixes #20743. + + *Yves Senn* + +* Correctly raise `ActiveRecord::AssociationTypeMismatch` when assigning + a wrong type to a namespaced association. + + Fixes #20545. + + *Diego Carrion* + +* Prevent error when using `force_reload: true` on an unassigned polymorphic + belongs_to association. + + Fixes #20426. + + *James Dabbs* + + +## Rails 4.2.3 (June 25, 2015) ## + +* Let `WITH` queries (Common Table Expressions) be explainable. + + *Vladimir Kochnev* + +* Fix n+1 query problem when eager loading nil associations (fixes #18312) + + *Sammy Larbi* + +* Fixed an error which would occur in dirty checking when calling + `update_attributes` from a getter. + + Fixes #20531. + + *Sean Griffin* + +* Ensure symbols passed to `ActiveRecord::Relation#select` are always treated + as columns. + + Fixes #20360. + + *Sean Griffin* + +* Clear query cache when `ActiveRecord::Base#reload` is called. + + *Shane Hender* + +* Pass `:extend` option for `has_and_belongs_to_many` associations to the + underlying `has_many :through`. + + *Jaehyun Shin* + +* Make `unscope` aware of "less than" and "greater than" conditions. + + *TAKAHASHI Kazuaki* + +* Revert behavior of `db:schema:load` back to loading the full + environment. This ensures that initializers are run. + + Fixes #19545. + + *Yves Senn* + +* Fix missing index when using `timestamps` with the `index` option. + + The `index` option used with `timestamps` should be passed to both + `column` definitions for `created_at` and `updated_at` rather than just + the first. + + *Paul Mucur* + +* Rename `:class` to `:anonymous_class` in association options. + + Fixes #19659. + + *Andrew White* + +* Fixed a bug where uniqueness validations would error on out of range values, + even if an validation should have prevented it from hitting the database. + + *Andrey Voronkov* + +* Foreign key related methods in the migration DSL respect + `ActiveRecord::Base.pluralize_table_names = false`. + + Fixes #19643. + + *Mehmet Emin Ä°NAÇ* + +* Reduce memory usage from loading types on pg. + + Fixes #19578. + + *Sean Griffin* + +* Fix referencing wrong table aliases while joining tables of has many through + association (only when calling calculation methods). + + Fixes #19276. + + *pinglamb* + +* Don't attempt to update counter caches, when the column wasn't selected. + + Fixes #19437. + + *Sean Griffin* + +* Correctly persist a serialized attribute that has been returned to + its default value by an in-place modification. + + Fixes #19467. + + *Matthew Draper* + +* Fix default `format` value in `ActiveRecord::Tasks::DatabaseTasks#schema_file`. + + *James Cox* + +* Dont enroll records in the transaction if they dont have commit callbacks. + That was causing a memory grow problem when creating a lot of records inside a transaction. + + Fixes #15549. + + *Will Bryant*, *Aaron Patterson* + +* Correctly create through records when created on a has many through + association when using `where`. + + Fixes #19073. + + *Sean Griffin* + + +## Rails 4.2.2 (June 16, 2015) ## + +* No Changes * + + +## Rails 4.2.1 (March 19, 2015) ## + +* Fixed ActiveRecord::Relation#becomes! and changed_attributes issues for type column + + Fixes #17139. + + *Miklos Fazekas* + +* `remove_reference` with `foreign_key: true` removes the foreign key before + removing the column. This fixes a bug where it was not possible to remove + the column on MySQL. + + Fixes #18664. + + *Yves Senn* + +* Add a `:foreign_key` option to `references` and associated migration + methods. The model and migration generators now use this option, rather than + the `add_foreign_key` form. + + *Sean Griffin* + +* Fix rounding problem for PostgreSQL timestamp column. + + If timestamp column have the precision, it need to format according to + the precision of timestamp column. + + *Ryuta Kamizono* + +* Respect the database default charset for `schema_migrations` table. + + The charset of `version` column in `schema_migrations` table is depend + on the database default charset and collation rather than the encoding + of the connection. + + *Ryuta Kamizono* + +* Respect custom primary keys for associations when calling `Relation#where` + + Fixes #18813. + + *Sean Griffin* + +* Fixed several edge cases which could result in a counter cache updating + twice or not updating at all for `has_many` and `has_many :through`. + + Fixes #10865. + + *Sean Griffin* + +* Foreign keys added by migrations were given random, generated names. This + meant a different `structure.sql` would be generated every time a developer + ran migrations on their machine. + + The generated part of foreign key names is now a hash of the table name and + column name, which is consistent every time you run the migration. + + *Chris Sinjakli* + +* Fixed ActiveRecord::Relation#group method when argument is SQL reserved key word: + + SplitTest.group(:key).count + Property.group(:value).count + + *Bogdan Gusiev* + +* Don't define autosave association callbacks twice from + `accepts_nested_attributes_for`. + + Fixes #18704. + + *Sean Griffin* + +* Integer types will no longer raise a `RangeError` when assigning an + attribute, but will instead raise when going to the database. + + Fixes several vague issues which were never reported directly. See the + commit message from the commit which added this line for some examples. + + *Sean Griffin* + +* Values which would error while being sent to the database (such as an + ASCII-8BIT string with invalid UTF-8 bytes on Sqlite3), no longer error on + assignment. They will still error when sent to the database, but you are + given the ability to re-assign it to a valid value. + + Fixes #18580. + + *Sean Griffin* + +* Don't remove join dependencies in `Relation#exists?` + + Fixes #18632. + + *Sean Griffin* + +* Invalid values assigned to a JSON column are assumed to be `nil`. + + Fixes #18629. + + *Sean Griffin* + +* No longer issue deprecation warning when including a scope with extensions. + Previously every scope with extension methods was transformed into an + instance dependent scope. Including such a scope would wrongfully issue a + deprecation warning. This is no longer the case. + + Fixes #18467. + + *Yves Senn* + +* Correctly use the type provided by `serialize` when updating records using + optimistic locking. + + Fixes #18385. + + *Sean Griffin* + +* `attribute_will_change!` will no longer cause non-persistable attributes to + be sent to the database. + + Fixes #18407. + + *Sean Griffin* + +* Format the datetime string according to the precision of the datetime field. + + Incompatible to rounding behavior between MySQL 5.6 and earlier. + + In 5.5, when you insert `2014-08-17 12:30:00.999999` the fractional part + is ignored. In 5.6, it's rounded to `2014-08-17 12:30:01`: + + http://bugs.mysql.com/bug.php?id=68760 + + *Ryuta Kamizono* + +* Allow precision option for MySQL datetimes. + + *Ryuta Kamizono* + +* Clear query cache on rollback. + + *Florian Weingarten* + +* Fixed setting of foreign_key for through associations while building of new record. + + Fixes #12698. + + *Ivan Antropov* + +* Fixed automatic inverse_of for models nested in module. + + *Andrew McCloud* + +* Fix `reaping_frequency` option when the value is a string. + + This usually happens when it is configured using `DATABASE_URL`. + + *korbin* + +* Fix error message when trying to create an associated record and the foreign + key is missing. + + Before this fix the following exception was being raised: + + NoMethodError: undefined method `val' for # + + Now the message is: + + ActiveRecord::UnknownAttributeError: unknown attribute 'foreign_key' for Model. + + *Rafael Mendonça França* + +* Fix change detection problem for PostgreSQL bytea type and + `ArgumentError: string contains null byte` exception with pg-0.18. + + Fixes #17680. + + *Lars Kanis* + +* When a table has a composite primary key, the `primary_key` method for + SQLite3 and PostgreSQL adapters was only returning the first field of the key. + Ensures that it will return nil instead, as Active Record doesn't support + composite primary keys. + + Fixes #18070. + + *arthurnn* + +* Ensure `first!` and friends work on loaded associations. + + Fixes #18237. + + *Sean Griffin* + +* Dump the default `nil` for PostgreSQL UUID primary key. + + *Ryuta Kamizono* + +* Don't raise when writing an attribute with an out-of-range datetime passed + by the user. + + *Grey Baker* + +* Fixes bug with 'ActiveRecord::Type::Numeric' that causes negative values to + be marked as having changed when set to the same negative value. + + Fixes #18161. + + *Daniel Fox* + + +## Rails 4.2.0 (December 20, 2014) ## + +* Introduce `force: :cascade` option for `create_table`. Using this option + will recreate tables even if they have dependent objects (like foreign keys). + `db/schema.rb` now uses `force: :cascade`. This makes it possible to + reload the schema when foreign keys are in place. + + *Matthew Draper*, *Yves Senn* + +* `db:schema:load` and `db:structure:load` no longer purge the database + before loading the schema. This is left for the user to do. + `db:test:prepare` will still purge the database. + + Fixes #17945. + + *Yves Senn* + +* Fix undesirable RangeError by Type::Integer. Add Type::UnsignedInteger. + + *Ryuta Kamizono* + +* Add `foreign_type` option to `has_one` and `has_many` association macros. + + This option enables to define the column name of associated object's type for polymorphic associations. + + *Ulisses Almeida, Kassio Borges* + +* `add_timestamps` and `remove_timestamps` now properly reversible with + options. + + *Noam Gagliardi-Rabinovich* + +* Bring back `db:test:prepare` to synchronize the test database schema. + + Manual synchronization using `bin/rake db:test:prepare` is required + when a migration is rolled-back, edited and reapplied. + + `ActiveRecord::Base.maintain_test_schema` now uses `db:test:prepare` + to synchronize the schema. Plugins can use this task as a hook to + provide custom behavior after the schema has been loaded. + + NOTE: `test:prepare` runs before the schema is synchronized. + + Fixes #17171, #15787. + + *Yves Senn* + +* Change `reflections` public api to return the keys as String objects. + + Fixes #16928. + + *arthurnn* + +* Renaming a table in pg also renames the primary key index. + + Fixes #12856 + + *Sean Griffin* + +* Make it possible to access fixtures excluded by a `default_scope`. + + *Yves Senn* + +* Fix preloading of associations with a scope containing joins along with + conditions on the joined association. + + *Siddharth Sharma* + +* Add `Table#name` to match `TableDefinition#name`. + + *Cody Cutrer* + +* Cache `CollectionAssociation#reader` proxies separately before and after + the owner has been saved so that the proxy is not cached without the + owner's id. + + *Ben Woosley* + +* `ActiveRecord::ReadOnlyRecord` now has a descriptive message. + + *Franky W.* + +* Fix preloading of associations which unscope a default scope. + + Fixes #11036. + + *Byron Bischoff* + +* Added SchemaDumper support for tables with jsonb columns. + + *Ted O'Meara* + +* Deprecate `sanitize_sql_hash_for_conditions` without replacement. Using a + `Relation` for performing queries and updates is the prefered API. + + *Sean Griffin* + +* Queries now properly type cast values that are part of a join statement, + even when using type decorators such as `serialize`. + + *Melanie Gilman & Sean Griffin* + +* MySQL enum type lookups, with values matching another type, no longer result + in an endless loop. + + Fixes #17402. + + *Yves Senn* + +* Raise `ArgumentError` when the body of a scope is not callable. + + *Mauro George* + +* Use type column first in multi-column indexes created with `add-reference`. + + *Derek Prior* + +* Fix `Relation.rewhere` to work with Range values. + + *Dan Olson* + +* `AR::UnknownAttributeError` now includes the class name of a record. + + User.new(name: "Yuki Nishijima", project_attributes: {name: "kaminari"}) + # => ActiveRecord::UnknownAttributeError: unknown attribute 'name' for User. + + *Yuki Nishijima* + +* Fix a regression causing `after_create` callbacks to run before associated + records are autosaved. + + Fixes #17209. + + *Agis Anastasopoulos* + +* Honor overridden `rack.test` in Rack environment for the connection + management middleware. + + *Simon Eskildsen* + +* Add a truncate method to the connection. + + *Aaron Patterson* + +* Don't autosave unchanged has_one through records. + + *Alan Kennedy*, *Steve Parrington* + +* Do not dump foreign keys for ignored tables. + + *Yves Senn* + +* PostgreSQL adapter correctly dumps foreign keys targeting tables + outside the schema search path. + + Fixes #16907. + + *Matthew Draper*, *Yves Senn* + +* When a thread is killed, rollback the active transaction, instead of + committing it during the stack unwind. Previously, we could commit half- + completed work. This fix only works for Ruby 2.0+; on 1.9, we can't + distinguish a thread kill from an ordinary non-local (block) return, so must + default to committing. + + *Chris Hanks* + +* A `NullRelation` should represent nothing. This fixes a bug where + `Comment.where(post_id: Post.none)` returned a non-empty result. + + Fixes #15176. + + *Matthew Draper*, *Yves Senn* + +* Include default column limits in schema.rb. Allows defaults to be changed + in the future without affecting old migrations that assumed old defaults. + + *Jeremy Kemper* + +* MySQL: schema.rb now includes TEXT and BLOB column limits. + + *Jeremy Kemper* + +* MySQL: correct LONGTEXT and LONGBLOB limits from 2GB to their true 4GB. + + *Jeremy Kemper* + +* SQLite3Adapter now checks for views in `table_exists?`. Fixes #14041. + + *Girish Sonawane* + +* Introduce `connection.supports_views?` to check whether the current adapter + has support for SQL views. Connection adapters should define this method. + + *Yves Senn* + +* Allow included modules to override association methods. + + Fixes #16684. + + *Yves Senn* + +* Schema loading rake tasks (like `db:schema:load` and `db:setup`) maintain + the database connection to the current environment. + + Fixes #16757. + + *Joshua Cody*, *Yves Senn* + +* MySQL: set the connection collation along with the charset. + + Sets the connection collation to the database collation configured in + database.yml. Otherwise, `SET NAMES utf8mb4` will use the default + collation for that charset (utf8mb4_general_ci) when you may have chosen + a different collation, like utf8mb4_unicode_ci. + + This only applies to literal string comparisons, not column values, so it + is unlikely to affect you. + + *Jeremy Kemper* + +* `default_sequence_name` from the PostgreSQL adapter returns a `String`. + + *Yves Senn* + +* Fix a regression where whitespaces were stripped from DISTINCT queries in + PostgreSQL. + + *Agis Anastasopoulos* + + Fixes #16623. + +* Fix has_many :through relation merging failing when dynamic conditions are + passed as a lambda with an arity of one. + + Fixes #16128. + + *Agis Anastasopoulos* + +* Fix `Relation#exists?` to work with polymorphic associations. + + Fixes #15821. + + *Kassio Borges* + +* Currently, Active Record rescues any errors raised within + `after_rollback`/`after_create` callbacks and prints them to the logs. + Future versions of Rails will not rescue these errors anymore and + just bubble them up like the other callbacks. + + This commit adds an opt-in flag to enable not rescuing the errors. + + Example: + + # Do not swallow errors in after_commit/after_rollback callbacks. + config.active_record.raise_in_transactional_callbacks = true + + Fixes #13460. + + *arthurnn* + +* Fix an issue where custom accessor methods (such as those generated by + `enum`) with the same name as a global method are incorrectly overridden + when subclassing. + + Fixes #16288. + + *Godfrey Chan* + +* `*_was` and `changes` now work correctly for in-place attribute changes as + well. + + *Sean Griffin* + +* Fix regression on `after_commit` that did not fire with nested transactions. + + Fixes #16425. + + *arthurnn* + +* Do not try to write timestamps when a table has no timestamps columns. + + Fixes #8813. + + *Sergey Potapov* + +* `index_exists?` with `:name` option does verify specified columns. + + Example: + + add_index :articles, :title, name: "idx_title" + + # Before: + index_exists? :articles, :title, name: "idx_title" # => `true` + index_exists? :articles, :body, name: "idx_title" # => `true` + + # After: + index_exists? :articles, :title, name: "idx_title" # => `true` + index_exists? :articles, :body, name: "idx_title" # => `false` + + *Yves Senn*, *Matthew Draper* + +* `add_timestamps` and `t.timestamps` now require you to pass the `:null` option. + Not passing the option is deprecated but the default is still `null: true`. + With Rails 5 this will change to `null: false`. + + *Sean Griffin* + +* When calling `update_columns` on a record that is not persisted, the error + message now reflects whether that object is a new record or has been + destroyed. + + *Lachlan Sylvester* + +* Define `id_was` to get the previous value of the primary key. + + Currently when we call `id_was` and we have a custom primary key name, + Active Record will return the current value of the primary key. This + makes it impossible to correctly do an update operation if you change the + id. + + Fixes #16413. + + *Rafael Mendonça França* + +* Deprecate `DatabaseTasks.load_schema` to act on the current connection. + Use `.load_schema_current` instead. In the future `load_schema` will + require the `configuration` to act on as an argument. + + *Yves Senn* + +* Fix automatic maintaining test schema to properly handle sql structure + schema format. + + Fixes #15394. + + *Wojciech WnÄ™trzak* + +* Fix type casting to Decimal from Float with large precision. + + *Tomohiro Hashidate* + +* Deprecate `Reflection#source_macro` + + `Reflection#source_macro` is no longer needed in Active Record + source so it has been deprecated. Code that used `source_macro` + was removed in #16353. + + *Eileen M. Uchtitelle*, *Aaron Patterson* + +* No verbose backtrace by `db:drop` when database does not exist. + + Fixes #16295. + + *Kenn Ejima* + +* Add support for PostgreSQL JSONB. + + Example: + + create_table :posts do |t| + t.jsonb :meta_data + end + + *Philippe Creux*, *Chris Teague* + +* `db:purge` with MySQL respects `Rails.env`. + + *Yves Senn* + +* `change_column_default :table, :column, nil` with PostgreSQL will issue a + `DROP DEFAULT` instead of a `DEFAULT NULL` query. + + Fixes #16261. + + *Matthew Draper*, *Yves Senn* + +* Allow to specify a type for the foreign key column in `references` + and `add_reference`. + + Example: + + change_table :vehicle do |t| + t.references :station, type: :uuid + end + + *Andrey Novikov*, *Åukasz Sarnacki* + +* `create_join_table` removes a common prefix when generating the join table. + This matches the existing behavior of HABTM associations. + + Fixes #13683. + + *Stefan Kanev* + +* Do not swallow errors on `compute_type` when having a bad `alias_method` on + a class. + + *arthurnn* + +* PostgreSQL invalid `uuid` are convert to nil. + + *Abdelkader Boudih* + +* Restore 4.0 behavior for using serialize attributes with `JSON` as coder. + + With 4.1.x, `serialize` started returning a string when `JSON` was passed as + the second attribute. It will now return a hash as per previous versions. + + Example: + + class Post < ActiveRecord::Base + serialize :comment, JSON + end + + class Comment + include ActiveModel::Model + attr_accessor :category, :text + end + + post = Post.create! + post.comment = Comment.new(category: "Animals", text: "This is a comment about squirrels.") + post.save! + + # 4.0 + post.comment # => {"category"=>"Animals", "text"=>"This is a comment about squirrels."} + + # 4.1 before + post.comment # => "#" + + # 4.1 after + post.comment # => {"category"=>"Animals", "text"=>"This is a comment about squirrels."} + + When using `JSON` as the coder in `serialize`, Active Record will use the + new `ActiveRecord::Coders::JSON` coder which delegates its `dump/load` to + `ActiveSupport::JSON.encode/decode`. This ensures special objects are dumped + correctly using the `#as_json` hook. + + To keep the previous behaviour, supply a custom coder instead + ([example](https://gist.github.com/jenncoop/8c4142bbe59da77daa63)). + + Fixes #15594. + + *Jenn Cooper* + +* Do not use `RENAME INDEX` syntax for MariaDB 10.0. + + Fixes #15931. + + *Jeff Browning* + +* Calling `#empty?` on a `has_many` association would use the value from the + counter cache if one exists. + + *David Verhasselt* + +* Fix the schema dump generated for tables without constraints and with + primary key with default value of custom PostgreSQL function result. + + Fixes #16111. + + *Andrey Novikov* + +* Fix the SQL generated when a `delete_all` is run on an association to not + produce an `IN` statements. + + Before: + + UPDATE "categorizations" SET "category_id" = NULL WHERE + "categorizations"."category_id" = 1 AND "categorizations"."id" IN (1, 2) + + After: + + UPDATE "categorizations" SET "category_id" = NULL WHERE + "categorizations"."category_id" = 1 + + *Eileen M. Uchitelle, Aaron Patterson* + +* Avoid type casting boolean and `ActiveSupport::Duration` values to numeric + values for string columns. Otherwise, in some database, the string column + values will be coerced to a numeric allowing false or 0.seconds match any + string starting with a non-digit. + + Example: + + App.where(apikey: false) # => SELECT * FROM users WHERE apikey = '0' + + *Dylan Thacker-Smith* + +* Add a `:required` option to singular associations, providing a nicer + API for presence validations on associations. + + *Sean Griffin* + +* Fix an error in `reset_counters` when associations have `select` scope. + (Call to `count` generated invalid SQL.) + + *Cade Truitt* + +* After a successful `reload`, `new_record?` is always false. + + Fixes #12101. + + *Matthew Draper* + +* PostgreSQL renaming table doesn't attempt to rename non existent sequences. + + *Abdelkader Boudih* + +* Move 'dependent: :destroy' handling for `belongs_to` + from `before_destroy` to `after_destroy` callback chain + + Fixes #12380. + + *Ivan Antropov* + +* Detect in-place modifications on String attributes. + + Before this change, an attribute modified in-place had to be marked as + changed in order for it to be persisted in the database. Now it is no longer + required. + + Before: + + user = User.first + user.name << ' Griffin' + user.name_will_change! + user.save + user.reload.name # => "Sean Griffin" + + After: + + user = User.first + user.name << ' Griffin' + user.save + user.reload.name # => "Sean Griffin" + + *Sean Griffin* + +* Add `ActiveRecord::Base#validate!` that raises `RecordInvalid` if the record + is invalid. + + *Bogdan Gusiev*, *Marc Schütz* + +* Support for adding and removing foreign keys. Foreign keys are now + a part of `schema.rb`. This is supported by Mysql2Adapter, MysqlAdapter + and PostgreSQLAdapter. + + Many thanks to *Matthew Higgins* for laying the foundation with his work on + [foreigner](https://github.com/matthuhiggins/foreigner). + + Example: + + # within your migrations: + add_foreign_key :articles, :authors + remove_foreign_key :articles, :authors + + *Yves Senn* + +* Fix subtle bugs regarding attribute assignment on models with no primary + key. `'id'` will no longer be part of the attributes hash. + + *Sean Griffin* + +* Deprecate automatic counter caches on `has_many :through`. The behavior was + broken and inconsistent. + + *Sean Griffin* + +* `preload` preserves readonly flag for associations. + + See #15853. + + *Yves Senn* + +* Assume numeric types have changed if they were assigned to a value that + would fail numericality validation, regardless of the old value. Previously + this would only occur if the old value was 0. + + Example: + + model = Model.create!(number: 5) + model.number = '5wibble' + model.number_changed? # => true + + Fixes #14731. + + *Sean Griffin* + +* `reload` no longer merges with the existing attributes. + The attribute hash is fully replaced. The record is put into the same state + as it would be with `Model.find(model.id)`. + + *Sean Griffin* + +* The object returned from `select_all` must respond to `column_types`. + If this is not the case a `NoMethodError` is raised. + + *Sean Griffin* + +* Detect in-place modifications of PG array types + + *Sean Griffin* + +* Add `bin/rake db:purge` task to empty the current database. + + *Yves Senn* + +* Deprecate `serialized_attributes` without replacement. + + *Sean Griffin* + +* Correctly extract IPv6 addresses from `DATABASE_URI`: the square brackets + are part of the URI structure, not the actual host. + + Fixes #15705. + + *Andy Bakun*, *Aaron Stone* + +* Ensure both parent IDs are set on join records when both sides of a + through association are new. + + *Sean Griffin* + +* `ActiveRecord::Dirty` now detects in-place changes to mutable values. + Serialized attributes on ActiveRecord models will no longer save when + unchanged. + + Fixes #8328. + + *Sean Griffin* + +* `Pluck` now works when selecting columns from different tables with the same + name. + + Fixes #15649. + + *Sean Griffin* + +* Remove `cache_attributes` and friends. All attributes are cached. + + *Sean Griffin* + +* Remove deprecated method `ActiveRecord::Base.quoted_locking_column`. + + *Akshay Vishnoi* + +* `ActiveRecord::FinderMethods.find` with block can handle proc parameter as + `Enumerable#find` does. + + Fixes #15382. + + *James Yang* + +* Make timezone aware attributes work with PostgreSQL array columns. + + Fixes #13402. + + *Kuldeep Aggarwal*, *Sean Griffin* + +* `ActiveRecord::SchemaMigration` has no primary key regardless of the + `primary_key_prefix_type` configuration. + + Fixes #15051. + + *JoseLuis Torres*, *Yves Senn* + +* `rake db:migrate:status` works with legacy migration numbers like `00018_xyz.rb`. + + Fixes #15538. + + *Yves Senn* + +* Baseclass becomes! subclass. + + Before this change, a record which changed its STI type, could not be + updated. + + Fixes #14785. + + *Matthew Draper*, *Earl St Sauver*, *Edo Balvers* + +* Remove deprecated `ActiveRecord::Migrator.proper_table_name`. Use the + `proper_table_name` instance method on `ActiveRecord::Migration` instead. + + *Akshay Vishnoi* + +* Fix regression on eager loading association based on SQL query rather than + existing column. + + Fixes #15480. + + *Lauro Caetano*, *Carlos Antonio da Silva* + +* Deprecate returning `nil` from `column_for_attribute` when no column exists. + It will return a null object in Rails 5.0 + + *Sean Griffin* + +* Implemented `ActiveRecord::Base#pretty_print` to work with PP. + + *Ethan* + +* Preserve type when dumping PostgreSQL point, bit, bit varying and money + columns. + + *Yves Senn* + +* New records remain new after YAML serialization. + + *Sean Griffin* + +* PostgreSQL support default values for enum types. Fixes #7814. + + *Yves Senn* + +* PostgreSQL `default_sequence_name` respects schema. Fixes #7516. + + *Yves Senn* + +* Fix `columns_for_distinct` of PostgreSQL adapter to work correctly + with orders without sort direction modifiers. + + *Nikolay Kondratyev* + +* PostgreSQL `reset_pk_sequence!` respects schemas. Fixes #14719. + + *Yves Senn* + +* Keep PostgreSQL `hstore` and `json` attributes as `Hash` in `@attributes`. + Fixes duplication in combination with `store_accessor`. + + Fixes #15369. + + *Yves Senn* + +* `rake railties:install:migrations` respects the order of railties. + + *Arun Agrawal* + +* Fix redefine a `has_and_belongs_to_many` inside inherited class + Fixing regression case, where redefining the same `has_and_belongs_to_many` + definition into a subclass would raise. + + Fixes #14983. + + *arthurnn* + +* Fix `has_and_belongs_to_many` public reflection. + When defining a `has_and_belongs_to_many`, internally we convert that to two has_many. + But as `reflections` is a public API, people expect to see the right macro. + + Fixes #14682. + + *arthurnn* + +* Fix serialization for records with an attribute named `format`. + + Fixes #15188. + + *Godfrey Chan* + +* When a `group` is set, `sum`, `size`, `average`, `minimum` and `maximum` + on a NullRelation should return a Hash. + + *Kuldeep Aggarwal* + +* Fix serialized fields returning serialized data after being updated with + `update_column`. + + *Simon Hørup Eskildsen* + +* Fix polymorphic eager loading when using a String as foreign key. + + Fixes #14734. + + *Lauro Caetano* + +* Change belongs_to touch to be consistent with timestamp updates + + If a model is set up with a belongs_to: touch relationship the parent + record will only be touched if the record was modified. This makes it + consistent with timestamp updating on the record itself. + + *Brock Trappitt* + +* Fix the inferred table name of a `has_and_belongs_to_many` auxiliary + table inside a schema. + + Fixes #14824. + + *Eric Chahin* + +* Remove unused `:timestamp` type. Transparently alias it to `:datetime` + in all cases. Fixes inconsistencies when column types are sent outside of + `ActiveRecord`, such as for XML Serialization. + + *Sean Griffin* + +* Fix bug that added `table_name_prefix` and `table_name_suffix` to + extension names in PostgreSQL when migrating. + + *Joao Carlos* + +* The `:index` option in migrations, which previously was only available for + `references`, now works with any column types. + + *Marc Schütz* + +* Add support for counter name to be passed as parameter on `CounterCache::ClassMethods#reset_counters`. + + *jnormore* + +* Restrict deletion of record when using `delete_all` with `uniq`, `group`, `having` + or `offset`. + + In these cases the generated query ignored them and that caused unintended + records to be deleted. + + Fixes #11985. + + *Leandro Facchinetti* + +* Floats with limit >= 25 that get turned into doubles in MySQL no longer have + their limit dropped from the schema. + + Fixes #14135. + + *Aaron Nelson* + +* Fix how to calculate associated class name when using namespaced `has_and_belongs_to_many` + association. + + Fixes #14709. + + *Kassio Borges* + +* `ActiveRecord::Relation::Merger#filter_binds` now compares equivalent symbols and + strings in column names as equal. + + This fixes a rare case in which more bind values are passed than there are + placeholders for them in the generated SQL statement, which can make PostgreSQL + throw a `StatementInvalid` exception. + + *Nat Budin* + +* Fix `stored_attributes` to correctly merge the details of stored + attributes defined in parent classes. + + Fixes #14672. + + *Brad Bennett*, *Jessica Yao*, *Lakshmi Parthasarathy* + +* `change_column_default` allows `[]` as argument to `change_column_default`. + + Fixes #11586. + + *Yves Senn* + +* Handle `name` and `"char"` column types in the PostgreSQL adapter. + + `name` and `"char"` are special character types used internally by + PostgreSQL and are used by internal system catalogs. These field types + can sometimes show up in structure-sniffing queries that feature internal system + structures or with certain PostgreSQL extensions. + + *J Smith*, *Yves Senn* + +* Fix `PostgreSQLAdapter::OID::Float#type_cast` to convert Infinity and + NaN PostgreSQL values into a native Ruby `Float::INFINITY` and `Float::NAN` + + Before: + + Point.create(value: 1.0/0) + Point.last.value # => 0.0 + + After: + + Point.create(value: 1.0/0) + Point.last.value # => Infinity + + *Innokenty Mikhailov* + +* Allow the PostgreSQL adapter to handle bigserial primary key types again. + + Fixes #10410. + + *Patrick Robertson* + +* Deprecate joining, eager loading and preloading of instance dependent + associations without replacement. These operations happen before instances + are created. The current behavior is unexpected and can result in broken + behavior. + + Fixes #15024. + + *Yves Senn* + +* Fix `has_and_belongs_to_many` CollectionAssociation size calculations. + + `has_and_belongs_to_many` should fall back to using the normal CollectionAssociation's + size calculation if the collection is not cached or loaded. + + Fixes #14913, #14914. + + *Fred Wu* + +* Return a non zero status when running `rake db:migrate:status` and migration table does + not exist. + + *Paul B.* + +* Add support for module-level `table_name_suffix` in models. + + This makes `table_name_suffix` work the same way as `table_name_prefix` when + using namespaced models. + + *Jenner LaFave* + +* Revert the behaviour of `ActiveRecord::Relation#join` changed through 4.0 => 4.1 to 4.0. + + In 4.1.0 `Relation#join` is delegated to `Arel#SelectManager`. + In 4.0 series it is delegated to `Array#join`. + + *Bogdan Gusiev* + +* Log nil binary column values correctly. + + When an object with a binary column is updated with a nil value + in that column, the SQL logger would throw an exception when trying + to log that nil value. This only occurs when updating a record + that already has a non-nil value in that column since an initial nil + value isn't included in the SQL anyway (at least, when dirty checking + is enabled.) The column's new value will now be logged as `` + to parallel the existing `` for non-nil values. + + *James Coleman* + +* Rails will now pass a custom validation context through to autosave associations + in order to validate child associations with the same context. + + Fixes #13854. + + *Eric Chahin*, *Aaron Nelson*, *Kevin Casey* + +* Stringify all variables keys of MySQL connection configuration. + + When `sql_mode` variable for MySQL adapters set in configuration as `String` + was ignored and overwritten by strict mode option. + + Fixes #14895. + + *Paul Nikitochkin* + +* Ensure SQLite3 statements are closed on errors. + + Fixes #13631. + + *Timur Alperovich* + +* Give `ActiveRecord::PredicateBuilder` private methods the privacy they deserve. + + *Hector Satre* + +* When using a custom `join_table` name on a `habtm`, rails was not saving it + on Reflections. This causes a problem when rails loads fixtures, because it + uses the reflections to set database with fixtures. + + Fixes #14845. + + *Kassio Borges* + +* Reset the cache when modifying a Relation with cached Arel. + Additionally display a warning message to make the user aware. + + *Yves Senn* + +* PostgreSQL should internally use `:datetime` consistently for TimeStamp. Assures + different spellings of timestamps are treated the same. + + Example: + + mytimestamp.simplified_type('timestamp without time zone') + # => :datetime + mytimestamp.simplified_type('timestamp(6) without time zone') + # => also :datetime (previously would be :timestamp) + + See #14513. + + *Jefferson Lai* + +* `ActiveRecord::Base.no_touching` no longer triggers callbacks or start empty transactions. + + Fixes #14841. + + *Lucas Mazza* + +* Fix name collision with `Array#select!` with `Relation#select!`. + + Fixes #14752. + + *Earl St Sauver* + +* Fix unexpected behavior for `has_many :through` associations going through + a scoped `has_many`. + + If a `has_many` association is adjusted using a scope, and another + `has_many :through` uses this association, then the scope adjustment is + unexpectedly neglected. + + Fixes #14537. + + *Jan Habermann* + +* `@destroyed` should always be set to `false` when an object is duped. + + *Kuldeep Aggarwal* + +* Enable `has_many` associations to support irregular inflections. + + Fixes #8928. + + *arthurnn*, *Javier Goizueta* + +* Fix `count` used with a grouping not returning a Hash. + + Fixes #14721. + + *Eric Chahin* + +* `sanitize_sql_like` helper method to escape a string for safe use in an SQL + LIKE statement. + + Example: + + class Article + def self.search(term) + where("title LIKE ?", sanitize_sql_like(term)) + end + end + + Article.search("20% _reduction_") + # => Query looks like "... title LIKE '20\% \_reduction\_' ..." + + *Rob Gilson*, *Yves Senn* + +* Do not quote uuid default value on `change_column`. + + Fixes #14604. + + *Eric Chahin* + +* The comparison between `Relation` and `CollectionProxy` should be consistent. + + Example: + + author.posts == Post.where(author_id: author.id) + # => true + Post.where(author_id: author.id) == author.posts + # => true + + Fixes #13506. + + *Lauro Caetano* + +* Calling `delete_all` on an unloaded `CollectionProxy` no longer + generates an SQL statement containing each id of the collection: + + Before: + + DELETE FROM `model` WHERE `model`.`parent_id` = 1 + AND `model`.`id` IN (1, 2, 3...) + + After: + + DELETE FROM `model` WHERE `model`.`parent_id` = 1 + + *Eileen M. Uchitelle*, *Aaron Patterson* + +* Fix invalid SQL when aggregate methods (`empty?`, `any?`, `count`) used + with `select`. + + Fixes #13648. + + *Simon Woker* + +* PostgreSQL adapter only warns once for every missing OID per connection. + + Fixes #14275. + + *Matthew Draper*, *Yves Senn* + +* PostgreSQL adapter automatically reloads it's type map when encountering + unknown OIDs. + + Fixes #14678. + + *Matthew Draper*, *Yves Senn* + +* Fix insertion of records via `has_many :through` association with scope. + + Fixes #3548. + + *Ivan Antropov* + +* Auto-generate stable fixture UUIDs on PostgreSQL. + + Fixes #11524. + + *Roderick van Domburg* + +* Fix a problem where an enum would overwrite values of another enum with the + same name in an unrelated class. + + Fixes #14607. + + *Evan Whalen* + +* PostgreSQL and SQLite string columns no longer have a default limit of 255. + + Fixes #13435, #9153. + + *Vladimir Sazhin*, *Toms Mikoss*, *Yves Senn* + +* Make possible to have an association called `records`. + + Fixes #11645. + + *prathamesh-sonpatki* + +* `to_sql` on an association now matches the query that is actually executed, where it + could previously have incorrectly accrued additional conditions (e.g. as a result of + a previous query). `CollectionProxy` now always defers to the association scope's + `arel` method so the (incorrect) inherited one should be entirely concealed. + + Fixes #14003. + + *Jefferson Lai* + +* Block a few default Class methods as scope name. + + For instance, this will raise: + + scope :public, -> { where(status: 1) } + + *arthurnn* + +* Fix error when using `with_options` with lambda. + + Fixes #9805. + + *Lauro Caetano* + +* Switch `sqlite3:///` URLs (which were temporarily + deprecated in 4.1) from relative to absolute. + + If you still want the previous interpretation, you should replace + `sqlite3:///my/path` with `sqlite3:my/path`. + + *Matthew Draper* + +* Treat blank UUID values as `nil`. + + Example: + + Sample.new(uuid_field: '') #=> + + *Dmitry Lavrov* + +* Enable support for materialized views on PostgreSQL >= 9.3. + + *Dave Lee* + +* The PostgreSQL adapter supports custom domains. Fixes #14305. + + *Yves Senn* + +* PostgreSQL `Column#type` is now determined through the corresponding OID. + The column types stay the same except for enum columns. They no longer have + `nil` as type but `enum`. + + See #7814. + + *Yves Senn* + +* Fix error when specifying a non-empty default value on a PostgreSQL array + column. + + Fixes #10613. + + *Luke Steensen* + +* Fix error where `.persisted?` throws SystemStackError for an unsaved model with a + custom primary key that did not save due to validation error. + + Fixes #14393. + + *Chris Finne* + +* Introduce `validate` as an alias for `valid?`. + + This is more intuitive when you want to run validations but don't care about the return value. + + *Henrik Nyh* + +* Create indexes inline in CREATE TABLE for MySQL. + + This is important, because adding an index on a temporary table after it has been created + would commit the transaction. + + It also allows creating and dropping indexed tables with fewer queries and fewer permissions + required. + + Example: + + create_table :temp, temporary: true, as: "SELECT id, name, zip FROM a_really_complicated_query" do |t| + t.index :zip + end + # => CREATE TEMPORARY TABLE temp (INDEX (zip)) AS SELECT id, name, zip FROM a_really_complicated_query + + *Cody Cutrer*, *Steve Rice*, *Rafael Mendonça Franca* + +* Use singular table name in generated migrations when + `ActiveRecord::Base.pluralize_table_names` is `false`. + + Fixes #13426. + + *Kuldeep Aggarwal* + +* `touch` accepts many attributes to be touched at once. + + Example: + + # touches :signed_at, :sealed_at, and :updated_at/on attributes. + Photo.last.touch(:signed_at, :sealed_at) + + *James Pinto* + +* `rake db:structure:dump` only dumps schema information if the schema + migration table exists. + + Fixes #14217. + + *Yves Senn* + +* Reap connections that were checked out by now-dead threads, instead + of waiting until they disconnect by themselves. Before this change, + a suitably constructed series of short-lived threads could starve + the connection pool, without ever having more than a couple alive at + the same time. + + *Matthew Draper* + +* `pk_and_sequence_for` now ensures that only the pg_depend entries + pointing to pg_class, and thus only sequence objects, are considered. + + *Josh Williams* + +* `where.not` adds `references` for `includes` like normal `where` calls do. + + Fixes #14406. + + *Yves Senn* + +* Extend fixture `$LABEL` replacement to allow string interpolation. + + Example: + + martin: + email: $LABEL@email.com + + users(:martin).email # => martin@email.com + + *Eric Steele* + +* Add support for `Relation` be passed as parameter on `QueryCache#select_all`. + + Fixes #14361. + + *arthurnn* + +* Passing an Active Record object to `find` or `exists?` is now deprecated. + Call `.id` on the object first. + + *Aaron Patterson* + +* Only use BINARY for MySQL case sensitive uniqueness check when column + has a case insensitive collation. + + *Ryuta Kamizono* + +* Support for MySQL 5.6 fractional seconds. + + *arthurnn*, *Tatsuhiko Miyagawa* + +* Support for PostgreSQL `citext` data type enabling case-insensitive + `where` values without needing to wrap in UPPER/LOWER sql functions. + + *Troy Kruthoff*, *Lachlan Sylvester* + +* Only save has_one associations if record has changes. + Previously after save related callbacks, such as `#after_commit`, were triggered when the has_one + object did not get saved to the db. + + *Alan Kennedy* + +* Allow strings to specify the `#order` value. + + Example: + + Model.order(id: 'asc').to_sql == Model.order(id: :asc).to_sql + + *Marcelo Casiraghi*, *Robin Dupret* + +* Dynamically register PostgreSQL enum OIDs. This prevents "unknown OID" + warnings on enum columns. + + *Dieter Komendera* + +* `includes` is able to detect the right preloading strategy when string + joins are involved. + + Fixes #14109. + + *Aaron Patterson*, *Yves Senn* + +* Fix error with validation with enum fields for records where the value for + any enum attribute is always evaluated as 0 during uniqueness validation. + + Fixes #14172. + + *Vilius Luneckas* *Ahmed AbouElhamayed* + +* `before_add` callbacks are fired before the record is saved on + `has_and_belongs_to_many` associations *and* on `has_many :through` + associations. Before this change, `before_add` callbacks would be fired + before the record was saved on `has_and_belongs_to_many` associations, but + *not* on `has_many :through` associations. + + Fixes #14144. + +* Fix STI classes not defining an attribute method if there is a conflicting + private method defined on its ancestors. + + Fixes #11569. + + *Godfrey Chan* + +* Coerce strings when reading attributes. Fixes #10485. + + Example: + + book = Book.new(title: 12345) + book.save! + book.title # => "12345" + + *Yves Senn* + +* Deprecate half-baked support for PostgreSQL range values with excluding beginnings. + We currently map PostgreSQL ranges to Ruby ranges. This conversion is not fully + possible because the Ruby range does not support excluded beginnings. + + The current solution of incrementing the beginning is not correct and is now + deprecated. For subtypes where we don't know how to increment (e.g. `#succ` + is not defined) it will raise an `ArgumentException` for ranges with excluding + beginnings. + + *Yves Senn* + +* Support for user created range types in PostgreSQL. + + *Yves Senn* + +Please check [4-1-stable](https://github.com/rails/rails/blob/4-1-stable/activerecord/CHANGELOG.md) for previous changes. diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/MIT-LICENSE b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/MIT-LICENSE new file mode 100644 index 0000000..2950f05 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/MIT-LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2004-2014 David Heinemeier Hansson + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/README.rdoc b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/README.rdoc new file mode 100644 index 0000000..c2e5266 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/README.rdoc @@ -0,0 +1,218 @@ += Active Record -- Object-relational mapping in Rails + +Active Record connects classes to relational database tables to establish an +almost zero-configuration persistence layer for applications. The library +provides a base class that, when subclassed, sets up a mapping between the new +class and an existing table in the database. In the context of an application, +these classes are commonly referred to as *models*. Models can also be +connected to other models; this is done by defining *associations*. + +Active Record relies heavily on naming in that it uses class and association +names to establish mappings between respective database tables and foreign key +columns. Although these mappings can be defined explicitly, it's recommended +to follow naming conventions, especially when getting started with the +library. + +A short rundown of some of the major features: + +* Automated mapping between classes and tables, attributes and columns. + + class Product < ActiveRecord::Base + end + + {Learn more}[link:classes/ActiveRecord/Base.html] + +The Product class is automatically mapped to the table named "products", +which might look like this: + + CREATE TABLE products ( + id int(11) NOT NULL auto_increment, + name varchar(255), + PRIMARY KEY (id) + ); + +This would also define the following accessors: `Product#name` and +`Product#name=(new_name)`. + + +* Associations between objects defined by simple class methods. + + class Firm < ActiveRecord::Base + has_many :clients + has_one :account + belongs_to :conglomerate + end + + {Learn more}[link:classes/ActiveRecord/Associations/ClassMethods.html] + + +* Aggregations of value objects. + + class Account < ActiveRecord::Base + composed_of :balance, class_name: 'Money', + mapping: %w(balance amount) + composed_of :address, + mapping: [%w(address_street street), %w(address_city city)] + end + + {Learn more}[link:classes/ActiveRecord/Aggregations/ClassMethods.html] + + +* Validation rules that can differ for new or existing objects. + + class Account < ActiveRecord::Base + validates :subdomain, :name, :email_address, :password, presence: true + validates :subdomain, uniqueness: true + validates :terms_of_service, acceptance: true, on: :create + validates :password, :email_address, confirmation: true, on: :create + end + + {Learn more}[link:classes/ActiveRecord/Validations.html] + + +* Callbacks available for the entire life cycle (instantiation, saving, destroying, validating, etc.). + + class Person < ActiveRecord::Base + before_destroy :invalidate_payment_plan + # the `invalidate_payment_plan` method gets called just before Person#destroy + end + + {Learn more}[link:classes/ActiveRecord/Callbacks.html] + + +* Inheritance hierarchies. + + class Company < ActiveRecord::Base; end + class Firm < Company; end + class Client < Company; end + class PriorityClient < Client; end + + {Learn more}[link:classes/ActiveRecord/Base.html] + + +* Transactions. + + # Database transaction + Account.transaction do + david.withdrawal(100) + mary.deposit(100) + end + + {Learn more}[link:classes/ActiveRecord/Transactions/ClassMethods.html] + + +* Reflections on columns, associations, and aggregations. + + reflection = Firm.reflect_on_association(:clients) + reflection.klass # => Client (class) + Firm.columns # Returns an array of column descriptors for the firms table + + {Learn more}[link:classes/ActiveRecord/Reflection/ClassMethods.html] + + +* Database abstraction through simple adapters. + + # connect to SQLite3 + ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: 'dbfile.sqlite3') + + # connect to MySQL with authentication + ActiveRecord::Base.establish_connection( + adapter: 'mysql2', + host: 'localhost', + username: 'me', + password: 'secret', + database: 'activerecord' + ) + + {Learn more}[link:classes/ActiveRecord/Base.html] and read about the built-in support for + MySQL[link:classes/ActiveRecord/ConnectionAdapters/MysqlAdapter.html], + PostgreSQL[link:classes/ActiveRecord/ConnectionAdapters/PostgreSQLAdapter.html], and + SQLite3[link:classes/ActiveRecord/ConnectionAdapters/SQLite3Adapter.html]. + + +* Logging support for Log4r[https://github.com/colbygk/log4r] and Logger[http://www.ruby-doc.org/stdlib/libdoc/logger/rdoc]. + + ActiveRecord::Base.logger = ActiveSupport::Logger.new(STDOUT) + ActiveRecord::Base.logger = Log4r::Logger.new('Application Log') + + +* Database agnostic schema management with Migrations. + + class AddSystemSettings < ActiveRecord::Migration + def up + create_table :system_settings do |t| + t.string :name + t.string :label + t.text :value + t.string :type + t.integer :position + end + + SystemSetting.create name: 'notice', label: 'Use notice?', value: 1 + end + + def down + drop_table :system_settings + end + end + + {Learn more}[link:classes/ActiveRecord/Migration.html] + + +== Philosophy + +Active Record is an implementation of the object-relational mapping (ORM) +pattern[http://www.martinfowler.com/eaaCatalog/activeRecord.html] by the same +name described by Martin Fowler: + + "An object that wraps a row in a database table or view, + encapsulates the database access, and adds domain logic on that data." + +Active Record attempts to provide a coherent wrapper as a solution for the inconvenience that is +object-relational mapping. The prime directive for this mapping has been to minimize +the amount of code needed to build a real-world domain model. This is made possible +by relying on a number of conventions that make it easy for Active Record to infer +complex relations and structures from a minimal amount of explicit direction. + +Convention over Configuration: +* No XML files! +* Lots of reflection and run-time extension +* Magic is not inherently a bad word + +Admit the Database: +* Lets you drop down to SQL for odd cases and performance +* Doesn't attempt to duplicate or replace data definitions + + +== Download and installation + +The latest version of Active Record can be installed with RubyGems: + + % [sudo] gem install activerecord + +Source code can be downloaded as part of the Rails project on GitHub: + +* https://github.com/rails/rails/tree/4-2-stable/activerecord + + +== License + +Active Record is released under the MIT license: + +* http://www.opensource.org/licenses/MIT + + +== Support + +API documentation is at: + +* http://api.rubyonrails.org + +Bug reports can be filed for the Ruby on Rails project here: + +* https://github.com/rails/rails/issues + +Feature requests should be discussed on the rails-core mailing list here: + +* https://groups.google.com/forum/?fromgroups#!forum/rubyonrails-core + diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/examples/performance.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/examples/performance.rb new file mode 100644 index 0000000..d3546ce --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/examples/performance.rb @@ -0,0 +1,184 @@ +require File.expand_path('../../../load_paths', __FILE__) +require "active_record" +require 'benchmark/ips' + +TIME = (ENV['BENCHMARK_TIME'] || 20).to_i +RECORDS = (ENV['BENCHMARK_RECORDS'] || TIME*1000).to_i + +conn = { adapter: 'sqlite3', database: ':memory:' } + +ActiveRecord::Base.establish_connection(conn) + +class User < ActiveRecord::Base + connection.create_table :users, force: true do |t| + t.string :name, :email + t.timestamps + end + + has_many :exhibits +end + +class Exhibit < ActiveRecord::Base + connection.create_table :exhibits, force: true do |t| + t.belongs_to :user + t.string :name + t.text :notes + t.timestamps + end + + belongs_to :user + + def look; attributes end + def feel; look; user.name end + + def self.with_name + where("name IS NOT NULL") + end + + def self.with_notes + where("notes IS NOT NULL") + end + + def self.look(exhibits) exhibits.each { |e| e.look } end + def self.feel(exhibits) exhibits.each { |e| e.feel } end +end + +def progress_bar(int); print "." if (int%100).zero? ; end + +puts 'Generating data...' + +module ActiveRecord + class Faker + LOREM = %Q{Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse non aliquet diam. Curabitur vel urna metus, quis malesuada elit. + Integer consequat tincidunt felis. Etiam non erat dolor. Vivamus imperdiet nibh sit amet diam eleifend id posuere diam malesuada. Mauris at accumsan sem. + Donec id lorem neque. Fusce erat lorem, ornare eu congue vitae, malesuada quis neque. Maecenas vel urna a velit pretium fermentum. Donec tortor enim, + tempor venenatis egestas a, tempor sed ipsum. Ut arcu justo, faucibus non imperdiet ac, interdum at diam. Pellentesque ipsum enim, venenatis ut iaculis vitae, + varius vitae sem. Sed rutrum quam ac elit euismod bibendum. Donec ultricies ultricies magna, at lacinia libero mollis aliquam. Sed ac arcu in tortor elementum + tincidunt vel interdum sem. Curabitur eget erat arcu. Praesent eget eros leo. Nam magna enim, sollicitudin vehicula scelerisque in, vulputate ut libero. + Praesent varius tincidunt commodo}.split + + def self.name + LOREM.grep(/^\w*$/).sort_by { rand }.first(2).join ' ' + end + + def self.email + LOREM.grep(/^\w*$/).sort_by { rand }.first(2).join('@') + ".com" + end + end +end + +# pre-compute the insert statements and fake data compilation, +# so the benchmarks below show the actual runtime for the execute +# method, minus the setup steps + +# Using the same paragraph for all exhibits because it is very slow +# to generate unique paragraphs for all exhibits. +notes = ActiveRecord::Faker::LOREM.join ' ' +today = Date.today + +puts "Inserting #{RECORDS} users and exhibits..." +RECORDS.times do |record| + user = User.create( + created_at: today, + name: ActiveRecord::Faker.name, + email: ActiveRecord::Faker.email + ) + + Exhibit.create( + created_at: today, + name: ActiveRecord::Faker.name, + user: user, + notes: notes + ) + progress_bar(record) +end +puts "Done!\n" + +Benchmark.ips(TIME) do |x| + ar_obj = Exhibit.find(1) + attrs = { name: 'sam' } + attrs_first = { name: 'sam' } + attrs_second = { name: 'tom' } + exhibit = { + name: ActiveRecord::Faker.name, + notes: notes, + created_at: Date.today + } + + x.report("Model#id") do + ar_obj.id + end + + x.report 'Model.new (instantiation)' do + Exhibit.new + end + + x.report 'Model.new (setting attributes)' do + Exhibit.new(attrs) + end + + x.report 'Model.first' do + Exhibit.first.look + end + + x.report 'Model.take' do + Exhibit.take + end + + x.report("Model.all limit(100)") do + Exhibit.look Exhibit.limit(100) + end + + x.report("Model.all take(100)") do + Exhibit.look Exhibit.take(100) + end + + x.report "Model.all limit(100) with relationship" do + Exhibit.feel Exhibit.limit(100).includes(:user) + end + + x.report "Model.all limit(10,000)" do + Exhibit.look Exhibit.limit(10000) + end + + x.report 'Model.named_scope' do + Exhibit.limit(10).with_name.with_notes + end + + x.report 'Model.create' do + Exhibit.create(exhibit) + end + + x.report 'Resource#attributes=' do + e = Exhibit.new(attrs_first) + e.attributes = attrs_second + end + + x.report 'Resource#update' do + Exhibit.first.update(name: 'bob') + end + + x.report 'Resource#destroy' do + Exhibit.first.destroy + end + + x.report 'Model.transaction' do + Exhibit.transaction { Exhibit.new } + end + + x.report 'Model.find(id)' do + User.find(1) + end + + x.report 'Model.find_by_sql' do + Exhibit.find_by_sql("SELECT * FROM exhibits WHERE id = #{(rand * 1000 + 1).to_i}").first + end + + x.report "Model.log" do + Exhibit.connection.send(:log, "hello", "world") {} + end + + x.report "AR.execute(query)" do + ActiveRecord::Base.connection.execute("SELECT * FROM exhibits WHERE id = #{(rand * 1000 + 1).to_i}") + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/examples/simple.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/examples/simple.rb new file mode 100644 index 0000000..4ed5d80 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/examples/simple.rb @@ -0,0 +1,14 @@ +require File.expand_path('../../../load_paths', __FILE__) +require 'active_record' + +class Person < ActiveRecord::Base + establish_connection adapter: 'sqlite3', database: 'foobar.db' + connection.create_table table_name, force: true do |t| + t.string :name + end +end + +bob = Person.create!(name: 'bob') +puts Person.all.inspect +bob.destroy +puts Person.all.inspect diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record.rb new file mode 100644 index 0000000..be3d70f --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record.rb @@ -0,0 +1,175 @@ +#-- +# Copyright (c) 2004-2014 David Heinemeier Hansson +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +#++ + +require 'active_support' +require 'active_support/rails' +require 'active_model' +require 'arel' + +require 'active_record/version' +require 'active_record/attribute_set' + +module ActiveRecord + extend ActiveSupport::Autoload + + autoload :Attribute + autoload :Base + autoload :Callbacks + autoload :Core + autoload :ConnectionHandling + autoload :CounterCache + autoload :DynamicMatchers + autoload :Enum + autoload :Explain + autoload :Inheritance + autoload :Integration + autoload :LegacyYamlAdapter + autoload :Migration + autoload :Migrator, 'active_record/migration' + autoload :ModelSchema + autoload :NestedAttributes + autoload :NoTouching + autoload :Persistence + autoload :QueryCache + autoload :Querying + autoload :ReadonlyAttributes + autoload :RecordInvalid, 'active_record/validations' + autoload :Reflection + autoload :RuntimeRegistry + autoload :Sanitization + autoload :Schema + autoload :SchemaDumper + autoload :SchemaMigration + autoload :Scoping + autoload :Serialization + autoload :StatementCache + autoload :Store + autoload :Timestamp + autoload :Transactions + autoload :Translation + autoload :Validations + + eager_autoload do + autoload :ActiveRecordError, 'active_record/errors' + autoload :ConnectionNotEstablished, 'active_record/errors' + autoload :ConnectionAdapters, 'active_record/connection_adapters/abstract_adapter' + + autoload :Aggregations + autoload :Associations + autoload :AttributeAssignment + autoload :AttributeMethods + autoload :AutosaveAssociation + + autoload :Relation + autoload :AssociationRelation + autoload :NullRelation + + autoload_under 'relation' do + autoload :QueryMethods + autoload :FinderMethods + autoload :Calculations + autoload :PredicateBuilder + autoload :SpawnMethods + autoload :Batches + autoload :Delegation + end + + autoload :Result + end + + module Coders + autoload :YAMLColumn, 'active_record/coders/yaml_column' + autoload :JSON, 'active_record/coders/json' + end + + module AttributeMethods + extend ActiveSupport::Autoload + + eager_autoload do + autoload :BeforeTypeCast + autoload :Dirty + autoload :PrimaryKey + autoload :Query + autoload :Read + autoload :TimeZoneConversion + autoload :Write + autoload :Serialization + end + end + + module Locking + extend ActiveSupport::Autoload + + eager_autoload do + autoload :Optimistic + autoload :Pessimistic + end + end + + module ConnectionAdapters + extend ActiveSupport::Autoload + + eager_autoload do + autoload :AbstractAdapter + autoload :ConnectionManagement, "active_record/connection_adapters/abstract/connection_pool" + end + end + + module Scoping + extend ActiveSupport::Autoload + + eager_autoload do + autoload :Named + autoload :Default + end + end + + module Tasks + extend ActiveSupport::Autoload + + autoload :DatabaseTasks + autoload :SQLiteDatabaseTasks, 'active_record/tasks/sqlite_database_tasks' + autoload :MySQLDatabaseTasks, 'active_record/tasks/mysql_database_tasks' + autoload :PostgreSQLDatabaseTasks, + 'active_record/tasks/postgresql_database_tasks' + end + + autoload :TestFixtures, 'active_record/fixtures' + + def self.eager_load! + super + ActiveRecord::Locking.eager_load! + ActiveRecord::Scoping.eager_load! + ActiveRecord::Associations.eager_load! + ActiveRecord::AttributeMethods.eager_load! + ActiveRecord::ConnectionAdapters.eager_load! + end +end + +ActiveSupport.on_load(:active_record) do + Arel::Table.engine = self +end + +ActiveSupport.on_load(:i18n) do + I18n.load_path << File.dirname(__FILE__) + '/active_record/locale/en.yml' +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/aggregations.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/aggregations.rb new file mode 100644 index 0000000..1040e6e --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/aggregations.rb @@ -0,0 +1,266 @@ +module ActiveRecord + # = Active Record Aggregations + module Aggregations # :nodoc: + extend ActiveSupport::Concern + + def clear_aggregation_cache #:nodoc: + @aggregation_cache.clear if persisted? + end + + # Active Record implements aggregation through a macro-like class method called +composed_of+ + # for representing attributes as value objects. It expresses relationships like "Account [is] + # composed of Money [among other things]" or "Person [is] composed of [an] address". Each call + # to the macro adds a description of how the value objects are created from the attributes of + # the entity object (when the entity is initialized either as a new object or from finding an + # existing object) and how it can be turned back into attributes (when the entity is saved to + # the database). + # + # class Customer < ActiveRecord::Base + # composed_of :balance, class_name: "Money", mapping: %w(balance amount) + # composed_of :address, mapping: [ %w(address_street street), %w(address_city city) ] + # end + # + # The customer class now has the following methods to manipulate the value objects: + # * Customer#balance, Customer#balance=(money) + # * Customer#address, Customer#address=(address) + # + # These methods will operate with value objects like the ones described below: + # + # class Money + # include Comparable + # attr_reader :amount, :currency + # EXCHANGE_RATES = { "USD_TO_DKK" => 6 } + # + # def initialize(amount, currency = "USD") + # @amount, @currency = amount, currency + # end + # + # def exchange_to(other_currency) + # exchanged_amount = (amount * EXCHANGE_RATES["#{currency}_TO_#{other_currency}"]).floor + # Money.new(exchanged_amount, other_currency) + # end + # + # def ==(other_money) + # amount == other_money.amount && currency == other_money.currency + # end + # + # def <=>(other_money) + # if currency == other_money.currency + # amount <=> other_money.amount + # else + # amount <=> other_money.exchange_to(currency).amount + # end + # end + # end + # + # class Address + # attr_reader :street, :city + # def initialize(street, city) + # @street, @city = street, city + # end + # + # def close_to?(other_address) + # city == other_address.city + # end + # + # def ==(other_address) + # city == other_address.city && street == other_address.street + # end + # end + # + # Now it's possible to access attributes from the database through the value objects instead. If + # you choose to name the composition the same as the attribute's name, it will be the only way to + # access that attribute. That's the case with our +balance+ attribute. You interact with the value + # objects just like you would with any other attribute: + # + # customer.balance = Money.new(20) # sets the Money value object and the attribute + # customer.balance # => Money value object + # customer.balance.exchange_to("DKK") # => Money.new(120, "DKK") + # customer.balance > Money.new(10) # => true + # customer.balance == Money.new(20) # => true + # customer.balance < Money.new(5) # => false + # + # Value objects can also be composed of multiple attributes, such as the case of Address. The order + # of the mappings will determine the order of the parameters. + # + # customer.address_street = "Hyancintvej" + # customer.address_city = "Copenhagen" + # customer.address # => Address.new("Hyancintvej", "Copenhagen") + # + # customer.address_street = "Vesterbrogade" + # customer.address # => Address.new("Hyancintvej", "Copenhagen") + # customer.clear_aggregation_cache + # customer.address # => Address.new("Vesterbrogade", "Copenhagen") + # + # customer.address = Address.new("May Street", "Chicago") + # customer.address_street # => "May Street" + # customer.address_city # => "Chicago" + # + # == Writing value objects + # + # Value objects are immutable and interchangeable objects that represent a given value, such as + # a Money object representing $5. Two Money objects both representing $5 should be equal (through + # methods such as == and <=> from Comparable if ranking makes sense). This is + # unlike entity objects where equality is determined by identity. An entity class such as Customer can + # easily have two different objects that both have an address on Hyancintvej. Entity identity is + # determined by object or relational unique identifiers (such as primary keys). Normal + # ActiveRecord::Base classes are entity objects. + # + # It's also important to treat the value objects as immutable. Don't allow the Money object to have + # its amount changed after creation. Create a new Money object with the new value instead. The + # Money#exchange_to method is an example of this. It returns a new value object instead of changing + # its own values. Active Record won't persist value objects that have been changed through means + # other than the writer method. + # + # The immutable requirement is enforced by Active Record by freezing any object assigned as a value + # object. Attempting to change it afterwards will result in a RuntimeError. + # + # Read more about value objects on http://c2.com/cgi/wiki?ValueObject and on the dangers of not + # keeping value objects immutable on http://c2.com/cgi/wiki?ValueObjectsShouldBeImmutable + # + # == Custom constructors and converters + # + # By default value objects are initialized by calling the new constructor of the value + # class passing each of the mapped attributes, in the order specified by the :mapping + # option, as arguments. If the value class doesn't support this convention then +composed_of+ allows + # a custom constructor to be specified. + # + # When a new value is assigned to the value object, the default assumption is that the new value + # is an instance of the value class. Specifying a custom converter allows the new value to be automatically + # converted to an instance of value class if necessary. + # + # For example, the NetworkResource model has +network_address+ and +cidr_range+ attributes that should be + # aggregated using the NetAddr::CIDR value class (http://www.ruby-doc.org/gems/docs/n/netaddr-1.5.0/NetAddr/CIDR.html). + # The constructor for the value class is called +create+ and it expects a CIDR address string as a parameter. + # New values can be assigned to the value object using either another NetAddr::CIDR object, a string + # or an array. The :constructor and :converter options can be used to meet + # these requirements: + # + # class NetworkResource < ActiveRecord::Base + # composed_of :cidr, + # class_name: 'NetAddr::CIDR', + # mapping: [ %w(network_address network), %w(cidr_range bits) ], + # allow_nil: true, + # constructor: Proc.new { |network_address, cidr_range| NetAddr::CIDR.create("#{network_address}/#{cidr_range}") }, + # converter: Proc.new { |value| NetAddr::CIDR.create(value.is_a?(Array) ? value.join('/') : value) } + # end + # + # # This calls the :constructor + # network_resource = NetworkResource.new(network_address: '192.168.0.1', cidr_range: 24) + # + # # These assignments will both use the :converter + # network_resource.cidr = [ '192.168.2.1', 8 ] + # network_resource.cidr = '192.168.0.1/24' + # + # # This assignment won't use the :converter as the value is already an instance of the value class + # network_resource.cidr = NetAddr::CIDR.create('192.168.2.1/8') + # + # # Saving and then reloading will use the :constructor on reload + # network_resource.save + # network_resource.reload + # + # == Finding records by a value object + # + # Once a +composed_of+ relationship is specified for a model, records can be loaded from the database + # by specifying an instance of the value object in the conditions hash. The following example + # finds all customers with +balance_amount+ equal to 20 and +balance_currency+ equal to "USD": + # + # Customer.where(balance: Money.new(20, "USD")) + # + module ClassMethods + # Adds reader and writer methods for manipulating a value object: + # composed_of :address adds address and address=(new_address) methods. + # + # Options are: + # * :class_name - Specifies the class name of the association. Use it only if that name + # can't be inferred from the part id. So composed_of :address will by default be linked + # to the Address class, but if the real class name is CompanyAddress, you'll have to specify it + # with this option. + # * :mapping - Specifies the mapping of entity attributes to attributes of the value + # object. Each mapping is represented as an array where the first item is the name of the + # entity attribute and the second item is the name of the attribute in the value object. The + # order in which mappings are defined determines the order in which attributes are sent to the + # value class constructor. + # * :allow_nil - Specifies that the value object will not be instantiated when all mapped + # attributes are +nil+. Setting the value object to +nil+ has the effect of writing +nil+ to all + # mapped attributes. + # This defaults to +false+. + # * :constructor - A symbol specifying the name of the constructor method or a Proc that + # is called to initialize the value object. The constructor is passed all of the mapped attributes, + # in the order that they are defined in the :mapping option, as arguments and uses them + # to instantiate a :class_name object. + # The default is :new. + # * :converter - A symbol specifying the name of a class method of :class_name + # or a Proc that is called when a new value is assigned to the value object. The converter is + # passed the single value that is used in the assignment and is only called if the new value is + # not an instance of :class_name. If :allow_nil is set to true, the converter + # can return nil to skip the assignment. + # + # Option examples: + # composed_of :temperature, mapping: %w(reading celsius) + # composed_of :balance, class_name: "Money", mapping: %w(balance amount), + # converter: Proc.new { |balance| balance.to_money } + # composed_of :address, mapping: [ %w(address_street street), %w(address_city city) ] + # composed_of :gps_location + # composed_of :gps_location, allow_nil: true + # composed_of :ip_address, + # class_name: 'IPAddr', + # mapping: %w(ip to_i), + # constructor: Proc.new { |ip| IPAddr.new(ip, Socket::AF_INET) }, + # converter: Proc.new { |ip| ip.is_a?(Integer) ? IPAddr.new(ip, Socket::AF_INET) : IPAddr.new(ip.to_s) } + # + def composed_of(part_id, options = {}) + options.assert_valid_keys(:class_name, :mapping, :allow_nil, :constructor, :converter) + + name = part_id.id2name + class_name = options[:class_name] || name.camelize + mapping = options[:mapping] || [ name, name ] + mapping = [ mapping ] unless mapping.first.is_a?(Array) + allow_nil = options[:allow_nil] || false + constructor = options[:constructor] || :new + converter = options[:converter] + + reader_method(name, class_name, mapping, allow_nil, constructor) + writer_method(name, class_name, mapping, allow_nil, converter) + + reflection = ActiveRecord::Reflection.create(:composed_of, part_id, nil, options, self) + Reflection.add_aggregate_reflection self, part_id, reflection + end + + private + def reader_method(name, class_name, mapping, allow_nil, constructor) + define_method(name) do + if @aggregation_cache[name].nil? && (!allow_nil || mapping.any? {|key, _| !_read_attribute(key).nil? }) + attrs = mapping.collect {|key, _| _read_attribute(key)} + object = constructor.respond_to?(:call) ? + constructor.call(*attrs) : + class_name.constantize.send(constructor, *attrs) + @aggregation_cache[name] = object + end + @aggregation_cache[name] + end + end + + def writer_method(name, class_name, mapping, allow_nil, converter) + define_method("#{name}=") do |part| + klass = class_name.constantize + if part.is_a?(Hash) + part = klass.new(*part.values) + end + + unless part.is_a?(klass) || converter.nil? || part.nil? + part = converter.respond_to?(:call) ? converter.call(part) : klass.send(converter, part) + end + + if part.nil? && allow_nil + mapping.each { |key, _| self[key] = nil } + @aggregation_cache[name] = nil + else + mapping.each { |key, value| self[key] = part.send(value) } + @aggregation_cache[name] = part.freeze + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/association_relation.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/association_relation.rb new file mode 100644 index 0000000..c6bc06e --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/association_relation.rb @@ -0,0 +1,35 @@ +module ActiveRecord + class AssociationRelation < Relation + def initialize(klass, table, association) + super(klass, table) + @association = association + end + + def proxy_association + @association + end + + def ==(other) + other == to_a + end + + def build(*args, &block) + scoping { @association.build(*args, &block) } + end + alias new build + + def create(*args, &block) + scoping { @association.create(*args, &block) } + end + + def create!(*args, &block) + scoping { @association.create!(*args, &block) } + end + + private + + def exec_queries + super.each { |r| @association.set_inverse_instance r } + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations.rb new file mode 100644 index 0000000..bb162b3 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations.rb @@ -0,0 +1,1725 @@ +require 'active_support/core_ext/enumerable' +require 'active_support/core_ext/string/conversions' +require 'active_support/core_ext/module/remove_method' +require 'active_record/errors' + +module ActiveRecord + class AssociationNotFoundError < ConfigurationError #:nodoc: + def initialize(record, association_name) + super("Association named '#{association_name}' was not found on #{record.class.name}; perhaps you misspelled it?") + end + end + + class InverseOfAssociationNotFoundError < ActiveRecordError #:nodoc: + def initialize(reflection, associated_class = nil) + super("Could not find the inverse association for #{reflection.name} (#{reflection.options[:inverse_of].inspect} in #{associated_class.nil? ? reflection.class_name : associated_class.name})") + end + end + + class HasManyThroughAssociationNotFoundError < ActiveRecordError #:nodoc: + def initialize(owner_class_name, reflection) + super("Could not find the association #{reflection.options[:through].inspect} in model #{owner_class_name}") + end + end + + class HasManyThroughAssociationPolymorphicSourceError < ActiveRecordError #:nodoc: + def initialize(owner_class_name, reflection, source_reflection) + super("Cannot have a has_many :through association '#{owner_class_name}##{reflection.name}' on the polymorphic object '#{source_reflection.class_name}##{source_reflection.name}' without 'source_type'. Try adding 'source_type: \"#{reflection.name.to_s.classify}\"' to 'has_many :through' definition.") + end + end + + class HasManyThroughAssociationPolymorphicThroughError < ActiveRecordError #:nodoc: + def initialize(owner_class_name, reflection) + super("Cannot have a has_many :through association '#{owner_class_name}##{reflection.name}' which goes through the polymorphic association '#{owner_class_name}##{reflection.through_reflection.name}'.") + end + end + + class HasManyThroughAssociationPointlessSourceTypeError < ActiveRecordError #:nodoc: + def initialize(owner_class_name, reflection, source_reflection) + super("Cannot have a has_many :through association '#{owner_class_name}##{reflection.name}' with a :source_type option if the '#{reflection.through_reflection.class_name}##{source_reflection.name}' is not polymorphic. Try removing :source_type on your association.") + end + end + + class HasOneThroughCantAssociateThroughCollection < ActiveRecordError #:nodoc: + def initialize(owner_class_name, reflection, through_reflection) + super("Cannot have a has_one :through association '#{owner_class_name}##{reflection.name}' where the :through association '#{owner_class_name}##{through_reflection.name}' is a collection. Specify a has_one or belongs_to association in the :through option instead.") + end + end + + class HasOneAssociationPolymorphicThroughError < ActiveRecordError #:nodoc: + def initialize(owner_class_name, reflection) + super("Cannot have a has_one :through association '#{owner_class_name}##{reflection.name}' which goes through the polymorphic association '#{owner_class_name}##{reflection.through_reflection.name}'.") + end + end + + class HasManyThroughSourceAssociationNotFoundError < ActiveRecordError #:nodoc: + def initialize(reflection) + through_reflection = reflection.through_reflection + source_reflection_names = reflection.source_reflection_names + source_associations = reflection.through_reflection.klass._reflections.keys + super("Could not find the source association(s) #{source_reflection_names.collect{ |a| a.inspect }.to_sentence(:two_words_connector => ' or ', :last_word_connector => ', or ', :locale => :en)} in model #{through_reflection.klass}. Try 'has_many #{reflection.name.inspect}, :through => #{through_reflection.name.inspect}, :source => '. Is it one of #{source_associations.to_sentence(:two_words_connector => ' or ', :last_word_connector => ', or ', :locale => :en)}?") + end + end + + class HasManyThroughCantAssociateThroughHasOneOrManyReflection < ActiveRecordError #:nodoc: + def initialize(owner, reflection) + super("Cannot modify association '#{owner.class.name}##{reflection.name}' because the source reflection class '#{reflection.source_reflection.class_name}' is associated to '#{reflection.through_reflection.class_name}' via :#{reflection.source_reflection.macro}.") + end + end + + class HasManyThroughCantAssociateNewRecords < ActiveRecordError #:nodoc: + def initialize(owner, reflection) + super("Cannot associate new records through '#{owner.class.name}##{reflection.name}' on '#{reflection.source_reflection.class_name rescue nil}##{reflection.source_reflection.name rescue nil}'. Both records must have an id in order to create the has_many :through record associating them.") + end + end + + class HasManyThroughCantDissociateNewRecords < ActiveRecordError #:nodoc: + def initialize(owner, reflection) + super("Cannot dissociate new records through '#{owner.class.name}##{reflection.name}' on '#{reflection.source_reflection.class_name rescue nil}##{reflection.source_reflection.name rescue nil}'. Both records must have an id in order to delete the has_many :through record associating them.") + end + end + + class HasManyThroughNestedAssociationsAreReadonly < ActiveRecordError #:nodoc: + def initialize(owner, reflection) + super("Cannot modify association '#{owner.class.name}##{reflection.name}' because it goes through more than one other association.") + end + end + + class EagerLoadPolymorphicError < ActiveRecordError #:nodoc: + def initialize(reflection) + super("Cannot eagerly load the polymorphic association #{reflection.name.inspect}") + end + end + + class ReadOnlyAssociation < ActiveRecordError #:nodoc: + def initialize(reflection) + super("Cannot add to a has_many :through association. Try adding to #{reflection.through_reflection.name.inspect}.") + end + end + + # This error is raised when trying to destroy a parent instance in N:1 or 1:1 associations + # (has_many, has_one) when there is at least 1 child associated instance. + # ex: if @project.tasks.size > 0, DeleteRestrictionError will be raised when trying to destroy @project + class DeleteRestrictionError < ActiveRecordError #:nodoc: + def initialize(name) + super("Cannot delete record because of dependent #{name}") + end + end + + # See ActiveRecord::Associations::ClassMethods for documentation. + module Associations # :nodoc: + extend ActiveSupport::Autoload + extend ActiveSupport::Concern + + # These classes will be loaded when associations are created. + # So there is no need to eager load them. + autoload :Association, 'active_record/associations/association' + autoload :SingularAssociation, 'active_record/associations/singular_association' + autoload :CollectionAssociation, 'active_record/associations/collection_association' + autoload :ForeignAssociation, 'active_record/associations/foreign_association' + autoload :CollectionProxy, 'active_record/associations/collection_proxy' + + autoload :BelongsToAssociation, 'active_record/associations/belongs_to_association' + autoload :BelongsToPolymorphicAssociation, 'active_record/associations/belongs_to_polymorphic_association' + autoload :HasManyAssociation, 'active_record/associations/has_many_association' + autoload :HasManyThroughAssociation, 'active_record/associations/has_many_through_association' + autoload :HasOneAssociation, 'active_record/associations/has_one_association' + autoload :HasOneThroughAssociation, 'active_record/associations/has_one_through_association' + autoload :ThroughAssociation, 'active_record/associations/through_association' + + module Builder #:nodoc: + autoload :Association, 'active_record/associations/builder/association' + autoload :SingularAssociation, 'active_record/associations/builder/singular_association' + autoload :CollectionAssociation, 'active_record/associations/builder/collection_association' + + autoload :BelongsTo, 'active_record/associations/builder/belongs_to' + autoload :HasOne, 'active_record/associations/builder/has_one' + autoload :HasMany, 'active_record/associations/builder/has_many' + autoload :HasAndBelongsToMany, 'active_record/associations/builder/has_and_belongs_to_many' + end + + eager_autoload do + autoload :Preloader, 'active_record/associations/preloader' + autoload :JoinDependency, 'active_record/associations/join_dependency' + autoload :AssociationScope, 'active_record/associations/association_scope' + autoload :AliasTracker, 'active_record/associations/alias_tracker' + end + + # Clears out the association cache. + def clear_association_cache #:nodoc: + @association_cache.clear if persisted? + end + + # :nodoc: + attr_reader :association_cache + + # Returns the association instance for the given name, instantiating it if it doesn't already exist + def association(name) #:nodoc: + association = association_instance_get(name) + + if association.nil? + raise AssociationNotFoundError.new(self, name) unless reflection = self.class._reflect_on_association(name) + association = reflection.association_class.new(self, reflection) + association_instance_set(name, association) + end + + association + end + + private + # Returns the specified association instance if it responds to :loaded?, nil otherwise. + def association_instance_get(name) + @association_cache[name] + end + + # Set the specified association instance. + def association_instance_set(name, association) + @association_cache[name] = association + end + + # \Associations are a set of macro-like class methods for tying objects together through + # foreign keys. They express relationships like "Project has one Project Manager" + # or "Project belongs to a Portfolio". Each macro adds a number of methods to the + # class which are specialized according to the collection or association symbol and the + # options hash. It works much the same way as Ruby's own attr* + # methods. + # + # class Project < ActiveRecord::Base + # belongs_to :portfolio + # has_one :project_manager + # has_many :milestones + # has_and_belongs_to_many :categories + # end + # + # The project class now has the following methods (and more) to ease the traversal and + # manipulation of its relationships: + # * Project#portfolio, Project#portfolio=(portfolio), Project#portfolio.nil? + # * Project#project_manager, Project#project_manager=(project_manager), Project#project_manager.nil?, + # * Project#milestones.empty?, Project#milestones.size, Project#milestones, Project#milestones<<(milestone), + # Project#milestones.delete(milestone), Project#milestones.destroy(milestone), Project#milestones.find(milestone_id), + # Project#milestones.build, Project#milestones.create + # * Project#categories.empty?, Project#categories.size, Project#categories, Project#categories<<(category1), + # Project#categories.delete(category1), Project#categories.destroy(category1) + # + # === A word of warning + # + # Don't create associations that have the same name as instance methods of + # ActiveRecord::Base. Since the association adds a method with that name to + # its model, it will override the inherited method and break things. + # For instance, +attributes+ and +connection+ would be bad choices for association names. + # + # == Auto-generated methods + # See also Instance Public methods below for more details. + # + # === Singular associations (one-to-one) + # | | belongs_to | + # generated methods | belongs_to | :polymorphic | has_one + # ----------------------------------+------------+--------------+--------- + # other(force_reload=false) | X | X | X + # other=(other) | X | X | X + # build_other(attributes={}) | X | | X + # create_other(attributes={}) | X | | X + # create_other!(attributes={}) | X | | X + # + # ===Collection associations (one-to-many / many-to-many) + # | | | has_many + # generated methods | habtm | has_many | :through + # ----------------------------------+-------+----------+---------- + # others(force_reload=false) | X | X | X + # others=(other,other,...) | X | X | X + # other_ids | X | X | X + # other_ids=(id,id,...) | X | X | X + # others<< | X | X | X + # others.push | X | X | X + # others.concat | X | X | X + # others.build(attributes={}) | X | X | X + # others.create(attributes={}) | X | X | X + # others.create!(attributes={}) | X | X | X + # others.size | X | X | X + # others.length | X | X | X + # others.count | X | X | X + # others.sum(*args) | X | X | X + # others.empty? | X | X | X + # others.clear | X | X | X + # others.delete(other,other,...) | X | X | X + # others.delete_all | X | X | X + # others.destroy(other,other,...) | X | X | X + # others.destroy_all | X | X | X + # others.find(*args) | X | X | X + # others.exists? | X | X | X + # others.distinct | X | X | X + # others.uniq | X | X | X + # others.reset | X | X | X + # + # === Overriding generated methods + # + # Association methods are generated in a module that is included into the model class, + # which allows you to easily override with your own methods and call the original + # generated method with +super+. For example: + # + # class Car < ActiveRecord::Base + # belongs_to :owner + # belongs_to :old_owner + # def owner=(new_owner) + # self.old_owner = self.owner + # super + # end + # end + # + # If your model class is Project, the module is + # named Project::GeneratedFeatureMethods. The GeneratedFeatureMethods module is + # included in the model class immediately after the (anonymous) generated attributes methods + # module, meaning an association will override the methods for an attribute with the same name. + # + # == Cardinality and associations + # + # Active Record associations can be used to describe one-to-one, one-to-many and many-to-many + # relationships between models. Each model uses an association to describe its role in + # the relation. The +belongs_to+ association is always used in the model that has + # the foreign key. + # + # === One-to-one + # + # Use +has_one+ in the base, and +belongs_to+ in the associated model. + # + # class Employee < ActiveRecord::Base + # has_one :office + # end + # class Office < ActiveRecord::Base + # belongs_to :employee # foreign key - employee_id + # end + # + # === One-to-many + # + # Use +has_many+ in the base, and +belongs_to+ in the associated model. + # + # class Manager < ActiveRecord::Base + # has_many :employees + # end + # class Employee < ActiveRecord::Base + # belongs_to :manager # foreign key - manager_id + # end + # + # === Many-to-many + # + # There are two ways to build a many-to-many relationship. + # + # The first way uses a +has_many+ association with the :through option and a join model, so + # there are two stages of associations. + # + # class Assignment < ActiveRecord::Base + # belongs_to :programmer # foreign key - programmer_id + # belongs_to :project # foreign key - project_id + # end + # class Programmer < ActiveRecord::Base + # has_many :assignments + # has_many :projects, through: :assignments + # end + # class Project < ActiveRecord::Base + # has_many :assignments + # has_many :programmers, through: :assignments + # end + # + # For the second way, use +has_and_belongs_to_many+ in both models. This requires a join table + # that has no corresponding model or primary key. + # + # class Programmer < ActiveRecord::Base + # has_and_belongs_to_many :projects # foreign keys in the join table + # end + # class Project < ActiveRecord::Base + # has_and_belongs_to_many :programmers # foreign keys in the join table + # end + # + # Choosing which way to build a many-to-many relationship is not always simple. + # If you need to work with the relationship model as its own entity, + # use has_many :through. Use +has_and_belongs_to_many+ when working with legacy schemas or when + # you never work directly with the relationship itself. + # + # == Is it a +belongs_to+ or +has_one+ association? + # + # Both express a 1-1 relationship. The difference is mostly where to place the foreign + # key, which goes on the table for the class declaring the +belongs_to+ relationship. + # + # class User < ActiveRecord::Base + # # I reference an account. + # belongs_to :account + # end + # + # class Account < ActiveRecord::Base + # # One user references me. + # has_one :user + # end + # + # The tables for these classes could look something like: + # + # CREATE TABLE users ( + # id int(11) NOT NULL auto_increment, + # account_id int(11) default NULL, + # name varchar default NULL, + # PRIMARY KEY (id) + # ) + # + # CREATE TABLE accounts ( + # id int(11) NOT NULL auto_increment, + # name varchar default NULL, + # PRIMARY KEY (id) + # ) + # + # == Unsaved objects and associations + # + # You can manipulate objects and associations before they are saved to the database, but + # there is some special behavior you should be aware of, mostly involving the saving of + # associated objects. + # + # You can set the :autosave option on a has_one, belongs_to, + # has_many, or has_and_belongs_to_many association. Setting it + # to +true+ will _always_ save the members, whereas setting it to +false+ will + # _never_ save the members. More details about :autosave option is available at + # AutosaveAssociation. + # + # === One-to-one associations + # + # * Assigning an object to a +has_one+ association automatically saves that object and + # the object being replaced (if there is one), in order to update their foreign + # keys - except if the parent object is unsaved (new_record? == true). + # * If either of these saves fail (due to one of the objects being invalid), an + # ActiveRecord::RecordNotSaved exception is raised and the assignment is + # cancelled. + # * If you wish to assign an object to a +has_one+ association without saving it, + # use the build_association method (documented below). The object being + # replaced will still be saved to update its foreign key. + # * Assigning an object to a +belongs_to+ association does not save the object, since + # the foreign key field belongs on the parent. It does not save the parent either. + # + # === Collections + # + # * Adding an object to a collection (+has_many+ or +has_and_belongs_to_many+) automatically + # saves that object, except if the parent object (the owner of the collection) is not yet + # stored in the database. + # * If saving any of the objects being added to a collection (via push or similar) + # fails, then push returns +false+. + # * If saving fails while replacing the collection (via association=), an + # ActiveRecord::RecordNotSaved exception is raised and the assignment is + # cancelled. + # * You can add an object to a collection without automatically saving it by using the + # collection.build method (documented below). + # * All unsaved (new_record? == true) members of the collection are automatically + # saved when the parent is saved. + # + # == Customizing the query + # + # \Associations are built from Relations, and you can use the Relation syntax + # to customize them. For example, to add a condition: + # + # class Blog < ActiveRecord::Base + # has_many :published_posts, -> { where published: true }, class_name: 'Post' + # end + # + # Inside the -> { ... } block you can use all of the usual Relation methods. + # + # === Accessing the owner object + # + # Sometimes it is useful to have access to the owner object when building the query. The owner + # is passed as a parameter to the block. For example, the following association would find all + # events that occur on the user's birthday: + # + # class User < ActiveRecord::Base + # has_many :birthday_events, ->(user) { where starts_on: user.birthday }, class_name: 'Event' + # end + # + # Note: Joining, eager loading and preloading of these associations is not fully possible. + # These operations happen before instance creation and the scope will be called with a +nil+ argument. + # This can lead to unexpected behavior and is deprecated. + # + # == Association callbacks + # + # Similar to the normal callbacks that hook into the life cycle of an Active Record object, + # you can also define callbacks that get triggered when you add an object to or remove an + # object from an association collection. + # + # class Project + # has_and_belongs_to_many :developers, after_add: :evaluate_velocity + # + # def evaluate_velocity(developer) + # ... + # end + # end + # + # It's possible to stack callbacks by passing them as an array. Example: + # + # class Project + # has_and_belongs_to_many :developers, + # after_add: [:evaluate_velocity, Proc.new { |p, d| p.shipping_date = Time.now}] + # end + # + # Possible callbacks are: +before_add+, +after_add+, +before_remove+ and +after_remove+. + # + # If any of the +before_add+ callbacks throw an exception, the object will not be + # added to the collection. + # + # Similarly, if any of the +before_remove+ callbacks throw an exception, the object + # will not be removed from the collection. + # + # == Association extensions + # + # The proxy objects that control the access to associations can be extended through anonymous + # modules. This is especially beneficial for adding new finders, creators, and other + # factory-type methods that are only used as part of this association. + # + # class Account < ActiveRecord::Base + # has_many :people do + # def find_or_create_by_name(name) + # first_name, last_name = name.split(" ", 2) + # find_or_create_by(first_name: first_name, last_name: last_name) + # end + # end + # end + # + # person = Account.first.people.find_or_create_by_name("David Heinemeier Hansson") + # person.first_name # => "David" + # person.last_name # => "Heinemeier Hansson" + # + # If you need to share the same extensions between many associations, you can use a named + # extension module. + # + # module FindOrCreateByNameExtension + # def find_or_create_by_name(name) + # first_name, last_name = name.split(" ", 2) + # find_or_create_by(first_name: first_name, last_name: last_name) + # end + # end + # + # class Account < ActiveRecord::Base + # has_many :people, -> { extending FindOrCreateByNameExtension } + # end + # + # class Company < ActiveRecord::Base + # has_many :people, -> { extending FindOrCreateByNameExtension } + # end + # + # Some extensions can only be made to work with knowledge of the association's internals. + # Extensions can access relevant state using the following methods (where +items+ is the + # name of the association): + # + # * record.association(:items).owner - Returns the object the association is part of. + # * record.association(:items).reflection - Returns the reflection object that describes the association. + # * record.association(:items).target - Returns the associated object for +belongs_to+ and +has_one+, or + # the collection of associated objects for +has_many+ and +has_and_belongs_to_many+. + # + # However, inside the actual extension code, you will not have access to the record as + # above. In this case, you can access proxy_association. For example, + # record.association(:items) and record.items.proxy_association will return + # the same object, allowing you to make calls like proxy_association.owner inside + # association extensions. + # + # == Association Join Models + # + # Has Many associations can be configured with the :through option to use an + # explicit join model to retrieve the data. This operates similarly to a + # +has_and_belongs_to_many+ association. The advantage is that you're able to add validations, + # callbacks, and extra attributes on the join model. Consider the following schema: + # + # class Author < ActiveRecord::Base + # has_many :authorships + # has_many :books, through: :authorships + # end + # + # class Authorship < ActiveRecord::Base + # belongs_to :author + # belongs_to :book + # end + # + # @author = Author.first + # @author.authorships.collect { |a| a.book } # selects all books that the author's authorships belong to + # @author.books # selects all books by using the Authorship join model + # + # You can also go through a +has_many+ association on the join model: + # + # class Firm < ActiveRecord::Base + # has_many :clients + # has_many :invoices, through: :clients + # end + # + # class Client < ActiveRecord::Base + # belongs_to :firm + # has_many :invoices + # end + # + # class Invoice < ActiveRecord::Base + # belongs_to :client + # end + # + # @firm = Firm.first + # @firm.clients.flat_map { |c| c.invoices } # select all invoices for all clients of the firm + # @firm.invoices # selects all invoices by going through the Client join model + # + # Similarly you can go through a +has_one+ association on the join model: + # + # class Group < ActiveRecord::Base + # has_many :users + # has_many :avatars, through: :users + # end + # + # class User < ActiveRecord::Base + # belongs_to :group + # has_one :avatar + # end + # + # class Avatar < ActiveRecord::Base + # belongs_to :user + # end + # + # @group = Group.first + # @group.users.collect { |u| u.avatar }.compact # select all avatars for all users in the group + # @group.avatars # selects all avatars by going through the User join model. + # + # An important caveat with going through +has_one+ or +has_many+ associations on the + # join model is that these associations are *read-only*. For example, the following + # would not work following the previous example: + # + # @group.avatars << Avatar.new # this would work if User belonged_to Avatar rather than the other way around + # @group.avatars.delete(@group.avatars.last) # so would this + # + # == Setting Inverses + # + # If you are using a +belongs_to+ on the join model, it is a good idea to set the + # :inverse_of option on the +belongs_to+, which will mean that the following example + # works correctly (where tags is a +has_many+ :through association): + # + # @post = Post.first + # @tag = @post.tags.build name: "ruby" + # @tag.save + # + # The last line ought to save the through record (a Taggable). This will only work if the + # :inverse_of is set: + # + # class Taggable < ActiveRecord::Base + # belongs_to :post + # belongs_to :tag, inverse_of: :taggings + # end + # + # If you do not set the :inverse_of record, the association will + # do its best to match itself up with the correct inverse. Automatic + # inverse detection only works on has_many, has_one, and + # belongs_to associations. + # + # Extra options on the associations, as defined in the + # AssociationReflection::INVALID_AUTOMATIC_INVERSE_OPTIONS constant, will + # also prevent the association's inverse from being found automatically. + # + # The automatic guessing of the inverse association uses a heuristic based + # on the name of the class, so it may not work for all associations, + # especially the ones with non-standard names. + # + # You can turn off the automatic detection of inverse associations by setting + # the :inverse_of option to false like so: + # + # class Taggable < ActiveRecord::Base + # belongs_to :tag, inverse_of: false + # end + # + # == Nested \Associations + # + # You can actually specify *any* association with the :through option, including an + # association which has a :through option itself. For example: + # + # class Author < ActiveRecord::Base + # has_many :posts + # has_many :comments, through: :posts + # has_many :commenters, through: :comments + # end + # + # class Post < ActiveRecord::Base + # has_many :comments + # end + # + # class Comment < ActiveRecord::Base + # belongs_to :commenter + # end + # + # @author = Author.first + # @author.commenters # => People who commented on posts written by the author + # + # An equivalent way of setting up this association this would be: + # + # class Author < ActiveRecord::Base + # has_many :posts + # has_many :commenters, through: :posts + # end + # + # class Post < ActiveRecord::Base + # has_many :comments + # has_many :commenters, through: :comments + # end + # + # class Comment < ActiveRecord::Base + # belongs_to :commenter + # end + # + # When using a nested association, you will not be able to modify the association because there + # is not enough information to know what modification to make. For example, if you tried to + # add a Commenter in the example above, there would be no way to tell how to set up the + # intermediate Post and Comment objects. + # + # == Polymorphic \Associations + # + # Polymorphic associations on models are not restricted on what types of models they + # can be associated with. Rather, they specify an interface that a +has_many+ association + # must adhere to. + # + # class Asset < ActiveRecord::Base + # belongs_to :attachable, polymorphic: true + # end + # + # class Post < ActiveRecord::Base + # has_many :assets, as: :attachable # The :as option specifies the polymorphic interface to use. + # end + # + # @asset.attachable = @post + # + # This works by using a type column in addition to a foreign key to specify the associated + # record. In the Asset example, you'd need an +attachable_id+ integer column and an + # +attachable_type+ string column. + # + # Using polymorphic associations in combination with single table inheritance (STI) is + # a little tricky. In order for the associations to work as expected, ensure that you + # store the base model for the STI models in the type column of the polymorphic + # association. To continue with the asset example above, suppose there are guest posts + # and member posts that use the posts table for STI. In this case, there must be a +type+ + # column in the posts table. + # + # Note: The attachable_type= method is being called when assigning an +attachable+. + # The +class_name+ of the +attachable+ is passed as a String. + # + # class Asset < ActiveRecord::Base + # belongs_to :attachable, polymorphic: true + # + # def attachable_type=(class_name) + # super(class_name.constantize.base_class.to_s) + # end + # end + # + # class Post < ActiveRecord::Base + # # because we store "Post" in attachable_type now dependent: :destroy will work + # has_many :assets, as: :attachable, dependent: :destroy + # end + # + # class GuestPost < Post + # end + # + # class MemberPost < Post + # end + # + # == Caching + # + # All of the methods are built on a simple caching principle that will keep the result + # of the last query around unless specifically instructed not to. The cache is even + # shared across methods to make it even cheaper to use the macro-added methods without + # worrying too much about performance at the first go. + # + # project.milestones # fetches milestones from the database + # project.milestones.size # uses the milestone cache + # project.milestones.empty? # uses the milestone cache + # project.milestones(true).size # fetches milestones from the database + # project.milestones # uses the milestone cache + # + # == Eager loading of associations + # + # Eager loading is a way to find objects of a certain class and a number of named associations. + # It is one of the easiest ways to prevent the dreaded N+1 problem in which fetching 100 + # posts that each need to display their author triggers 101 database queries. Through the + # use of eager loading, the number of queries will be reduced from 101 to 2. + # + # class Post < ActiveRecord::Base + # belongs_to :author + # has_many :comments + # end + # + # Consider the following loop using the class above: + # + # Post.all.each do |post| + # puts "Post: " + post.title + # puts "Written by: " + post.author.name + # puts "Last comment on: " + post.comments.first.created_on + # end + # + # To iterate over these one hundred posts, we'll generate 201 database queries. Let's + # first just optimize it for retrieving the author: + # + # Post.includes(:author).each do |post| + # + # This references the name of the +belongs_to+ association that also used the :author + # symbol. After loading the posts, find will collect the +author_id+ from each one and load + # all the referenced authors with one query. Doing so will cut down the number of queries + # from 201 to 102. + # + # We can improve upon the situation further by referencing both associations in the finder with: + # + # Post.includes(:author, :comments).each do |post| + # + # This will load all comments with a single query. This reduces the total number of queries + # to 3. In general, the number of queries will be 1 plus the number of associations + # named (except if some of the associations are polymorphic +belongs_to+ - see below). + # + # To include a deep hierarchy of associations, use a hash: + # + # Post.includes(:author, { comments: { author: :gravatar } }).each do |post| + # + # The above code will load all the comments and all of their associated + # authors and gravatars. You can mix and match any combination of symbols, + # arrays, and hashes to retrieve the associations you want to load. + # + # All of this power shouldn't fool you into thinking that you can pull out huge amounts + # of data with no performance penalty just because you've reduced the number of queries. + # The database still needs to send all the data to Active Record and it still needs to + # be processed. So it's no catch-all for performance problems, but it's a great way to + # cut down on the number of queries in a situation as the one described above. + # + # Since only one table is loaded at a time, conditions or orders cannot reference tables + # other than the main one. If this is the case, Active Record falls back to the previously + # used LEFT OUTER JOIN based strategy. For example: + # + # Post.includes([:author, :comments]).where(['comments.approved = ?', true]) + # + # This will result in a single SQL query with joins along the lines of: + # LEFT OUTER JOIN comments ON comments.post_id = posts.id and + # LEFT OUTER JOIN authors ON authors.id = posts.author_id. Note that using conditions + # like this can have unintended consequences. + # In the above example posts with no approved comments are not returned at all, because + # the conditions apply to the SQL statement as a whole and not just to the association. + # + # You must disambiguate column references for this fallback to happen, for example + # order: "author.name DESC" will work but order: "name DESC" will not. + # + # If you want to load all posts (including posts with no approved comments) then write + # your own LEFT OUTER JOIN query using ON + # + # Post.joins("LEFT OUTER JOIN comments ON comments.post_id = posts.id AND comments.approved = '1'") + # + # In this case it is usually more natural to include an association which has conditions defined on it: + # + # class Post < ActiveRecord::Base + # has_many :approved_comments, -> { where approved: true }, class_name: 'Comment' + # end + # + # Post.includes(:approved_comments) + # + # This will load posts and eager load the +approved_comments+ association, which contains + # only those comments that have been approved. + # + # If you eager load an association with a specified :limit option, it will be ignored, + # returning all the associated objects: + # + # class Picture < ActiveRecord::Base + # has_many :most_recent_comments, -> { order('id DESC').limit(10) }, class_name: 'Comment' + # end + # + # Picture.includes(:most_recent_comments).first.most_recent_comments # => returns all associated comments. + # + # Eager loading is supported with polymorphic associations. + # + # class Address < ActiveRecord::Base + # belongs_to :addressable, polymorphic: true + # end + # + # A call that tries to eager load the addressable model + # + # Address.includes(:addressable) + # + # This will execute one query to load the addresses and load the addressables with one + # query per addressable type. + # For example if all the addressables are either of class Person or Company then a total + # of 3 queries will be executed. The list of addressable types to load is determined on + # the back of the addresses loaded. This is not supported if Active Record has to fallback + # to the previous implementation of eager loading and will raise ActiveRecord::EagerLoadPolymorphicError. + # The reason is that the parent model's type is a column value so its corresponding table + # name cannot be put in the +FROM+/+JOIN+ clauses of that query. + # + # == Table Aliasing + # + # Active Record uses table aliasing in the case that a table is referenced multiple times + # in a join. If a table is referenced only once, the standard table name is used. The + # second time, the table is aliased as #{reflection_name}_#{parent_table_name}. + # Indexes are appended for any more successive uses of the table name. + # + # Post.joins(:comments) + # # => SELECT ... FROM posts INNER JOIN comments ON ... + # Post.joins(:special_comments) # STI + # # => SELECT ... FROM posts INNER JOIN comments ON ... AND comments.type = 'SpecialComment' + # Post.joins(:comments, :special_comments) # special_comments is the reflection name, posts is the parent table name + # # => SELECT ... FROM posts INNER JOIN comments ON ... INNER JOIN comments special_comments_posts + # + # Acts as tree example: + # + # TreeMixin.joins(:children) + # # => SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ... + # TreeMixin.joins(children: :parent) + # # => SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ... + # INNER JOIN parents_mixins ... + # TreeMixin.joins(children: {parent: :children}) + # # => SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ... + # INNER JOIN parents_mixins ... + # INNER JOIN mixins childrens_mixins_2 + # + # Has and Belongs to Many join tables use the same idea, but add a _join suffix: + # + # Post.joins(:categories) + # # => SELECT ... FROM posts INNER JOIN categories_posts ... INNER JOIN categories ... + # Post.joins(categories: :posts) + # # => SELECT ... FROM posts INNER JOIN categories_posts ... INNER JOIN categories ... + # INNER JOIN categories_posts posts_categories_join INNER JOIN posts posts_categories + # Post.joins(categories: {posts: :categories}) + # # => SELECT ... FROM posts INNER JOIN categories_posts ... INNER JOIN categories ... + # INNER JOIN categories_posts posts_categories_join INNER JOIN posts posts_categories + # INNER JOIN categories_posts categories_posts_join INNER JOIN categories categories_posts_2 + # + # If you wish to specify your own custom joins using joins method, those table + # names will take precedence over the eager associations: + # + # Post.joins(:comments).joins("inner join comments ...") + # # => SELECT ... FROM posts INNER JOIN comments_posts ON ... INNER JOIN comments ... + # Post.joins(:comments, :special_comments).joins("inner join comments ...") + # # => SELECT ... FROM posts INNER JOIN comments comments_posts ON ... + # INNER JOIN comments special_comments_posts ... + # INNER JOIN comments ... + # + # Table aliases are automatically truncated according to the maximum length of table identifiers + # according to the specific database. + # + # == Modules + # + # By default, associations will look for objects within the current module scope. Consider: + # + # module MyApplication + # module Business + # class Firm < ActiveRecord::Base + # has_many :clients + # end + # + # class Client < ActiveRecord::Base; end + # end + # end + # + # When Firm#clients is called, it will in turn call + # MyApplication::Business::Client.find_all_by_firm_id(firm.id). + # If you want to associate with a class in another module scope, this can be done by + # specifying the complete class name. + # + # module MyApplication + # module Business + # class Firm < ActiveRecord::Base; end + # end + # + # module Billing + # class Account < ActiveRecord::Base + # belongs_to :firm, class_name: "MyApplication::Business::Firm" + # end + # end + # end + # + # == Bi-directional associations + # + # When you specify an association there is usually an association on the associated model + # that specifies the same relationship in reverse. For example, with the following models: + # + # class Dungeon < ActiveRecord::Base + # has_many :traps + # has_one :evil_wizard + # end + # + # class Trap < ActiveRecord::Base + # belongs_to :dungeon + # end + # + # class EvilWizard < ActiveRecord::Base + # belongs_to :dungeon + # end + # + # The +traps+ association on +Dungeon+ and the +dungeon+ association on +Trap+ are + # the inverse of each other and the inverse of the +dungeon+ association on +EvilWizard+ + # is the +evil_wizard+ association on +Dungeon+ (and vice-versa). By default, + # Active Record doesn't know anything about these inverse relationships and so no object + # loading optimization is possible. For example: + # + # d = Dungeon.first + # t = d.traps.first + # d.level == t.dungeon.level # => true + # d.level = 10 + # d.level == t.dungeon.level # => false + # + # The +Dungeon+ instances +d+ and t.dungeon in the above example refer to + # the same object data from the database, but are actually different in-memory copies + # of that data. Specifying the :inverse_of option on associations lets you tell + # Active Record about inverse relationships and it will optimise object loading. For + # example, if we changed our model definitions to: + # + # class Dungeon < ActiveRecord::Base + # has_many :traps, inverse_of: :dungeon + # has_one :evil_wizard, inverse_of: :dungeon + # end + # + # class Trap < ActiveRecord::Base + # belongs_to :dungeon, inverse_of: :traps + # end + # + # class EvilWizard < ActiveRecord::Base + # belongs_to :dungeon, inverse_of: :evil_wizard + # end + # + # Then, from our code snippet above, +d+ and t.dungeon are actually the same + # in-memory instance and our final d.level == t.dungeon.level will return +true+. + # + # There are limitations to :inverse_of support: + # + # * does not work with :through associations. + # * does not work with :polymorphic associations. + # * for +belongs_to+ associations +has_many+ inverse associations are ignored. + # + # == Deleting from associations + # + # === Dependent associations + # + # +has_many+, +has_one+ and +belongs_to+ associations support the :dependent option. + # This allows you to specify that associated records should be deleted when the owner is + # deleted. + # + # For example: + # + # class Author + # has_many :posts, dependent: :destroy + # end + # Author.find(1).destroy # => Will destroy all of the author's posts, too + # + # The :dependent option can have different values which specify how the deletion + # is done. For more information, see the documentation for this option on the different + # specific association types. When no option is given, the behavior is to do nothing + # with the associated records when destroying a record. + # + # Note that :dependent is implemented using Rails' callback + # system, which works by processing callbacks in order. Therefore, other + # callbacks declared either before or after the :dependent option + # can affect what it does. + # + # === Delete or destroy? + # + # +has_many+ and +has_and_belongs_to_many+ associations have the methods destroy, + # delete, destroy_all and delete_all. + # + # For +has_and_belongs_to_many+, delete and destroy are the same: they + # cause the records in the join table to be removed. + # + # For +has_many+, destroy and destroy_all will always call the destroy method of the + # record(s) being removed so that callbacks are run. However delete and delete_all will either + # do the deletion according to the strategy specified by the :dependent option, or + # if no :dependent option is given, then it will follow the default strategy. + # The default strategy is to do nothing (leave the foreign keys with the parent ids set), except for + # +has_many+ :through, where the default strategy is delete_all (delete + # the join records, without running their callbacks). + # + # There is also a clear method which is the same as delete_all, except that + # it returns the association rather than the records which have been deleted. + # + # === What gets deleted? + # + # There is a potential pitfall here: +has_and_belongs_to_many+ and +has_many+ :through + # associations have records in join tables, as well as the associated records. So when we + # call one of these deletion methods, what exactly should be deleted? + # + # The answer is that it is assumed that deletion on an association is about removing the + # link between the owner and the associated object(s), rather than necessarily the + # associated objects themselves. So with +has_and_belongs_to_many+ and +has_many+ + # :through, the join records will be deleted, but the associated records won't. + # + # This makes sense if you think about it: if you were to call post.tags.delete(Tag.find_by(name: 'food')) + # you would want the 'food' tag to be unlinked from the post, rather than for the tag itself + # to be removed from the database. + # + # However, there are examples where this strategy doesn't make sense. For example, suppose + # a person has many projects, and each project has many tasks. If we deleted one of a person's + # tasks, we would probably not want the project to be deleted. In this scenario, the delete method + # won't actually work: it can only be used if the association on the join model is a + # +belongs_to+. In other situations you are expected to perform operations directly on + # either the associated records or the :through association. + # + # With a regular +has_many+ there is no distinction between the "associated records" + # and the "link", so there is only one choice for what gets deleted. + # + # With +has_and_belongs_to_many+ and +has_many+ :through, if you want to delete the + # associated records themselves, you can always do something along the lines of + # person.tasks.each(&:destroy). + # + # == Type safety with ActiveRecord::AssociationTypeMismatch + # + # If you attempt to assign an object to an association that doesn't match the inferred + # or specified :class_name, you'll get an ActiveRecord::AssociationTypeMismatch. + # + # == Options + # + # All of the association macros can be specialized through options. This makes cases + # more complex than the simple and guessable ones possible. + module ClassMethods + # Specifies a one-to-many association. The following methods for retrieval and query of + # collections of associated objects will be added: + # + # +collection+ is a placeholder for the symbol passed as the +name+ argument, so + # has_many :clients would add among others clients.empty?. + # + # [collection(force_reload = false)] + # Returns an array of all the associated objects. + # An empty array is returned if none are found. + # [collection<<(object, ...)] + # Adds one or more objects to the collection by setting their foreign keys to the collection's primary key. + # Note that this operation instantly fires update SQL without waiting for the save or update call on the + # parent object, unless the parent object is a new record. + # [collection.delete(object, ...)] + # Removes one or more objects from the collection by setting their foreign keys to +NULL+. + # Objects will be in addition destroyed if they're associated with dependent: :destroy, + # and deleted if they're associated with dependent: :delete_all. + # + # If the :through option is used, then the join records are deleted (rather than + # nullified) by default, but you can specify dependent: :destroy or + # dependent: :nullify to override this. + # [collection.destroy(object, ...)] + # Removes one or more objects from the collection by running destroy on + # each record, regardless of any dependent option, ensuring callbacks are run. + # + # If the :through option is used, then the join records are destroyed + # instead, not the objects themselves. + # [collection=objects] + # Replaces the collections content by deleting and adding objects as appropriate. If the :through + # option is true callbacks in the join models are triggered except destroy callbacks, since deletion is + # direct. + # [collection_singular_ids] + # Returns an array of the associated objects' ids + # [collection_singular_ids=ids] + # Replace the collection with the objects identified by the primary keys in +ids+. This + # method loads the models and calls collection=. See above. + # [collection.clear] + # Removes every object from the collection. This destroys the associated objects if they + # are associated with dependent: :destroy, deletes them directly from the + # database if dependent: :delete_all, otherwise sets their foreign keys to +NULL+. + # If the :through option is true no destroy callbacks are invoked on the join models. + # Join models are directly deleted. + # [collection.empty?] + # Returns +true+ if there are no associated objects. + # [collection.size] + # Returns the number of associated objects. + # [collection.find(...)] + # Finds an associated object according to the same rules as ActiveRecord::Base.find. + # [collection.exists?(...)] + # Checks whether an associated object with the given conditions exists. + # Uses the same rules as ActiveRecord::Base.exists?. + # [collection.build(attributes = {}, ...)] + # Returns one or more new objects of the collection type that have been instantiated + # with +attributes+ and linked to this object through a foreign key, but have not yet + # been saved. + # [collection.create(attributes = {})] + # Returns a new object of the collection type that has been instantiated + # with +attributes+, linked to this object through a foreign key, and that has already + # been saved (if it passed the validation). *Note*: This only works if the base model + # already exists in the DB, not if it is a new (unsaved) record! + # [collection.create!(attributes = {})] + # Does the same as collection.create, but raises ActiveRecord::RecordInvalid + # if the record is invalid. + # + # === Example + # + # A Firm class declares has_many :clients, which will add: + # * Firm#clients (similar to Client.where(firm_id: id)) + # * Firm#clients<< + # * Firm#clients.delete + # * Firm#clients.destroy + # * Firm#clients= + # * Firm#client_ids + # * Firm#client_ids= + # * Firm#clients.clear + # * Firm#clients.empty? (similar to firm.clients.size == 0) + # * Firm#clients.size (similar to Client.count "firm_id = #{id}") + # * Firm#clients.find (similar to Client.where(firm_id: id).find(id)) + # * Firm#clients.exists?(name: 'ACME') (similar to Client.exists?(name: 'ACME', firm_id: firm.id)) + # * Firm#clients.build (similar to Client.new("firm_id" => id)) + # * Firm#clients.create (similar to c = Client.new("firm_id" => id); c.save; c) + # * Firm#clients.create! (similar to c = Client.new("firm_id" => id); c.save!) + # The declaration can also include an +options+ hash to specialize the behavior of the association. + # + # === Scopes + # + # You can pass a second argument +scope+ as a callable (i.e. proc or + # lambda) to retrieve a specific set of records or customize the generated + # query when you access the associated collection. + # + # Scope examples: + # has_many :comments, -> { where(author_id: 1) } + # has_many :employees, -> { joins(:address) } + # has_many :posts, ->(post) { where("max_post_length > ?", post.length) } + # + # === Extensions + # + # The +extension+ argument allows you to pass a block into a has_many + # association. This is useful for adding new finders, creators and other + # factory-type methods to be used as part of the association. + # + # Extension examples: + # has_many :employees do + # def find_or_create_by_name(name) + # first_name, last_name = name.split(" ", 2) + # find_or_create_by(first_name: first_name, last_name: last_name) + # end + # end + # + # === Options + # [:class_name] + # Specify the class name of the association. Use it only if that name can't be inferred + # from the association name. So has_many :products will by default be linked + # to the Product class, but if the real class name is SpecialProduct, you'll have to + # specify it with this option. + # [:foreign_key] + # Specify the foreign key used for the association. By default this is guessed to be the name + # of this class in lower-case and "_id" suffixed. So a Person class that makes a +has_many+ + # association will use "person_id" as the default :foreign_key. + # [:foreign_type] + # Specify the column used to store the associated object's type, if this is a polymorphic + # association. By default this is guessed to be the name of the polymorphic association + # specified on "as" option with a "_type" suffix. So a class that defines a + # has_many :tags, as: :taggable association will use "taggable_type" as the + # default :foreign_type. + # [:primary_key] + # Specify the name of the column to use as the primary key for the association. By default this is +id+. + # [:dependent] + # Controls what happens to the associated objects when + # their owner is destroyed. Note that these are implemented as + # callbacks, and Rails executes callbacks in order. Therefore, other + # similar callbacks may affect the :dependent behavior, and the + # :dependent behavior may affect other callbacks. + # + # * :destroy causes all the associated objects to also be destroyed. + # * :delete_all causes all the associated objects to be deleted directly from the database (so callbacks will not be executed). + # * :nullify causes the foreign keys to be set to +NULL+. Callbacks are not executed. + # * :restrict_with_exception causes an exception to be raised if there are any associated records. + # * :restrict_with_error causes an error to be added to the owner if there are any associated objects. + # + # If using with the :through option, the association on the join model must be + # a +belongs_to+, and the records which get deleted are the join records, rather than + # the associated records. + # [:counter_cache] + # This option can be used to configure a custom named :counter_cache. You only need this option, + # when you customized the name of your :counter_cache on the belongs_to association. + # [:as] + # Specifies a polymorphic interface (See belongs_to). + # [:through] + # Specifies an association through which to perform the query. This can be any other type + # of association, including other :through associations. Options for :class_name, + # :primary_key and :foreign_key are ignored, as the association uses the + # source reflection. + # + # If the association on the join model is a +belongs_to+, the collection can be modified + # and the records on the :through model will be automatically created and removed + # as appropriate. Otherwise, the collection is read-only, so you should manipulate the + # :through association directly. + # + # If you are going to modify the association (rather than just read from it), then it is + # a good idea to set the :inverse_of option on the source association on the + # join model. This allows associated records to be built which will automatically create + # the appropriate join model records when they are saved. (See the 'Association Join Models' + # section above.) + # [:source] + # Specifies the source association name used by has_many :through queries. + # Only use it if the name cannot be inferred from the association. + # has_many :subscribers, through: :subscriptions will look for either :subscribers or + # :subscriber on Subscription, unless a :source is given. + # [:source_type] + # Specifies type of the source association used by has_many :through queries where the source + # association is a polymorphic +belongs_to+. + # [:validate] + # If +false+, don't validate the associated objects when saving the parent object. true by default. + # [:autosave] + # If true, always save the associated objects or destroy them if marked for destruction, + # when saving the parent object. If false, never save or destroy the associated objects. + # By default, only save associated objects that are new records. This option is implemented as a + # +before_save+ callback. Because callbacks are run in the order they are defined, associated objects + # may need to be explicitly saved in any user-defined +before_save+ callbacks. + # + # Note that accepts_nested_attributes_for sets :autosave to true. + # [:inverse_of] + # Specifies the name of the belongs_to association on the associated object + # that is the inverse of this has_many association. Does not work in combination + # with :through or :as options. + # See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail. + # + # Option examples: + # has_many :comments, -> { order "posted_on" } + # has_many :comments, -> { includes :author } + # has_many :people, -> { where(deleted: false).order("name") }, class_name: "Person" + # has_many :tracks, -> { order "position" }, dependent: :destroy + # has_many :comments, dependent: :nullify + # has_many :tags, as: :taggable + # has_many :reports, -> { readonly } + # has_many :subscribers, through: :subscriptions, source: :user + def has_many(name, scope = nil, options = {}, &extension) + reflection = Builder::HasMany.build(self, name, scope, options, &extension) + Reflection.add_reflection self, name, reflection + end + + # Specifies a one-to-one association with another class. This method should only be used + # if the other class contains the foreign key. If the current class contains the foreign key, + # then you should use +belongs_to+ instead. See also ActiveRecord::Associations::ClassMethods's overview + # on when to use +has_one+ and when to use +belongs_to+. + # + # The following methods for retrieval and query of a single associated object will be added: + # + # +association+ is a placeholder for the symbol passed as the +name+ argument, so + # has_one :manager would add among others manager.nil?. + # + # [association(force_reload = false)] + # Returns the associated object. +nil+ is returned if none is found. + # [association=(associate)] + # Assigns the associate object, extracts the primary key, sets it as the foreign key, + # and saves the associate object. To avoid database inconsistencies, permanently deletes an existing + # associated object when assigning a new one, even if the new one isn't saved to database. + # [build_association(attributes = {})] + # Returns a new object of the associated type that has been instantiated + # with +attributes+ and linked to this object through a foreign key, but has not + # yet been saved. + # [create_association(attributes = {})] + # Returns a new object of the associated type that has been instantiated + # with +attributes+, linked to this object through a foreign key, and that + # has already been saved (if it passed the validation). + # [create_association!(attributes = {})] + # Does the same as create_association, but raises ActiveRecord::RecordInvalid + # if the record is invalid. + # + # === Example + # + # An Account class declares has_one :beneficiary, which will add: + # * Account#beneficiary (similar to Beneficiary.where(account_id: id).first) + # * Account#beneficiary=(beneficiary) (similar to beneficiary.account_id = account.id; beneficiary.save) + # * Account#build_beneficiary (similar to Beneficiary.new("account_id" => id)) + # * Account#create_beneficiary (similar to b = Beneficiary.new("account_id" => id); b.save; b) + # * Account#create_beneficiary! (similar to b = Beneficiary.new("account_id" => id); b.save!; b) + # + # === Scopes + # + # You can pass a second argument +scope+ as a callable (i.e. proc or + # lambda) to retrieve a specific record or customize the generated query + # when you access the associated object. + # + # Scope examples: + # has_one :author, -> { where(comment_id: 1) } + # has_one :employer, -> { joins(:company) } + # has_one :dob, ->(dob) { where("Date.new(2000, 01, 01) > ?", dob) } + # + # === Options + # + # The declaration can also include an +options+ hash to specialize the behavior of the association. + # + # Options are: + # [:class_name] + # Specify the class name of the association. Use it only if that name can't be inferred + # from the association name. So has_one :manager will by default be linked to the Manager class, but + # if the real class name is Person, you'll have to specify it with this option. + # [:dependent] + # Controls what happens to the associated object when + # its owner is destroyed: + # + # * :destroy causes the associated object to also be destroyed + # * :delete causes the associated object to be deleted directly from the database (so callbacks will not execute) + # * :nullify causes the foreign key to be set to +NULL+. Callbacks are not executed. + # * :restrict_with_exception causes an exception to be raised if there is an associated record + # * :restrict_with_error causes an error to be added to the owner if there is an associated object + # [:foreign_key] + # Specify the foreign key used for the association. By default this is guessed to be the name + # of this class in lower-case and "_id" suffixed. So a Person class that makes a +has_one+ association + # will use "person_id" as the default :foreign_key. + # [:foreign_type] + # Specify the column used to store the associated object's type, if this is a polymorphic + # association. By default this is guessed to be the name of the polymorphic association + # specified on "as" option with a "_type" suffix. So a class that defines a + # has_one :tag, as: :taggable association will use "taggable_type" as the + # default :foreign_type. + # [:primary_key] + # Specify the method that returns the primary key used for the association. By default this is +id+. + # [:as] + # Specifies a polymorphic interface (See belongs_to). + # [:through] + # Specifies a Join Model through which to perform the query. Options for :class_name, + # :primary_key, and :foreign_key are ignored, as the association uses the + # source reflection. You can only use a :through query through a has_one + # or belongs_to association on the join model. + # [:source] + # Specifies the source association name used by has_one :through queries. + # Only use it if the name cannot be inferred from the association. + # has_one :favorite, through: :favorites will look for a + # :favorite on Favorite, unless a :source is given. + # [:source_type] + # Specifies type of the source association used by has_one :through queries where the source + # association is a polymorphic +belongs_to+. + # [:validate] + # If +false+, don't validate the associated object when saving the parent object. +false+ by default. + # [:autosave] + # If true, always save the associated object or destroy it if marked for destruction, + # when saving the parent object. If false, never save or destroy the associated object. + # By default, only save the associated object if it's a new record. + # + # Note that accepts_nested_attributes_for sets :autosave to true. + # [:inverse_of] + # Specifies the name of the belongs_to association on the associated object + # that is the inverse of this has_one association. Does not work in combination + # with :through or :as options. + # See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail. + # [:required] + # When set to +true+, the association will also have its presence validated. + # This will validate the association itself, not the id. You can use + # +:inverse_of+ to avoid an extra query during validation. + # + # Option examples: + # has_one :credit_card, dependent: :destroy # destroys the associated credit card + # has_one :credit_card, dependent: :nullify # updates the associated records foreign + # # key value to NULL rather than destroying it + # has_one :last_comment, -> { order 'posted_on' }, class_name: "Comment" + # has_one :project_manager, -> { where role: 'project_manager' }, class_name: "Person" + # has_one :attachment, as: :attachable + # has_one :boss, -> { readonly } + # has_one :club, through: :membership + # has_one :primary_address, -> { where primary: true }, through: :addressables, source: :addressable + # has_one :credit_card, required: true + def has_one(name, scope = nil, options = {}) + reflection = Builder::HasOne.build(self, name, scope, options) + Reflection.add_reflection self, name, reflection + end + + # Specifies a one-to-one association with another class. This method should only be used + # if this class contains the foreign key. If the other class contains the foreign key, + # then you should use +has_one+ instead. See also ActiveRecord::Associations::ClassMethods's overview + # on when to use +has_one+ and when to use +belongs_to+. + # + # Methods will be added for retrieval and query for a single associated object, for which + # this object holds an id: + # + # +association+ is a placeholder for the symbol passed as the +name+ argument, so + # belongs_to :author would add among others author.nil?. + # + # [association(force_reload = false)] + # Returns the associated object. +nil+ is returned if none is found. + # [association=(associate)] + # Assigns the associate object, extracts the primary key, and sets it as the foreign key. + # [build_association(attributes = {})] + # Returns a new object of the associated type that has been instantiated + # with +attributes+ and linked to this object through a foreign key, but has not yet been saved. + # [create_association(attributes = {})] + # Returns a new object of the associated type that has been instantiated + # with +attributes+, linked to this object through a foreign key, and that + # has already been saved (if it passed the validation). + # [create_association!(attributes = {})] + # Does the same as create_association, but raises ActiveRecord::RecordInvalid + # if the record is invalid. + # + # === Example + # + # A Post class declares belongs_to :author, which will add: + # * Post#author (similar to Author.find(author_id)) + # * Post#author=(author) (similar to post.author_id = author.id) + # * Post#build_author (similar to post.author = Author.new) + # * Post#create_author (similar to post.author = Author.new; post.author.save; post.author) + # * Post#create_author! (similar to post.author = Author.new; post.author.save!; post.author) + # The declaration can also include an +options+ hash to specialize the behavior of the association. + # + # === Scopes + # + # You can pass a second argument +scope+ as a callable (i.e. proc or + # lambda) to retrieve a specific record or customize the generated query + # when you access the associated object. + # + # Scope examples: + # belongs_to :user, -> { where(id: 2) } + # belongs_to :user, -> { joins(:friends) } + # belongs_to :level, ->(level) { where("game_level > ?", level.current) } + # + # === Options + # + # [:class_name] + # Specify the class name of the association. Use it only if that name can't be inferred + # from the association name. So belongs_to :author will by default be linked to the Author class, but + # if the real class name is Person, you'll have to specify it with this option. + # [:foreign_key] + # Specify the foreign key used for the association. By default this is guessed to be the name + # of the association with an "_id" suffix. So a class that defines a belongs_to :person + # association will use "person_id" as the default :foreign_key. Similarly, + # belongs_to :favorite_person, class_name: "Person" will use a foreign key + # of "favorite_person_id". + # [:foreign_type] + # Specify the column used to store the associated object's type, if this is a polymorphic + # association. By default this is guessed to be the name of the association with a "_type" + # suffix. So a class that defines a belongs_to :taggable, polymorphic: true + # association will use "taggable_type" as the default :foreign_type. + # [:primary_key] + # Specify the method that returns the primary key of associated object used for the association. + # By default this is id. + # [:dependent] + # If set to :destroy, the associated object is destroyed when this object is. If set to + # :delete, the associated object is deleted *without* calling its destroy method. + # This option should not be specified when belongs_to is used in conjunction with + # a has_many relationship on another class because of the potential to leave + # orphaned records behind. + # [:counter_cache] + # Caches the number of belonging objects on the associate class through the use of +increment_counter+ + # and +decrement_counter+. The counter cache is incremented when an object of this + # class is created and decremented when it's destroyed. This requires that a column + # named #{table_name}_count (such as +comments_count+ for a belonging Comment class) + # is used on the associate class (such as a Post class) - that is the migration for + # #{table_name}_count is created on the associate class (such that Post.comments_count will + # return the count cached, see note below). You can also specify a custom counter + # cache column by providing a column name instead of a +true+/+false+ value to this + # option (e.g., counter_cache: :my_custom_counter.) + # Note: Specifying a counter cache will add it to that model's list of readonly attributes + # using +attr_readonly+. + # [:polymorphic] + # Specify this association is a polymorphic association by passing +true+. + # Note: If you've enabled the counter cache, then you may want to add the counter cache attribute + # to the +attr_readonly+ list in the associated classes (e.g. class Post; attr_readonly :comments_count; end). + # [:validate] + # If +false+, don't validate the associated objects when saving the parent object. +false+ by default. + # [:autosave] + # If true, always save the associated object or destroy it if marked for destruction, when + # saving the parent object. + # If false, never save or destroy the associated object. + # By default, only save the associated object if it's a new record. + # + # Note that accepts_nested_attributes_for sets :autosave to true. + # [:touch] + # If true, the associated object will be touched (the updated_at/on attributes set to current time) + # when this record is either saved or destroyed. If you specify a symbol, that attribute + # will be updated with the current time in addition to the updated_at/on attribute. + # [:inverse_of] + # Specifies the name of the has_one or has_many association on the associated + # object that is the inverse of this belongs_to association. Does not work in + # combination with the :polymorphic options. + # See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail. + # [:required] + # When set to +true+, the association will also have its presence validated. + # This will validate the association itself, not the id. You can use + # +:inverse_of+ to avoid an extra query during validation. + # + # Option examples: + # belongs_to :firm, foreign_key: "client_of" + # belongs_to :person, primary_key: "name", foreign_key: "person_name" + # belongs_to :author, class_name: "Person", foreign_key: "author_id" + # belongs_to :valid_coupon, ->(o) { where "discounts > ?", o.payments_count }, + # class_name: "Coupon", foreign_key: "coupon_id" + # belongs_to :attachable, polymorphic: true + # belongs_to :project, -> { readonly } + # belongs_to :post, counter_cache: true + # belongs_to :company, touch: true + # belongs_to :company, touch: :employees_last_updated_at + # belongs_to :company, required: true + def belongs_to(name, scope = nil, options = {}) + reflection = Builder::BelongsTo.build(self, name, scope, options) + Reflection.add_reflection self, name, reflection + end + + # Specifies a many-to-many relationship with another class. This associates two classes via an + # intermediate join table. Unless the join table is explicitly specified as an option, it is + # guessed using the lexical order of the class names. So a join between Developer and Project + # will give the default join table name of "developers_projects" because "D" precedes "P" alphabetically. + # Note that this precedence is calculated using the < operator for String. This + # means that if the strings are of different lengths, and the strings are equal when compared + # up to the shortest length, then the longer string is considered of higher + # lexical precedence than the shorter one. For example, one would expect the tables "paper_boxes" and "papers" + # to generate a join table name of "papers_paper_boxes" because of the length of the name "paper_boxes", + # but it in fact generates a join table name of "paper_boxes_papers". Be aware of this caveat, and use the + # custom :join_table option if you need to. + # If your tables share a common prefix, it will only appear once at the beginning. For example, + # the tables "catalog_categories" and "catalog_products" generate a join table name of "catalog_categories_products". + # + # The join table should not have a primary key or a model associated with it. You must manually generate the + # join table with a migration such as this: + # + # class CreateDevelopersProjectsJoinTable < ActiveRecord::Migration + # def change + # create_table :developers_projects, id: false do |t| + # t.integer :developer_id + # t.integer :project_id + # end + # end + # end + # + # It's also a good idea to add indexes to each of those columns to speed up the joins process. + # However, in MySQL it is advised to add a compound index for both of the columns as MySQL only + # uses one index per table during the lookup. + # + # Adds the following methods for retrieval and query: + # + # +collection+ is a placeholder for the symbol passed as the +name+ argument, so + # has_and_belongs_to_many :categories would add among others categories.empty?. + # + # [collection(force_reload = false)] + # Returns an array of all the associated objects. + # An empty array is returned if none are found. + # [collection<<(object, ...)] + # Adds one or more objects to the collection by creating associations in the join table + # (collection.push and collection.concat are aliases to this method). + # Note that this operation instantly fires update SQL without waiting for the save or update call on the + # parent object, unless the parent object is a new record. + # [collection.delete(object, ...)] + # Removes one or more objects from the collection by removing their associations from the join table. + # This does not destroy the objects. + # [collection.destroy(object, ...)] + # Removes one or more objects from the collection by running destroy on each association in the join table, overriding any dependent option. + # This does not destroy the objects. + # [collection=objects] + # Replaces the collection's content by deleting and adding objects as appropriate. + # [collection_singular_ids] + # Returns an array of the associated objects' ids. + # [collection_singular_ids=ids] + # Replace the collection by the objects identified by the primary keys in +ids+. + # [collection.clear] + # Removes every object from the collection. This does not destroy the objects. + # [collection.empty?] + # Returns +true+ if there are no associated objects. + # [collection.size] + # Returns the number of associated objects. + # [collection.find(id)] + # Finds an associated object responding to the +id+ and that + # meets the condition that it has to be associated with this object. + # Uses the same rules as ActiveRecord::Base.find. + # [collection.exists?(...)] + # Checks whether an associated object with the given conditions exists. + # Uses the same rules as ActiveRecord::Base.exists?. + # [collection.build(attributes = {})] + # Returns a new object of the collection type that has been instantiated + # with +attributes+ and linked to this object through the join table, but has not yet been saved. + # [collection.create(attributes = {})] + # Returns a new object of the collection type that has been instantiated + # with +attributes+, linked to this object through the join table, and that has already been + # saved (if it passed the validation). + # + # === Example + # + # A Developer class declares has_and_belongs_to_many :projects, which will add: + # * Developer#projects + # * Developer#projects<< + # * Developer#projects.delete + # * Developer#projects.destroy + # * Developer#projects= + # * Developer#project_ids + # * Developer#project_ids= + # * Developer#projects.clear + # * Developer#projects.empty? + # * Developer#projects.size + # * Developer#projects.find(id) + # * Developer#projects.exists?(...) + # * Developer#projects.build (similar to Project.new("developer_id" => id)) + # * Developer#projects.create (similar to c = Project.new("developer_id" => id); c.save; c) + # The declaration may include an +options+ hash to specialize the behavior of the association. + # + # === Scopes + # + # You can pass a second argument +scope+ as a callable (i.e. proc or + # lambda) to retrieve a specific set of records or customize the generated + # query when you access the associated collection. + # + # Scope examples: + # has_and_belongs_to_many :projects, -> { includes :milestones, :manager } + # has_and_belongs_to_many :categories, ->(category) { + # where("default_category = ?", category.name) + # } + # + # === Extensions + # + # The +extension+ argument allows you to pass a block into a + # has_and_belongs_to_many association. This is useful for adding new + # finders, creators and other factory-type methods to be used as part of + # the association. + # + # Extension examples: + # has_and_belongs_to_many :contractors do + # def find_or_create_by_name(name) + # first_name, last_name = name.split(" ", 2) + # find_or_create_by(first_name: first_name, last_name: last_name) + # end + # end + # + # === Options + # + # [:class_name] + # Specify the class name of the association. Use it only if that name can't be inferred + # from the association name. So has_and_belongs_to_many :projects will by default be linked to the + # Project class, but if the real class name is SuperProject, you'll have to specify it with this option. + # [:join_table] + # Specify the name of the join table if the default based on lexical order isn't what you want. + # WARNING: If you're overwriting the table name of either class, the +table_name+ method + # MUST be declared underneath any +has_and_belongs_to_many+ declaration in order to work. + # [:foreign_key] + # Specify the foreign key used for the association. By default this is guessed to be the name + # of this class in lower-case and "_id" suffixed. So a Person class that makes + # a +has_and_belongs_to_many+ association to Project will use "person_id" as the + # default :foreign_key. + # [:association_foreign_key] + # Specify the foreign key used for the association on the receiving side of the association. + # By default this is guessed to be the name of the associated class in lower-case and "_id" suffixed. + # So if a Person class makes a +has_and_belongs_to_many+ association to Project, + # the association will use "project_id" as the default :association_foreign_key. + # [:readonly] + # If true, all the associated objects are readonly through the association. + # [:validate] + # If +false+, don't validate the associated objects when saving the parent object. +true+ by default. + # [:autosave] + # If true, always save the associated objects or destroy them if marked for destruction, when + # saving the parent object. + # If false, never save or destroy the associated objects. + # By default, only save associated objects that are new records. + # + # Note that accepts_nested_attributes_for sets :autosave to true. + # + # Option examples: + # has_and_belongs_to_many :projects + # has_and_belongs_to_many :projects, -> { includes :milestones, :manager } + # has_and_belongs_to_many :nations, class_name: "Country" + # has_and_belongs_to_many :categories, join_table: "prods_cats" + # has_and_belongs_to_many :categories, -> { readonly } + def has_and_belongs_to_many(name, scope = nil, options = {}, &extension) + if scope.is_a?(Hash) + options = scope + scope = nil + end + + habtm_reflection = ActiveRecord::Reflection::HasAndBelongsToManyReflection.new(name, scope, options, self) + + builder = Builder::HasAndBelongsToMany.new name, self, options + + join_model = builder.through_model + + # FIXME: we should move this to the internal constants. Also people + # should never directly access this constant so I'm not happy about + # setting it. + const_set join_model.name, join_model + + middle_reflection = builder.middle_reflection join_model + + Builder::HasMany.define_callbacks self, middle_reflection + Reflection.add_reflection self, middle_reflection.name, middle_reflection + middle_reflection.parent_reflection = [name.to_s, habtm_reflection] + + include Module.new { + class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def destroy_associations + association(:#{middle_reflection.name}).delete_all(:delete_all) + association(:#{name}).reset + super + end + RUBY + } + + hm_options = {} + hm_options[:through] = middle_reflection.name + hm_options[:source] = join_model.right_reflection.name + + [:before_add, :after_add, :before_remove, :after_remove, :autosave, :validate, :join_table, :class_name, :extend].each do |k| + hm_options[k] = options[k] if options.key? k + end + + has_many name, scope, hm_options, &extension + self._reflections[name.to_s].parent_reflection = [name.to_s, habtm_reflection] + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/alias_tracker.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/alias_tracker.rb new file mode 100644 index 0000000..0c3234e --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/alias_tracker.rb @@ -0,0 +1,87 @@ +require 'active_support/core_ext/string/conversions' + +module ActiveRecord + module Associations + # Keeps track of table aliases for ActiveRecord::Associations::ClassMethods::JoinDependency and + # ActiveRecord::Associations::ThroughAssociationScope + class AliasTracker # :nodoc: + attr_reader :aliases, :connection + + def self.empty(connection) + new connection, Hash.new(0) + end + + def self.create(connection, table_joins) + if table_joins.empty? + empty connection + else + aliases = Hash.new { |h,k| + h[k] = initial_count_for(connection, k, table_joins) + } + new connection, aliases + end + end + + def self.initial_count_for(connection, name, table_joins) + # quoted_name should be downcased as some database adapters (Oracle) return quoted name in uppercase + quoted_name = connection.quote_table_name(name).downcase + + counts = table_joins.map do |join| + if join.is_a?(Arel::Nodes::StringJoin) + # Table names + table aliases + join.left.downcase.scan( + /join(?:\s+\w+)?\s+(\S+\s+)?#{quoted_name}\son/ + ).size + elsif join.respond_to? :left + join.left.table_name == name ? 1 : 0 + else + # this branch is reached by two tests: + # + # activerecord/test/cases/associations/cascaded_eager_loading_test.rb:37 + # with :posts + # + # activerecord/test/cases/associations/eager_test.rb:1133 + # with :comments + # + 0 + end + end + + counts.sum + end + + # table_joins is an array of arel joins which might conflict with the aliases we assign here + def initialize(connection, aliases) + @aliases = aliases + @connection = connection + end + + def aliased_table_for(table_name, aliased_name) + if aliases[table_name].zero? + # If it's zero, we can have our table_name + aliases[table_name] = 1 + Arel::Table.new(table_name) + else + # Otherwise, we need to use an alias + aliased_name = connection.table_alias_for(aliased_name) + + # Update the count + aliases[aliased_name] += 1 + + table_alias = if aliases[aliased_name] > 1 + "#{truncate(aliased_name)}_#{aliases[aliased_name]}" + else + aliased_name + end + Arel::Table.new(table_name).alias(table_alias) + end + end + + private + + def truncate(name) + name.slice(0, connection.table_alias_length - 2) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/association.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/association.rb new file mode 100644 index 0000000..e7d97c6 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/association.rb @@ -0,0 +1,265 @@ +require 'active_support/core_ext/array/wrap' + +module ActiveRecord + module Associations + # = Active Record Associations + # + # This is the root class of all associations ('+ Foo' signifies an included module Foo): + # + # Association + # SingularAssociation + # HasOneAssociation + # HasOneThroughAssociation + ThroughAssociation + # BelongsToAssociation + # BelongsToPolymorphicAssociation + # CollectionAssociation + # HasManyAssociation + # HasManyThroughAssociation + ThroughAssociation + class Association #:nodoc: + attr_reader :owner, :target, :reflection + attr_accessor :inversed + + delegate :options, :to => :reflection + + def initialize(owner, reflection) + reflection.check_validity! + + @owner, @reflection = owner, reflection + + reset + reset_scope + end + + # Returns the name of the table of the associated class: + # + # post.comments.aliased_table_name # => "comments" + # + def aliased_table_name + klass.table_name + end + + # Resets the \loaded flag to +false+ and sets the \target to +nil+. + def reset + @loaded = false + @target = nil + @stale_state = nil + @inversed = false + end + + # Reloads the \target and returns +self+ on success. + def reload + reset + reset_scope + load_target + self unless target.nil? + end + + # Has the \target been already \loaded? + def loaded? + @loaded + end + + # Asserts the \target has been loaded setting the \loaded flag to +true+. + def loaded! + @loaded = true + @stale_state = stale_state + @inversed = false + end + + # The target is stale if the target no longer points to the record(s) that the + # relevant foreign_key(s) refers to. If stale, the association accessor method + # on the owner will reload the target. It's up to subclasses to implement the + # stale_state method if relevant. + # + # Note that if the target has not been loaded, it is not considered stale. + def stale_target? + !inversed && loaded? && @stale_state != stale_state + end + + # Sets the target of this association to \target, and the \loaded flag to +true+. + def target=(target) + @target = target + loaded! + end + + def scope + target_scope.merge(association_scope) + end + + # The scope for this association. + # + # Note that the association_scope is merged into the target_scope only when the + # scope method is called. This is because at that point the call may be surrounded + # by scope.scoping { ... } or with_scope { ... } etc, which affects the scope which + # actually gets built. + def association_scope + if klass + @association_scope ||= AssociationScope.scope(self, klass.connection) + end + end + + def reset_scope + @association_scope = nil + end + + # Set the inverse association, if possible + def set_inverse_instance(record) + if invertible_for?(record) + inverse = record.association(inverse_reflection_for(record).name) + inverse.target = owner + inverse.inversed = true + end + record + end + + # Returns the class of the target. belongs_to polymorphic overrides this to look at the + # polymorphic_type field on the owner. + def klass + reflection.klass + end + + # Can be overridden (i.e. in ThroughAssociation) to merge in other scopes (i.e. the + # through association's scope) + def target_scope + AssociationRelation.create(klass, klass.arel_table, self).merge!(klass.all) + end + + # Loads the \target if needed and returns it. + # + # This method is abstract in the sense that it relies on +find_target+, + # which is expected to be provided by descendants. + # + # If the \target is already \loaded it is just returned. Thus, you can call + # +load_target+ unconditionally to get the \target. + # + # ActiveRecord::RecordNotFound is rescued within the method, and it is + # not reraised. The proxy is \reset and +nil+ is the return value. + def load_target + @target = find_target if (@stale_state && stale_target?) || find_target? + + loaded! unless loaded? + target + rescue ActiveRecord::RecordNotFound + reset + end + + def interpolate(sql, record = nil) + if sql.respond_to?(:to_proc) + owner.instance_exec(record, &sql) + else + sql + end + end + + # We can't dump @reflection since it contains the scope proc + def marshal_dump + ivars = (instance_variables - [:@reflection]).map { |name| [name, instance_variable_get(name)] } + [@reflection.name, ivars] + end + + def marshal_load(data) + reflection_name, ivars = data + ivars.each { |name, val| instance_variable_set(name, val) } + @reflection = @owner.class._reflect_on_association(reflection_name) + end + + def initialize_attributes(record) #:nodoc: + skip_assign = [reflection.foreign_key, reflection.type].compact + attributes = create_scope.except(*(record.changed - skip_assign)) + record.assign_attributes(attributes) + set_inverse_instance(record) + end + + private + + def find_target? + !loaded? && (!owner.new_record? || foreign_key_present?) && klass + end + + def creation_attributes + attributes = {} + + if (reflection.has_one? || reflection.collection?) && !options[:through] + attributes[reflection.foreign_key] = owner[reflection.active_record_primary_key] + + if reflection.options[:as] + attributes[reflection.type] = owner.class.base_class.name + end + end + + attributes + end + + # Sets the owner attributes on the given record + def set_owner_attributes(record) + creation_attributes.each { |key, value| record[key] = value } + end + + # Returns true if there is a foreign key present on the owner which + # references the target. This is used to determine whether we can load + # the target if the owner is currently a new record (and therefore + # without a key). If the owner is a new record then foreign_key must + # be present in order to load target. + # + # Currently implemented by belongs_to (vanilla and polymorphic) and + # has_one/has_many :through associations which go through a belongs_to. + def foreign_key_present? + false + end + + # Raises ActiveRecord::AssociationTypeMismatch unless +record+ is of + # the kind of the class of the associated objects. Meant to be used as + # a sanity check when you are about to assign an associated record. + def raise_on_type_mismatch!(record) + unless record.is_a?(reflection.klass) + fresh_class = reflection.class_name.safe_constantize + unless fresh_class && record.is_a?(fresh_class) + message = "#{reflection.class_name}(##{reflection.klass.object_id}) expected, got #{record.class}(##{record.class.object_id})" + raise ActiveRecord::AssociationTypeMismatch, message + end + end + end + + # Can be redefined by subclasses, notably polymorphic belongs_to + # The record parameter is necessary to support polymorphic inverses as we must check for + # the association in the specific class of the record. + def inverse_reflection_for(record) + reflection.inverse_of + end + + # Returns true if inverse association on the given record needs to be set. + # This method is redefined by subclasses. + def invertible_for?(record) + foreign_key_for?(record) && inverse_reflection_for(record) + end + + # Returns true if record contains the foreign_key + def foreign_key_for?(record) + record.has_attribute?(reflection.foreign_key) + end + + # This should be implemented to return the values of the relevant key(s) on the owner, + # so that when stale_state is different from the value stored on the last find_target, + # the target is stale. + # + # This is only relevant to certain associations, which is why it returns nil by default. + def stale_state + end + + def build_record(attributes) + reflection.build_association(attributes) do |record| + initialize_attributes(record) + end + end + + # Returns true if statement cache should be skipped on the association reader. + def skip_statement_cache? + reflection.scope_chain.any?(&:any?) || + scope.eager_loading? || + klass.current_scope || + klass.default_scopes.any? || + reflection.source_reflection.active_record.default_scopes.any? + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/association_scope.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/association_scope.rb new file mode 100644 index 0000000..db51e0e --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/association_scope.rb @@ -0,0 +1,195 @@ +module ActiveRecord + module Associations + class AssociationScope #:nodoc: + def self.scope(association, connection) + INSTANCE.scope association, connection + end + + class BindSubstitution + def initialize(block) + @block = block + end + + def bind_value(scope, column, value, alias_tracker) + substitute = alias_tracker.connection.substitute_at(column) + scope.bind_values += [[column, @block.call(value)]] + substitute + end + end + + def self.create(&block) + block = block ? block : lambda { |val| val } + new BindSubstitution.new(block) + end + + def initialize(bind_substitution) + @bind_substitution = bind_substitution + end + + INSTANCE = create + + def scope(association, connection) + klass = association.klass + reflection = association.reflection + scope = klass.unscoped + owner = association.owner + alias_tracker = AliasTracker.empty connection + + scope.extending! Array(reflection.options[:extend]) + add_constraints(scope, owner, klass, reflection, alias_tracker) + end + + def join_type + Arel::Nodes::InnerJoin + end + + def self.get_bind_values(owner, chain) + binds = [] + last_reflection = chain.last + + binds << last_reflection.join_id_for(owner) + if last_reflection.type + binds << owner.class.base_class.name + end + + chain.each_cons(2).each do |reflection, next_reflection| + if reflection.type + binds << next_reflection.klass.base_class.name + end + end + binds + end + + private + + def construct_tables(chain, klass, refl, alias_tracker) + chain.map do |reflection| + alias_tracker.aliased_table_for( + table_name_for(reflection, klass, refl), + table_alias_for(reflection, refl, reflection != refl) + ) + end + end + + def table_alias_for(reflection, refl, join = false) + name = "#{reflection.plural_name}_#{alias_suffix(refl)}" + name << "_join" if join + name + end + + def join(table, constraint) + table.create_join(table, table.create_on(constraint), join_type) + end + + def column_for(table_name, column_name, alias_tracker) + columns = alias_tracker.connection.schema_cache.columns_hash(table_name) + columns[column_name] + end + + def bind_value(scope, column, value, alias_tracker) + @bind_substitution.bind_value scope, column, value, alias_tracker + end + + def bind(scope, table_name, column_name, value, tracker) + column = column_for table_name, column_name, tracker + bind_value scope, column, value, tracker + end + + def last_chain_scope(scope, table, reflection, owner, tracker, assoc_klass) + join_keys = reflection.join_keys(assoc_klass) + key = join_keys.key + foreign_key = join_keys.foreign_key + + bind_val = bind scope, table.table_name, key.to_s, owner[foreign_key], tracker + scope = scope.where(table[key].eq(bind_val)) + + if reflection.type + value = owner.class.base_class.name + bind_val = bind scope, table.table_name, reflection.type, value, tracker + scope = scope.where(table[reflection.type].eq(bind_val)) + else + scope + end + end + + def next_chain_scope(scope, table, reflection, tracker, assoc_klass, foreign_table, next_reflection) + join_keys = reflection.join_keys(assoc_klass) + key = join_keys.key + foreign_key = join_keys.foreign_key + + constraint = table[key].eq(foreign_table[foreign_key]) + + if reflection.type + value = next_reflection.klass.base_class.name + bind_val = bind scope, table.table_name, reflection.type, value, tracker + scope = scope.where(table[reflection.type].eq(bind_val)) + end + + scope = scope.joins(join(foreign_table, constraint)) + end + + def add_constraints(scope, owner, assoc_klass, refl, tracker) + chain = refl.chain + scope_chain = refl.scope_chain + + tables = construct_tables(chain, assoc_klass, refl, tracker) + + owner_reflection = chain.last + table = tables.last + scope = last_chain_scope(scope, table, owner_reflection, owner, tracker, assoc_klass) + + chain.each_with_index do |reflection, i| + table, foreign_table = tables.shift, tables.first + + unless reflection == chain.last + next_reflection = chain[i + 1] + scope = next_chain_scope(scope, table, reflection, tracker, assoc_klass, foreign_table, next_reflection) + end + + is_first_chain = i == 0 + klass = is_first_chain ? assoc_klass : reflection.klass + + # Exclude the scope of the association itself, because that + # was already merged in the #scope method. + scope_chain[i].each do |scope_chain_item| + item = eval_scope(klass, scope_chain_item, owner) + + if scope_chain_item == refl.scope + scope.merge! item.except(:where, :includes, :bind) + end + + if is_first_chain + scope.includes! item.includes_values + end + + scope.unscope!(*item.unscope_values) + scope.where_values += item.where_values + scope.bind_values += item.bind_values + scope.order_values |= item.order_values + end + end + + scope + end + + def alias_suffix(refl) + refl.name + end + + def table_name_for(reflection, klass, refl) + if reflection == refl + # If this is a polymorphic belongs_to, we want to get the klass from the + # association because it depends on the polymorphic_type attribute of + # the owner + klass.table_name + else + reflection.table_name + end + end + + def eval_scope(klass, scope, owner) + klass.unscoped.instance_exec(owner, &scope) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/belongs_to_association.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/belongs_to_association.rb new file mode 100644 index 0000000..0b6c803 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/belongs_to_association.rb @@ -0,0 +1,119 @@ +module ActiveRecord + # = Active Record Belongs To Association + module Associations + class BelongsToAssociation < SingularAssociation #:nodoc: + + def handle_dependency + target.send(options[:dependent]) if load_target + end + + def replace(record) + if record + raise_on_type_mismatch!(record) + update_counters(record) + replace_keys(record) + set_inverse_instance(record) + @updated = true + else + decrement_counters + remove_keys + end + + self.target = record + end + + def reset + super + @updated = false + end + + def updated? + @updated + end + + def decrement_counters # :nodoc: + with_cache_name { |name| decrement_counter name } + end + + def increment_counters # :nodoc: + with_cache_name { |name| increment_counter name } + end + + private + + def find_target? + !loaded? && foreign_key_present? && klass + end + + def with_cache_name + counter_cache_name = reflection.counter_cache_column + return unless counter_cache_name && owner.persisted? + yield counter_cache_name + end + + def update_counters(record) + with_cache_name do |name| + return unless different_target? record + record.class.increment_counter(name, record.id) + decrement_counter name + end + end + + def decrement_counter(counter_cache_name) + if foreign_key_present? + klass.decrement_counter(counter_cache_name, target_id) + end + end + + def increment_counter(counter_cache_name) + if foreign_key_present? + klass.increment_counter(counter_cache_name, target_id) + if target && !stale_target? && counter_cache_available_in_memory?(counter_cache_name) + target.increment(counter_cache_name) + end + end + end + + # Checks whether record is different to the current target, without loading it + def different_target?(record) + record.id != owner._read_attribute(reflection.foreign_key) + end + + def replace_keys(record) + owner[reflection.foreign_key] = record._read_attribute(reflection.association_primary_key(record.class)) + end + + def remove_keys + owner[reflection.foreign_key] = nil + end + + def foreign_key_present? + owner._read_attribute(reflection.foreign_key) + end + + # NOTE - for now, we're only supporting inverse setting from belongs_to back onto + # has_one associations. + def invertible_for?(record) + inverse = inverse_reflection_for(record) + inverse && inverse.has_one? + end + + def target_id + if options[:primary_key] + owner.send(reflection.name).try(:id) + else + owner._read_attribute(reflection.foreign_key) + end + end + + def stale_state + result = owner._read_attribute(reflection.foreign_key) + result && result.to_s + end + + def counter_cache_available_in_memory?(counter_cache_name) + target.respond_to?(counter_cache_name) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/belongs_to_polymorphic_association.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/belongs_to_polymorphic_association.rb new file mode 100644 index 0000000..b710cf6 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/belongs_to_polymorphic_association.rb @@ -0,0 +1,40 @@ +module ActiveRecord + # = Active Record Belongs To Polymorphic Association + module Associations + class BelongsToPolymorphicAssociation < BelongsToAssociation #:nodoc: + def klass + type = owner[reflection.foreign_type] + type.presence && type.constantize + end + + private + + def replace_keys(record) + super + owner[reflection.foreign_type] = record.class.base_class.name + end + + def remove_keys + super + owner[reflection.foreign_type] = nil + end + + def different_target?(record) + super || record.class != klass + end + + def inverse_reflection_for(record) + reflection.polymorphic_inverse_of(record.class) + end + + def raise_on_type_mismatch!(record) + # A polymorphic association cannot have a type mismatch, by definition + end + + def stale_state + foreign_key = super + foreign_key && [foreign_key.to_s, owner[reflection.foreign_type].to_s] + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/builder/association.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/builder/association.rb new file mode 100644 index 0000000..c11f535 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/builder/association.rb @@ -0,0 +1,149 @@ +require 'active_support/core_ext/module/attribute_accessors' + +# This is the parent Association class which defines the variables +# used by all associations. +# +# The hierarchy is defined as follows: +# Association +# - SingularAssociation +# - BelongsToAssociation +# - HasOneAssociation +# - CollectionAssociation +# - HasManyAssociation + +module ActiveRecord::Associations::Builder + class Association #:nodoc: + class << self + attr_accessor :extensions + # TODO: This class accessor is needed to make activerecord-deprecated_finders work. + # We can move it to a constant in 5.0. + attr_accessor :valid_options + end + self.extensions = [] + + self.valid_options = [:class_name, :anonymous_class, :foreign_key, :validate] + + attr_reader :name, :scope, :options + + def self.build(model, name, scope, options, &block) + if model.dangerous_attribute_method?(name) + raise ArgumentError, "You tried to define an association named #{name} on the model #{model.name}, but " \ + "this will conflict with a method #{name} already defined by Active Record. " \ + "Please choose a different association name." + end + + builder = create_builder model, name, scope, options, &block + reflection = builder.build(model) + define_accessors model, reflection + define_callbacks model, reflection + define_validations model, reflection + builder.define_extensions model + reflection + end + + def self.create_builder(model, name, scope, options, &block) + raise ArgumentError, "association names must be a Symbol" unless name.kind_of?(Symbol) + + new(model, name, scope, options, &block) + end + + def initialize(model, name, scope, options) + # TODO: Move this to create_builder as soon we drop support to activerecord-deprecated_finders. + if scope.is_a?(Hash) + options = scope + scope = nil + end + + # TODO: Remove this model argument as soon we drop support to activerecord-deprecated_finders. + @name = name + @scope = scope + @options = options + + validate_options + + if scope && scope.arity == 0 + @scope = proc { instance_exec(&scope) } + end + end + + def build(model) + ActiveRecord::Reflection.create(macro, name, scope, options, model) + end + + def macro + raise NotImplementedError + end + + def valid_options + Association.valid_options + Association.extensions.flat_map(&:valid_options) + end + + def validate_options + options.assert_valid_keys(valid_options) + end + + def define_extensions(model) + end + + def self.define_callbacks(model, reflection) + if dependent = reflection.options[:dependent] + check_dependent_options(dependent) + add_destroy_callbacks(model, reflection) + end + + Association.extensions.each do |extension| + extension.build model, reflection + end + end + + # Defines the setter and getter methods for the association + # class Post < ActiveRecord::Base + # has_many :comments + # end + # + # Post.first.comments and Post.first.comments= methods are defined by this method... + def self.define_accessors(model, reflection) + mixin = model.generated_association_methods + name = reflection.name + define_readers(mixin, name) + define_writers(mixin, name) + end + + def self.define_readers(mixin, name) + mixin.class_eval <<-CODE, __FILE__, __LINE__ + 1 + def #{name}(*args) + association(:#{name}).reader(*args) + end + CODE + end + + def self.define_writers(mixin, name) + mixin.class_eval <<-CODE, __FILE__, __LINE__ + 1 + def #{name}=(value) + association(:#{name}).writer(value) + end + CODE + end + + def self.define_validations(model, reflection) + # noop + end + + def self.valid_dependent_options + raise NotImplementedError + end + + private + + def self.check_dependent_options(dependent) + unless valid_dependent_options.include? dependent + raise ArgumentError, "The :dependent option must be one of #{valid_dependent_options}, but is :#{dependent}" + end + end + + def self.add_destroy_callbacks(model, reflection) + name = reflection.name + model.before_destroy lambda { |o| o.association(name).handle_dependency } + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/builder/belongs_to.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/builder/belongs_to.rb new file mode 100644 index 0000000..954ea38 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/builder/belongs_to.rb @@ -0,0 +1,116 @@ +module ActiveRecord::Associations::Builder + class BelongsTo < SingularAssociation #:nodoc: + def macro + :belongs_to + end + + def valid_options + super + [:foreign_type, :polymorphic, :touch, :counter_cache] + end + + def self.valid_dependent_options + [:destroy, :delete] + end + + def self.define_callbacks(model, reflection) + super + add_counter_cache_callbacks(model, reflection) if reflection.options[:counter_cache] + add_touch_callbacks(model, reflection) if reflection.options[:touch] + end + + def self.define_accessors(mixin, reflection) + super + add_counter_cache_methods mixin + end + + private + + def self.add_counter_cache_methods(mixin) + return if mixin.method_defined? :belongs_to_counter_cache_after_update + + mixin.class_eval do + def belongs_to_counter_cache_after_update(reflection) + foreign_key = reflection.foreign_key + cache_column = reflection.counter_cache_column + + if (@_after_create_counter_called ||= false) + @_after_create_counter_called = false + elsif attribute_changed?(foreign_key) && !new_record? && reflection.constructable? + model = reflection.klass + foreign_key_was = attribute_was foreign_key + foreign_key = attribute foreign_key + + if foreign_key && model.respond_to?(:increment_counter) + model.increment_counter(cache_column, foreign_key) + end + if foreign_key_was && model.respond_to?(:decrement_counter) + model.decrement_counter(cache_column, foreign_key_was) + end + end + end + end + end + + def self.add_counter_cache_callbacks(model, reflection) + cache_column = reflection.counter_cache_column + + model.after_update lambda { |record| + record.belongs_to_counter_cache_after_update(reflection) + } + + klass = reflection.class_name.safe_constantize + klass.attr_readonly cache_column if klass && klass.respond_to?(:attr_readonly) + end + + def self.touch_record(o, foreign_key, name, touch) # :nodoc: + old_foreign_id = o.changed_attributes[foreign_key] + + if old_foreign_id + association = o.association(name) + reflection = association.reflection + if reflection.polymorphic? + klass = o.public_send("#{reflection.foreign_type}_was").constantize + else + klass = association.klass + end + old_record = klass.find_by(klass.primary_key => old_foreign_id) + + if old_record + if touch != true + old_record.touch touch + else + old_record.touch + end + end + end + + record = o.send name + if record && record.persisted? + if touch != true + record.touch touch + else + record.touch + end + end + end + + def self.add_touch_callbacks(model, reflection) + foreign_key = reflection.foreign_key + n = reflection.name + touch = reflection.options[:touch] + + callback = lambda { |record| + BelongsTo.touch_record(record, foreign_key, n, touch) + } + + model.after_save callback, if: :changed? + model.after_touch callback + model.after_destroy callback + end + + def self.add_destroy_callbacks(model, reflection) + name = reflection.name + model.after_destroy lambda { |o| o.association(name).handle_dependency } + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/builder/collection_association.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/builder/collection_association.rb new file mode 100644 index 0000000..9f76e25 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/builder/collection_association.rb @@ -0,0 +1,95 @@ +# This class is inherited by the has_many and has_many_and_belongs_to_many association classes + +require 'active_record/associations' + +module ActiveRecord::Associations::Builder + class CollectionAssociation < Association #:nodoc: + + CALLBACKS = [:before_add, :after_add, :before_remove, :after_remove] + + def valid_options + super + [:table_name, :before_add, + :after_add, :before_remove, :after_remove, :extend] + end + + attr_reader :block_extension + + def initialize(model, name, scope, options) + super + @mod = nil + if block_given? + @mod = Module.new(&Proc.new) + @scope = wrap_scope @scope, @mod + end + end + + def self.define_callbacks(model, reflection) + super + name = reflection.name + options = reflection.options + CALLBACKS.each { |callback_name| + define_callback(model, callback_name, name, options) + } + end + + def define_extensions(model) + if @mod + extension_module_name = "#{model.name.demodulize}#{name.to_s.camelize}AssociationExtension" + model.parent.const_set(extension_module_name, @mod) + end + end + + def self.define_callback(model, callback_name, name, options) + full_callback_name = "#{callback_name}_for_#{name}" + + # TODO : why do i need method_defined? I think its because of the inheritance chain + model.class_attribute full_callback_name unless model.method_defined?(full_callback_name) + callbacks = Array(options[callback_name.to_sym]).map do |callback| + case callback + when Symbol + ->(method, owner, record) { owner.send(callback, record) } + when Proc + ->(method, owner, record) { callback.call(owner, record) } + else + ->(method, owner, record) { callback.send(method, owner, record) } + end + end + model.send "#{full_callback_name}=", callbacks + end + + # Defines the setter and getter methods for the collection_singular_ids. + def self.define_readers(mixin, name) + super + + mixin.class_eval <<-CODE, __FILE__, __LINE__ + 1 + def #{name.to_s.singularize}_ids + association(:#{name}).ids_reader + end + CODE + end + + def self.define_writers(mixin, name) + super + + mixin.class_eval <<-CODE, __FILE__, __LINE__ + 1 + def #{name.to_s.singularize}_ids=(ids) + association(:#{name}).ids_writer(ids) + end + CODE + end + + private + + def wrap_scope(scope, mod) + if scope + if scope.arity > 0 + proc { |owner| instance_exec(owner, &scope).extending(mod) } + else + proc { instance_exec(&scope).extending(mod) } + end + else + proc { extending(mod) } + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/builder/has_and_belongs_to_many.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/builder/has_and_belongs_to_many.rb new file mode 100644 index 0000000..3ae6e0d --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/builder/has_and_belongs_to_many.rb @@ -0,0 +1,128 @@ +module ActiveRecord::Associations::Builder + class HasAndBelongsToMany # :nodoc: + class JoinTableResolver + KnownTable = Struct.new :join_table + + class KnownClass + def initialize(lhs_class, rhs_class_name) + @lhs_class = lhs_class + @rhs_class_name = rhs_class_name + @join_table = nil + end + + def join_table + @join_table ||= [@lhs_class.table_name, klass.table_name].sort.join("\0").gsub(/^(.*[._])(.+)\0\1(.+)/, '\1\2_\3').tr("\0", "_") + end + + private + + def klass + @lhs_class.send(:compute_type, @rhs_class_name) + end + end + + def self.build(lhs_class, name, options) + if options[:join_table] + KnownTable.new options[:join_table].to_s + else + class_name = options.fetch(:class_name) { + name.to_s.camelize.singularize + } + KnownClass.new lhs_class, class_name + end + end + end + + attr_reader :lhs_model, :association_name, :options + + def initialize(association_name, lhs_model, options) + @association_name = association_name + @lhs_model = lhs_model + @options = options + end + + def through_model + habtm = JoinTableResolver.build lhs_model, association_name, options + + join_model = Class.new(ActiveRecord::Base) { + class << self; + attr_accessor :left_model + attr_accessor :name + attr_accessor :table_name_resolver + attr_accessor :left_reflection + attr_accessor :right_reflection + end + + def self.table_name + table_name_resolver.join_table + end + + def self.compute_type(class_name) + left_model.compute_type class_name + end + + def self.add_left_association(name, options) + belongs_to name, options + self.left_reflection = _reflect_on_association(name) + end + + def self.add_right_association(name, options) + rhs_name = name.to_s.singularize.to_sym + belongs_to rhs_name, options + self.right_reflection = _reflect_on_association(rhs_name) + end + + def self.retrieve_connection + left_model.retrieve_connection + end + + } + + join_model.name = "HABTM_#{association_name.to_s.camelize}" + join_model.table_name_resolver = habtm + join_model.left_model = lhs_model + + join_model.add_left_association :left_side, anonymous_class: lhs_model + join_model.add_right_association association_name, belongs_to_options(options) + join_model + end + + def middle_reflection(join_model) + middle_name = [lhs_model.name.downcase.pluralize, + association_name].join('_').gsub(/::/, '_').to_sym + middle_options = middle_options join_model + hm_builder = HasMany.create_builder(lhs_model, + middle_name, + nil, + middle_options) + hm_builder.build lhs_model + end + + private + + def middle_options(join_model) + middle_options = {} + middle_options[:class_name] = "#{lhs_model.name}::#{join_model.name}" + middle_options[:source] = join_model.left_reflection.name + if options.key? :foreign_key + middle_options[:foreign_key] = options[:foreign_key] + end + middle_options + end + + def belongs_to_options(options) + rhs_options = {} + + if options.key? :class_name + rhs_options[:foreign_key] = options[:class_name].to_s.foreign_key + rhs_options[:class_name] = options[:class_name] + end + + if options.key? :association_foreign_key + rhs_options[:foreign_key] = options[:association_foreign_key] + end + + rhs_options + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/builder/has_many.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/builder/has_many.rb new file mode 100644 index 0000000..1b87f92 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/builder/has_many.rb @@ -0,0 +1,15 @@ +module ActiveRecord::Associations::Builder + class HasMany < CollectionAssociation #:nodoc: + def macro + :has_many + end + + def valid_options + super + [:primary_key, :dependent, :as, :through, :source, :source_type, :inverse_of, :counter_cache, :join_table, :foreign_type] + end + + def self.valid_dependent_options + [:destroy, :delete_all, :nullify, :restrict_with_error, :restrict_with_exception] + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/builder/has_one.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/builder/has_one.rb new file mode 100644 index 0000000..1387717 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/builder/has_one.rb @@ -0,0 +1,23 @@ +module ActiveRecord::Associations::Builder + class HasOne < SingularAssociation #:nodoc: + def macro + :has_one + end + + def valid_options + valid = super + [:as, :foreign_type] + valid += [:through, :source, :source_type] if options[:through] + valid + end + + def self.valid_dependent_options + [:destroy, :delete, :nullify, :restrict_with_error, :restrict_with_exception] + end + + private + + def self.add_destroy_callbacks(model, reflection) + super unless reflection.options[:through] + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/builder/singular_association.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/builder/singular_association.rb new file mode 100644 index 0000000..6e6dd72 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/builder/singular_association.rb @@ -0,0 +1,38 @@ +# This class is inherited by the has_one and belongs_to association classes + +module ActiveRecord::Associations::Builder + class SingularAssociation < Association #:nodoc: + def valid_options + super + [:dependent, :primary_key, :inverse_of, :required] + end + + def self.define_accessors(model, reflection) + super + define_constructors(model.generated_association_methods, reflection.name) if reflection.constructable? + end + + # Defines the (build|create)_association methods for belongs_to or has_one association + def self.define_constructors(mixin, name) + mixin.class_eval <<-CODE, __FILE__, __LINE__ + 1 + def build_#{name}(*args, &block) + association(:#{name}).build(*args, &block) + end + + def create_#{name}(*args, &block) + association(:#{name}).create(*args, &block) + end + + def create_#{name}!(*args, &block) + association(:#{name}).create!(*args, &block) + end + CODE + end + + def self.define_validations(model, reflection) + super + if reflection.options[:required] + model.validates_presence_of reflection.name + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/collection_association.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/collection_association.rb new file mode 100644 index 0000000..f3d3186 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/collection_association.rb @@ -0,0 +1,643 @@ +module ActiveRecord + module Associations + # = Active Record Association Collection + # + # CollectionAssociation is an abstract class that provides common stuff to + # ease the implementation of association proxies that represent + # collections. See the class hierarchy in Association. + # + # CollectionAssociation: + # HasManyAssociation => has_many + # HasManyThroughAssociation + ThroughAssociation => has_many :through + # + # CollectionAssociation class provides common methods to the collections + # defined by +has_and_belongs_to_many+, +has_many+ or +has_many+ with + # +:through association+ option. + # + # You need to be careful with assumptions regarding the target: The proxy + # does not fetch records from the database until it needs them, but new + # ones created with +build+ are added to the target. So, the target may be + # non-empty and still lack children waiting to be read from the database. + # If you look directly to the database you cannot assume that's the entire + # collection because new records may have been added to the target, etc. + # + # If you need to work on all current children, new and existing records, + # +load_target+ and the +loaded+ flag are your friends. + class CollectionAssociation < Association #:nodoc: + + # Implements the reader method, e.g. foo.items for Foo.has_many :items + def reader(force_reload = false) + if force_reload + klass.uncached { reload } + elsif stale_target? + reload + end + + if owner.new_record? + # Cache the proxy separately before the owner has an id + # or else a post-save proxy will still lack the id + @new_record_proxy ||= CollectionProxy.create(klass, self) + else + @proxy ||= CollectionProxy.create(klass, self) + end + end + + # Implements the writer method, e.g. foo.items= for Foo.has_many :items + def writer(records) + replace(records) + end + + # Implements the ids reader method, e.g. foo.item_ids for Foo.has_many :items + def ids_reader + if loaded? + load_target.map do |record| + record.send(reflection.association_primary_key) + end + else + column = "#{reflection.quoted_table_name}.#{reflection.association_primary_key}" + scope.pluck(column) + end + end + + # Implements the ids writer method, e.g. foo.item_ids= for Foo.has_many :items + def ids_writer(ids) + pk_type = reflection.primary_key_type + ids = Array(ids).reject { |id| id.blank? } + ids.map! { |i| pk_type.type_cast_from_user(i) } + replace(klass.find(ids).index_by { |r| r.id }.values_at(*ids)) + end + + def reset + super + @target = [] + end + + def select(*fields) + if block_given? + load_target.select.each { |e| yield e } + else + scope.select(*fields) + end + end + + def find(*args) + if block_given? + load_target.find(*args) { |*block_args| yield(*block_args) } + else + if options[:inverse_of] && loaded? + args_flatten = args.flatten + raise RecordNotFound, "Couldn't find #{scope.klass.name} without an ID" if args_flatten.blank? + result = find_by_scan(*args) + + result_size = Array(result).size + if !result || result_size != args_flatten.size + scope.raise_record_not_found_exception!(args_flatten, result_size, args_flatten.size) + else + result + end + else + scope.find(*args) + end + end + end + + def first(*args) + first_nth_or_last(:first, *args) + end + + def second(*args) + first_nth_or_last(:second, *args) + end + + def third(*args) + first_nth_or_last(:third, *args) + end + + def fourth(*args) + first_nth_or_last(:fourth, *args) + end + + def fifth(*args) + first_nth_or_last(:fifth, *args) + end + + def forty_two(*args) + first_nth_or_last(:forty_two, *args) + end + + def last(*args) + first_nth_or_last(:last, *args) + end + + def take(n = nil) + if loaded? + n ? target.take(n) : target.first + else + scope.take(n).tap do |record| + set_inverse_instance record if record.is_a? ActiveRecord::Base + end + end + end + + def build(attributes = {}, &block) + if attributes.is_a?(Array) + attributes.collect { |attr| build(attr, &block) } + else + add_to_target(build_record(attributes)) do |record| + yield(record) if block_given? + end + end + end + + def create(attributes = {}, &block) + _create_record(attributes, &block) + end + + def create!(attributes = {}, &block) + _create_record(attributes, true, &block) + end + + # Add +records+ to this association. Returns +self+ so method calls may + # be chained. Since << flattens its argument list and inserts each record, + # +push+ and +concat+ behave identically. + def concat(*records) + if owner.new_record? + load_target + concat_records(records) + else + transaction { concat_records(records) } + end + end + + # Starts a transaction in the association class's database connection. + # + # class Author < ActiveRecord::Base + # has_many :books + # end + # + # Author.first.books.transaction do + # # same effect as calling Book.transaction + # end + def transaction(*args) + reflection.klass.transaction(*args) do + yield + end + end + + # Removes all records from the association without calling callbacks + # on the associated records. It honors the +:dependent+ option. However + # if the +:dependent+ value is +:destroy+ then in that case the +:delete_all+ + # deletion strategy for the association is applied. + # + # You can force a particular deletion strategy by passing a parameter. + # + # Example: + # + # @author.books.delete_all(:nullify) + # @author.books.delete_all(:delete_all) + # + # See delete for more info. + def delete_all(dependent = nil) + if dependent && ![:nullify, :delete_all].include?(dependent) + raise ArgumentError, "Valid values are :nullify or :delete_all" + end + + dependent = if dependent + dependent + elsif options[:dependent] == :destroy + :delete_all + else + options[:dependent] + end + + delete_or_nullify_all_records(dependent).tap do + reset + loaded! + end + end + + # Destroy all the records from this association. + # + # See destroy for more info. + def destroy_all + destroy(load_target).tap do + reset + loaded! + end + end + + # Count all records using SQL. Construct options and pass them with + # scope to the target class's +count+. + def count(column_name = nil, count_options = {}) + # TODO: Remove count_options argument as soon we remove support to + # activerecord-deprecated_finders. + column_name, count_options = nil, column_name if column_name.is_a?(Hash) + + relation = scope + if association_scope.distinct_value + # This is needed because 'SELECT count(DISTINCT *)..' is not valid SQL. + column_name ||= reflection.klass.primary_key + relation = relation.distinct + end + + value = relation.count(column_name) + + limit = options[:limit] + offset = options[:offset] + + if limit || offset + [ [value - offset.to_i, 0].max, limit.to_i ].min + else + value + end + end + + # Removes +records+ from this association calling +before_remove+ and + # +after_remove+ callbacks. + # + # This method is abstract in the sense that +delete_records+ has to be + # provided by descendants. Note this method does not imply the records + # are actually removed from the database, that depends precisely on + # +delete_records+. They are in any case removed from the collection. + def delete(*records) + return if records.empty? + _options = records.extract_options! + dependent = _options[:dependent] || options[:dependent] + + records = find(records) if records.any? { |record| record.kind_of?(Fixnum) || record.kind_of?(String) } + delete_or_destroy(records, dependent) + end + + # Deletes the +records+ and removes them from this association calling + # +before_remove+ , +after_remove+ , +before_destroy+ and +after_destroy+ callbacks. + # + # Note that this method removes records from the database ignoring the + # +:dependent+ option. + def destroy(*records) + return if records.empty? + records = find(records) if records.any? { |record| record.kind_of?(Fixnum) || record.kind_of?(String) } + delete_or_destroy(records, :destroy) + end + + # Returns the size of the collection by executing a SELECT COUNT(*) + # query if the collection hasn't been loaded, and calling + # collection.size if it has. + # + # If the collection has been already loaded +size+ and +length+ are + # equivalent. If not and you are going to need the records anyway + # +length+ will take one less query. Otherwise +size+ is more efficient. + # + # This method is abstract in the sense that it relies on + # +count_records+, which is a method descendants have to provide. + def size + if !find_target? || loaded? + if association_scope.distinct_value + target.uniq.size + else + target.size + end + elsif !loaded? && !association_scope.group_values.empty? + load_target.size + elsif !loaded? && !association_scope.distinct_value && target.is_a?(Array) + unsaved_records = target.select { |r| r.new_record? } + unsaved_records.size + count_records + else + count_records + end + end + + # Returns the size of the collection calling +size+ on the target. + # + # If the collection has been already loaded +length+ and +size+ are + # equivalent. If not and you are going to need the records anyway this + # method will take one less query. Otherwise +size+ is more efficient. + def length + load_target.size + end + + # Returns true if the collection is empty. + # + # If the collection has been loaded + # it is equivalent to collection.size.zero?. If the + # collection has not been loaded, it is equivalent to + # collection.exists?. If the collection has not already been + # loaded and you are going to fetch the records anyway it is better to + # check collection.length.zero?. + def empty? + if loaded? + size.zero? + else + @target.blank? && !scope.exists? + end + end + + # Returns true if the collections is not empty. + # Equivalent to +!collection.empty?+. + def any? + if block_given? + load_target.any? { |*block_args| yield(*block_args) } + else + !empty? + end + end + + # Returns true if the collection has more than 1 record. + # Equivalent to +collection.size > 1+. + def many? + if block_given? + load_target.many? { |*block_args| yield(*block_args) } + else + size > 1 + end + end + + def distinct + seen = {} + load_target.find_all do |record| + seen[record.id] = true unless seen.key?(record.id) + end + end + alias uniq distinct + + # Replace this collection with +other_array+. This will perform a diff + # and delete/add only records that have changed. + def replace(other_array) + other_array.each { |val| raise_on_type_mismatch!(val) } + original_target = load_target.dup + + if owner.new_record? + replace_records(other_array, original_target) + else + replace_common_records_in_memory(other_array, original_target) + if other_array != original_target + transaction { replace_records(other_array, original_target) } + end + end + end + + def include?(record) + if record.is_a?(reflection.klass) + if record.new_record? + include_in_memory?(record) + else + loaded? ? target.include?(record) : scope.exists?(record.id) + end + else + false + end + end + + def load_target + if find_target? + @target = merge_target_lists(find_target, target) + end + + loaded! + target + end + + def add_to_target(record, skip_callbacks = false, &block) + if association_scope.distinct_value + index = @target.index(record) + end + replace_on_target(record, index, skip_callbacks, &block) + end + + def replace_on_target(record, index, skip_callbacks) + callback(:before_add, record) unless skip_callbacks + yield(record) if block_given? + + if index + @target[index] = record + else + @target << record + end + + callback(:after_add, record) unless skip_callbacks + set_inverse_instance(record) + + record + end + + def scope(opts = {}) + scope = super() + scope.none! if opts.fetch(:nullify, true) && null_scope? + scope + end + + def null_scope? + owner.new_record? && !foreign_key_present? + end + + private + def get_records + return scope.to_a if skip_statement_cache? + + conn = klass.connection + sc = reflection.association_scope_cache(conn, owner) do + StatementCache.create(conn) { |params| + as = AssociationScope.create { params.bind } + target_scope.merge as.scope(self, conn) + } + end + + binds = AssociationScope.get_bind_values(owner, reflection.chain) + sc.execute binds, klass, klass.connection + end + + def find_target + records = get_records + records.each { |record| set_inverse_instance(record) } + records + end + + # We have some records loaded from the database (persisted) and some that are + # in-memory (memory). The same record may be represented in the persisted array + # and in the memory array. + # + # So the task of this method is to merge them according to the following rules: + # + # * The final array must not have duplicates + # * The order of the persisted array is to be preserved + # * Any changes made to attributes on objects in the memory array are to be preserved + # * Otherwise, attributes should have the value found in the database + def merge_target_lists(persisted, memory) + return persisted if memory.empty? + return memory if persisted.empty? + + persisted.map! do |record| + if mem_record = memory.delete(record) + + ((record.attribute_names & mem_record.attribute_names) - mem_record.changes.keys).each do |name| + mem_record[name] = record[name] + end + + mem_record + else + record + end + end + + persisted + memory + end + + def _create_record(attributes, raise = false, &block) + unless owner.persisted? + raise ActiveRecord::RecordNotSaved, "You cannot call create unless the parent is saved" + end + + if attributes.is_a?(Array) + attributes.collect { |attr| _create_record(attr, raise, &block) } + else + transaction do + add_to_target(build_record(attributes)) do |record| + yield(record) if block_given? + insert_record(record, true, raise) + end + end + end + end + + # Do the relevant stuff to insert the given record into the association collection. + def insert_record(record, validate = true, raise = false) + raise NotImplementedError + end + + def create_scope + scope.scope_for_create.stringify_keys + end + + def delete_or_destroy(records, method) + records = records.flatten + records.each { |record| raise_on_type_mismatch!(record) } + existing_records = records.reject { |r| r.new_record? } + + if existing_records.empty? + remove_records(existing_records, records, method) + else + transaction { remove_records(existing_records, records, method) } + end + end + + def remove_records(existing_records, records, method) + records.each { |record| callback(:before_remove, record) } + + delete_records(existing_records, method) if existing_records.any? + records.each { |record| target.delete(record) } + + records.each { |record| callback(:after_remove, record) } + end + + # Delete the given records from the association, using one of the methods :destroy, + # :delete_all or :nullify (or nil, in which case a default is used). + def delete_records(records, method) + raise NotImplementedError + end + + def replace_records(new_target, original_target) + delete(target - new_target) + + unless concat(new_target - target) + @target = original_target + raise RecordNotSaved, "Failed to replace #{reflection.name} because one or more of the " \ + "new records could not be saved." + end + + target + end + + def replace_common_records_in_memory(new_target, original_target) + common_records = new_target & original_target + common_records.each do |record| + skip_callbacks = true + replace_on_target(record, @target.index(record), skip_callbacks) + end + end + + def concat_records(records, should_raise = false) + result = true + + records.flatten.each do |record| + raise_on_type_mismatch!(record) + add_to_target(record) do |rec| + result &&= insert_record(rec, true, should_raise) unless owner.new_record? + end + end + + result && records + end + + def callback(method, record) + callbacks_for(method).each do |callback| + callback.call(method, owner, record) + end + end + + def callbacks_for(callback_name) + full_callback_name = "#{callback_name}_for_#{reflection.name}" + owner.class.send(full_callback_name) + end + + # Should we deal with assoc.first or assoc.last by issuing an independent query to + # the database, or by getting the target, and then taking the first/last item from that? + # + # If the args is just a non-empty options hash, go to the database. + # + # Otherwise, go to the database only if none of the following are true: + # * target already loaded + # * owner is new record + # * target contains new or changed record(s) + def fetch_first_nth_or_last_using_find?(args) + if args.first.is_a?(Hash) + true + else + !(loaded? || + owner.new_record? || + target.any? { |record| record.new_record? || record.changed? }) + end + end + + def include_in_memory?(record) + if reflection.is_a?(ActiveRecord::Reflection::ThroughReflection) + assoc = owner.association(reflection.through_reflection.name) + assoc.reader.any? { |source| + target_association = source.send(reflection.source_reflection.name) + + if target_association.respond_to?(:include?) + target_association.include?(record) + else + target_association == record + end + } || target.include?(record) + else + target.include?(record) + end + end + + # If the :inverse_of option has been + # specified, then #find scans the entire collection. + def find_by_scan(*args) + expects_array = args.first.kind_of?(Array) + ids = args.flatten.compact.map{ |arg| arg.to_s }.uniq + + if ids.size == 1 + id = ids.first + record = load_target.detect { |r| id == r.id.to_s } + expects_array ? [ record ] : record + else + load_target.select { |r| ids.include?(r.id.to_s) } + end + end + + # Fetches the first/last using SQL if possible, otherwise from the target array. + def first_nth_or_last(type, *args) + args.shift if args.first.is_a?(Hash) && args.first.empty? + + collection = fetch_first_nth_or_last_using_find?(args) ? scope : load_target + collection.send(type, *args).tap do |record| + set_inverse_instance record if record.is_a? ActiveRecord::Base + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/collection_proxy.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/collection_proxy.rb new file mode 100644 index 0000000..af472e3 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/collection_proxy.rb @@ -0,0 +1,1033 @@ +module ActiveRecord + module Associations + # Association proxies in Active Record are middlemen between the object that + # holds the association, known as the @owner, and the actual associated + # object, known as the @target. The kind of association any proxy is + # about is available in @reflection. That's an instance of the class + # ActiveRecord::Reflection::AssociationReflection. + # + # For example, given + # + # class Blog < ActiveRecord::Base + # has_many :posts + # end + # + # blog = Blog.first + # + # the association proxy in blog.posts has the object in +blog+ as + # @owner, the collection of its posts as @target, and + # the @reflection object represents a :has_many macro. + # + # This class delegates unknown methods to @target via + # method_missing. + # + # The @target object is not \loaded until needed. For example, + # + # blog.posts.count + # + # is computed directly through SQL and does not trigger by itself the + # instantiation of the actual post records. + class CollectionProxy < Relation + delegate(*(ActiveRecord::Calculations.public_instance_methods - [:count]), to: :scope) + delegate :find_nth, to: :scope + + def initialize(klass, association) #:nodoc: + @association = association + super klass, klass.arel_table + merge! association.scope(nullify: false) + end + + def target + @association.target + end + + def load_target + @association.load_target + end + + # Returns +true+ if the association has been loaded, otherwise +false+. + # + # person.pets.loaded? # => false + # person.pets + # person.pets.loaded? # => true + def loaded? + @association.loaded? + end + + # Works in two ways. + # + # *First:* Specify a subset of fields to be selected from the result set. + # + # class Person < ActiveRecord::Base + # has_many :pets + # end + # + # person.pets + # # => [ + # # #, + # # #, + # # # + # # ] + # + # person.pets.select(:name) + # # => [ + # # #, + # # #, + # # # + # # ] + # + # person.pets.select(:id, :name ) + # # => [ + # # #, + # # #, + # # # + # # ] + # + # Be careful because this also means you're initializing a model + # object with only the fields that you've selected. If you attempt + # to access a field except +id+ that is not in the initialized record you'll + # receive: + # + # person.pets.select(:name).first.person_id + # # => ActiveModel::MissingAttributeError: missing attribute: person_id + # + # *Second:* You can pass a block so it can be used just like Array#select. + # This builds an array of objects from the database for the scope, + # converting them into an array and iterating through them using + # Array#select. + # + # person.pets.select { |pet| pet.name =~ /oo/ } + # # => [ + # # #, + # # # + # # ] + # + # person.pets.select(:name) { |pet| pet.name =~ /oo/ } + # # => [ + # # #, + # # # + # # ] + def select(*fields, &block) + @association.select(*fields, &block) + end + + # Finds an object in the collection responding to the +id+. Uses the same + # rules as ActiveRecord::Base.find. Returns ActiveRecord::RecordNotFound + # error if the object cannot be found. + # + # class Person < ActiveRecord::Base + # has_many :pets + # end + # + # person.pets + # # => [ + # # #, + # # #, + # # # + # # ] + # + # person.pets.find(1) # => # + # person.pets.find(4) # => ActiveRecord::RecordNotFound: Couldn't find Pet with id=4 + # + # person.pets.find(2) { |pet| pet.name.downcase! } + # # => # + # + # person.pets.find(2, 3) + # # => [ + # # #, + # # # + # # ] + def find(*args, &block) + @association.find(*args, &block) + end + + # Returns the first record, or the first +n+ records, from the collection. + # If the collection is empty, the first form returns +nil+, and the second + # form returns an empty array. + # + # class Person < ActiveRecord::Base + # has_many :pets + # end + # + # person.pets + # # => [ + # # #, + # # #, + # # # + # # ] + # + # person.pets.first # => # + # + # person.pets.first(2) + # # => [ + # # #, + # # # + # # ] + # + # another_person_without.pets # => [] + # another_person_without.pets.first # => nil + # another_person_without.pets.first(3) # => [] + def first(*args) + @association.first(*args) + end + + # Same as +first+ except returns only the second record. + def second(*args) + @association.second(*args) + end + + # Same as +first+ except returns only the third record. + def third(*args) + @association.third(*args) + end + + # Same as +first+ except returns only the fourth record. + def fourth(*args) + @association.fourth(*args) + end + + # Same as +first+ except returns only the fifth record. + def fifth(*args) + @association.fifth(*args) + end + + # Same as +first+ except returns only the forty second record. + # Also known as accessing "the reddit". + def forty_two(*args) + @association.forty_two(*args) + end + + # Returns the last record, or the last +n+ records, from the collection. + # If the collection is empty, the first form returns +nil+, and the second + # form returns an empty array. + # + # class Person < ActiveRecord::Base + # has_many :pets + # end + # + # person.pets + # # => [ + # # #, + # # #, + # # # + # # ] + # + # person.pets.last # => # + # + # person.pets.last(2) + # # => [ + # # #, + # # # + # # ] + # + # another_person_without.pets # => [] + # another_person_without.pets.last # => nil + # another_person_without.pets.last(3) # => [] + def last(*args) + @association.last(*args) + end + + def take(n = nil) + @association.take(n) + end + + # Returns a new object of the collection type that has been instantiated + # with +attributes+ and linked to this object, but have not yet been saved. + # You can pass an array of attributes hashes, this will return an array + # with the new objects. + # + # class Person + # has_many :pets + # end + # + # person.pets.build + # # => # + # + # person.pets.build(name: 'Fancy-Fancy') + # # => # + # + # person.pets.build([{name: 'Spook'}, {name: 'Choo-Choo'}, {name: 'Brain'}]) + # # => [ + # # #, + # # #, + # # # + # # ] + # + # person.pets.size # => 5 # size of the collection + # person.pets.count # => 0 # count from database + def build(attributes = {}, &block) + @association.build(attributes, &block) + end + alias_method :new, :build + + # Returns a new object of the collection type that has been instantiated with + # attributes, linked to this object and that has already been saved (if it + # passes the validations). + # + # class Person + # has_many :pets + # end + # + # person.pets.create(name: 'Fancy-Fancy') + # # => # + # + # person.pets.create([{name: 'Spook'}, {name: 'Choo-Choo'}]) + # # => [ + # # #, + # # # + # # ] + # + # person.pets.size # => 3 + # person.pets.count # => 3 + # + # person.pets.find(1, 2, 3) + # # => [ + # # #, + # # #, + # # # + # # ] + def create(attributes = {}, &block) + @association.create(attributes, &block) + end + + # Like +create+, except that if the record is invalid, raises an exception. + # + # class Person + # has_many :pets + # end + # + # class Pet + # validates :name, presence: true + # end + # + # person.pets.create!(name: nil) + # # => ActiveRecord::RecordInvalid: Validation failed: Name can't be blank + def create!(attributes = {}, &block) + @association.create!(attributes, &block) + end + + # Add one or more records to the collection by setting their foreign keys + # to the association's primary key. Since << flattens its argument list and + # inserts each record, +push+ and +concat+ behave identically. Returns +self+ + # so method calls may be chained. + # + # class Person < ActiveRecord::Base + # has_many :pets + # end + # + # person.pets.size # => 0 + # person.pets.concat(Pet.new(name: 'Fancy-Fancy')) + # person.pets.concat(Pet.new(name: 'Spook'), Pet.new(name: 'Choo-Choo')) + # person.pets.size # => 3 + # + # person.id # => 1 + # person.pets + # # => [ + # # #, + # # #, + # # # + # # ] + # + # person.pets.concat([Pet.new(name: 'Brain'), Pet.new(name: 'Benny')]) + # person.pets.size # => 5 + def concat(*records) + @association.concat(*records) + end + + # Replaces this collection with +other_array+. This will perform a diff + # and delete/add only records that have changed. + # + # class Person < ActiveRecord::Base + # has_many :pets + # end + # + # person.pets + # # => [#] + # + # other_pets = [Pet.new(name: 'Puff', group: 'celebrities'] + # + # person.pets.replace(other_pets) + # + # person.pets + # # => [#] + # + # If the supplied array has an incorrect association type, it raises + # an ActiveRecord::AssociationTypeMismatch error: + # + # person.pets.replace(["doo", "ggie", "gaga"]) + # # => ActiveRecord::AssociationTypeMismatch: Pet expected, got String + def replace(other_array) + @association.replace(other_array) + end + + # Deletes all the records from the collection according to the strategy + # specified by the +:dependent+ option. If no +:dependent+ option is given, + # then it will follow the default strategy. + # + # For +has_many :through+ associations, the default deletion strategy is + # +:delete_all+. + # + # For +has_many+ associations, the default deletion strategy is +:nullify+. + # This sets the foreign keys to +NULL+. + # + # class Person < ActiveRecord::Base + # has_many :pets # dependent: :nullify option by default + # end + # + # person.pets.size # => 3 + # person.pets + # # => [ + # # #, + # # #, + # # # + # # ] + # + # person.pets.delete_all + # # => [ + # # #, + # # #, + # # # + # # ] + # + # person.pets.size # => 0 + # person.pets # => [] + # + # Pet.find(1, 2, 3) + # # => [ + # # #, + # # #, + # # # + # # ] + # + # Both +has_many+ and +has_many :through+ dependencies default to the + # +:delete_all+ strategy if the +:dependent+ option is set to +:destroy+. + # Records are not instantiated and callbacks will not be fired. + # + # class Person < ActiveRecord::Base + # has_many :pets, dependent: :destroy + # end + # + # person.pets.size # => 3 + # person.pets + # # => [ + # # #, + # # #, + # # # + # # ] + # + # person.pets.delete_all + # + # Pet.find(1, 2, 3) + # # => ActiveRecord::RecordNotFound + # + # If it is set to :delete_all, all the objects are deleted + # *without* calling their +destroy+ method. + # + # class Person < ActiveRecord::Base + # has_many :pets, dependent: :delete_all + # end + # + # person.pets.size # => 3 + # person.pets + # # => [ + # # #, + # # #, + # # # + # # ] + # + # person.pets.delete_all + # + # Pet.find(1, 2, 3) + # # => ActiveRecord::RecordNotFound + def delete_all(dependent = nil) + @association.delete_all(dependent) + end + + # Deletes the records of the collection directly from the database + # ignoring the +:dependent+ option. Records are instantiated and it + # invokes +before_remove+, +after_remove+ , +before_destroy+ and + # +after_destroy+ callbacks. + # + # class Person < ActiveRecord::Base + # has_many :pets + # end + # + # person.pets.size # => 3 + # person.pets + # # => [ + # # #, + # # #, + # # # + # # ] + # + # person.pets.destroy_all + # + # person.pets.size # => 0 + # person.pets # => [] + # + # Pet.find(1) # => Couldn't find Pet with id=1 + def destroy_all + @association.destroy_all + end + + # Deletes the +records+ supplied from the collection according to the strategy + # specified by the +:dependent+ option. If no +:dependent+ option is given, + # then it will follow the default strategy. Returns an array with the + # deleted records. + # + # For +has_many :through+ associations, the default deletion strategy is + # +:delete_all+. + # + # For +has_many+ associations, the default deletion strategy is +:nullify+. + # This sets the foreign keys to +NULL+. + # + # class Person < ActiveRecord::Base + # has_many :pets # dependent: :nullify option by default + # end + # + # person.pets.size # => 3 + # person.pets + # # => [ + # # #, + # # #, + # # # + # # ] + # + # person.pets.delete(Pet.find(1)) + # # => [#] + # + # person.pets.size # => 2 + # person.pets + # # => [ + # # #, + # # # + # # ] + # + # Pet.find(1) + # # => # + # + # If it is set to :destroy all the +records+ are removed by calling + # their +destroy+ method. See +destroy+ for more information. + # + # class Person < ActiveRecord::Base + # has_many :pets, dependent: :destroy + # end + # + # person.pets.size # => 3 + # person.pets + # # => [ + # # #, + # # #, + # # # + # # ] + # + # person.pets.delete(Pet.find(1), Pet.find(3)) + # # => [ + # # #, + # # # + # # ] + # + # person.pets.size # => 1 + # person.pets + # # => [#] + # + # Pet.find(1, 3) + # # => ActiveRecord::RecordNotFound: Couldn't find all Pets with IDs (1, 3) + # + # If it is set to :delete_all, all the +records+ are deleted + # *without* calling their +destroy+ method. + # + # class Person < ActiveRecord::Base + # has_many :pets, dependent: :delete_all + # end + # + # person.pets.size # => 3 + # person.pets + # # => [ + # # #, + # # #, + # # # + # # ] + # + # person.pets.delete(Pet.find(1)) + # # => [#] + # + # person.pets.size # => 2 + # person.pets + # # => [ + # # #, + # # # + # # ] + # + # Pet.find(1) + # # => ActiveRecord::RecordNotFound: Couldn't find Pet with id=1 + # + # You can pass +Fixnum+ or +String+ values, it finds the records + # responding to the +id+ and executes delete on them. + # + # class Person < ActiveRecord::Base + # has_many :pets + # end + # + # person.pets.size # => 3 + # person.pets + # # => [ + # # #, + # # #, + # # # + # # ] + # + # person.pets.delete("1") + # # => [#] + # + # person.pets.delete(2, 3) + # # => [ + # # #, + # # # + # # ] + def delete(*records) + @association.delete(*records) + end + + # Destroys the +records+ supplied and removes them from the collection. + # This method will _always_ remove record from the database ignoring + # the +:dependent+ option. Returns an array with the removed records. + # + # class Person < ActiveRecord::Base + # has_many :pets + # end + # + # person.pets.size # => 3 + # person.pets + # # => [ + # # #, + # # #, + # # # + # # ] + # + # person.pets.destroy(Pet.find(1)) + # # => [#] + # + # person.pets.size # => 2 + # person.pets + # # => [ + # # #, + # # # + # # ] + # + # person.pets.destroy(Pet.find(2), Pet.find(3)) + # # => [ + # # #, + # # # + # # ] + # + # person.pets.size # => 0 + # person.pets # => [] + # + # Pet.find(1, 2, 3) # => ActiveRecord::RecordNotFound: Couldn't find all Pets with IDs (1, 2, 3) + # + # You can pass +Fixnum+ or +String+ values, it finds the records + # responding to the +id+ and then deletes them from the database. + # + # person.pets.size # => 3 + # person.pets + # # => [ + # # #, + # # #, + # # # + # # ] + # + # person.pets.destroy("4") + # # => # + # + # person.pets.size # => 2 + # person.pets + # # => [ + # # #, + # # # + # # ] + # + # person.pets.destroy(5, 6) + # # => [ + # # #, + # # # + # # ] + # + # person.pets.size # => 0 + # person.pets # => [] + # + # Pet.find(4, 5, 6) # => ActiveRecord::RecordNotFound: Couldn't find all Pets with IDs (4, 5, 6) + def destroy(*records) + @association.destroy(*records) + end + + # Specifies whether the records should be unique or not. + # + # class Person < ActiveRecord::Base + # has_many :pets + # end + # + # person.pets.select(:name) + # # => [ + # # #, + # # # + # # ] + # + # person.pets.select(:name).distinct + # # => [#] + def distinct + @association.distinct + end + alias uniq distinct + + # Count all records using SQL. + # + # class Person < ActiveRecord::Base + # has_many :pets + # end + # + # person.pets.count # => 3 + # person.pets + # # => [ + # # #, + # # #, + # # # + # # ] + def count(column_name = nil, options = {}) + # TODO: Remove options argument as soon we remove support to + # activerecord-deprecated_finders. + @association.count(column_name, options) + end + + # Returns the size of the collection. If the collection hasn't been loaded, + # it executes a SELECT COUNT(*) query. Else it calls collection.size. + # + # If the collection has been already loaded +size+ and +length+ are + # equivalent. If not and you are going to need the records anyway + # +length+ will take one less query. Otherwise +size+ is more efficient. + # + # class Person < ActiveRecord::Base + # has_many :pets + # end + # + # person.pets.size # => 3 + # # executes something like SELECT COUNT(*) FROM "pets" WHERE "pets"."person_id" = 1 + # + # person.pets # This will execute a SELECT * FROM query + # # => [ + # # #, + # # #, + # # # + # # ] + # + # person.pets.size # => 3 + # # Because the collection is already loaded, this will behave like + # # collection.size and no SQL count query is executed. + def size + @association.size + end + + # Returns the size of the collection calling +size+ on the target. + # If the collection has been already loaded, +length+ and +size+ are + # equivalent. If not and you are going to need the records anyway this + # method will take one less query. Otherwise +size+ is more efficient. + # + # class Person < ActiveRecord::Base + # has_many :pets + # end + # + # person.pets.length # => 3 + # # executes something like SELECT "pets".* FROM "pets" WHERE "pets"."person_id" = 1 + # + # # Because the collection is loaded, you can + # # call the collection with no additional queries: + # person.pets + # # => [ + # # #, + # # #, + # # # + # # ] + def length + @association.length + end + + # Returns +true+ if the collection is empty. If the collection has been + # loaded it is equivalent + # to collection.size.zero?. If the collection has not been loaded, + # it is equivalent to collection.exists?. If the collection has + # not already been loaded and you are going to fetch the records anyway it + # is better to check collection.length.zero?. + # + # class Person < ActiveRecord::Base + # has_many :pets + # end + # + # person.pets.count # => 1 + # person.pets.empty? # => false + # + # person.pets.delete_all + # + # person.pets.count # => 0 + # person.pets.empty? # => true + def empty? + @association.empty? + end + + # Returns +true+ if the collection is not empty. + # + # class Person < ActiveRecord::Base + # has_many :pets + # end + # + # person.pets.count # => 0 + # person.pets.any? # => false + # + # person.pets << Pet.new(name: 'Snoop') + # person.pets.count # => 0 + # person.pets.any? # => true + # + # You can also pass a +block+ to define criteria. The behavior + # is the same, it returns true if the collection based on the + # criteria is not empty. + # + # person.pets + # # => [#] + # + # person.pets.any? do |pet| + # pet.group == 'cats' + # end + # # => false + # + # person.pets.any? do |pet| + # pet.group == 'dogs' + # end + # # => true + def any?(&block) + @association.any?(&block) + end + + # Returns true if the collection has more than one record. + # Equivalent to collection.size > 1. + # + # class Person < ActiveRecord::Base + # has_many :pets + # end + # + # person.pets.count # => 1 + # person.pets.many? # => false + # + # person.pets << Pet.new(name: 'Snoopy') + # person.pets.count # => 2 + # person.pets.many? # => true + # + # You can also pass a +block+ to define criteria. The + # behavior is the same, it returns true if the collection + # based on the criteria has more than one record. + # + # person.pets + # # => [ + # # #, + # # #, + # # # + # # ] + # + # person.pets.many? do |pet| + # pet.group == 'dogs' + # end + # # => false + # + # person.pets.many? do |pet| + # pet.group == 'cats' + # end + # # => true + def many?(&block) + @association.many?(&block) + end + + # Returns +true+ if the given +record+ is present in the collection. + # + # class Person < ActiveRecord::Base + # has_many :pets + # end + # + # person.pets # => [#] + # + # person.pets.include?(Pet.find(20)) # => true + # person.pets.include?(Pet.find(21)) # => false + def include?(record) + !!@association.include?(record) + end + + def arel + scope.arel + end + + def proxy_association + @association + end + + # We don't want this object to be put on the scoping stack, because + # that could create an infinite loop where we call an @association + # method, which gets the current scope, which is this object, which + # delegates to @association, and so on. + def scoping + @association.scope.scoping { yield } + end + + # Returns a Relation object for the records in this association + def scope + @association.scope + end + alias spawn scope + + # Equivalent to Array#==. Returns +true+ if the two arrays + # contain the same number of elements and if each element is equal + # to the corresponding element in the +other+ array, otherwise returns + # +false+. + # + # class Person < ActiveRecord::Base + # has_many :pets + # end + # + # person.pets + # # => [ + # # #, + # # # + # # ] + # + # other = person.pets.to_ary + # + # person.pets == other + # # => true + # + # other = [Pet.new(id: 1), Pet.new(id: 2)] + # + # person.pets == other + # # => false + def ==(other) + load_target == other + end + + # Returns a new array of objects from the collection. If the collection + # hasn't been loaded, it fetches the records from the database. + # + # class Person < ActiveRecord::Base + # has_many :pets + # end + # + # person.pets + # # => [ + # # #, + # # #, + # # # + # # ] + # + # other_pets = person.pets.to_ary + # # => [ + # # #, + # # #, + # # # + # # ] + # + # other_pets.replace([Pet.new(name: 'BooGoo')]) + # + # other_pets + # # => [#] + # + # person.pets + # # This is not affected by replace + # # => [ + # # #, + # # #, + # # # + # # ] + def to_ary + load_target.dup + end + alias_method :to_a, :to_ary + + # Adds one or more +records+ to the collection by setting their foreign keys + # to the association's primary key. Returns +self+, so several appends may be + # chained together. + # + # class Person < ActiveRecord::Base + # has_many :pets + # end + # + # person.pets.size # => 0 + # person.pets << Pet.new(name: 'Fancy-Fancy') + # person.pets << [Pet.new(name: 'Spook'), Pet.new(name: 'Choo-Choo')] + # person.pets.size # => 3 + # + # person.id # => 1 + # person.pets + # # => [ + # # #, + # # #, + # # # + # # ] + def <<(*records) + proxy_association.concat(records) && self + end + alias_method :push, :<< + alias_method :append, :<< + + def prepend(*args) + raise NoMethodError, "prepend on association is not defined. Please use << or append" + end + + # Equivalent to +delete_all+. The difference is that returns +self+, instead + # of an array with the deleted objects, so methods can be chained. See + # +delete_all+ for more information. + def clear + delete_all + self + end + + # Reloads the collection from the database. Returns +self+. + # Equivalent to collection(true). + # + # class Person < ActiveRecord::Base + # has_many :pets + # end + # + # person.pets # fetches pets from the database + # # => [#] + # + # person.pets # uses the pets cache + # # => [#] + # + # person.pets.reload # fetches pets from the database + # # => [#] + # + # person.pets(true) # fetches pets from the database + # # => [#] + def reload + proxy_association.reload + self + end + + # Unloads the association. Returns +self+. + # + # class Person < ActiveRecord::Base + # has_many :pets + # end + # + # person.pets # fetches pets from the database + # # => [#] + # + # person.pets # uses the pets cache + # # => [#] + # + # person.pets.reset # clears the pets cache + # + # person.pets # fetches pets from the database + # # => [#] + def reset + proxy_association.reset + proxy_association.reset_scope + self + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/foreign_association.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/foreign_association.rb new file mode 100644 index 0000000..fe48ece --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/foreign_association.rb @@ -0,0 +1,11 @@ +module ActiveRecord::Associations + module ForeignAssociation + def foreign_key_present? + if reflection.klass.primary_key + owner.attribute_present?(reflection.active_record_primary_key) + else + false + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/has_many_association.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/has_many_association.rb new file mode 100644 index 0000000..de3a347 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/has_many_association.rb @@ -0,0 +1,199 @@ +module ActiveRecord + # = Active Record Has Many Association + module Associations + # This is the proxy that handles a has many association. + # + # If the association has a :through option further specialization + # is provided by its child HasManyThroughAssociation. + class HasManyAssociation < CollectionAssociation #:nodoc: + include ForeignAssociation + + def handle_dependency + case options[:dependent] + when :restrict_with_exception + raise ActiveRecord::DeleteRestrictionError.new(reflection.name) unless empty? + + when :restrict_with_error + unless empty? + record = klass.human_attribute_name(reflection.name).downcase + owner.errors.add(:base, :"restrict_dependent_destroy.many", record: record) + false + end + + else + if options[:dependent] == :destroy + # No point in executing the counter update since we're going to destroy the parent anyway + load_target.each { |t| t.destroyed_by_association = reflection } + destroy_all + else + delete_all + end + end + end + + def insert_record(record, validate = true, raise = false) + set_owner_attributes(record) + set_inverse_instance(record) + + if raise + record.save!(:validate => validate) + else + record.save(:validate => validate) + end + end + + def empty? + if has_cached_counter? + size.zero? + else + super + end + end + + private + + # Returns the number of records in this collection. + # + # If the association has a counter cache it gets that value. Otherwise + # it will attempt to do a count via SQL, bounded to :limit if + # there's one. Some configuration options like :group make it impossible + # to do an SQL count, in those cases the array count will be used. + # + # That does not depend on whether the collection has already been loaded + # or not. The +size+ method is the one that takes the loaded flag into + # account and delegates to +count_records+ if needed. + # + # If the collection is empty the target is set to an empty array and + # the loaded flag is set to true as well. + def count_records + count = if has_cached_counter? + owner._read_attribute cached_counter_attribute_name + else + scope.count + end + + # If there's nothing in the database and @target has no new records + # we are certain the current target is an empty array. This is a + # documented side-effect of the method that may avoid an extra SELECT. + @target ||= [] and loaded! if count == 0 + + [association_scope.limit_value, count].compact.min + end + + + # Returns whether a counter cache should be used for this association. + # + # The counter_cache option must be given on either the owner or inverse + # association, and the column must be present on the owner. + def has_cached_counter?(reflection = reflection()) + if reflection.options[:counter_cache] || (inverse = inverse_which_updates_counter_cache(reflection)) && inverse.options[:counter_cache] + owner.attribute_present?(cached_counter_attribute_name(reflection)) + end + end + + def cached_counter_attribute_name(reflection = reflection()) + if reflection.options[:counter_cache] + reflection.options[:counter_cache].to_s + else + "#{reflection.name}_count" + end + end + + def update_counter(difference, reflection = reflection()) + update_counter_in_database(difference, reflection) + update_counter_in_memory(difference, reflection) + end + + def update_counter_in_database(difference, reflection = reflection()) + if has_cached_counter?(reflection) + counter = cached_counter_attribute_name(reflection) + owner.class.update_counters(owner.id, counter => difference) + end + end + + def update_counter_in_memory(difference, reflection = reflection()) + if counter_must_be_updated_by_has_many?(reflection) + counter = cached_counter_attribute_name(reflection) + owner[counter] += difference + owner.send(:clear_attribute_changes, counter) # eww + end + end + + # This shit is nasty. We need to avoid the following situation: + # + # * An associated record is deleted via record.destroy + # * Hence the callbacks run, and they find a belongs_to on the record with a + # :counter_cache options which points back at our owner. So they update the + # counter cache. + # * In which case, we must make sure to *not* update the counter cache, or else + # it will be decremented twice. + # + # Hence this method. + def inverse_which_updates_counter_cache(reflection = reflection()) + counter_name = cached_counter_attribute_name(reflection) + inverse_which_updates_counter_named(counter_name, reflection) + end + alias inverse_updates_counter_cache? inverse_which_updates_counter_cache + + def inverse_which_updates_counter_named(counter_name, reflection) + reflection.klass._reflections.values.find { |inverse_reflection| + inverse_reflection.belongs_to? && + inverse_reflection.counter_cache_column == counter_name + } + end + alias inverse_updates_counter_named? inverse_which_updates_counter_named + + def inverse_updates_counter_in_memory?(reflection) + inverse = inverse_which_updates_counter_cache(reflection) + inverse && inverse == reflection.inverse_of + end + + def counter_must_be_updated_by_has_many?(reflection) + !inverse_updates_counter_in_memory?(reflection) && has_cached_counter?(reflection) + end + + def delete_count(method, scope) + if method == :delete_all + scope.delete_all + else + scope.update_all(reflection.foreign_key => nil) + end + end + + def delete_or_nullify_all_records(method) + count = delete_count(method, self.scope) + update_counter(-count) + end + + # Deletes the records according to the :dependent option. + def delete_records(records, method) + if method == :destroy + records.each(&:destroy!) + update_counter(-records.length) unless inverse_updates_counter_cache? + else + scope = self.scope.where(reflection.klass.primary_key => records) + update_counter(-delete_count(method, scope)) + end + end + + def concat_records(records, *) + update_counter_if_success(super, records.length) + end + + def _create_record(attributes, *) + if attributes.is_a?(Array) + super + else + update_counter_if_success(super, 1) + end + end + + def update_counter_if_success(saved_successfully, difference) + if saved_successfully + update_counter_in_memory(difference) + end + saved_successfully + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/has_many_through_association.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/has_many_through_association.rb new file mode 100644 index 0000000..613ad71 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/has_many_through_association.rb @@ -0,0 +1,247 @@ +require 'active_support/core_ext/string/filters' + +module ActiveRecord + # = Active Record Has Many Through Association + module Associations + class HasManyThroughAssociation < HasManyAssociation #:nodoc: + include ThroughAssociation + + def initialize(owner, reflection) + super + + @through_records = {} + @through_association = nil + end + + # Returns the size of the collection by executing a SELECT COUNT(*) query + # if the collection hasn't been loaded, and by calling collection.size if + # it has. If the collection will likely have a size greater than zero, + # and if fetching the collection will be needed afterwards, one less + # SELECT query will be generated by using #length instead. + def size + if has_cached_counter? + owner._read_attribute cached_counter_attribute_name(reflection) + elsif loaded? + target.size + else + super + end + end + + def concat(*records) + unless owner.new_record? + records.flatten.each do |record| + raise_on_type_mismatch!(record) + end + end + + super + end + + def concat_records(records) + ensure_not_nested + + records = super(records, true) + + if owner.new_record? && records + records.flatten.each do |record| + build_through_record(record) + end + end + + records + end + + def insert_record(record, validate = true, raise = false) + ensure_not_nested + + if record.new_record? + if raise + record.save!(:validate => validate) + else + return unless record.save(:validate => validate) + end + end + + save_through_record(record) + if has_cached_counter? && !through_reflection_updates_counter_cache? + ActiveSupport::Deprecation.warn(<<-MSG.squish) + Automatic updating of counter caches on through associations has been + deprecated, and will be removed in Rails 5. Instead, please set the + appropriate `counter_cache` options on the `has_many` and `belongs_to` + for your associations to #{through_reflection.name}. + MSG + + update_counter_in_database(1) + end + record + end + + private + + def through_association + @through_association ||= owner.association(through_reflection.name) + end + + # The through record (built with build_record) is temporarily cached + # so that it may be reused if insert_record is subsequently called. + # + # However, after insert_record has been called, the cache is cleared in + # order to allow multiple instances of the same record in an association. + def build_through_record(record) + @through_records[record.object_id] ||= begin + ensure_mutable + + through_record = through_association.build(*options_for_through_record) + through_record.send("#{source_reflection.name}=", record) + + if options[:source_type] + through_record.send("#{source_reflection.foreign_type}=", options[:source_type]) + end + + through_record + end + end + + def options_for_through_record + [through_scope_attributes] + end + + def through_scope_attributes + scope.where_values_hash(through_association.reflection.name.to_s). + except!(through_association.reflection.foreign_key, + through_association.reflection.klass.inheritance_column) + end + + def save_through_record(record) + build_through_record(record).save! + ensure + @through_records.delete(record.object_id) + end + + def build_record(attributes) + ensure_not_nested + + record = super(attributes) + + inverse = source_reflection.inverse_of + if inverse + if inverse.collection? + record.send(inverse.name) << build_through_record(record) + elsif inverse.has_one? + record.send("#{inverse.name}=", build_through_record(record)) + end + end + + record + end + + def target_reflection_has_associated_record? + !(through_reflection.belongs_to? && owner[through_reflection.foreign_key].blank?) + end + + def update_through_counter?(method) + case method + when :destroy + !inverse_updates_counter_cache?(through_reflection) + when :nullify + false + else + true + end + end + + def delete_or_nullify_all_records(method) + delete_records(load_target, method) + end + + def delete_records(records, method) + ensure_not_nested + + scope = through_association.scope + scope.where! construct_join_attributes(*records) + + case method + when :destroy + if scope.klass.primary_key + count = scope.destroy_all.length + else + scope.each do |record| + record._run_destroy_callbacks + end + + arel = scope.arel + + stmt = Arel::DeleteManager.new arel.engine + stmt.from scope.klass.arel_table + stmt.wheres = arel.constraints + + count = scope.klass.connection.delete(stmt, 'SQL', scope.bind_values) + end + when :nullify + count = scope.update_all(source_reflection.foreign_key => nil) + else + count = scope.delete_all + end + + delete_through_records(records) + + if source_reflection.options[:counter_cache] && method != :destroy + counter = source_reflection.counter_cache_column + klass.decrement_counter counter, records.map(&:id) + end + + if through_reflection.collection? && update_through_counter?(method) + update_counter(-count, through_reflection) + else + update_counter(-count) + end + end + + def through_records_for(record) + attributes = construct_join_attributes(record) + candidates = Array.wrap(through_association.target) + candidates.find_all do |c| + attributes.all? do |key, value| + c.public_send(key) == value + end + end + end + + def delete_through_records(records) + records.each do |record| + through_records = through_records_for(record) + + if through_reflection.collection? + through_records.each { |r| through_association.target.delete(r) } + else + if through_records.include?(through_association.target) + through_association.target = nil + end + end + + @through_records.delete(record.object_id) + end + end + + def find_target + return [] unless target_reflection_has_associated_record? + get_records + end + + # NOTE - not sure that we can actually cope with inverses here + def invertible_for?(record) + false + end + + def has_cached_counter?(reflection = reflection()) + owner.attribute_present?(cached_counter_attribute_name(reflection)) + end + + def through_reflection_updates_counter_cache? + counter_name = cached_counter_attribute_name + inverse_updates_counter_named?(counter_name, through_reflection) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/has_one_association.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/has_one_association.rb new file mode 100644 index 0000000..74b8c53 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/has_one_association.rb @@ -0,0 +1,106 @@ +module ActiveRecord + # = Active Record Belongs To Has One Association + module Associations + class HasOneAssociation < SingularAssociation #:nodoc: + include ForeignAssociation + + def handle_dependency + case options[:dependent] + when :restrict_with_exception + raise ActiveRecord::DeleteRestrictionError.new(reflection.name) if load_target + + when :restrict_with_error + if load_target + record = klass.human_attribute_name(reflection.name).downcase + owner.errors.add(:base, :"restrict_dependent_destroy.one", record: record) + false + end + + else + delete + end + end + + def replace(record, save = true) + raise_on_type_mismatch!(record) if record + load_target + + return self.target if !(target || record) + + assigning_another_record = target != record + if assigning_another_record || record.changed? + save &&= owner.persisted? + + transaction_if(save) do + remove_target!(options[:dependent]) if target && !target.destroyed? && assigning_another_record + + if record + set_owner_attributes(record) + set_inverse_instance(record) + + if save && !record.save + nullify_owner_attributes(record) + set_owner_attributes(target) if target + raise RecordNotSaved, "Failed to save the new associated #{reflection.name}." + end + end + end + end + + self.target = record + end + + def delete(method = options[:dependent]) + if load_target + case method + when :delete + target.delete + when :destroy + target.destroy + when :nullify + target.update_columns(reflection.foreign_key => nil) + end + end + end + + private + + # The reason that the save param for replace is false, if for create (not just build), + # is because the setting of the foreign keys is actually handled by the scoping when + # the record is instantiated, and so they are set straight away and do not need to be + # updated within replace. + def set_new_record(record) + replace(record, false) + end + + def remove_target!(method) + case method + when :delete + target.delete + when :destroy + target.destroy + else + nullify_owner_attributes(target) + + if target.persisted? && owner.persisted? && !target.save + set_owner_attributes(target) + raise RecordNotSaved, "Failed to remove the existing associated #{reflection.name}. " + + "The record failed to save after its foreign key was set to nil." + end + end + end + + def nullify_owner_attributes(record) + record[reflection.foreign_key] = nil + end + + def transaction_if(value) + if value + reflection.klass.transaction { yield } + else + yield + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/has_one_through_association.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/has_one_through_association.rb new file mode 100644 index 0000000..08e0ec6 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/has_one_through_association.rb @@ -0,0 +1,36 @@ +module ActiveRecord + # = Active Record Has One Through Association + module Associations + class HasOneThroughAssociation < HasOneAssociation #:nodoc: + include ThroughAssociation + + def replace(record) + create_through_record(record) + self.target = record + end + + private + + def create_through_record(record) + ensure_not_nested + + through_proxy = owner.association(through_reflection.name) + through_record = through_proxy.send(:load_target) + + if through_record && !record + through_record.destroy + elsif record + attributes = construct_join_attributes(record) + + if through_record + through_record.update(attributes) + elsif owner.new_record? + through_proxy.build(attributes) + else + through_proxy.create(attributes) + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/join_dependency.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/join_dependency.rb new file mode 100644 index 0000000..329c0ee --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/join_dependency.rb @@ -0,0 +1,288 @@ +module ActiveRecord + module Associations + class JoinDependency # :nodoc: + autoload :JoinBase, 'active_record/associations/join_dependency/join_base' + autoload :JoinAssociation, 'active_record/associations/join_dependency/join_association' + + class Aliases # :nodoc: + def initialize(tables) + @tables = tables + @alias_cache = tables.each_with_object({}) { |table,h| + h[table.node] = table.columns.each_with_object({}) { |column,i| + i[column.name] = column.alias + } + } + @name_and_alias_cache = tables.each_with_object({}) { |table,h| + h[table.node] = table.columns.map { |column| + [column.name, column.alias] + } + } + end + + def columns + @tables.flat_map { |t| t.column_aliases } + end + + # An array of [column_name, alias] pairs for the table + def column_aliases(node) + @name_and_alias_cache[node] + end + + def column_alias(node, column) + @alias_cache[node][column] + end + + class Table < Struct.new(:node, :columns) + def table + Arel::Nodes::TableAlias.new node.table, node.aliased_table_name + end + + def column_aliases + t = table + columns.map { |column| t[column.name].as Arel.sql column.alias } + end + end + Column = Struct.new(:name, :alias) + end + + attr_reader :alias_tracker, :base_klass, :join_root + + def self.make_tree(associations) + hash = {} + walk_tree associations, hash + hash + end + + def self.walk_tree(associations, hash) + case associations + when Symbol, String + hash[associations.to_sym] ||= {} + when Array + associations.each do |assoc| + walk_tree assoc, hash + end + when Hash + associations.each do |k,v| + cache = hash[k] ||= {} + walk_tree v, cache + end + else + raise ConfigurationError, associations.inspect + end + end + + # base is the base class on which operation is taking place. + # associations is the list of associations which are joined using hash, symbol or array. + # joins is the list of all string join commands and arel nodes. + # + # Example : + # + # class Physician < ActiveRecord::Base + # has_many :appointments + # has_many :patients, through: :appointments + # end + # + # If I execute `@physician.patients.to_a` then + # base # => Physician + # associations # => [] + # joins # => [# Physician + # associations # => [:appointments] + # joins # => [] + # + def initialize(base, associations, joins) + @alias_tracker = AliasTracker.create(base.connection, joins) + @alias_tracker.aliased_table_for(base.table_name, base.table_name) # Updates the count for base.table_name to 1 + tree = self.class.make_tree associations + @join_root = JoinBase.new base, build(tree, base) + @join_root.children.each { |child| construct_tables! @join_root, child } + end + + def reflections + join_root.drop(1).map!(&:reflection) + end + + def join_constraints(outer_joins) + joins = join_root.children.flat_map { |child| + make_inner_joins join_root, child + } + + joins.concat outer_joins.flat_map { |oj| + if join_root.match? oj.join_root + walk join_root, oj.join_root + else + oj.join_root.children.flat_map { |child| + make_outer_joins oj.join_root, child + } + end + } + end + + def aliases + Aliases.new join_root.each_with_index.map { |join_part,i| + columns = join_part.column_names.each_with_index.map { |column_name,j| + Aliases::Column.new column_name, "t#{i}_r#{j}" + } + Aliases::Table.new(join_part, columns) + } + end + + def instantiate(result_set, aliases) + primary_key = aliases.column_alias(join_root, join_root.primary_key) + + seen = Hash.new { |h,parent_klass| + h[parent_klass] = Hash.new { |i,parent_id| + i[parent_id] = Hash.new { |j,child_klass| j[child_klass] = {} } + } + } + + model_cache = Hash.new { |h,klass| h[klass] = {} } + parents = model_cache[join_root] + column_aliases = aliases.column_aliases join_root + + message_bus = ActiveSupport::Notifications.instrumenter + + payload = { + record_count: result_set.length, + class_name: join_root.base_klass.name + } + + message_bus.instrument('instantiation.active_record', payload) do + result_set.each { |row_hash| + parent_key = primary_key ? row_hash[primary_key] : row_hash + parent = parents[parent_key] ||= join_root.instantiate(row_hash, column_aliases) + construct(parent, join_root, row_hash, result_set, seen, model_cache, aliases) + } + end + + parents.values + end + + private + + def make_constraints(parent, child, tables, join_type) + chain = child.reflection.chain + foreign_table = parent.table + foreign_klass = parent.base_klass + child.join_constraints(foreign_table, foreign_klass, child, join_type, tables, child.reflection.scope_chain, chain) + end + + def make_outer_joins(parent, child) + tables = table_aliases_for(parent, child) + join_type = Arel::Nodes::OuterJoin + info = make_constraints parent, child, tables, join_type + + [info] + child.children.flat_map { |c| make_outer_joins(child, c) } + end + + def make_inner_joins(parent, child) + tables = child.tables + join_type = Arel::Nodes::InnerJoin + info = make_constraints parent, child, tables, join_type + + [info] + child.children.flat_map { |c| make_inner_joins(child, c) } + end + + def table_aliases_for(parent, node) + node.reflection.chain.map { |reflection| + alias_tracker.aliased_table_for( + reflection.table_name, + table_alias_for(reflection, parent, reflection != node.reflection) + ) + } + end + + def construct_tables!(parent, node) + node.tables = table_aliases_for(parent, node) + node.children.each { |child| construct_tables! node, child } + end + + def table_alias_for(reflection, parent, join) + name = "#{reflection.plural_name}_#{parent.table_name}" + name << "_join" if join + name + end + + def walk(left, right) + intersection, missing = right.children.map { |node1| + [left.children.find { |node2| node1.match? node2 }, node1] + }.partition(&:first) + + ojs = missing.flat_map { |_,n| make_outer_joins left, n } + intersection.flat_map { |l,r| walk l, r }.concat ojs + end + + def find_reflection(klass, name) + klass._reflect_on_association(name) or + raise ConfigurationError, "Association named '#{ name }' was not found on #{ klass.name }; perhaps you misspelled it?" + end + + def build(associations, base_klass) + associations.map do |name, right| + reflection = find_reflection base_klass, name + reflection.check_validity! + reflection.check_eager_loadable! + + if reflection.polymorphic? + raise EagerLoadPolymorphicError.new(reflection) + end + + JoinAssociation.new reflection, build(right, reflection.klass) + end + end + + def construct(ar_parent, parent, row, rs, seen, model_cache, aliases) + return if ar_parent.nil? + primary_id = ar_parent.id + + parent.children.each do |node| + if node.reflection.collection? + other = ar_parent.association(node.reflection.name) + other.loaded! + else + if ar_parent.association_cache.key?(node.reflection.name) + model = ar_parent.association(node.reflection.name).target + construct(model, node, row, rs, seen, model_cache, aliases) + next + end + end + + key = aliases.column_alias(node, node.primary_key) + id = row[key] + if id.nil? + nil_association = ar_parent.association(node.reflection.name) + nil_association.loaded! + next + end + + model = seen[parent.base_klass][primary_id][node.base_klass][id] + + if model + construct(model, node, row, rs, seen, model_cache, aliases) + else + model = construct_model(ar_parent, node, row, model_cache, id, aliases) + seen[parent.base_klass][primary_id][node.base_klass][id] = model + construct(model, node, row, rs, seen, model_cache, aliases) + end + end + end + + def construct_model(record, node, row, model_cache, id, aliases) + model = model_cache[node][id] ||= node.instantiate(row, + aliases.column_aliases(node)) + other = record.association(node.reflection.name) + + if node.reflection.collection? + other.target.push(model) + else + other.target = model + end + + other.set_inverse_instance(model) + model + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/join_dependency/join_association.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/join_dependency/join_association.rb new file mode 100644 index 0000000..5dede55 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/join_dependency/join_association.rb @@ -0,0 +1,122 @@ +require 'active_record/associations/join_dependency/join_part' + +module ActiveRecord + module Associations + class JoinDependency # :nodoc: + class JoinAssociation < JoinPart # :nodoc: + # The reflection of the association represented + attr_reader :reflection + + attr_accessor :tables + + def initialize(reflection, children) + super(reflection.klass, children) + + @reflection = reflection + @tables = nil + end + + def match?(other) + return true if self == other + super && reflection == other.reflection + end + + JoinInformation = Struct.new :joins, :binds + + def join_constraints(foreign_table, foreign_klass, node, join_type, tables, scope_chain, chain) + joins = [] + bind_values = [] + tables = tables.reverse + + scope_chain_index = 0 + scope_chain = scope_chain.reverse + + # The chain starts with the target table, but we want to end with it here (makes + # more sense in this context), so we reverse + chain.reverse_each do |reflection| + table = tables.shift + klass = reflection.klass + + join_keys = reflection.join_keys(klass) + key = join_keys.key + foreign_key = join_keys.foreign_key + + constraint = build_constraint(klass, table, key, foreign_table, foreign_key) + + scope_chain_items = scope_chain[scope_chain_index].map do |item| + if item.is_a?(Relation) + item + else + ActiveRecord::Relation.create(klass, table).instance_exec(node, &item) + end + end + scope_chain_index += 1 + + scope_chain_items.concat [klass.send(:build_default_scope, ActiveRecord::Relation.create(klass, table))].compact + + rel = scope_chain_items.inject(scope_chain_items.shift) do |left, right| + left.merge right + end + + if rel && !rel.arel.constraints.empty? + bind_values.concat rel.bind_values + constraint = constraint.and rel.arel.constraints + end + + if reflection.type + value = foreign_klass.base_class.name + column = klass.columns_hash[reflection.type.to_s] + + substitute = klass.connection.substitute_at(column) + bind_values.push [column, value] + constraint = constraint.and table[reflection.type].eq substitute + end + + joins << table.create_join(table, table.create_on(constraint), join_type) + + # The current table in this iteration becomes the foreign table in the next + foreign_table, foreign_klass = table, klass + end + + JoinInformation.new joins, bind_values + end + + # Builds equality condition. + # + # Example: + # + # class Physician < ActiveRecord::Base + # has_many :appointments + # end + # + # If I execute `Physician.joins(:appointments).to_a` then + # klass # => Physician + # table # => # + # key # => physician_id + # foreign_table # => # + # foreign_key # => id + # + def build_constraint(klass, table, key, foreign_table, foreign_key) + constraint = table[key].eq(foreign_table[foreign_key]) + + if klass.finder_needs_type_condition? + constraint = table.create_and([ + constraint, + klass.send(:type_condition, table) + ]) + end + + constraint + end + + def table + tables.first + end + + def aliased_table_name + table.table_alias || table.name + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/join_dependency/join_base.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/join_dependency/join_base.rb new file mode 100644 index 0000000..3a26c25 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/join_dependency/join_base.rb @@ -0,0 +1,22 @@ +require 'active_record/associations/join_dependency/join_part' + +module ActiveRecord + module Associations + class JoinDependency # :nodoc: + class JoinBase < JoinPart # :nodoc: + def match?(other) + return true if self == other + super && base_klass == other.base_klass + end + + def table + base_klass.arel_table + end + + def aliased_table_name + base_klass.table_name + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/join_dependency/join_part.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/join_dependency/join_part.rb new file mode 100644 index 0000000..9c6573f --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/join_dependency/join_part.rb @@ -0,0 +1,71 @@ +module ActiveRecord + module Associations + class JoinDependency # :nodoc: + # A JoinPart represents a part of a JoinDependency. It is inherited + # by JoinBase and JoinAssociation. A JoinBase represents the Active Record which + # everything else is being joined onto. A JoinAssociation represents an association which + # is joining to the base. A JoinAssociation may result in more than one actual join + # operations (for example a has_and_belongs_to_many JoinAssociation would result in + # two; one for the join table and one for the target table). + class JoinPart # :nodoc: + include Enumerable + + # The Active Record class which this join part is associated 'about'; for a JoinBase + # this is the actual base model, for a JoinAssociation this is the target model of the + # association. + attr_reader :base_klass, :children + + delegate :table_name, :column_names, :primary_key, :to => :base_klass + + def initialize(base_klass, children) + @base_klass = base_klass + @children = children + end + + def name + reflection.name + end + + def match?(other) + self.class == other.class + end + + def each(&block) + yield self + children.each { |child| child.each(&block) } + end + + # An Arel::Table for the active_record + def table + raise NotImplementedError + end + + # The alias for the active_record's table + def aliased_table_name + raise NotImplementedError + end + + def extract_record(row, column_names_with_alias) + # This code is performance critical as it is called per row. + # see: https://github.com/rails/rails/pull/12185 + hash = {} + + index = 0 + length = column_names_with_alias.length + + while index < length + column_name, alias_name = column_names_with_alias[index] + hash[column_name] = row[alias_name] + index += 1 + end + + hash + end + + def instantiate(row, aliases) + base_klass.instantiate(extract_record(row, aliases)) + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/preloader.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/preloader.rb new file mode 100644 index 0000000..423ac6a --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/preloader.rb @@ -0,0 +1,203 @@ +module ActiveRecord + module Associations + # Implements the details of eager loading of Active Record associations. + # + # Suppose that you have the following two Active Record models: + # + # class Author < ActiveRecord::Base + # # columns: name, age + # has_many :books + # end + # + # class Book < ActiveRecord::Base + # # columns: title, sales, author_id + # end + # + # When you load an author with all associated books Active Record will make + # multiple queries like this: + # + # Author.includes(:books).where(name: ['bell hooks', 'Homer']).to_a + # + # => SELECT `authors`.* FROM `authors` WHERE `name` IN ('bell hooks', 'Homer') + # => SELECT `books`.* FROM `books` WHERE `author_id` IN (2, 5) + # + # Active Record saves the ids of the records from the first query to use in + # the second. Depending on the number of associations involved there can be + # arbitrarily many SQL queries made. + # + # However, if there is a WHERE clause that spans across tables Active + # Record will fall back to a slightly more resource-intensive single query: + # + # Author.includes(:books).where(books: {title: 'Illiad'}).to_a + # => SELECT `authors`.`id` AS t0_r0, `authors`.`name` AS t0_r1, `authors`.`age` AS t0_r2, + # `books`.`id` AS t1_r0, `books`.`title` AS t1_r1, `books`.`sales` AS t1_r2 + # FROM `authors` + # LEFT OUTER JOIN `books` ON `authors`.`id` = `books`.`author_id` + # WHERE `books`.`title` = 'Illiad' + # + # This could result in many rows that contain redundant data and it performs poorly at scale + # and is therefore only used when necessary. + # + class Preloader #:nodoc: + extend ActiveSupport::Autoload + + eager_autoload do + autoload :Association, 'active_record/associations/preloader/association' + autoload :SingularAssociation, 'active_record/associations/preloader/singular_association' + autoload :CollectionAssociation, 'active_record/associations/preloader/collection_association' + autoload :ThroughAssociation, 'active_record/associations/preloader/through_association' + + autoload :HasMany, 'active_record/associations/preloader/has_many' + autoload :HasManyThrough, 'active_record/associations/preloader/has_many_through' + autoload :HasOne, 'active_record/associations/preloader/has_one' + autoload :HasOneThrough, 'active_record/associations/preloader/has_one_through' + autoload :BelongsTo, 'active_record/associations/preloader/belongs_to' + end + + # Eager loads the named associations for the given Active Record record(s). + # + # In this description, 'association name' shall refer to the name passed + # to an association creation method. For example, a model that specifies + # belongs_to :author, has_many :buyers has association + # names +:author+ and +:buyers+. + # + # == Parameters + # +records+ is an array of ActiveRecord::Base. This array needs not be flat, + # i.e. +records+ itself may also contain arrays of records. In any case, + # +preload_associations+ will preload the all associations records by + # flattening +records+. + # + # +associations+ specifies one or more associations that you want to + # preload. It may be: + # - a Symbol or a String which specifies a single association name. For + # example, specifying +:books+ allows this method to preload all books + # for an Author. + # - an Array which specifies multiple association names. This array + # is processed recursively. For example, specifying [:avatar, :books] + # allows this method to preload an author's avatar as well as all of his + # books. + # - a Hash which specifies multiple association names, as well as + # association names for the to-be-preloaded association objects. For + # example, specifying { author: :avatar } will preload a + # book's author, as well as that author's avatar. + # + # +:associations+ has the same format as the +:include+ option for + # ActiveRecord::Base.find. So +associations+ could look like this: + # + # :books + # [ :books, :author ] + # { author: :avatar } + # [ :books, { author: :avatar } ] + + NULL_RELATION = Struct.new(:values, :bind_values).new({}, []) + + def preload(records, associations, preload_scope = nil) + records = Array.wrap(records).compact.uniq + associations = Array.wrap(associations) + preload_scope = preload_scope || NULL_RELATION + + if records.empty? + [] + else + associations.flat_map { |association| + preloaders_on association, records, preload_scope + } + end + end + + private + + def preloaders_on(association, records, scope) + case association + when Hash + preloaders_for_hash(association, records, scope) + when Symbol + preloaders_for_one(association, records, scope) + when String + preloaders_for_one(association.to_sym, records, scope) + else + raise ArgumentError, "#{association.inspect} was not recognised for preload" + end + end + + def preloaders_for_hash(association, records, scope) + association.flat_map { |parent, child| + loaders = preloaders_for_one parent, records, scope + + recs = loaders.flat_map(&:preloaded_records).uniq + loaders.concat Array.wrap(child).flat_map { |assoc| + preloaders_on assoc, recs, scope + } + loaders + } + end + + # Not all records have the same class, so group then preload group on the reflection + # itself so that if various subclass share the same association then we do not split + # them unnecessarily + # + # Additionally, polymorphic belongs_to associations can have multiple associated + # classes, depending on the polymorphic_type field. So we group by the classes as + # well. + def preloaders_for_one(association, records, scope) + grouped_records(association, records).flat_map do |reflection, klasses| + klasses.map do |rhs_klass, rs| + loader = preloader_for(reflection, rs, rhs_klass).new(rhs_klass, rs, reflection, scope) + loader.run self + loader + end + end + end + + def grouped_records(association, records) + h = {} + records.each do |record| + next unless record + assoc = record.association(association) + klasses = h[assoc.reflection] ||= {} + (klasses[assoc.klass] ||= []) << record + end + h + end + + class AlreadyLoaded # :nodoc: + attr_reader :owners, :reflection + + def initialize(klass, owners, reflection, preload_scope) + @owners = owners + @reflection = reflection + end + + def run(preloader); end + + def preloaded_records + owners.flat_map { |owner| owner.association(reflection.name).target } + end + end + + class NullPreloader # :nodoc: + def self.new(klass, owners, reflection, preload_scope); self; end + def self.run(preloader); end + def self.preloaded_records; []; end + end + + def preloader_for(reflection, owners, rhs_klass) + return NullPreloader unless rhs_klass + + if owners.first.association(reflection.name).loaded? + return AlreadyLoaded + end + reflection.check_preloadable! + + case reflection.macro + when :has_many + reflection.options[:through] ? HasManyThrough : HasMany + when :has_one + reflection.options[:through] ? HasOneThrough : HasOne + when :belongs_to + BelongsTo + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/preloader/association.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/preloader/association.rb new file mode 100644 index 0000000..41c4630 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/preloader/association.rb @@ -0,0 +1,166 @@ +module ActiveRecord + module Associations + class Preloader + class Association #:nodoc: + attr_reader :owners, :reflection, :preload_scope, :model, :klass + attr_reader :preloaded_records + + def initialize(klass, owners, reflection, preload_scope) + @klass = klass + @owners = owners + @reflection = reflection + @preload_scope = preload_scope + @model = owners.first && owners.first.class + @scope = nil + @owners_by_key = nil + @preloaded_records = [] + end + + def run(preloader) + preload(preloader) + end + + def preload(preloader) + raise NotImplementedError + end + + def scope + @scope ||= build_scope + end + + def records_for(ids) + query_scope(ids) + end + + def query_scope(ids) + scope.where(association_key.in(ids)) + end + + def table + klass.arel_table + end + + # The name of the key on the associated records + def association_key_name + raise NotImplementedError + end + + # This is overridden by HABTM as the condition should be on the foreign_key column in + # the join table + def association_key + table[association_key_name] + end + + # The name of the key on the model which declares the association + def owner_key_name + raise NotImplementedError + end + + def owners_by_key + @owners_by_key ||= if key_conversion_required? + owners.group_by do |owner| + owner[owner_key_name].to_s + end + else + owners.group_by do |owner| + owner[owner_key_name] + end + end + end + + def options + reflection.options + end + + private + + def associated_records_by_owner(preloader) + owners_map = owners_by_key + owner_keys = owners_map.keys.compact + + # Each record may have multiple owners, and vice-versa + records_by_owner = owners.each_with_object({}) do |owner,h| + h[owner] = [] + end + + if owner_keys.any? + # Some databases impose a limit on the number of ids in a list (in Oracle it's 1000) + # Make several smaller queries if necessary or make one query if the adapter supports it + sliced = owner_keys.each_slice(klass.connection.in_clause_length || owner_keys.size) + + records = load_slices sliced + records.each do |record, owner_key| + owners_map[owner_key].each do |owner| + records_by_owner[owner] << record + end + end + end + + records_by_owner + end + + def key_conversion_required? + association_key_type != owner_key_type + end + + def association_key_type + @klass.type_for_attribute(association_key_name.to_s).type + end + + def owner_key_type + @model.type_for_attribute(owner_key_name.to_s).type + end + + def load_slices(slices) + @preloaded_records = slices.flat_map { |slice| + records_for(slice) + } + + @preloaded_records.map { |record| + key = record[association_key_name] + key = key.to_s if key_conversion_required? + + [record, key] + } + end + + def reflection_scope + @reflection_scope ||= reflection.scope ? klass.unscoped.instance_exec(nil, &reflection.scope) : klass.unscoped + end + + def build_scope + scope = klass.unscoped + + values = reflection_scope.values + reflection_binds = reflection_scope.bind_values + preload_values = preload_scope.values + preload_binds = preload_scope.bind_values + + scope.where_values = Array(values[:where]) + Array(preload_values[:where]) + scope.references_values = Array(values[:references]) + Array(preload_values[:references]) + scope.bind_values = (reflection_binds + preload_binds) + + scope._select! preload_values[:select] || values[:select] || table[Arel.star] + scope.includes! preload_values[:includes] || values[:includes] + scope.joins! preload_values[:joins] || values[:joins] + scope.order! preload_values[:order] || values[:order] + + if preload_values[:reordering] || values[:reordering] + scope.reordering_value = true + end + + if preload_values[:readonly] || values[:readonly] + scope.readonly! + end + + if options[:as] + scope.where!(klass.table_name => { reflection.type => model.base_class.sti_name }) + end + + scope.unscope_values = Array(values[:unscope]) + Array(preload_values[:unscope]) + klass.default_scoped.merge(scope) + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/preloader/belongs_to.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/preloader/belongs_to.rb new file mode 100644 index 0000000..5091d47 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/preloader/belongs_to.rb @@ -0,0 +1,17 @@ +module ActiveRecord + module Associations + class Preloader + class BelongsTo < SingularAssociation #:nodoc: + + def association_key_name + reflection.options[:primary_key] || klass && klass.primary_key + end + + def owner_key_name + reflection.foreign_key + end + + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/preloader/collection_association.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/preloader/collection_association.rb new file mode 100644 index 0000000..5adffcd --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/preloader/collection_association.rb @@ -0,0 +1,24 @@ +module ActiveRecord + module Associations + class Preloader + class CollectionAssociation < Association #:nodoc: + + private + + def build_scope + super.order(preload_scope.values[:order] || reflection_scope.values[:order]) + end + + def preload(preloader) + associated_records_by_owner(preloader).each do |owner, records| + association = owner.association(reflection.name) + association.loaded! + association.target.concat(records) + records.each { |record| association.set_inverse_instance(record) } + end + end + + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/preloader/has_many.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/preloader/has_many.rb new file mode 100644 index 0000000..3ea91a8 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/preloader/has_many.rb @@ -0,0 +1,17 @@ +module ActiveRecord + module Associations + class Preloader + class HasMany < CollectionAssociation #:nodoc: + + def association_key_name + reflection.foreign_key + end + + def owner_key_name + reflection.active_record_primary_key + end + + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/preloader/has_many_through.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/preloader/has_many_through.rb new file mode 100644 index 0000000..7b37b59 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/preloader/has_many_through.rb @@ -0,0 +1,19 @@ +module ActiveRecord + module Associations + class Preloader + class HasManyThrough < CollectionAssociation #:nodoc: + include ThroughAssociation + + def associated_records_by_owner(preloader) + records_by_owner = super + + if reflection_scope.distinct_value + records_by_owner.each_value { |records| records.uniq! } + end + + records_by_owner + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/preloader/has_one.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/preloader/has_one.rb new file mode 100644 index 0000000..24728e9 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/preloader/has_one.rb @@ -0,0 +1,23 @@ +module ActiveRecord + module Associations + class Preloader + class HasOne < SingularAssociation #:nodoc: + + def association_key_name + reflection.foreign_key + end + + def owner_key_name + reflection.active_record_primary_key + end + + private + + def build_scope + super.order(preload_scope.values[:order] || reflection_scope.values[:order]) + end + + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/preloader/has_one_through.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/preloader/has_one_through.rb new file mode 100644 index 0000000..f063f85 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/preloader/has_one_through.rb @@ -0,0 +1,9 @@ +module ActiveRecord + module Associations + class Preloader + class HasOneThrough < SingularAssociation #:nodoc: + include ThroughAssociation + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/preloader/singular_association.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/preloader/singular_association.rb new file mode 100644 index 0000000..f60647a --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/preloader/singular_association.rb @@ -0,0 +1,21 @@ +module ActiveRecord + module Associations + class Preloader + class SingularAssociation < Association #:nodoc: + + private + + def preload(preloader) + associated_records_by_owner(preloader).each do |owner, associated_records| + record = associated_records.first + + association = owner.association(reflection.name) + association.target = record + association.set_inverse_instance(record) if record + end + end + + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/preloader/through_association.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/preloader/through_association.rb new file mode 100644 index 0000000..12bf3ef --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/preloader/through_association.rb @@ -0,0 +1,96 @@ +module ActiveRecord + module Associations + class Preloader + module ThroughAssociation #:nodoc: + def through_reflection + reflection.through_reflection + end + + def source_reflection + reflection.source_reflection + end + + def associated_records_by_owner(preloader) + preloader.preload(owners, + through_reflection.name, + through_scope) + + through_records = owners.map do |owner| + association = owner.association through_reflection.name + + [owner, Array(association.reader)] + end + + reset_association owners, through_reflection.name + + middle_records = through_records.flat_map { |(_,rec)| rec } + + preloaders = preloader.preload(middle_records, + source_reflection.name, + reflection_scope) + + @preloaded_records = preloaders.flat_map(&:preloaded_records) + + middle_to_pl = preloaders.each_with_object({}) do |pl,h| + pl.owners.each { |middle| + h[middle] = pl + } + end + + record_offset = {} + @preloaded_records.each_with_index do |record,i| + record_offset[record] = i + end + + through_records.each_with_object({}) { |(lhs,center),records_by_owner| + pl_to_middle = center.group_by { |record| middle_to_pl[record] } + + records_by_owner[lhs] = pl_to_middle.flat_map do |pl, middles| + rhs_records = middles.flat_map { |r| + association = r.association source_reflection.name + + association.reader + }.compact + + rhs_records.sort_by { |rhs| record_offset[rhs] } + end + } + end + + private + + def reset_association(owners, association_name) + should_reset = (through_scope != through_reflection.klass.unscoped) || + (reflection.options[:source_type] && through_reflection.collection?) + + # Don't cache the association - we would only be caching a subset + if should_reset + owners.each { |owner| + owner.association(association_name).reset + } + end + end + + + def through_scope + scope = through_reflection.klass.unscoped + + if options[:source_type] + scope.where! reflection.foreign_type => options[:source_type] + else + unless reflection_scope.where_values.empty? + scope.includes_values = Array(reflection_scope.values[:includes] || options[:source]) + scope.where_values = reflection_scope.values[:where] + scope.bind_values = reflection_scope.bind_values + end + + scope.references! reflection_scope.values[:references] + scope = scope.order reflection_scope.values[:order] if scope.eager_loading? + end + + scope + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/singular_association.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/singular_association.rb new file mode 100644 index 0000000..964a8af --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/singular_association.rb @@ -0,0 +1,80 @@ +module ActiveRecord + module Associations + class SingularAssociation < Association #:nodoc: + # Implements the reader method, e.g. foo.bar for Foo.has_one :bar + def reader(force_reload = false) + if force_reload && klass + klass.uncached { reload } + elsif !loaded? || stale_target? + reload + end + + target + end + + # Implements the writer method, e.g. foo.bar= for Foo.belongs_to :bar + def writer(record) + replace(record) + end + + def create(attributes = {}, &block) + _create_record(attributes, &block) + end + + def create!(attributes = {}, &block) + _create_record(attributes, true, &block) + end + + def build(attributes = {}) + record = build_record(attributes) + yield(record) if block_given? + set_new_record(record) + record + end + + private + + def create_scope + scope.scope_for_create.stringify_keys.except(klass.primary_key) + end + + def get_records + return scope.limit(1).to_a if skip_statement_cache? + + conn = klass.connection + sc = reflection.association_scope_cache(conn, owner) do + StatementCache.create(conn) { |params| + as = AssociationScope.create { params.bind } + target_scope.merge(as.scope(self, conn)).limit(1) + } + end + + binds = AssociationScope.get_bind_values(owner, reflection.chain) + sc.execute binds, klass, klass.connection + end + + def find_target + if record = get_records.first + set_inverse_instance record + end + end + + def replace(record) + raise NotImplementedError, "Subclasses must implement a replace(record) method" + end + + def set_new_record(record) + replace(record) + end + + def _create_record(attributes, raise_error = false) + record = build_record(attributes) + yield(record) if block_given? + saved = record.save + set_new_record(record) + raise RecordInvalid.new(record) if !saved && raise_error + record + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/through_association.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/through_association.rb new file mode 100644 index 0000000..df7e859 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/through_association.rb @@ -0,0 +1,101 @@ +module ActiveRecord + # = Active Record Through Association + module Associations + module ThroughAssociation #:nodoc: + + delegate :source_reflection, :through_reflection, :to => :reflection + + protected + + # We merge in these scopes for two reasons: + # + # 1. To get the default_scope conditions for any of the other reflections in the chain + # 2. To get the type conditions for any STI models in the chain + def target_scope + scope = super + reflection.chain.drop(1).each do |reflection| + relation = reflection.klass.all + scope.merge!( + relation.except(:select, :create_with, :includes, :preload, :joins, :eager_load) + ) + end + scope + end + + private + + # Construct attributes for :through pointing to owner and associate. This is used by the + # methods which create and delete records on the association. + # + # We only support indirectly modifying through associations which has a belongs_to source. + # This is the "has_many :tags, through: :taggings" situation, where the join model + # typically has a belongs_to on both side. In other words, associations which could also + # be represented as has_and_belongs_to_many associations. + # + # We do not support creating/deleting records on the association where the source has + # some other type, because this opens up a whole can of worms, and in basically any + # situation it is more natural for the user to just create or modify their join records + # directly as required. + def construct_join_attributes(*records) + ensure_mutable + + if source_reflection.association_primary_key(reflection.klass) == reflection.klass.primary_key + join_attributes = { source_reflection.name => records } + else + join_attributes = { + source_reflection.foreign_key => + records.map { |record| + record.send(source_reflection.association_primary_key(reflection.klass)) + } + } + end + + if options[:source_type] + join_attributes[source_reflection.foreign_type] = + records.map { |record| record.class.base_class.name } + end + + if records.count == 1 + Hash[join_attributes.map { |k, v| [k, v.first] }] + else + join_attributes + end + end + + # Note: this does not capture all cases, for example it would be crazy to try to + # properly support stale-checking for nested associations. + def stale_state + if through_reflection.belongs_to? + owner[through_reflection.foreign_key] && owner[through_reflection.foreign_key].to_s + end + end + + def foreign_key_present? + through_reflection.belongs_to? && !owner[through_reflection.foreign_key].nil? + end + + def ensure_mutable + unless source_reflection.belongs_to? + raise HasManyThroughCantAssociateThroughHasOneOrManyReflection.new(owner, reflection) + end + end + + def ensure_not_nested + if reflection.nested? + raise HasManyThroughNestedAssociationsAreReadonly.new(owner, reflection) + end + end + + def build_record(attributes) + inverse = source_reflection.inverse_of + target = through_association.target + + if inverse && target && !target.is_a?(Array) + attributes[inverse.foreign_key] = target.id + end + + super(attributes) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attribute.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attribute.rb new file mode 100644 index 0000000..8037216 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attribute.rb @@ -0,0 +1,163 @@ +module ActiveRecord + class Attribute # :nodoc: + class << self + def from_database(name, value, type) + FromDatabase.new(name, value, type) + end + + def from_user(name, value, type) + FromUser.new(name, value, type) + end + + def with_cast_value(name, value, type) + WithCastValue.new(name, value, type) + end + + def null(name) + Null.new(name) + end + + def uninitialized(name, type) + Uninitialized.new(name, type) + end + end + + attr_reader :name, :value_before_type_cast, :type + + # This method should not be called directly. + # Use #from_database or #from_user + def initialize(name, value_before_type_cast, type) + @name = name + @value_before_type_cast = value_before_type_cast + @type = type + end + + def value + # `defined?` is cheaper than `||=` when we get back falsy values + @value = original_value unless defined?(@value) + @value + end + + def original_value + type_cast(value_before_type_cast) + end + + def value_for_database + type.type_cast_for_database(value) + end + + def changed_from?(old_value) + type.changed?(old_value, value, value_before_type_cast) + end + + def changed_in_place_from?(old_value) + has_been_read? && type.changed_in_place?(old_value, value) + end + + def with_value_from_user(value) + self.class.from_user(name, value, type) + end + + def with_value_from_database(value) + self.class.from_database(name, value, type) + end + + def with_cast_value(value) + self.class.with_cast_value(name, value, type) + end + + def type_cast(*) + raise NotImplementedError + end + + def initialized? + true + end + + def came_from_user? + false + end + + def ==(other) + self.class == other.class && + name == other.name && + value_before_type_cast == other.value_before_type_cast && + type == other.type + end + + protected + + def initialize_dup(other) + if defined?(@value) && @value.duplicable? + @value = @value.dup + end + end + + private + + def has_been_read? + defined?(@value) + end + + class FromDatabase < Attribute # :nodoc: + def type_cast(value) + type.type_cast_from_database(value) + end + end + + class FromUser < Attribute # :nodoc: + def type_cast(value) + type.type_cast_from_user(value) + end + + def came_from_user? + true + end + end + + class WithCastValue < Attribute # :nodoc: + def type_cast(value) + value + end + + def changed_in_place_from?(old_value) + false + end + end + + class Null < Attribute # :nodoc: + def initialize(name) + super(name, nil, Type::Value.new) + end + + def value + nil + end + + def with_value_from_database(value) + raise ActiveModel::MissingAttributeError, "can't write unknown attribute `#{name}`" + end + alias_method :with_value_from_user, :with_value_from_database + end + + class Uninitialized < Attribute # :nodoc: + def initialize(name, type) + super(name, nil, type) + end + + def value + if block_given? + yield name + end + end + + def value_for_database + end + + def initialized? + false + end + end + private_constant :FromDatabase, :FromUser, :Null, :Uninitialized + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attribute_assignment.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attribute_assignment.rb new file mode 100644 index 0000000..e9e65a6 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attribute_assignment.rb @@ -0,0 +1,212 @@ +require 'active_model/forbidden_attributes_protection' + +module ActiveRecord + module AttributeAssignment + extend ActiveSupport::Concern + include ActiveModel::ForbiddenAttributesProtection + + # Allows you to set all the attributes by passing in a hash of attributes with + # keys matching the attribute names (which again matches the column names). + # + # If the passed hash responds to permitted? method and the return value + # of this method is +false+ an ActiveModel::ForbiddenAttributesError + # exception is raised. + # + # cat = Cat.new(name: "Gorby", status: "yawning") + # cat.attributes # => { "name" => "Gorby", "status" => "yawning", "created_at" => nil, "updated_at" => nil} + # cat.assign_attributes(status: "sleeping") + # cat.attributes # => { "name" => "Gorby", "status" => "sleeping", "created_at" => nil, "updated_at" => nil } + # + # New attributes will be persisted in the database when the object is saved. + # + # Aliased to attributes=. + def assign_attributes(new_attributes) + if !new_attributes.respond_to?(:stringify_keys) + raise ArgumentError, "When assigning attributes, you must pass a hash as an argument." + end + return if new_attributes.blank? + + attributes = new_attributes.stringify_keys + multi_parameter_attributes = [] + nested_parameter_attributes = [] + + attributes = sanitize_for_mass_assignment(attributes) + + attributes.each do |k, v| + if k.include?("(") + multi_parameter_attributes << [ k, v ] + elsif v.is_a?(Hash) + nested_parameter_attributes << [ k, v ] + else + _assign_attribute(k, v) + end + end + + assign_nested_parameter_attributes(nested_parameter_attributes) unless nested_parameter_attributes.empty? + assign_multiparameter_attributes(multi_parameter_attributes) unless multi_parameter_attributes.empty? + end + + alias attributes= assign_attributes + + private + + def _assign_attribute(k, v) + public_send("#{k}=", v) + rescue NoMethodError, NameError + if respond_to?("#{k}=") + raise + else + raise UnknownAttributeError.new(self, k) + end + end + + # Assign any deferred nested attributes after the base attributes have been set. + def assign_nested_parameter_attributes(pairs) + pairs.each { |k, v| _assign_attribute(k, v) } + end + + # Instantiates objects for all attribute classes that needs more than one constructor parameter. This is done + # by calling new on the column type or aggregation type (through composed_of) object with these parameters. + # So having the pairs written_on(1) = "2004", written_on(2) = "6", written_on(3) = "24", will instantiate + # written_on (a date type) with Date.new("2004", "6", "24"). You can also specify a typecast character in the + # parentheses to have the parameters typecasted before they're used in the constructor. Use i for Fixnum and + # f for Float. If all the values for a given attribute are empty, the attribute will be set to +nil+. + def assign_multiparameter_attributes(pairs) + execute_callstack_for_multiparameter_attributes( + extract_callstack_for_multiparameter_attributes(pairs) + ) + end + + def execute_callstack_for_multiparameter_attributes(callstack) + errors = [] + callstack.each do |name, values_with_empty_parameters| + begin + send("#{name}=", MultiparameterAttribute.new(self, name, values_with_empty_parameters).read_value) + rescue => ex + errors << AttributeAssignmentError.new("error on assignment #{values_with_empty_parameters.values.inspect} to #{name} (#{ex.message})", ex, name) + end + end + unless errors.empty? + error_descriptions = errors.map { |ex| ex.message }.join(",") + raise MultiparameterAssignmentErrors.new(errors), "#{errors.size} error(s) on assignment of multiparameter attributes [#{error_descriptions}]" + end + end + + def extract_callstack_for_multiparameter_attributes(pairs) + attributes = {} + + pairs.each do |(multiparameter_name, value)| + attribute_name = multiparameter_name.split("(").first + attributes[attribute_name] ||= {} + + parameter_value = value.empty? ? nil : type_cast_attribute_value(multiparameter_name, value) + attributes[attribute_name][find_parameter_position(multiparameter_name)] ||= parameter_value + end + + attributes + end + + def type_cast_attribute_value(multiparameter_name, value) + multiparameter_name =~ /\([0-9]*([if])\)/ ? value.send("to_" + $1) : value + end + + def find_parameter_position(multiparameter_name) + multiparameter_name.scan(/\(([0-9]*).*\)/).first.first.to_i + end + + class MultiparameterAttribute #:nodoc: + attr_reader :object, :name, :values, :cast_type + + def initialize(object, name, values) + @object = object + @name = name + @values = values + end + + def read_value + return if values.values.compact.empty? + + @cast_type = object.type_for_attribute(name) + klass = cast_type.klass + + if klass == Time + read_time + elsif klass == Date + read_date + else + read_other + end + end + + private + + def instantiate_time_object(set_values) + if object.class.send(:create_time_zone_conversion_attribute?, name, cast_type) + Time.zone.local(*set_values) + else + Time.send(object.class.default_timezone, *set_values) + end + end + + def read_time + # If column is a :time (and not :date or :datetime) there is no need to validate if + # there are year/month/day fields + if cast_type.type == :time + # if the column is a time set the values to their defaults as January 1, 1970, but only if they're nil + { 1 => 1970, 2 => 1, 3 => 1 }.each do |key,value| + values[key] ||= value + end + else + # else column is a timestamp, so if Date bits were not provided, error + validate_required_parameters!([1,2,3]) + + # If Date bits were provided but blank, then return nil + return if blank_date_parameter? + end + + max_position = extract_max_param(6) + set_values = values.values_at(*(1..max_position)) + # If Time bits are not there, then default to 0 + (3..5).each { |i| set_values[i] = set_values[i].presence || 0 } + instantiate_time_object(set_values) + end + + def read_date + return if blank_date_parameter? + set_values = values.values_at(1,2,3) + begin + Date.new(*set_values) + rescue ArgumentError # if Date.new raises an exception on an invalid date + instantiate_time_object(set_values).to_date # we instantiate Time object and convert it back to a date thus using Time's logic in handling invalid dates + end + end + + def read_other + max_position = extract_max_param + positions = (1..max_position) + validate_required_parameters!(positions) + + values.slice(*positions) + end + + # Checks whether some blank date parameter exists. Note that this is different + # than the validate_required_parameters! method, since it just checks for blank + # positions instead of missing ones, and does not raise in case one blank position + # exists. The caller is responsible to handle the case of this returning true. + def blank_date_parameter? + (1..3).any? { |position| values[position].blank? } + end + + # If some position is not provided, it errors out a missing parameter exception. + def validate_required_parameters!(positions) + if missing_parameter = positions.detect { |position| !values.key?(position) } + raise ArgumentError.new("Missing Parameter - #{name}(#{missing_parameter})") + end + end + + def extract_max_param(upper_cap = 100) + [values.keys.max, upper_cap].min + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attribute_decorators.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attribute_decorators.rb new file mode 100644 index 0000000..5b96623 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attribute_decorators.rb @@ -0,0 +1,66 @@ +module ActiveRecord + module AttributeDecorators # :nodoc: + extend ActiveSupport::Concern + + included do + class_attribute :attribute_type_decorations, instance_accessor: false # :internal: + self.attribute_type_decorations = TypeDecorator.new + end + + module ClassMethods # :nodoc: + def decorate_attribute_type(column_name, decorator_name, &block) + matcher = ->(name, _) { name == column_name.to_s } + key = "_#{column_name}_#{decorator_name}" + decorate_matching_attribute_types(matcher, key, &block) + end + + def decorate_matching_attribute_types(matcher, decorator_name, &block) + clear_caches_calculated_from_columns + decorator_name = decorator_name.to_s + + # Create new hashes so we don't modify parent classes + self.attribute_type_decorations = attribute_type_decorations.merge(decorator_name => [matcher, block]) + end + + private + + def add_user_provided_columns(*) + super.map do |column| + decorated_type = attribute_type_decorations.apply(column.name, column.cast_type) + column.with_type(decorated_type) + end + end + end + + class TypeDecorator # :nodoc: + delegate :clear, to: :@decorations + + def initialize(decorations = {}) + @decorations = decorations + end + + def merge(*args) + TypeDecorator.new(@decorations.merge(*args)) + end + + def apply(name, type) + decorations = decorators_for(name, type) + decorations.inject(type) do |new_type, block| + block.call(new_type) + end + end + + private + + def decorators_for(name, type) + matching(name, type).map(&:last) + end + + def matching(name, type) + @decorations.values.select do |(matcher, _)| + matcher.call(name, type) + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attribute_methods.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attribute_methods.rb new file mode 100644 index 0000000..d766996 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attribute_methods.rb @@ -0,0 +1,439 @@ +require 'active_support/core_ext/enumerable' +require 'active_support/core_ext/string/filters' +require 'mutex_m' +require 'thread_safe' + +module ActiveRecord + # = Active Record Attribute Methods + module AttributeMethods + extend ActiveSupport::Concern + include ActiveModel::AttributeMethods + + included do + initialize_generated_modules + include Read + include Write + include BeforeTypeCast + include Query + include PrimaryKey + include TimeZoneConversion + include Dirty + include Serialization + + delegate :column_for_attribute, to: :class + end + + AttrNames = Module.new { + def self.set_name_cache(name, value) + const_name = "ATTR_#{name}" + unless const_defined? const_name + const_set const_name, value.dup.freeze + end + end + } + + BLACKLISTED_CLASS_METHODS = %w(private public protected allocate new name parent superclass) + + class AttributeMethodCache + def initialize + @module = Module.new + @method_cache = ThreadSafe::Cache.new + end + + def [](name) + @method_cache.compute_if_absent(name) do + safe_name = name.unpack('h*').first + temp_method = "__temp__#{safe_name}" + ActiveRecord::AttributeMethods::AttrNames.set_name_cache safe_name, name + @module.module_eval method_body(temp_method, safe_name), __FILE__, __LINE__ + @module.instance_method temp_method + end + end + + private + + # Override this method in the subclasses for method body. + def method_body(method_name, const_name) + raise NotImplementedError, "Subclasses must implement a method_body(method_name, const_name) method." + end + end + + class GeneratedAttributeMethods < Module; end # :nodoc: + + module ClassMethods + def inherited(child_class) #:nodoc: + child_class.initialize_generated_modules + super + end + + def initialize_generated_modules # :nodoc: + @generated_attribute_methods = GeneratedAttributeMethods.new { extend Mutex_m } + @attribute_methods_generated = false + include @generated_attribute_methods + + super + end + + # Generates all the attribute related methods for columns in the database + # accessors, mutators and query methods. + def define_attribute_methods # :nodoc: + return false if @attribute_methods_generated + # Use a mutex; we don't want two threads simultaneously trying to define + # attribute methods. + generated_attribute_methods.synchronize do + return false if @attribute_methods_generated + superclass.define_attribute_methods unless self == base_class + super(column_names) + @attribute_methods_generated = true + end + true + end + + def undefine_attribute_methods # :nodoc: + generated_attribute_methods.synchronize do + super if defined?(@attribute_methods_generated) && @attribute_methods_generated + @attribute_methods_generated = false + end + end + + # Raises a ActiveRecord::DangerousAttributeError exception when an + # \Active \Record method is defined in the model, otherwise +false+. + # + # class Person < ActiveRecord::Base + # def save + # 'already defined by Active Record' + # end + # end + # + # Person.instance_method_already_implemented?(:save) + # # => ActiveRecord::DangerousAttributeError: save is defined by ActiveRecord + # + # Person.instance_method_already_implemented?(:name) + # # => false + def instance_method_already_implemented?(method_name) + if dangerous_attribute_method?(method_name) + raise DangerousAttributeError, "#{method_name} is defined by Active Record. Check to make sure that you don't have an attribute or method with the same name." + end + + if superclass == Base + super + else + # If ThisClass < ... < SomeSuperClass < ... < Base and SomeSuperClass + # defines its own attribute method, then we don't want to overwrite that. + defined = method_defined_within?(method_name, superclass, Base) && + ! superclass.instance_method(method_name).owner.is_a?(GeneratedAttributeMethods) + defined || super + end + end + + # A method name is 'dangerous' if it is already (re)defined by Active Record, but + # not by any ancestors. (So 'puts' is not dangerous but 'save' is.) + def dangerous_attribute_method?(name) # :nodoc: + method_defined_within?(name, Base) + end + + def method_defined_within?(name, klass, superklass = klass.superclass) # :nodoc: + if klass.method_defined?(name) || klass.private_method_defined?(name) + if superklass.method_defined?(name) || superklass.private_method_defined?(name) + klass.instance_method(name).owner != superklass.instance_method(name).owner + else + true + end + else + false + end + end + + # A class method is 'dangerous' if it is already (re)defined by Active Record, but + # not by any ancestors. (So 'puts' is not dangerous but 'new' is.) + def dangerous_class_method?(method_name) + BLACKLISTED_CLASS_METHODS.include?(method_name.to_s) || class_method_defined_within?(method_name, Base) + end + + def class_method_defined_within?(name, klass, superklass = klass.superclass) # :nodoc + if klass.respond_to?(name, true) + if superklass.respond_to?(name, true) + klass.method(name).owner != superklass.method(name).owner + else + true + end + else + false + end + end + + # Returns +true+ if +attribute+ is an attribute method and table exists, + # +false+ otherwise. + # + # class Person < ActiveRecord::Base + # end + # + # Person.attribute_method?('name') # => true + # Person.attribute_method?(:age=) # => true + # Person.attribute_method?(:nothing) # => false + def attribute_method?(attribute) + super || (table_exists? && column_names.include?(attribute.to_s.sub(/=$/, ''))) + end + + # Returns an array of column names as strings if it's not an abstract class and + # table exists. Otherwise it returns an empty array. + # + # class Person < ActiveRecord::Base + # end + # + # Person.attribute_names + # # => ["id", "created_at", "updated_at", "name", "age"] + def attribute_names + @attribute_names ||= if !abstract_class? && table_exists? + column_names + else + [] + end + end + + # Returns the column object for the named attribute. + # Returns nil if the named attribute does not exist. + # + # class Person < ActiveRecord::Base + # end + # + # person = Person.new + # person.column_for_attribute(:name) # the result depends on the ConnectionAdapter + # # => # + # + # person.column_for_attribute(:nothing) + # # => nil + def column_for_attribute(name) + column = columns_hash[name.to_s] + if column.nil? + ActiveSupport::Deprecation.warn(<<-MSG.squish) + `#column_for_attribute` will return a null object for non-existent + columns in Rails 5. Use `#has_attribute?` if you need to check for + an attribute's existence. + MSG + end + column + end + end + + # A Person object with a name attribute can ask person.respond_to?(:name), + # person.respond_to?(:name=), and person.respond_to?(:name?) + # which will all return +true+. It also define the attribute methods if they have + # not been generated. + # + # class Person < ActiveRecord::Base + # end + # + # person = Person.new + # person.respond_to(:name) # => true + # person.respond_to(:name=) # => true + # person.respond_to(:name?) # => true + # person.respond_to('age') # => true + # person.respond_to('age=') # => true + # person.respond_to('age?') # => true + # person.respond_to(:nothing) # => false + def respond_to?(name, include_private = false) + return false unless super + name = name.to_s + + # If the result is true then check for the select case. + # For queries selecting a subset of columns, return false for unselected columns. + # We check defined?(@attributes) not to issue warnings if called on objects that + # have been allocated but not yet initialized. + if defined?(@attributes) && self.class.column_names.include?(name) + return has_attribute?(name) + end + + return true + end + + # Returns +true+ if the given attribute is in the attributes hash, otherwise +false+. + # + # class Person < ActiveRecord::Base + # end + # + # person = Person.new + # person.has_attribute?(:name) # => true + # person.has_attribute?('age') # => true + # person.has_attribute?(:nothing) # => false + def has_attribute?(attr_name) + @attributes.key?(attr_name.to_s) + end + + # Returns an array of names for the attributes available on this object. + # + # class Person < ActiveRecord::Base + # end + # + # person = Person.new + # person.attribute_names + # # => ["id", "created_at", "updated_at", "name", "age"] + def attribute_names + @attributes.keys + end + + # Returns a hash of all the attributes with their names as keys and the values of the attributes as values. + # + # class Person < ActiveRecord::Base + # end + # + # person = Person.create(name: 'Francesco', age: 22) + # person.attributes + # # => {"id"=>3, "created_at"=>Sun, 21 Oct 2012 04:53:04, "updated_at"=>Sun, 21 Oct 2012 04:53:04, "name"=>"Francesco", "age"=>22} + def attributes + @attributes.to_hash + end + + # Returns an #inspect-like string for the value of the + # attribute +attr_name+. String attributes are truncated up to 50 + # characters, Date and Time attributes are returned in the + # :db format, Array attributes are truncated up to 10 values. + # Other attributes return the value of #inspect without + # modification. + # + # person = Person.create!(name: 'David Heinemeier Hansson ' * 3) + # + # person.attribute_for_inspect(:name) + # # => "\"David Heinemeier Hansson David Heinemeier Hansson ...\"" + # + # person.attribute_for_inspect(:created_at) + # # => "\"2012-10-22 00:15:07\"" + # + # person.attribute_for_inspect(:tag_ids) + # # => "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...]" + def attribute_for_inspect(attr_name) + value = read_attribute(attr_name) + + if value.is_a?(String) && value.length > 50 + "#{value[0, 50]}...".inspect + elsif value.is_a?(Date) || value.is_a?(Time) + %("#{value.to_s(:db)}") + elsif value.is_a?(Array) && value.size > 10 + inspected = value.first(10).inspect + %(#{inspected[0...-1]}, ...]) + else + value.inspect + end + end + + # Returns +true+ if the specified +attribute+ has been set by the user or by a + # database load and is neither +nil+ nor empty? (the latter only applies + # to objects that respond to empty?, most notably Strings). Otherwise, +false+. + # Note that it always returns +true+ with boolean attributes. + # + # class Task < ActiveRecord::Base + # end + # + # task = Task.new(title: '', is_done: false) + # task.attribute_present?(:title) # => false + # task.attribute_present?(:is_done) # => true + # task.title = 'Buy milk' + # task.is_done = true + # task.attribute_present?(:title) # => true + # task.attribute_present?(:is_done) # => true + def attribute_present?(attribute) + value = _read_attribute(attribute) + !value.nil? && !(value.respond_to?(:empty?) && value.empty?) + end + + # Returns the value of the attribute identified by attr_name after it has been typecast (for example, + # "2004-12-12" in a date column is cast to a date object, like Date.new(2004, 12, 12)). It raises + # ActiveModel::MissingAttributeError if the identified attribute is missing. + # + # Note: +:id+ is always present. + # + # Alias for the read_attribute method. + # + # class Person < ActiveRecord::Base + # belongs_to :organization + # end + # + # person = Person.new(name: 'Francesco', age: '22') + # person[:name] # => "Francesco" + # person[:age] # => 22 + # + # person = Person.select('id').first + # person[:name] # => ActiveModel::MissingAttributeError: missing attribute: name + # person[:organization_id] # => ActiveModel::MissingAttributeError: missing attribute: organization_id + def [](attr_name) + read_attribute(attr_name) { |n| missing_attribute(n, caller) } + end + + # Updates the attribute identified by attr_name with the specified +value+. + # (Alias for the protected write_attribute method). + # + # class Person < ActiveRecord::Base + # end + # + # person = Person.new + # person[:age] = '22' + # person[:age] # => 22 + # person[:age] # => Fixnum + def []=(attr_name, value) + write_attribute(attr_name, value) + end + + protected + + def clone_attribute_value(reader_method, attribute_name) # :nodoc: + value = send(reader_method, attribute_name) + value.duplicable? ? value.clone : value + rescue TypeError, NoMethodError + value + end + + def arel_attributes_with_values_for_create(attribute_names) # :nodoc: + arel_attributes_with_values(attributes_for_create(attribute_names)) + end + + def arel_attributes_with_values_for_update(attribute_names) # :nodoc: + arel_attributes_with_values(attributes_for_update(attribute_names)) + end + + def attribute_method?(attr_name) # :nodoc: + # We check defined? because Syck calls respond_to? before actually calling initialize. + defined?(@attributes) && @attributes.key?(attr_name) + end + + private + + # Returns a Hash of the Arel::Attributes and attribute values that have been + # typecasted for use in an Arel insert/update method. + def arel_attributes_with_values(attribute_names) + attrs = {} + arel_table = self.class.arel_table + + attribute_names.each do |name| + attrs[arel_table[name]] = typecasted_attribute_value(name) + end + attrs + end + + # Filters the primary keys and readonly attributes from the attribute names. + def attributes_for_update(attribute_names) + attribute_names.reject do |name| + readonly_attribute?(name) + end + end + + # Filters out the primary keys, from the attribute names, when the primary + # key is to be generated (e.g. the id attribute has no value). + def attributes_for_create(attribute_names) + attribute_names.reject do |name| + pk_attribute?(name) && id.nil? + end + end + + def readonly_attribute?(name) + self.class.readonly_attributes.include?(name) + end + + def pk_attribute?(name) + name == self.class.primary_key + end + + def typecasted_attribute_value(name) + _read_attribute(name) + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attribute_methods/before_type_cast.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attribute_methods/before_type_cast.rb new file mode 100644 index 0000000..56c1898 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attribute_methods/before_type_cast.rb @@ -0,0 +1,76 @@ +module ActiveRecord + module AttributeMethods + # = Active Record Attribute Methods Before Type Cast + # + # ActiveRecord::AttributeMethods::BeforeTypeCast provides a way to + # read the value of the attributes before typecasting and deserialization. + # + # class Task < ActiveRecord::Base + # end + # + # task = Task.new(id: '1', completed_on: '2012-10-21') + # task.id # => 1 + # task.completed_on # => Sun, 21 Oct 2012 + # + # task.attributes_before_type_cast + # # => {"id"=>"1", "completed_on"=>"2012-10-21", ... } + # task.read_attribute_before_type_cast('id') # => "1" + # task.read_attribute_before_type_cast('completed_on') # => "2012-10-21" + # + # In addition to #read_attribute_before_type_cast and #attributes_before_type_cast, + # it declares a method for all attributes with the *_before_type_cast + # suffix. + # + # task.id_before_type_cast # => "1" + # task.completed_on_before_type_cast # => "2012-10-21" + module BeforeTypeCast + extend ActiveSupport::Concern + + included do + attribute_method_suffix "_before_type_cast" + attribute_method_suffix "_came_from_user?" + end + + # Returns the value of the attribute identified by +attr_name+ before + # typecasting and deserialization. + # + # class Task < ActiveRecord::Base + # end + # + # task = Task.new(id: '1', completed_on: '2012-10-21') + # task.read_attribute('id') # => 1 + # task.read_attribute_before_type_cast('id') # => '1' + # task.read_attribute('completed_on') # => Sun, 21 Oct 2012 + # task.read_attribute_before_type_cast('completed_on') # => "2012-10-21" + # task.read_attribute_before_type_cast(:completed_on) # => "2012-10-21" + def read_attribute_before_type_cast(attr_name) + @attributes[attr_name.to_s].value_before_type_cast + end + + # Returns a hash of attributes before typecasting and deserialization. + # + # class Task < ActiveRecord::Base + # end + # + # task = Task.new(title: nil, is_done: true, completed_on: '2012-10-21') + # task.attributes + # # => {"id"=>nil, "title"=>nil, "is_done"=>true, "completed_on"=>Sun, 21 Oct 2012, "created_at"=>nil, "updated_at"=>nil} + # task.attributes_before_type_cast + # # => {"id"=>nil, "title"=>nil, "is_done"=>true, "completed_on"=>"2012-10-21", "created_at"=>nil, "updated_at"=>nil} + def attributes_before_type_cast + @attributes.values_before_type_cast + end + + private + + # Handle *_before_type_cast for method_missing. + def attribute_before_type_cast(attribute_name) + read_attribute_before_type_cast(attribute_name) + end + + def attribute_came_from_user?(attribute_name) + @attributes[attribute_name].came_from_user? + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attribute_methods/dirty.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attribute_methods/dirty.rb new file mode 100644 index 0000000..4bb831b --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attribute_methods/dirty.rb @@ -0,0 +1,191 @@ +require 'active_support/core_ext/module/attribute_accessors' + +module ActiveRecord + module AttributeMethods + module Dirty # :nodoc: + extend ActiveSupport::Concern + + include ActiveModel::Dirty + + included do + if self < ::ActiveRecord::Timestamp + raise "You cannot include Dirty after Timestamp" + end + + class_attribute :partial_writes, instance_writer: false + self.partial_writes = true + end + + # Attempts to +save+ the record and clears changed attributes if successful. + def save(*) + if status = super + changes_applied + end + status + end + + # Attempts to save! the record and clears changed attributes if successful. + def save!(*) + super.tap do + changes_applied + end + end + + # reload the record and clears changed attributes. + def reload(*) + super.tap do + clear_changes_information + end + end + + def initialize_dup(other) # :nodoc: + super + @original_raw_attributes = nil + calculate_changes_from_defaults + end + + def changes_applied + super + store_original_raw_attributes + end + + def clear_changes_information + super + original_raw_attributes.clear + end + + def changed_attributes + # This should only be set by methods which will call changed_attributes + # multiple times when it is known that the computed value cannot change. + if defined?(@cached_changed_attributes) + @cached_changed_attributes + else + super.reverse_merge(attributes_changed_in_place).freeze + end + end + + def changes + cache_changed_attributes do + super + end + end + + def attribute_changed_in_place?(attr_name) + old_value = original_raw_attribute(attr_name) + @attributes[attr_name].changed_in_place_from?(old_value) + end + + private + + def changes_include?(attr_name) + super || attribute_changed_in_place?(attr_name) + end + + def calculate_changes_from_defaults + @changed_attributes = nil + self.class.column_defaults.each do |attr, orig_value| + set_attribute_was(attr, orig_value) if _field_changed?(attr, orig_value) + end + end + + # Wrap write_attribute to remember original attribute value. + def write_attribute(attr, value) + attr = attr.to_s + + old_value = old_attribute_value(attr) + + result = super + store_original_raw_attribute(attr) + save_changed_attribute(attr, old_value) + result + end + + def raw_write_attribute(attr, value) + attr = attr.to_s + + result = super + original_raw_attributes[attr] = value + result + end + + def save_changed_attribute(attr, old_value) + clear_changed_attributes_cache + if attribute_changed_by_setter?(attr) + clear_attribute_changes(attr) unless _field_changed?(attr, old_value) + else + set_attribute_was(attr, old_value) if _field_changed?(attr, old_value) + end + end + + def old_attribute_value(attr) + if attribute_changed?(attr) + changed_attributes[attr] + else + clone_attribute_value(:_read_attribute, attr) + end + end + + def _update_record(*) + partial_writes? ? super(keys_for_partial_write) : super + end + + def _create_record(*) + partial_writes? ? super(keys_for_partial_write) : super + end + + # Serialized attributes should always be written in case they've been + # changed in place. + def keys_for_partial_write + changed & persistable_attribute_names + end + + def _field_changed?(attr, old_value) + @attributes[attr].changed_from?(old_value) + end + + def attributes_changed_in_place + changed_in_place.each_with_object({}) do |attr_name, h| + orig = @attributes[attr_name].original_value + h[attr_name] = orig + end + end + + def changed_in_place + self.class.attribute_names.select do |attr_name| + attribute_changed_in_place?(attr_name) + end + end + + def original_raw_attribute(attr_name) + original_raw_attributes.fetch(attr_name) do + read_attribute_before_type_cast(attr_name) + end + end + + def original_raw_attributes + @original_raw_attributes ||= {} + end + + def store_original_raw_attribute(attr_name) + original_raw_attributes[attr_name] = @attributes[attr_name].value_for_database rescue nil + end + + def store_original_raw_attributes + attribute_names.each do |attr| + store_original_raw_attribute(attr) + end + end + + def cache_changed_attributes + @cached_changed_attributes = changed_attributes + yield + ensure + clear_changed_attributes_cache + end + + def clear_changed_attributes_cache + remove_instance_variable(:@cached_changed_attributes) if defined?(@cached_changed_attributes) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attribute_methods/primary_key.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attribute_methods/primary_key.rb new file mode 100644 index 0000000..c28374e --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attribute_methods/primary_key.rb @@ -0,0 +1,128 @@ +require 'set' + +module ActiveRecord + module AttributeMethods + module PrimaryKey + extend ActiveSupport::Concern + + # Returns this record's primary key value wrapped in an Array if one is + # available. + def to_key + sync_with_transaction_state + key = self.id + [key] if key + end + + # Returns the primary key value. + def id + if pk = self.class.primary_key + sync_with_transaction_state + _read_attribute(pk) + end + end + + # Sets the primary key value. + def id=(value) + sync_with_transaction_state + write_attribute(self.class.primary_key, value) if self.class.primary_key + end + + # Queries the primary key value. + def id? + sync_with_transaction_state + query_attribute(self.class.primary_key) + end + + # Returns the primary key value before type cast. + def id_before_type_cast + sync_with_transaction_state + read_attribute_before_type_cast(self.class.primary_key) + end + + # Returns the primary key previous value. + def id_was + sync_with_transaction_state + attribute_was(self.class.primary_key) + end + + protected + + def attribute_method?(attr_name) + attr_name == 'id' || super + end + + module ClassMethods + def define_method_attribute(attr_name) + super + + if attr_name == primary_key && attr_name != 'id' + generated_attribute_methods.send(:alias_method, :id, primary_key) + end + end + + ID_ATTRIBUTE_METHODS = %w(id id= id? id_before_type_cast id_was).to_set + + def dangerous_attribute_method?(method_name) + super && !ID_ATTRIBUTE_METHODS.include?(method_name) + end + + # Defines the primary key field -- can be overridden in subclasses. + # Overwriting will negate any effect of the +primary_key_prefix_type+ + # setting, though. + def primary_key + @primary_key = reset_primary_key unless defined? @primary_key + @primary_key + end + + # Returns a quoted version of the primary key name, used to construct + # SQL statements. + def quoted_primary_key + @quoted_primary_key ||= connection.quote_column_name(primary_key) + end + + def reset_primary_key #:nodoc: + if self == base_class + self.primary_key = get_primary_key(base_class.name) + else + self.primary_key = base_class.primary_key + end + end + + def get_primary_key(base_name) #:nodoc: + if base_name && primary_key_prefix_type == :table_name + base_name.foreign_key(false) + elsif base_name && primary_key_prefix_type == :table_name_with_underscore + base_name.foreign_key + else + if ActiveRecord::Base != self && table_exists? + connection.schema_cache.primary_keys(table_name) + else + 'id' + end + end + end + + # Sets the name of the primary key column. + # + # class Project < ActiveRecord::Base + # self.primary_key = 'sysid' + # end + # + # You can also define the +primary_key+ method yourself: + # + # class Project < ActiveRecord::Base + # def self.primary_key + # 'foo_' + super + # end + # end + # + # Project.primary_key # => "foo_id" + def primary_key=(value) + @primary_key = value && value.to_s + @quoted_primary_key = nil + @attributes_builder = nil + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attribute_methods/query.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attribute_methods/query.rb new file mode 100644 index 0000000..dc689f3 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attribute_methods/query.rb @@ -0,0 +1,40 @@ +module ActiveRecord + module AttributeMethods + module Query + extend ActiveSupport::Concern + + included do + attribute_method_suffix "?" + end + + def query_attribute(attr_name) + value = self[attr_name] + + case value + when true then true + when false, nil then false + else + column = self.class.columns_hash[attr_name] + if column.nil? + if Numeric === value || value !~ /[^0-9]/ + !value.to_i.zero? + else + return false if ActiveRecord::ConnectionAdapters::Column::FALSE_VALUES.include?(value) + !value.blank? + end + elsif column.number? + !value.zero? + else + !value.blank? + end + end + end + + private + # Handle *? for method_missing. + def attribute?(attribute_name) + query_attribute(attribute_name) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attribute_methods/read.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attribute_methods/read.rb new file mode 100644 index 0000000..20f0936 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attribute_methods/read.rb @@ -0,0 +1,103 @@ +require 'active_support/core_ext/module/method_transplanting' + +module ActiveRecord + module AttributeMethods + module Read + ReaderMethodCache = Class.new(AttributeMethodCache) { + private + # We want to generate the methods via module_eval rather than + # define_method, because define_method is slower on dispatch. + # Evaluating many similar methods may use more memory as the instruction + # sequences are duplicated and cached (in MRI). define_method may + # be slower on dispatch, but if you're careful about the closure + # created, then define_method will consume much less memory. + # + # But sometimes the database might return columns with + # characters that are not allowed in normal method names (like + # 'my_column(omg)'. So to work around this we first define with + # the __temp__ identifier, and then use alias method to rename + # it to what we want. + # + # We are also defining a constant to hold the frozen string of + # the attribute name. Using a constant means that we do not have + # to allocate an object on each call to the attribute method. + # Making it frozen means that it doesn't get duped when used to + # key the @attributes in read_attribute. + def method_body(method_name, const_name) + <<-EOMETHOD + def #{method_name} + name = ::ActiveRecord::AttributeMethods::AttrNames::ATTR_#{const_name} + _read_attribute(name) { |n| missing_attribute(n, caller) } + end + EOMETHOD + end + }.new + + extend ActiveSupport::Concern + + module ClassMethods + [:cache_attributes, :cached_attributes, :cache_attribute?].each do |method_name| + define_method method_name do |*| + cached_attributes_deprecation_warning(method_name) + true + end + end + + protected + + def cached_attributes_deprecation_warning(method_name) + ActiveSupport::Deprecation.warn "Calling `#{method_name}` is no longer necessary. All attributes are cached." + end + + if Module.methods_transplantable? + def define_method_attribute(name) + method = ReaderMethodCache[name] + generated_attribute_methods.module_eval { define_method name, method } + end + else + def define_method_attribute(name) + safe_name = name.unpack('h*').first + temp_method = "__temp__#{safe_name}" + + ActiveRecord::AttributeMethods::AttrNames.set_name_cache safe_name, name + + generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1 + def #{temp_method} + name = ::ActiveRecord::AttributeMethods::AttrNames::ATTR_#{safe_name} + _read_attribute(name) { |n| missing_attribute(n, caller) } + end + STR + + generated_attribute_methods.module_eval do + alias_method name, temp_method + undef_method temp_method + end + end + end + end + + ID = 'id'.freeze + + # Returns the value of the attribute identified by attr_name after + # it has been typecast (for example, "2004-12-12" in a date column is cast + # to a date object, like Date.new(2004, 12, 12)). + def read_attribute(attr_name, &block) + name = attr_name.to_s + name = self.class.primary_key if name == ID + _read_attribute(name, &block) + end + + # This method exists to avoid the expensive primary_key check internally, without + # breaking compatibility with the read_attribute API + def _read_attribute(attr_name) # :nodoc: + @attributes.fetch_value(attr_name.to_s) { |n| yield n if block_given? } + end + + private + + def attribute(attribute_name) + _read_attribute(attribute_name) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attribute_methods/serialization.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attribute_methods/serialization.rb new file mode 100644 index 0000000..e5ec5dd --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attribute_methods/serialization.rb @@ -0,0 +1,70 @@ +require 'active_support/core_ext/string/filters' + +module ActiveRecord + module AttributeMethods + module Serialization + extend ActiveSupport::Concern + + module ClassMethods + # If you have an attribute that needs to be saved to the database as an + # object, and retrieved as the same object, then specify the name of that + # attribute using this method and it will be handled automatically. The + # serialization is done through YAML. If +class_name+ is specified, the + # serialized object must be of that class on assignment and retrieval. + # Otherwise SerializationTypeMismatch will be raised. + # + # ==== Parameters + # + # * +attr_name+ - The field name that should be serialized. + # * +class_name_or_coder+ - Optional, a coder object, which responds to `.load` / `.dump` + # or a class name that the object type should be equal to. + # + # ==== Example + # + # # Serialize a preferences attribute. + # class User < ActiveRecord::Base + # serialize :preferences + # end + # + # # Serialize preferences using JSON as coder. + # class User < ActiveRecord::Base + # serialize :preferences, JSON + # end + # + # # Serialize preferences as Hash using YAML coder. + # class User < ActiveRecord::Base + # serialize :preferences, Hash + # end + def serialize(attr_name, class_name_or_coder = Object) + # When ::JSON is used, force it to go through the Active Support JSON encoder + # to ensure special objects (e.g. Active Record models) are dumped correctly + # using the #as_json hook. + coder = if class_name_or_coder == ::JSON + Coders::JSON + elsif [:load, :dump].all? { |x| class_name_or_coder.respond_to?(x) } + class_name_or_coder + else + Coders::YAMLColumn.new(class_name_or_coder) + end + + decorate_attribute_type(attr_name, :serialize) do |type| + Type::Serialized.new(type, coder) + end + end + + def serialized_attributes + ActiveSupport::Deprecation.warn(<<-MSG.squish) + `serialized_attributes` is deprecated without replacement, and will + be removed in Rails 5.0. + MSG + + @serialized_attributes ||= Hash[ + columns.select { |t| t.cast_type.is_a?(Type::Serialized) }.map { |c| + [c.name, c.cast_type.coder] + } + ] + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attribute_methods/time_zone_conversion.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attribute_methods/time_zone_conversion.rb new file mode 100644 index 0000000..777f7ab --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attribute_methods/time_zone_conversion.rb @@ -0,0 +1,69 @@ +module ActiveRecord + module AttributeMethods + module TimeZoneConversion + class TimeZoneConverter < DelegateClass(Type::Value) # :nodoc: + include Type::Decorator + + def type_cast_from_database(value) + convert_time_to_time_zone(super) + end + + def type_cast_from_user(value) + if value.is_a?(Array) + value.map { |v| type_cast_from_user(v) } + elsif value.respond_to?(:in_time_zone) + begin + value.in_time_zone || super + rescue ArgumentError + nil + end + end + end + + def convert_time_to_time_zone(value) + if value.is_a?(Array) + value.map { |v| convert_time_to_time_zone(v) } + elsif value.acts_like?(:time) + value.in_time_zone + else + value + end + end + end + + extend ActiveSupport::Concern + + included do + mattr_accessor :time_zone_aware_attributes, instance_writer: false + self.time_zone_aware_attributes = false + + class_attribute :skip_time_zone_conversion_for_attributes, instance_writer: false + self.skip_time_zone_conversion_for_attributes = [] + end + + module ClassMethods + private + + def inherited(subclass) + # We need to apply this decorator here, rather than on module inclusion. The closure + # created by the matcher would otherwise evaluate for `ActiveRecord::Base`, not the + # sub class being decorated. As such, changes to `time_zone_aware_attributes`, or + # `skip_time_zone_conversion_for_attributes` would not be picked up. + subclass.class_eval do + matcher = ->(name, type) { create_time_zone_conversion_attribute?(name, type) } + decorate_matching_attribute_types(matcher, :_time_zone_conversion) do |type| + TimeZoneConverter.new(type) + end + end + super + end + + def create_time_zone_conversion_attribute?(name, cast_type) + time_zone_aware_attributes && + !self.skip_time_zone_conversion_for_attributes.include?(name.to_sym) && + (:datetime == cast_type.type) + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attribute_methods/write.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attribute_methods/write.rb new file mode 100644 index 0000000..16804f8 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attribute_methods/write.rb @@ -0,0 +1,83 @@ +require 'active_support/core_ext/module/method_transplanting' + +module ActiveRecord + module AttributeMethods + module Write + WriterMethodCache = Class.new(AttributeMethodCache) { + private + + def method_body(method_name, const_name) + <<-EOMETHOD + def #{method_name}(value) + name = ::ActiveRecord::AttributeMethods::AttrNames::ATTR_#{const_name} + write_attribute(name, value) + end + EOMETHOD + end + }.new + + extend ActiveSupport::Concern + + included do + attribute_method_suffix "=" + end + + module ClassMethods + protected + + if Module.methods_transplantable? + def define_method_attribute=(name) + method = WriterMethodCache[name] + generated_attribute_methods.module_eval { + define_method "#{name}=", method + } + end + else + def define_method_attribute=(name) + safe_name = name.unpack('h*').first + ActiveRecord::AttributeMethods::AttrNames.set_name_cache safe_name, name + + generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1 + def __temp__#{safe_name}=(value) + name = ::ActiveRecord::AttributeMethods::AttrNames::ATTR_#{safe_name} + write_attribute(name, value) + end + alias_method #{(name + '=').inspect}, :__temp__#{safe_name}= + undef_method :__temp__#{safe_name}= + STR + end + end + end + + # Updates the attribute identified by attr_name with the + # specified +value+. Empty strings for fixnum and float columns are + # turned into +nil+. + def write_attribute(attr_name, value) + write_attribute_with_type_cast(attr_name, value, true) + end + + def raw_write_attribute(attr_name, value) + write_attribute_with_type_cast(attr_name, value, false) + end + + private + # Handle *= for method_missing. + def attribute=(attribute_name, value) + write_attribute(attribute_name, value) + end + + def write_attribute_with_type_cast(attr_name, value, should_type_cast) + attr_name = attr_name.to_s + attr_name = self.class.primary_key if attr_name == 'id' && self.class.primary_key + + if should_type_cast + @attributes.write_from_user(attr_name, value) + else + @attributes.write_cast_value(attr_name, value) + end + + value + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attribute_set.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attribute_set.rb new file mode 100644 index 0000000..5e2ef81 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attribute_set.rb @@ -0,0 +1,81 @@ +require 'active_record/attribute_set/builder' + +module ActiveRecord + class AttributeSet # :nodoc: + def initialize(attributes) + @attributes = attributes + end + + def [](name) + attributes[name] || Attribute.null(name) + end + + def values_before_type_cast + attributes.transform_values(&:value_before_type_cast) + end + + def to_hash + initialized_attributes.transform_values(&:value) + end + alias_method :to_h, :to_hash + + def key?(name) + attributes.key?(name) && self[name].initialized? + end + + def keys + attributes.initialized_keys + end + + def fetch_value(name) + self[name].value { |n| yield n if block_given? } + end + + def write_from_database(name, value) + attributes[name] = self[name].with_value_from_database(value) + end + + def write_from_user(name, value) + attributes[name] = self[name].with_value_from_user(value) + end + + def write_cast_value(name, value) + attributes[name] = self[name].with_cast_value(value) + end + + def freeze + @attributes.freeze + super + end + + def initialize_dup(_) + @attributes = attributes.dup + super + end + + def initialize_clone(_) + @attributes = attributes.clone + super + end + + def reset(key) + if key?(key) + write_from_database(key, nil) + end + end + + def ==(other) + attributes == other.attributes + end + + protected + + attr_reader :attributes + + private + + def initialized_attributes + attributes.select { |_, attr| attr.initialized? } + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attribute_set/builder.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attribute_set/builder.rb new file mode 100644 index 0000000..3cd9002 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attribute_set/builder.rb @@ -0,0 +1,106 @@ +require 'active_record/attribute' + +module ActiveRecord + class AttributeSet # :nodoc: + class Builder # :nodoc: + attr_reader :types, :always_initialized + + def initialize(types, always_initialized = nil) + @types = types + @always_initialized = always_initialized + end + + def build_from_database(values = {}, additional_types = {}) + if always_initialized && !values.key?(always_initialized) + values[always_initialized] = nil + end + + attributes = LazyAttributeHash.new(types, values, additional_types) + AttributeSet.new(attributes) + end + end + end + + class LazyAttributeHash # :nodoc: + delegate :transform_values, to: :materialize + + def initialize(types, values, additional_types) + @types = types + @values = values + @additional_types = additional_types + @materialized = false + @delegate_hash = {} + end + + def key?(key) + delegate_hash.key?(key) || values.key?(key) || types.key?(key) + end + + def [](key) + delegate_hash[key] || assign_default_value(key) + end + + def []=(key, value) + if frozen? + raise RuntimeError, "Can't modify frozen hash" + end + delegate_hash[key] = value + end + + def initialized_keys + delegate_hash.keys | values.keys + end + + def initialize_dup(_) + @delegate_hash = delegate_hash.transform_values(&:dup) + super + end + + def select + keys = types.keys | values.keys | delegate_hash.keys + keys.each_with_object({}) do |key, hash| + attribute = self[key] + if yield(key, attribute) + hash[key] = attribute + end + end + end + + def ==(other) + if other.is_a?(LazyAttributeHash) + materialize == other.materialize + else + materialize == other + end + end + + protected + + attr_reader :types, :values, :additional_types, :delegate_hash + + def materialize + unless @materialized + values.each_key { |key| self[key] } + types.each_key { |key| self[key] } + unless frozen? + @materialized = true + end + end + delegate_hash + end + + private + + def assign_default_value(name) + type = additional_types.fetch(name, types[name]) + value_present = true + value = values.fetch(name) { value_present = false } + + if value_present + delegate_hash[name] = Attribute.from_database(name, value, type) + elsif types.key?(name) + delegate_hash[name] = Attribute.uninitialized(name, type) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attributes.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attributes.rb new file mode 100644 index 0000000..9cb7b67 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attributes.rb @@ -0,0 +1,146 @@ +module ActiveRecord + module Attributes # :nodoc: + extend ActiveSupport::Concern + + Type = ActiveRecord::Type + + included do + class_attribute :user_provided_columns, instance_accessor: false # :internal: + class_attribute :user_provided_defaults, instance_accessor: false # :internal: + self.user_provided_columns = {} + self.user_provided_defaults = {} + + delegate :persistable_attribute_names, to: :class + end + + module ClassMethods # :nodoc: + # Defines or overrides a attribute on this model. This allows customization of + # Active Record's type casting behavior, as well as adding support for user defined + # types. + # + # +name+ The name of the methods to define attribute methods for, and the column which + # this will persist to. + # + # +cast_type+ A type object that contains information about how to type cast the value. + # See the examples section for more information. + # + # ==== Options + # The options hash accepts the following options: + # + # +default+ is the default value that the column should use on a new record. + # + # ==== Examples + # + # The type detected by Active Record can be overridden. + # + # # db/schema.rb + # create_table :store_listings, force: true do |t| + # t.decimal :price_in_cents + # end + # + # # app/models/store_listing.rb + # class StoreListing < ActiveRecord::Base + # end + # + # store_listing = StoreListing.new(price_in_cents: '10.1') + # + # # before + # store_listing.price_in_cents # => BigDecimal.new(10.1) + # + # class StoreListing < ActiveRecord::Base + # attribute :price_in_cents, Type::Integer.new + # end + # + # # after + # store_listing.price_in_cents # => 10 + # + # Users may also define their own custom types, as long as they respond to the methods + # defined on the value type. The `type_cast` method on your type object will be called + # with values both from the database, and from your controllers. See + # `ActiveRecord::Attributes::Type::Value` for the expected API. It is recommended that your + # type objects inherit from an existing type, or the base value type. + # + # class MoneyType < ActiveRecord::Type::Integer + # def type_cast(value) + # if value.include?('$') + # price_in_dollars = value.gsub(/\$/, '').to_f + # price_in_dollars * 100 + # else + # value.to_i + # end + # end + # end + # + # class StoreListing < ActiveRecord::Base + # attribute :price_in_cents, MoneyType.new + # end + # + # store_listing = StoreListing.new(price_in_cents: '$10.00') + # store_listing.price_in_cents # => 1000 + def attribute(name, cast_type, options = {}) + name = name.to_s + clear_caches_calculated_from_columns + # Assign a new hash to ensure that subclasses do not share a hash + self.user_provided_columns = user_provided_columns.merge(name => cast_type) + + if options.key?(:default) + self.user_provided_defaults = user_provided_defaults.merge(name => options[:default]) + end + end + + # Returns an array of column objects for the table associated with this class. + def columns + @columns ||= add_user_provided_columns(connection.schema_cache.columns(table_name)) + end + + # Returns a hash of column objects for the table associated with this class. + def columns_hash + @columns_hash ||= Hash[columns.map { |c| [c.name, c] }] + end + + def persistable_attribute_names # :nodoc: + @persistable_attribute_names ||= connection.schema_cache.columns_hash(table_name).keys + end + + def reset_column_information # :nodoc: + super + clear_caches_calculated_from_columns + end + + private + + def add_user_provided_columns(schema_columns) + existing_columns = schema_columns.map do |column| + new_type = user_provided_columns[column.name] + if new_type + column.with_type(new_type) + else + column + end + end + + existing_column_names = existing_columns.map(&:name) + new_columns = user_provided_columns.except(*existing_column_names).map do |(name, type)| + connection.new_column(name, nil, type) + end + + existing_columns + new_columns + end + + def clear_caches_calculated_from_columns + @attributes_builder = nil + @column_names = nil + @column_types = nil + @columns = nil + @columns_hash = nil + @content_columns = nil + @default_attributes = nil + @persistable_attribute_names = nil + end + + def raw_default_values + super.merge(user_provided_defaults) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/autosave_association.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/autosave_association.rb new file mode 100644 index 0000000..b7402d1 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/autosave_association.rb @@ -0,0 +1,454 @@ +module ActiveRecord + # = Active Record Autosave Association + # + # +AutosaveAssociation+ is a module that takes care of automatically saving + # associated records when their parent is saved. In addition to saving, it + # also destroys any associated records that were marked for destruction. + # (See +mark_for_destruction+ and marked_for_destruction?). + # + # Saving of the parent, its associations, and the destruction of marked + # associations, all happen inside a transaction. This should never leave the + # database in an inconsistent state. + # + # If validations for any of the associations fail, their error messages will + # be applied to the parent. + # + # Note that it also means that associations marked for destruction won't + # be destroyed directly. They will however still be marked for destruction. + # + # Note that autosave: false is not same as not declaring :autosave. + # When the :autosave option is not present then new association records are + # saved but the updated association records are not saved. + # + # == Validation + # + # Children records are validated unless :validate is +false+. + # + # == Callbacks + # + # Association with autosave option defines several callbacks on your + # model (before_save, after_create, after_update). Please note that + # callbacks are executed in the order they were defined in + # model. You should avoid modifying the association content, before + # autosave callbacks are executed. Placing your callbacks after + # associations is usually a good practice. + # + # === One-to-one Example + # + # class Post < ActiveRecord::Base + # has_one :author, autosave: true + # end + # + # Saving changes to the parent and its associated model can now be performed + # automatically _and_ atomically: + # + # post = Post.find(1) + # post.title # => "The current global position of migrating ducks" + # post.author.name # => "alloy" + # + # post.title = "On the migration of ducks" + # post.author.name = "Eloy Duran" + # + # post.save + # post.reload + # post.title # => "On the migration of ducks" + # post.author.name # => "Eloy Duran" + # + # Destroying an associated model, as part of the parent's save action, is as + # simple as marking it for destruction: + # + # post.author.mark_for_destruction + # post.author.marked_for_destruction? # => true + # + # Note that the model is _not_ yet removed from the database: + # + # id = post.author.id + # Author.find_by(id: id).nil? # => false + # + # post.save + # post.reload.author # => nil + # + # Now it _is_ removed from the database: + # + # Author.find_by(id: id).nil? # => true + # + # === One-to-many Example + # + # When :autosave is not declared new children are saved when their parent is saved: + # + # class Post < ActiveRecord::Base + # has_many :comments # :autosave option is not declared + # end + # + # post = Post.new(title: 'ruby rocks') + # post.comments.build(body: 'hello world') + # post.save # => saves both post and comment + # + # post = Post.create(title: 'ruby rocks') + # post.comments.build(body: 'hello world') + # post.save # => saves both post and comment + # + # post = Post.create(title: 'ruby rocks') + # post.comments.create(body: 'hello world') + # post.save # => saves both post and comment + # + # When :autosave is true all children are saved, no matter whether they + # are new records or not: + # + # class Post < ActiveRecord::Base + # has_many :comments, autosave: true + # end + # + # post = Post.create(title: 'ruby rocks') + # post.comments.create(body: 'hello world') + # post.comments[0].body = 'hi everyone' + # post.comments.build(body: "good morning.") + # post.title += "!" + # post.save # => saves both post and comments. + # + # Destroying one of the associated models as part of the parent's save action + # is as simple as marking it for destruction: + # + # post.comments # => [#, # + # post.comments[1].mark_for_destruction + # post.comments[1].marked_for_destruction? # => true + # post.comments.length # => 2 + # + # Note that the model is _not_ yet removed from the database: + # + # id = post.comments.last.id + # Comment.find_by(id: id).nil? # => false + # + # post.save + # post.reload.comments.length # => 1 + # + # Now it _is_ removed from the database: + # + # Comment.find_by(id: id).nil? # => true + + module AutosaveAssociation + extend ActiveSupport::Concern + + module AssociationBuilderExtension #:nodoc: + def self.build(model, reflection) + model.send(:add_autosave_association_callbacks, reflection) + end + + def self.valid_options + [ :autosave ] + end + end + + included do + Associations::Builder::Association.extensions << AssociationBuilderExtension + end + + module ClassMethods + private + + def define_non_cyclic_method(name, &block) + return if method_defined?(name) + define_method(name) do |*args| + result = true; @_already_called ||= {} + # Loop prevention for validation of associations + unless @_already_called[name] + begin + @_already_called[name]=true + result = instance_eval(&block) + ensure + @_already_called[name]=false + end + end + + result + end + end + + # Adds validation and save callbacks for the association as specified by + # the +reflection+. + # + # For performance reasons, we don't check whether to validate at runtime. + # However the validation and callback methods are lazy and those methods + # get created when they are invoked for the very first time. However, + # this can change, for instance, when using nested attributes, which is + # called _after_ the association has been defined. Since we don't want + # the callbacks to get defined multiple times, there are guards that + # check if the save or validation methods have already been defined + # before actually defining them. + def add_autosave_association_callbacks(reflection) + save_method = :"autosave_associated_records_for_#{reflection.name}" + + if reflection.collection? + before_save :before_save_collection_association + + define_non_cyclic_method(save_method) { save_collection_association(reflection) } + # Doesn't use after_save as that would save associations added in after_create/after_update twice + after_create save_method + after_update save_method + elsif reflection.has_one? + define_method(save_method) { save_has_one_association(reflection) } unless method_defined?(save_method) + # Configures two callbacks instead of a single after_save so that + # the model may rely on their execution order relative to its + # own callbacks. + # + # For example, given that after_creates run before after_saves, if + # we configured instead an after_save there would be no way to fire + # a custom after_create callback after the child association gets + # created. + after_create save_method + after_update save_method + else + define_non_cyclic_method(save_method) { save_belongs_to_association(reflection) } + before_save save_method + end + + define_autosave_validation_callbacks(reflection) + end + + def define_autosave_validation_callbacks(reflection) + validation_method = :"validate_associated_records_for_#{reflection.name}" + if reflection.validate? && !method_defined?(validation_method) + if reflection.collection? + method = :validate_collection_association + else + method = :validate_single_association + end + + define_non_cyclic_method(validation_method) { send(method, reflection) } + validate validation_method + end + end + end + + # Reloads the attributes of the object as usual and clears marked_for_destruction flag. + def reload(options = nil) + @marked_for_destruction = false + @destroyed_by_association = nil + super + end + + # Marks this record to be destroyed as part of the parents save transaction. + # This does _not_ actually destroy the record instantly, rather child record will be destroyed + # when parent.save is called. + # + # Only useful if the :autosave option on the parent is enabled for this associated model. + def mark_for_destruction + @marked_for_destruction = true + end + + # Returns whether or not this record will be destroyed as part of the parents save transaction. + # + # Only useful if the :autosave option on the parent is enabled for this associated model. + def marked_for_destruction? + @marked_for_destruction + end + + # Records the association that is being destroyed and destroying this + # record in the process. + def destroyed_by_association=(reflection) + @destroyed_by_association = reflection + end + + # Returns the association for the parent being destroyed. + # + # Used to avoid updating the counter cache unnecessarily. + def destroyed_by_association + @destroyed_by_association + end + + # Returns whether or not this record has been changed in any way (including whether + # any of its nested autosave associations are likewise changed) + def changed_for_autosave? + new_record? || changed? || marked_for_destruction? || nested_records_changed_for_autosave? + end + + private + + # Returns the record for an association collection that should be validated + # or saved. If +autosave+ is +false+ only new records will be returned, + # unless the parent is/was a new record itself. + def associated_records_to_validate_or_save(association, new_record, autosave) + if new_record + association && association.target + elsif autosave + association.target.find_all { |record| record.changed_for_autosave? } + else + association.target.find_all { |record| record.new_record? } + end + end + + # go through nested autosave associations that are loaded in memory (without loading + # any new ones), and return true if is changed for autosave + def nested_records_changed_for_autosave? + @_nested_records_changed_for_autosave_already_called ||= false + return false if @_nested_records_changed_for_autosave_already_called + begin + @_nested_records_changed_for_autosave_already_called = true + self.class._reflections.values.any? do |reflection| + if reflection.options[:autosave] + association = association_instance_get(reflection.name) + association && Array.wrap(association.target).any?(&:changed_for_autosave?) + end + end + ensure + @_nested_records_changed_for_autosave_already_called = false + end + end + + # Validate the association if :validate or :autosave is + # turned on for the association. + def validate_single_association(reflection) + association = association_instance_get(reflection.name) + record = association && association.reader + association_valid?(reflection, record) if record + end + + # Validate the associated records if :validate or + # :autosave is turned on for the association specified by + # +reflection+. + def validate_collection_association(reflection) + if association = association_instance_get(reflection.name) + if records = associated_records_to_validate_or_save(association, new_record?, reflection.options[:autosave]) + records.each { |record| association_valid?(reflection, record) } + end + end + end + + # Returns whether or not the association is valid and applies any errors to + # the parent, self, if it wasn't. Skips any :autosave + # enabled records if they're marked_for_destruction? or destroyed. + def association_valid?(reflection, record) + return true if record.destroyed? || (reflection.options[:autosave] && record.marked_for_destruction?) + + validation_context = self.validation_context unless [:create, :update].include?(self.validation_context) + unless valid = record.valid?(validation_context) + if reflection.options[:autosave] + record.errors.each do |attribute, message| + attribute = "#{reflection.name}.#{attribute}" + errors[attribute] << message + errors[attribute].uniq! + end + else + errors.add(reflection.name) + end + end + valid + end + + # Is used as a before_save callback to check while saving a collection + # association whether or not the parent was a new record before saving. + def before_save_collection_association + @new_record_before_save = new_record? + true + end + + # Saves any new associated records, or all loaded autosave associations if + # :autosave is enabled on the association. + # + # In addition, it destroys all children that were marked for destruction + # with mark_for_destruction. + # + # This all happens inside a transaction, _if_ the Transactions module is included into + # ActiveRecord::Base after the AutosaveAssociation module, which it does by default. + def save_collection_association(reflection) + if association = association_instance_get(reflection.name) + autosave = reflection.options[:autosave] + + if records = associated_records_to_validate_or_save(association, @new_record_before_save, autosave) + if autosave + records_to_destroy = records.select(&:marked_for_destruction?) + records_to_destroy.each { |record| association.destroy(record) } + records -= records_to_destroy + end + + records.each do |record| + next if record.destroyed? + + saved = true + + if autosave != false && (@new_record_before_save || record.new_record?) + if autosave + saved = association.insert_record(record, false) + else + association.insert_record(record) unless reflection.nested? + end + elsif autosave + saved = record.save(:validate => false) + end + + raise ActiveRecord::Rollback unless saved + end + end + + # reconstruct the scope now that we know the owner's id + association.reset_scope if association.respond_to?(:reset_scope) + end + end + + # Saves the associated record if it's new or :autosave is enabled + # on the association. + # + # In addition, it will destroy the association if it was marked for + # destruction with mark_for_destruction. + # + # This all happens inside a transaction, _if_ the Transactions module is included into + # ActiveRecord::Base after the AutosaveAssociation module, which it does by default. + def save_has_one_association(reflection) + association = association_instance_get(reflection.name) + record = association && association.load_target + + if record && !record.destroyed? + autosave = reflection.options[:autosave] + + if autosave && record.marked_for_destruction? + record.destroy + elsif autosave != false + key = reflection.options[:primary_key] ? send(reflection.options[:primary_key]) : id + + if (autosave && record.changed_for_autosave?) || new_record? || record_changed?(reflection, record, key) + unless reflection.through_reflection + record[reflection.foreign_key] = key + end + + saved = record.save(:validate => !autosave) + raise ActiveRecord::Rollback if !saved && autosave + saved + end + end + end + end + + # If the record is new or it has changed, returns true. + def record_changed?(reflection, record, key) + record.new_record? || + (record.has_attribute?(reflection.foreign_key) && record[reflection.foreign_key] != key) || + record.attribute_changed?(reflection.foreign_key) + end + + # Saves the associated record if it's new or :autosave is enabled. + # + # In addition, it will destroy the association if it was marked for destruction. + def save_belongs_to_association(reflection) + association = association_instance_get(reflection.name) + record = association && association.load_target + if record && !record.destroyed? + autosave = reflection.options[:autosave] + + if autosave && record.marked_for_destruction? + self[reflection.foreign_key] = nil + record.destroy + elsif autosave != false + saved = record.save(:validate => !autosave) if record.new_record? || (autosave && record.changed_for_autosave?) + + if association.updated? + association_id = record.send(reflection.options[:primary_key] || :id) + self[reflection.foreign_key] = association_id + association.loaded! + end + + saved if autosave + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/base.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/base.rb new file mode 100644 index 0000000..26e78f7 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/base.rb @@ -0,0 +1,316 @@ +require 'yaml' +require 'set' +require 'active_support/benchmarkable' +require 'active_support/dependencies' +require 'active_support/descendants_tracker' +require 'active_support/time' +require 'active_support/core_ext/module/attribute_accessors' +require 'active_support/core_ext/class/delegating_attributes' +require 'active_support/core_ext/array/extract_options' +require 'active_support/core_ext/hash/deep_merge' +require 'active_support/core_ext/hash/slice' +require 'active_support/core_ext/hash/transform_values' +require 'active_support/core_ext/string/behavior' +require 'active_support/core_ext/kernel/singleton_class' +require 'active_support/core_ext/module/introspection' +require 'active_support/core_ext/object/duplicable' +require 'active_support/core_ext/class/subclasses' +require 'arel' +require 'active_record/attribute_decorators' +require 'active_record/errors' +require 'active_record/log_subscriber' +require 'active_record/explain_subscriber' +require 'active_record/relation/delegation' +require 'active_record/attributes' + +module ActiveRecord #:nodoc: + # = Active Record + # + # Active Record objects don't specify their attributes directly, but rather infer them from + # the table definition with which they're linked. Adding, removing, and changing attributes + # and their type is done directly in the database. Any change is instantly reflected in the + # Active Record objects. The mapping that binds a given Active Record class to a certain + # database table will happen automatically in most common cases, but can be overwritten for the uncommon ones. + # + # See the mapping rules in table_name and the full example in link:files/activerecord/README_rdoc.html for more insight. + # + # == Creation + # + # Active Records accept constructor parameters either in a hash or as a block. The hash + # method is especially useful when you're receiving the data from somewhere else, like an + # HTTP request. It works like this: + # + # user = User.new(name: "David", occupation: "Code Artist") + # user.name # => "David" + # + # You can also use block initialization: + # + # user = User.new do |u| + # u.name = "David" + # u.occupation = "Code Artist" + # end + # + # And of course you can just create a bare object and specify the attributes after the fact: + # + # user = User.new + # user.name = "David" + # user.occupation = "Code Artist" + # + # == Conditions + # + # Conditions can either be specified as a string, array, or hash representing the WHERE-part of an SQL statement. + # The array form is to be used when the condition input is tainted and requires sanitization. The string form can + # be used for statements that don't involve tainted data. The hash form works much like the array form, except + # only equality and range is possible. Examples: + # + # class User < ActiveRecord::Base + # def self.authenticate_unsafely(user_name, password) + # where("user_name = '#{user_name}' AND password = '#{password}'").first + # end + # + # def self.authenticate_safely(user_name, password) + # where("user_name = ? AND password = ?", user_name, password).first + # end + # + # def self.authenticate_safely_simply(user_name, password) + # where(user_name: user_name, password: password).first + # end + # end + # + # The authenticate_unsafely method inserts the parameters directly into the query + # and is thus susceptible to SQL-injection attacks if the user_name and +password+ + # parameters come directly from an HTTP request. The authenticate_safely and + # authenticate_safely_simply both will sanitize the user_name and +password+ + # before inserting them in the query, which will ensure that an attacker can't escape the + # query and fake the login (or worse). + # + # When using multiple parameters in the conditions, it can easily become hard to read exactly + # what the fourth or fifth question mark is supposed to represent. In those cases, you can + # resort to named bind variables instead. That's done by replacing the question marks with + # symbols and supplying a hash with values for the matching symbol keys: + # + # Company.where( + # "id = :id AND name = :name AND division = :division AND created_at > :accounting_date", + # { id: 3, name: "37signals", division: "First", accounting_date: '2005-01-01' } + # ).first + # + # Similarly, a simple hash without a statement will generate conditions based on equality with the SQL AND + # operator. For instance: + # + # Student.where(first_name: "Harvey", status: 1) + # Student.where(params[:student]) + # + # A range may be used in the hash to use the SQL BETWEEN operator: + # + # Student.where(grade: 9..12) + # + # An array may be used in the hash to use the SQL IN operator: + # + # Student.where(grade: [9,11,12]) + # + # When joining tables, nested hashes or keys written in the form 'table_name.column_name' + # can be used to qualify the table name of a particular condition. For instance: + # + # Student.joins(:schools).where(schools: { category: 'public' }) + # Student.joins(:schools).where('schools.category' => 'public' ) + # + # == Overwriting default accessors + # + # All column values are automatically available through basic accessors on the Active Record + # object, but sometimes you want to specialize this behavior. This can be done by overwriting + # the default accessors (using the same name as the attribute) and calling + # +super+ to actually change things. + # + # class Song < ActiveRecord::Base + # # Uses an integer of seconds to hold the length of the song + # + # def length=(minutes) + # super(minutes.to_i * 60) + # end + # + # def length + # super / 60 + # end + # end + # + # You can alternatively use self[:attribute]=(value) and self[:attribute] + # or write_attribute(:attribute, value) and read_attribute(:attribute). + # + # == Attribute query methods + # + # In addition to the basic accessors, query methods are also automatically available on the Active Record object. + # Query methods allow you to test whether an attribute value is present. + # For numeric values, present is defined as non-zero. + # + # For example, an Active Record User with the name attribute has a name? method that you can call + # to determine whether the user has a name: + # + # user = User.new(name: "David") + # user.name? # => true + # + # anonymous = User.new(name: "") + # anonymous.name? # => false + # + # == Accessing attributes before they have been typecasted + # + # Sometimes you want to be able to read the raw attribute data without having the column-determined + # typecast run its course first. That can be done by using the _before_type_cast + # accessors that all attributes have. For example, if your Account model has a balance attribute, + # you can call account.balance_before_type_cast or account.id_before_type_cast. + # + # This is especially useful in validation situations where the user might supply a string for an + # integer field and you want to display the original string back in an error message. Accessing the + # attribute normally would typecast the string to 0, which isn't what you want. + # + # == Dynamic attribute-based finders + # + # Dynamic attribute-based finders are a mildly deprecated way of getting (and/or creating) objects + # by simple queries without turning to SQL. They work by appending the name of an attribute + # to find_by_ like Person.find_by_user_name. + # Instead of writing Person.find_by(user_name: user_name), you can use + # Person.find_by_user_name(user_name). + # + # It's possible to add an exclamation point (!) on the end of the dynamic finders to get them to raise an + # ActiveRecord::RecordNotFound error if they do not return any records, + # like Person.find_by_last_name!. + # + # It's also possible to use multiple attributes in the same find by separating them with "_and_". + # + # Person.find_by(user_name: user_name, password: password) + # Person.find_by_user_name_and_password(user_name, password) # with dynamic finder + # + # It's even possible to call these dynamic finder methods on relations and named scopes. + # + # Payment.order("created_on").find_by_amount(50) + # + # == Saving arrays, hashes, and other non-mappable objects in text columns + # + # Active Record can serialize any object in text columns using YAML. To do so, you must + # specify this with a call to the class method +serialize+. + # This makes it possible to store arrays, hashes, and other non-mappable objects without doing + # any additional work. + # + # class User < ActiveRecord::Base + # serialize :preferences + # end + # + # user = User.create(preferences: { "background" => "black", "display" => large }) + # User.find(user.id).preferences # => { "background" => "black", "display" => large } + # + # You can also specify a class option as the second parameter that'll raise an exception + # if a serialized object is retrieved as a descendant of a class not in the hierarchy. + # + # class User < ActiveRecord::Base + # serialize :preferences, Hash + # end + # + # user = User.create(preferences: %w( one two three )) + # User.find(user.id).preferences # raises SerializationTypeMismatch + # + # When you specify a class option, the default value for that attribute will be a new + # instance of that class. + # + # class User < ActiveRecord::Base + # serialize :preferences, OpenStruct + # end + # + # user = User.new + # user.preferences.theme_color = "red" + # + # + # == Single table inheritance + # + # Active Record allows inheritance by storing the name of the class in a + # column that is named "type" by default. See ActiveRecord::Inheritance for + # more details. + # + # == Connection to multiple databases in different models + # + # Connections are usually created through ActiveRecord::Base.establish_connection and retrieved + # by ActiveRecord::Base.connection. All classes inheriting from ActiveRecord::Base will use this + # connection. But you can also set a class-specific connection. For example, if Course is an + # ActiveRecord::Base, but resides in a different database, you can just say Course.establish_connection + # and Course and all of its subclasses will use this connection instead. + # + # This feature is implemented by keeping a connection pool in ActiveRecord::Base that is + # a Hash indexed by the class. If a connection is requested, the retrieve_connection method + # will go up the class-hierarchy until a connection is found in the connection pool. + # + # == Exceptions + # + # * ActiveRecordError - Generic error class and superclass of all other errors raised by Active Record. + # * AdapterNotSpecified - The configuration hash used in establish_connection didn't include an + # :adapter key. + # * AdapterNotFound - The :adapter key used in establish_connection specified a + # non-existent adapter + # (or a bad spelling of an existing one). + # * AssociationTypeMismatch - The object assigned to the association wasn't of the type + # specified in the association definition. + # * AttributeAssignmentError - An error occurred while doing a mass assignment through the + # attributes= method. + # You can inspect the +attribute+ property of the exception object to determine which attribute + # triggered the error. + # * ConnectionNotEstablished - No connection has been established. Use establish_connection + # before querying. + # * MultiparameterAssignmentErrors - Collection of errors that occurred during a mass assignment using the + # attributes= method. The +errors+ property of this exception contains an array of + # AttributeAssignmentError + # objects that should be inspected to determine which attributes triggered the errors. + # * RecordInvalid - raised by save! and create! when the record is invalid. + # * RecordNotFound - No record responded to the +find+ method. Either the row with the given ID doesn't exist + # or the row didn't meet the additional restrictions. Some +find+ calls do not raise this exception to signal + # nothing was found, please check its documentation for further details. + # * SerializationTypeMismatch - The serialized object wasn't of the class specified as the second parameter. + # * StatementInvalid - The database server rejected the SQL statement. The precise error is added in the message. + # + # *Note*: The attributes listed are class-level attributes (accessible from both the class and instance level). + # So it's possible to assign a logger to the class through Base.logger= which will then be used by all + # instances in the current object space. + class Base + extend ActiveModel::Naming + + extend ActiveSupport::Benchmarkable + extend ActiveSupport::DescendantsTracker + + extend ConnectionHandling + extend QueryCache::ClassMethods + extend Querying + extend Translation + extend DynamicMatchers + extend Explain + extend Enum + extend Delegation::DelegateCache + + include Core + include Persistence + include ReadonlyAttributes + include ModelSchema + include Inheritance + include Scoping + include Sanitization + include AttributeAssignment + include ActiveModel::Conversion + include Integration + include Validations + include CounterCache + include Attributes + include AttributeDecorators + include Locking::Optimistic + include Locking::Pessimistic + include AttributeMethods + include Callbacks + include Timestamp + include Associations + include ActiveModel::SecurePassword + include AutosaveAssociation + include NestedAttributes + include Aggregations + include Transactions + include NoTouching + include Reflection + include Serialization + include Store + end + + ActiveSupport.run_load_hooks(:active_record, Base) +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/callbacks.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/callbacks.rb new file mode 100644 index 0000000..a3682f3 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/callbacks.rb @@ -0,0 +1,313 @@ +module ActiveRecord + # = Active Record Callbacks + # + # Callbacks are hooks into the life cycle of an Active Record object that allow you to trigger logic + # before or after an alteration of the object state. This can be used to make sure that associated and + # dependent objects are deleted when +destroy+ is called (by overwriting +before_destroy+) or to massage attributes + # before they're validated (by overwriting +before_validation+). As an example of the callbacks initiated, consider + # the Base#save call for a new record: + # + # * (-) save + # * (-) valid + # * (1) before_validation + # * (-) validate + # * (2) after_validation + # * (3) before_save + # * (4) before_create + # * (-) create + # * (5) after_create + # * (6) after_save + # * (7) after_commit + # + # Also, an after_rollback callback can be configured to be triggered whenever a rollback is issued. + # Check out ActiveRecord::Transactions for more details about after_commit and + # after_rollback. + # + # Additionally, an after_touch callback is triggered whenever an + # object is touched. + # + # Lastly an after_find and after_initialize callback is triggered for each object that + # is found and instantiated by a finder, with after_initialize being triggered after new objects + # are instantiated as well. + # + # There are nineteen callbacks in total, which give you immense power to react and prepare for each state in the + # Active Record life cycle. The sequence for calling Base#save for an existing record is similar, + # except that each _create callback is replaced by the corresponding _update callback. + # + # Examples: + # class CreditCard < ActiveRecord::Base + # # Strip everything but digits, so the user can specify "555 234 34" or + # # "5552-3434" and both will mean "55523434" + # before_validation(on: :create) do + # self.number = number.gsub(/[^0-9]/, "") if attribute_present?("number") + # end + # end + # + # class Subscription < ActiveRecord::Base + # before_create :record_signup + # + # private + # def record_signup + # self.signed_up_on = Date.today + # end + # end + # + # class Firm < ActiveRecord::Base + # # Destroys the associated clients and people when the firm is destroyed + # before_destroy { |record| Person.destroy_all "firm_id = #{record.id}" } + # before_destroy { |record| Client.destroy_all "client_of = #{record.id}" } + # end + # + # == Inheritable callback queues + # + # Besides the overwritable callback methods, it's also possible to register callbacks through the + # use of the callback macros. Their main advantage is that the macros add behavior into a callback + # queue that is kept intact down through an inheritance hierarchy. + # + # class Topic < ActiveRecord::Base + # before_destroy :destroy_author + # end + # + # class Reply < Topic + # before_destroy :destroy_readers + # end + # + # Now, when Topic#destroy is run only +destroy_author+ is called. When Reply#destroy is + # run, both +destroy_author+ and +destroy_readers+ are called. Contrast this to the following situation + # where the +before_destroy+ method is overridden: + # + # class Topic < ActiveRecord::Base + # def before_destroy() destroy_author end + # end + # + # class Reply < Topic + # def before_destroy() destroy_readers end + # end + # + # In that case, Reply#destroy would only run +destroy_readers+ and _not_ +destroy_author+. + # So, use the callback macros when you want to ensure that a certain callback is called for the entire + # hierarchy, and use the regular overwritable methods when you want to leave it up to each descendant + # to decide whether they want to call +super+ and trigger the inherited callbacks. + # + # *IMPORTANT:* In order for inheritance to work for the callback queues, you must specify the + # callbacks before specifying the associations. Otherwise, you might trigger the loading of a + # child before the parent has registered the callbacks and they won't be inherited. + # + # == Types of callbacks + # + # There are four types of callbacks accepted by the callback macros: Method references (symbol), callback objects, + # inline methods (using a proc), and inline eval methods (using a string). Method references and callback objects + # are the recommended approaches, inline methods using a proc are sometimes appropriate (such as for + # creating mix-ins), and inline eval methods are deprecated. + # + # The method reference callbacks work by specifying a protected or private method available in the object, like this: + # + # class Topic < ActiveRecord::Base + # before_destroy :delete_parents + # + # private + # def delete_parents + # self.class.delete_all "parent_id = #{id}" + # end + # end + # + # The callback objects have methods named after the callback called with the record as the only parameter, such as: + # + # class BankAccount < ActiveRecord::Base + # before_save EncryptionWrapper.new + # after_save EncryptionWrapper.new + # after_initialize EncryptionWrapper.new + # end + # + # class EncryptionWrapper + # def before_save(record) + # record.credit_card_number = encrypt(record.credit_card_number) + # end + # + # def after_save(record) + # record.credit_card_number = decrypt(record.credit_card_number) + # end + # + # alias_method :after_initialize, :after_save + # + # private + # def encrypt(value) + # # Secrecy is committed + # end + # + # def decrypt(value) + # # Secrecy is unveiled + # end + # end + # + # So you specify the object you want messaged on a given callback. When that callback is triggered, the object has + # a method by the name of the callback messaged. You can make these callbacks more flexible by passing in other + # initialization data such as the name of the attribute to work with: + # + # class BankAccount < ActiveRecord::Base + # before_save EncryptionWrapper.new("credit_card_number") + # after_save EncryptionWrapper.new("credit_card_number") + # after_initialize EncryptionWrapper.new("credit_card_number") + # end + # + # class EncryptionWrapper + # def initialize(attribute) + # @attribute = attribute + # end + # + # def before_save(record) + # record.send("#{@attribute}=", encrypt(record.send("#{@attribute}"))) + # end + # + # def after_save(record) + # record.send("#{@attribute}=", decrypt(record.send("#{@attribute}"))) + # end + # + # alias_method :after_initialize, :after_save + # + # private + # def encrypt(value) + # # Secrecy is committed + # end + # + # def decrypt(value) + # # Secrecy is unveiled + # end + # end + # + # The callback macros usually accept a symbol for the method they're supposed to run, but you can also + # pass a "method string", which will then be evaluated within the binding of the callback. Example: + # + # class Topic < ActiveRecord::Base + # before_destroy 'self.class.delete_all "parent_id = #{id}"' + # end + # + # Notice that single quotes (') are used so the #{id} part isn't evaluated until the callback + # is triggered. Also note that these inline callbacks can be stacked just like the regular ones: + # + # class Topic < ActiveRecord::Base + # before_destroy 'self.class.delete_all "parent_id = #{id}"', + # 'puts "Evaluated after parents are destroyed"' + # end + # + # == before_validation* returning statements + # + # If the returning value of a +before_validation+ callback can be evaluated to +false+, the process will be + # aborted and Base#save will return +false+. If Base#save! is called it will raise a + # ActiveRecord::RecordInvalid exception. Nothing will be appended to the errors object. + # + # == Canceling callbacks + # + # If a before_* callback returns +false+, all the later callbacks and the associated action are + # cancelled. + # Callbacks are generally run in the order they are defined, with the exception of callbacks defined as + # methods on the model, which are called last. + # + # == Ordering callbacks + # + # Sometimes the code needs that the callbacks execute in a specific order. For example, a +before_destroy+ + # callback (+log_children+ in this case) should be executed before the children get destroyed by the +dependent: destroy+ option. + # + # Let's look at the code below: + # + # class Topic < ActiveRecord::Base + # has_many :children, dependent: destroy + # + # before_destroy :log_children + # + # private + # def log_children + # # Child processing + # end + # end + # + # In this case, the problem is that when the +before_destroy+ callback is executed, the children are not available + # because the +destroy+ callback gets executed first. You can use the +prepend+ option on the +before_destroy+ callback to avoid this. + # + # class Topic < ActiveRecord::Base + # has_many :children, dependent: destroy + # + # before_destroy :log_children, prepend: true + # + # private + # def log_children + # # Child processing + # end + # end + # + # This way, the +before_destroy+ gets executed before the dependent: destroy is called, and the data is still available. + # + # == Transactions + # + # The entire callback chain of a +save+, save!, or +destroy+ call runs + # within a transaction. That includes after_* hooks. If everything + # goes fine a COMMIT is executed once the chain has been completed. + # + # If a before_* callback cancels the action a ROLLBACK is issued. You + # can also trigger a ROLLBACK raising an exception in any of the callbacks, + # including after_* hooks. Note, however, that in that case the client + # needs to be aware of it because an ordinary +save+ will raise such exception + # instead of quietly returning +false+. + # + # == Debugging callbacks + # + # The callback chain is accessible via the _*_callbacks method on an object. ActiveModel Callbacks support + # :before, :after and :around as values for the kind property. The kind property + # defines what part of the chain the callback runs in. + # + # To find all callbacks in the before_save callback chain: + # + # Topic._save_callbacks.select { |cb| cb.kind.eql?(:before) } + # + # Returns an array of callback objects that form the before_save chain. + # + # To further check if the before_save chain contains a proc defined as rest_when_dead use the filter property of the callback object: + # + # Topic._save_callbacks.select { |cb| cb.kind.eql?(:before) }.collect(&:filter).include?(:rest_when_dead) + # + # Returns true or false depending on whether the proc is contained in the before_save callback chain on a Topic model. + # + module Callbacks + extend ActiveSupport::Concern + + CALLBACKS = [ + :after_initialize, :after_find, :after_touch, :before_validation, :after_validation, + :before_save, :around_save, :after_save, :before_create, :around_create, + :after_create, :before_update, :around_update, :after_update, + :before_destroy, :around_destroy, :after_destroy, :after_commit, :after_rollback + ] + + module ClassMethods + include ActiveModel::Callbacks + end + + included do + include ActiveModel::Validations::Callbacks + + define_model_callbacks :initialize, :find, :touch, :only => :after + define_model_callbacks :save, :create, :update, :destroy + end + + def destroy #:nodoc: + _run_destroy_callbacks { super } + end + + def touch(*) #:nodoc: + _run_touch_callbacks { super } + end + + private + + def create_or_update #:nodoc: + _run_save_callbacks { super } + end + + def _create_record #:nodoc: + _run_create_callbacks { super } + end + + def _update_record(*) #:nodoc: + _run_update_callbacks { super } + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/coders/json.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/coders/json.rb new file mode 100644 index 0000000..75d3bfe --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/coders/json.rb @@ -0,0 +1,13 @@ +module ActiveRecord + module Coders # :nodoc: + class JSON # :nodoc: + def self.dump(obj) + ActiveSupport::JSON.encode(obj) + end + + def self.load(json) + ActiveSupport::JSON.decode(json) unless json.nil? + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/coders/yaml_column.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/coders/yaml_column.rb new file mode 100644 index 0000000..d3d7396 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/coders/yaml_column.rb @@ -0,0 +1,38 @@ +require 'yaml' + +module ActiveRecord + module Coders # :nodoc: + class YAMLColumn # :nodoc: + + attr_accessor :object_class + + def initialize(object_class = Object) + @object_class = object_class + end + + def dump(obj) + return if obj.nil? + + unless obj.is_a?(object_class) + raise SerializationTypeMismatch, + "Attribute was supposed to be a #{object_class}, but was a #{obj.class}. -- #{obj.inspect}" + end + YAML.dump obj + end + + def load(yaml) + return object_class.new if object_class != Object && yaml.nil? + return yaml unless yaml.is_a?(String) && yaml =~ /^---/ + obj = YAML.load(yaml) + + unless obj.is_a?(object_class) || obj.nil? + raise SerializationTypeMismatch, + "Attribute was supposed to be a #{object_class}, but was a #{obj.class}" + end + obj ||= object_class.new if object_class != Object + + obj + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/abstract/connection_pool.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/abstract/connection_pool.rb new file mode 100644 index 0000000..6ddf87d --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/abstract/connection_pool.rb @@ -0,0 +1,665 @@ +require 'thread' +require 'thread_safe' +require 'monitor' +require 'set' +require 'active_support/core_ext/string/filters' + +module ActiveRecord + # Raised when a connection could not be obtained within the connection + # acquisition timeout period: because max connections in pool + # are in use. + class ConnectionTimeoutError < ConnectionNotEstablished + end + + module ConnectionAdapters + # Connection pool base class for managing Active Record database + # connections. + # + # == Introduction + # + # A connection pool synchronizes thread access to a limited number of + # database connections. The basic idea is that each thread checks out a + # database connection from the pool, uses that connection, and checks the + # connection back in. ConnectionPool is completely thread-safe, and will + # ensure that a connection cannot be used by two threads at the same time, + # as long as ConnectionPool's contract is correctly followed. It will also + # handle cases in which there are more threads than connections: if all + # connections have been checked out, and a thread tries to checkout a + # connection anyway, then ConnectionPool will wait until some other thread + # has checked in a connection. + # + # == Obtaining (checking out) a connection + # + # Connections can be obtained and used from a connection pool in several + # ways: + # + # 1. Simply use ActiveRecord::Base.connection as with Active Record 2.1 and + # earlier (pre-connection-pooling). Eventually, when you're done with + # the connection(s) and wish it to be returned to the pool, you call + # ActiveRecord::Base.clear_active_connections!. This will be the + # default behavior for Active Record when used in conjunction with + # Action Pack's request handling cycle. + # 2. Manually check out a connection from the pool with + # ActiveRecord::Base.connection_pool.checkout. You are responsible for + # returning this connection to the pool when finished by calling + # ActiveRecord::Base.connection_pool.checkin(connection). + # 3. Use ActiveRecord::Base.connection_pool.with_connection(&block), which + # obtains a connection, yields it as the sole argument to the block, + # and returns it to the pool after the block completes. + # + # Connections in the pool are actually AbstractAdapter objects (or objects + # compatible with AbstractAdapter's interface). + # + # == Options + # + # There are several connection-pooling-related options that you can add to + # your database connection configuration: + # + # * +pool+: number indicating size of connection pool (default 5) + # * +checkout_timeout+: number of seconds to block and wait for a connection + # before giving up and raising a timeout error (default 5 seconds). + # * +reaping_frequency+: frequency in seconds to periodically run the + # Reaper, which attempts to find and recover connections from dead + # threads, which can occur if a programmer forgets to close a + # connection at the end of a thread or a thread dies unexpectedly. + # Regardless of this setting, the Reaper will be invoked before every + # blocking wait. (Default nil, which means don't schedule the Reaper). + class ConnectionPool + # Threadsafe, fair, FIFO queue. Meant to be used by ConnectionPool + # with which it shares a Monitor. But could be a generic Queue. + # + # The Queue in stdlib's 'thread' could replace this class except + # stdlib's doesn't support waiting with a timeout. + class Queue + def initialize(lock = Monitor.new) + @lock = lock + @cond = @lock.new_cond + @num_waiting = 0 + @queue = [] + end + + # Test if any threads are currently waiting on the queue. + def any_waiting? + synchronize do + @num_waiting > 0 + end + end + + # Returns the number of threads currently waiting on this + # queue. + def num_waiting + synchronize do + @num_waiting + end + end + + # Add +element+ to the queue. Never blocks. + def add(element) + synchronize do + @queue.push element + @cond.signal + end + end + + # If +element+ is in the queue, remove and return it, or nil. + def delete(element) + synchronize do + @queue.delete(element) + end + end + + # Remove all elements from the queue. + def clear + synchronize do + @queue.clear + end + end + + # Remove the head of the queue. + # + # If +timeout+ is not given, remove and return the head the + # queue if the number of available elements is strictly + # greater than the number of threads currently waiting (that + # is, don't jump ahead in line). Otherwise, return nil. + # + # If +timeout+ is given, block if it there is no element + # available, waiting up to +timeout+ seconds for an element to + # become available. + # + # Raises: + # - ConnectionTimeoutError if +timeout+ is given and no element + # becomes available after +timeout+ seconds, + def poll(timeout = nil) + synchronize do + if timeout + no_wait_poll || wait_poll(timeout) + else + no_wait_poll + end + end + end + + private + + def synchronize(&block) + @lock.synchronize(&block) + end + + # Test if the queue currently contains any elements. + def any? + !@queue.empty? + end + + # A thread can remove an element from the queue without + # waiting if an only if the number of currently available + # connections is strictly greater than the number of waiting + # threads. + def can_remove_no_wait? + @queue.size > @num_waiting + end + + # Removes and returns the head of the queue if possible, or nil. + def remove + @queue.shift + end + + # Remove and return the head the queue if the number of + # available elements is strictly greater than the number of + # threads currently waiting. Otherwise, return nil. + def no_wait_poll + remove if can_remove_no_wait? + end + + # Waits on the queue up to +timeout+ seconds, then removes and + # returns the head of the queue. + def wait_poll(timeout) + @num_waiting += 1 + + t0 = Time.now + elapsed = 0 + loop do + @cond.wait(timeout - elapsed) + + return remove if any? + + elapsed = Time.now - t0 + if elapsed >= timeout + msg = 'could not obtain a database connection within %0.3f seconds (waited %0.3f seconds)' % + [timeout, elapsed] + raise ConnectionTimeoutError, msg + end + end + ensure + @num_waiting -= 1 + end + end + + # Every +frequency+ seconds, the reaper will call +reap+ on +pool+. + # A reaper instantiated with a nil frequency will never reap the + # connection pool. + # + # Configure the frequency by setting "reaping_frequency" in your + # database yaml file. + class Reaper + attr_reader :pool, :frequency + + def initialize(pool, frequency) + @pool = pool + @frequency = frequency + end + + def run + return unless frequency + Thread.new(frequency, pool) { |t, p| + while true + sleep t + p.reap + end + } + end + end + + include MonitorMixin + + attr_accessor :automatic_reconnect, :checkout_timeout + attr_reader :spec, :connections, :size, :reaper + + # Creates a new ConnectionPool object. +spec+ is a ConnectionSpecification + # object which describes database connection information (e.g. adapter, + # host name, username, password, etc), as well as the maximum size for + # this ConnectionPool. + # + # The default ConnectionPool maximum size is 5. + def initialize(spec) + super() + + @spec = spec + + @checkout_timeout = (spec.config[:checkout_timeout] && spec.config[:checkout_timeout].to_f) || 5 + @reaper = Reaper.new(self, (spec.config[:reaping_frequency] && spec.config[:reaping_frequency].to_f)) + @reaper.run + + # default max pool size to 5 + @size = (spec.config[:pool] && spec.config[:pool].to_i) || 5 + + # The cache of reserved connections mapped to threads + @reserved_connections = ThreadSafe::Cache.new(:initial_capacity => @size) + + @connections = [] + @automatic_reconnect = true + + @available = Queue.new self + end + + # Retrieve the connection associated with the current thread, or call + # #checkout to obtain one if necessary. + # + # #connection can be called any number of times; the connection is + # held in a hash keyed by the thread id. + def connection + # this is correctly done double-checked locking + # (ThreadSafe::Cache's lookups have volatile semantics) + @reserved_connections[current_connection_id] || synchronize do + @reserved_connections[current_connection_id] ||= checkout + end + end + + # Is there an open connection that is being used for the current thread? + def active_connection? + synchronize do + @reserved_connections.fetch(current_connection_id) { + return false + }.in_use? + end + end + + # Signal that the thread is finished with the current connection. + # #release_connection releases the connection-thread association + # and returns the connection to the pool. + def release_connection(with_id = current_connection_id) + synchronize do + conn = @reserved_connections.delete(with_id) + checkin conn if conn + end + end + + # If a connection already exists yield it to the block. If no connection + # exists checkout a connection, yield it to the block, and checkin the + # connection when finished. + def with_connection + connection_id = current_connection_id + fresh_connection = true unless active_connection? + yield connection + ensure + release_connection(connection_id) if fresh_connection + end + + # Returns true if a connection has already been opened. + def connected? + synchronize { @connections.any? } + end + + # Disconnects all connections in the pool, and clears the pool. + def disconnect! + synchronize do + @reserved_connections.clear + @connections.each do |conn| + checkin conn + conn.disconnect! + end + @connections = [] + @available.clear + end + end + + # Clears the cache which maps classes. + def clear_reloadable_connections! + synchronize do + @reserved_connections.clear + @connections.each do |conn| + checkin conn + conn.disconnect! if conn.requires_reloading? + end + @connections.delete_if do |conn| + conn.requires_reloading? + end + @available.clear + @connections.each do |conn| + @available.add conn + end + end + end + + # Check-out a database connection from the pool, indicating that you want + # to use it. You should call #checkin when you no longer need this. + # + # This is done by either returning and leasing existing connection, or by + # creating a new connection and leasing it. + # + # If all connections are leased and the pool is at capacity (meaning the + # number of currently leased connections is greater than or equal to the + # size limit set), an ActiveRecord::ConnectionTimeoutError exception will be raised. + # + # Returns: an AbstractAdapter object. + # + # Raises: + # - ConnectionTimeoutError: no connection can be obtained from the pool. + def checkout + synchronize do + conn = acquire_connection + conn.lease + checkout_and_verify(conn) + end + end + + # Check-in a database connection back into the pool, indicating that you + # no longer need this connection. + # + # +conn+: an AbstractAdapter object, which was obtained by earlier by + # calling +checkout+ on this pool. + def checkin(conn) + synchronize do + owner = conn.owner + + conn._run_checkin_callbacks do + conn.expire + end + + release conn, owner + + @available.add conn + end + end + + # Remove a connection from the connection pool. The connection will + # remain open and active but will no longer be managed by this pool. + def remove(conn) + synchronize do + @connections.delete conn + @available.delete conn + + release conn, conn.owner + + @available.add checkout_new_connection if @available.any_waiting? + end + end + + # Recover lost connections for the pool. A lost connection can occur if + # a programmer forgets to checkin a connection at the end of a thread + # or a thread dies unexpectedly. + def reap + stale_connections = synchronize do + @connections.select do |conn| + conn.in_use? && !conn.owner.alive? + end + end + + stale_connections.each do |conn| + synchronize do + if conn.active? + conn.reset! + checkin conn + else + remove conn + end + end + end + end + + private + + # Acquire a connection by one of 1) immediately removing one + # from the queue of available connections, 2) creating a new + # connection if the pool is not at capacity, 3) waiting on the + # queue for a connection to become available. + # + # Raises: + # - ConnectionTimeoutError if a connection could not be acquired + def acquire_connection + if conn = @available.poll + conn + elsif @connections.size < @size + checkout_new_connection + else + reap + @available.poll(@checkout_timeout) + end + end + + def release(conn, owner) + thread_id = owner.object_id + + if @reserved_connections[thread_id] == conn + @reserved_connections.delete thread_id + end + end + + def new_connection + Base.send(spec.adapter_method, spec.config) + end + + def current_connection_id #:nodoc: + Base.connection_id ||= Thread.current.object_id + end + + def checkout_new_connection + raise ConnectionNotEstablished unless @automatic_reconnect + + c = new_connection + c.pool = self + @connections << c + c + end + + def checkout_and_verify(c) + c._run_checkout_callbacks do + c.verify! + end + c + rescue + remove c + c.disconnect! + raise + end + end + + # ConnectionHandler is a collection of ConnectionPool objects. It is used + # for keeping separate connection pools for Active Record models that connect + # to different databases. + # + # For example, suppose that you have 5 models, with the following hierarchy: + # + # class Author < ActiveRecord::Base + # end + # + # class BankAccount < ActiveRecord::Base + # end + # + # class Book < ActiveRecord::Base + # establish_connection "library_db" + # end + # + # class ScaryBook < Book + # end + # + # class GoodBook < Book + # end + # + # And a database.yml that looked like this: + # + # development: + # database: my_application + # host: localhost + # + # library_db: + # database: library + # host: some.library.org + # + # Your primary database in the development environment is "my_application" + # but the Book model connects to a separate database called "library_db" + # (this can even be a database on a different machine). + # + # Book, ScaryBook and GoodBook will all use the same connection pool to + # "library_db" while Author, BankAccount, and any other models you create + # will use the default connection pool to "my_application". + # + # The various connection pools are managed by a single instance of + # ConnectionHandler accessible via ActiveRecord::Base.connection_handler. + # All Active Record models use this handler to determine the connection pool that they + # should use. + class ConnectionHandler + def initialize + # These caches are keyed by klass.name, NOT klass. Keying them by klass + # alone would lead to memory leaks in development mode as all previous + # instances of the class would stay in memory. + @owner_to_pool = ThreadSafe::Cache.new(:initial_capacity => 2) do |h,k| + h[k] = ThreadSafe::Cache.new(:initial_capacity => 2) + end + @class_to_pool = ThreadSafe::Cache.new(:initial_capacity => 2) do |h,k| + h[k] = ThreadSafe::Cache.new + end + end + + def connection_pool_list + owner_to_pool.values.compact + end + + def connection_pools + ActiveSupport::Deprecation.warn(<<-MSG.squish) + In the next release, this will return the same as `#connection_pool_list`. + (An array of pools, rather than a hash mapping specs to pools.) + MSG + + Hash[connection_pool_list.map { |pool| [pool.spec, pool] }] + end + + def establish_connection(owner, spec) + @class_to_pool.clear + raise RuntimeError, "Anonymous class is not allowed." unless owner.name + owner_to_pool[owner.name] = ConnectionAdapters::ConnectionPool.new(spec) + end + + # Returns true if there are any active connections among the connection + # pools that the ConnectionHandler is managing. + def active_connections? + connection_pool_list.any?(&:active_connection?) + end + + # Returns any connections in use by the current thread back to the pool, + # and also returns connections to the pool cached by threads that are no + # longer alive. + def clear_active_connections! + connection_pool_list.each(&:release_connection) + end + + # Clears the cache which maps classes. + def clear_reloadable_connections! + connection_pool_list.each(&:clear_reloadable_connections!) + end + + def clear_all_connections! + connection_pool_list.each(&:disconnect!) + end + + # Locate the connection of the nearest super class. This can be an + # active or defined connection: if it is the latter, it will be + # opened and set as the active connection for the class it was defined + # for (not necessarily the current class). + def retrieve_connection(klass) #:nodoc: + pool = retrieve_connection_pool(klass) + raise ConnectionNotEstablished, "No connection pool for #{klass}" unless pool + conn = pool.connection + raise ConnectionNotEstablished, "No connection for #{klass} in connection pool" unless conn + conn + end + + # Returns true if a connection that's accessible to this class has + # already been opened. + def connected?(klass) + conn = retrieve_connection_pool(klass) + conn && conn.connected? + end + + # Remove the connection for this class. This will close the active + # connection and the defined connection (if they exist). The result + # can be used as an argument for establish_connection, for easily + # re-establishing the connection. + def remove_connection(owner) + if pool = owner_to_pool.delete(owner.name) + @class_to_pool.clear + pool.automatic_reconnect = false + pool.disconnect! + pool.spec.config + end + end + + # Retrieving the connection pool happens a lot so we cache it in @class_to_pool. + # This makes retrieving the connection pool O(1) once the process is warm. + # When a connection is established or removed, we invalidate the cache. + # + # Ideally we would use #fetch here, as class_to_pool[klass] may sometimes be nil. + # However, benchmarking (https://gist.github.com/jonleighton/3552829) showed that + # #fetch is significantly slower than #[]. So in the nil case, no caching will + # take place, but that's ok since the nil case is not the common one that we wish + # to optimise for. + def retrieve_connection_pool(klass) + class_to_pool[klass.name] ||= begin + until pool = pool_for(klass) + klass = klass.superclass + break unless klass <= Base + end + + class_to_pool[klass.name] = pool + end + end + + private + + def owner_to_pool + @owner_to_pool[Process.pid] + end + + def class_to_pool + @class_to_pool[Process.pid] + end + + def pool_for(owner) + owner_to_pool.fetch(owner.name) { + if ancestor_pool = pool_from_any_process_for(owner) + # A connection was established in an ancestor process that must have + # subsequently forked. We can't reuse the connection, but we can copy + # the specification and establish a new connection with it. + establish_connection owner, ancestor_pool.spec + else + owner_to_pool[owner.name] = nil + end + } + end + + def pool_from_any_process_for(owner) + owner_to_pool = @owner_to_pool.values.find { |v| v[owner.name] } + owner_to_pool && owner_to_pool[owner.name] + end + end + + class ConnectionManagement + def initialize(app) + @app = app + end + + def call(env) + testing = env['rack.test'] + + response = @app.call(env) + response[2] = ::Rack::BodyProxy.new(response[2]) do + ActiveRecord::Base.clear_active_connections! unless testing + end + + response + rescue Exception + ActiveRecord::Base.clear_active_connections! unless testing + raise + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/abstract/database_limits.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/abstract/database_limits.rb new file mode 100644 index 0000000..c0a2111 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/abstract/database_limits.rb @@ -0,0 +1,67 @@ +module ActiveRecord + module ConnectionAdapters # :nodoc: + module DatabaseLimits + + # Returns the maximum length of a table alias. + def table_alias_length + 255 + end + + # Returns the maximum length of a column name. + def column_name_length + 64 + end + + # Returns the maximum length of a table name. + def table_name_length + 64 + end + + # Returns the maximum allowed length for an index name. This + # limit is enforced by rails and Is less than or equal to + # index_name_length. The gap between + # index_name_length is to allow internal rails + # operations to use prefixes in temporary operations. + def allowed_index_name_length + index_name_length + end + + # Returns the maximum length of an index name. + def index_name_length + 64 + end + + # Returns the maximum number of columns per table. + def columns_per_table + 1024 + end + + # Returns the maximum number of indexes per table. + def indexes_per_table + 16 + end + + # Returns the maximum number of columns in a multicolumn index. + def columns_per_multicolumn_index + 16 + end + + # Returns the maximum number of elements in an IN (x,y,z) clause. + # nil means no limit. + def in_clause_length + nil + end + + # Returns the maximum length of an SQL query. + def sql_query_length + 1048575 + end + + # Returns maximum number of joins in a single query. + def joins_per_query + 256 + end + + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/abstract/database_statements.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/abstract/database_statements.rb new file mode 100644 index 0000000..9633e31 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/abstract/database_statements.rb @@ -0,0 +1,393 @@ +module ActiveRecord + module ConnectionAdapters # :nodoc: + module DatabaseStatements + def initialize + super + reset_transaction + end + + # Converts an arel AST to SQL + def to_sql(arel, binds = []) + if arel.respond_to?(:ast) + collected = visitor.accept(arel.ast, collector) + collected.compile(binds.dup, self) + else + arel + end + end + + # This is used in the StatementCache object. It returns an object that + # can be used to query the database repeatedly. + def cacheable_query(arel) # :nodoc: + if prepared_statements + ActiveRecord::StatementCache.query visitor, arel.ast + else + ActiveRecord::StatementCache.partial_query visitor, arel.ast, collector + end + end + + # Returns an ActiveRecord::Result instance. + def select_all(arel, name = nil, binds = []) + arel, binds = binds_from_relation arel, binds + select(to_sql(arel, binds), name, binds) + end + + # Returns a record hash with the column names as keys and column values + # as values. + def select_one(arel, name = nil, binds = []) + select_all(arel, name, binds).first + end + + # Returns a single value from a record + def select_value(arel, name = nil, binds = []) + if result = select_one(arel, name, binds) + result.values.first + end + end + + # Returns an array of the values of the first column in a select: + # select_values("SELECT id FROM companies LIMIT 3") => [1,2,3] + def select_values(arel, name = nil) + arel, binds = binds_from_relation arel, [] + select_rows(to_sql(arel, binds), name, binds).map(&:first) + end + + # Returns an array of arrays containing the field values. + # Order is the same as that returned by +columns+. + def select_rows(sql, name = nil, binds = []) + end + undef_method :select_rows + + # Executes the SQL statement in the context of this connection. + def execute(sql, name = nil) + end + undef_method :execute + + # Executes +sql+ statement in the context of this connection using + # +binds+ as the bind substitutes. +name+ is logged along with + # the executed +sql+ statement. + def exec_query(sql, name = 'SQL', binds = []) + end + + # Executes insert +sql+ statement in the context of this connection using + # +binds+ as the bind substitutes. +name+ is logged along with + # the executed +sql+ statement. + def exec_insert(sql, name, binds, pk = nil, sequence_name = nil) + exec_query(sql, name, binds) + end + + # Executes delete +sql+ statement in the context of this connection using + # +binds+ as the bind substitutes. +name+ is logged along with + # the executed +sql+ statement. + def exec_delete(sql, name, binds) + exec_query(sql, name, binds) + end + + # Executes the truncate statement. + def truncate(table_name, name = nil) + raise NotImplementedError + end + + # Executes update +sql+ statement in the context of this connection using + # +binds+ as the bind substitutes. +name+ is logged along with + # the executed +sql+ statement. + def exec_update(sql, name, binds) + exec_query(sql, name, binds) + end + + # Returns the last auto-generated ID from the affected table. + # + # +id_value+ will be returned unless the value is nil, in + # which case the database will attempt to calculate the last inserted + # id and return that value. + # + # If the next id was calculated in advance (as in Oracle), it should be + # passed in as +id_value+. + def insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = []) + sql, binds = sql_for_insert(to_sql(arel, binds), pk, id_value, sequence_name, binds) + value = exec_insert(sql, name, binds, pk, sequence_name) + id_value || last_inserted_id(value) + end + + # Executes the update statement and returns the number of rows affected. + def update(arel, name = nil, binds = []) + exec_update(to_sql(arel, binds), name, binds) + end + + # Executes the delete statement and returns the number of rows affected. + def delete(arel, name = nil, binds = []) + exec_delete(to_sql(arel, binds), name, binds) + end + + # Returns +true+ when the connection adapter supports prepared statement + # caching, otherwise returns +false+ + def supports_statement_cache? + false + end + + # Runs the given block in a database transaction, and returns the result + # of the block. + # + # == Nested transactions support + # + # Most databases don't support true nested transactions. At the time of + # writing, the only database that supports true nested transactions that + # we're aware of, is MS-SQL. + # + # In order to get around this problem, #transaction will emulate the effect + # of nested transactions, by using savepoints: + # http://dev.mysql.com/doc/refman/5.0/en/savepoint.html + # Savepoints are supported by MySQL and PostgreSQL. SQLite3 version >= '3.6.8' + # supports savepoints. + # + # It is safe to call this method if a database transaction is already open, + # i.e. if #transaction is called within another #transaction block. In case + # of a nested call, #transaction will behave as follows: + # + # - The block will be run without doing anything. All database statements + # that happen within the block are effectively appended to the already + # open database transaction. + # - However, if +:requires_new+ is set, the block will be wrapped in a + # database savepoint acting as a sub-transaction. + # + # === Caveats + # + # MySQL doesn't support DDL transactions. If you perform a DDL operation, + # then any created savepoints will be automatically released. For example, + # if you've created a savepoint, then you execute a CREATE TABLE statement, + # then the savepoint that was created will be automatically released. + # + # This means that, on MySQL, you shouldn't execute DDL operations inside + # a #transaction call that you know might create a savepoint. Otherwise, + # #transaction will raise exceptions when it tries to release the + # already-automatically-released savepoints: + # + # Model.connection.transaction do # BEGIN + # Model.connection.transaction(requires_new: true) do # CREATE SAVEPOINT active_record_1 + # Model.connection.create_table(...) + # # active_record_1 now automatically released + # end # RELEASE SAVEPOINT active_record_1 <--- BOOM! database error! + # end + # + # == Transaction isolation + # + # If your database supports setting the isolation level for a transaction, you can set + # it like so: + # + # Post.transaction(isolation: :serializable) do + # # ... + # end + # + # Valid isolation levels are: + # + # * :read_uncommitted + # * :read_committed + # * :repeatable_read + # * :serializable + # + # You should consult the documentation for your database to understand the + # semantics of these different levels: + # + # * http://www.postgresql.org/docs/9.1/static/transaction-iso.html + # * https://dev.mysql.com/doc/refman/5.0/en/set-transaction.html + # + # An ActiveRecord::TransactionIsolationError will be raised if: + # + # * The adapter does not support setting the isolation level + # * You are joining an existing open transaction + # * You are creating a nested (savepoint) transaction + # + # The mysql, mysql2 and postgresql adapters support setting the transaction + # isolation level. However, support is disabled for MySQL versions below 5, + # because they are affected by a bug[http://bugs.mysql.com/bug.php?id=39170] + # which means the isolation level gets persisted outside the transaction. + def transaction(options = {}) + options.assert_valid_keys :requires_new, :joinable, :isolation + + if !options[:requires_new] && current_transaction.joinable? + if options[:isolation] + raise ActiveRecord::TransactionIsolationError, "cannot set isolation when joining a transaction" + end + yield + else + transaction_manager.within_new_transaction(options) { yield } + end + rescue ActiveRecord::Rollback + # rollbacks are silently swallowed + end + + attr_reader :transaction_manager #:nodoc: + + delegate :within_new_transaction, :open_transactions, :current_transaction, :begin_transaction, :commit_transaction, :rollback_transaction, to: :transaction_manager + + def transaction_open? + current_transaction.open? + end + + def reset_transaction #:nodoc: + @transaction_manager = TransactionManager.new(self) + end + + # Register a record with the current transaction so that its after_commit and after_rollback callbacks + # can be called. + def add_transaction_record(record) + current_transaction.add_record(record) + end + + def transaction_state + current_transaction.state + end + + # Begins the transaction (and turns off auto-committing). + def begin_db_transaction() end + + def transaction_isolation_levels + { + read_uncommitted: "READ UNCOMMITTED", + read_committed: "READ COMMITTED", + repeatable_read: "REPEATABLE READ", + serializable: "SERIALIZABLE" + } + end + + # Begins the transaction with the isolation level set. Raises an error by + # default; adapters that support setting the isolation level should implement + # this method. + def begin_isolated_db_transaction(isolation) + raise ActiveRecord::TransactionIsolationError, "adapter does not support setting transaction isolation" + end + + # Commits the transaction (and turns on auto-committing). + def commit_db_transaction() end + + # Rolls back the transaction (and turns on auto-committing). Must be + # done if the transaction block raises an exception or returns false. + def rollback_db_transaction + exec_rollback_db_transaction + end + + def exec_rollback_db_transaction() end #:nodoc: + + def rollback_to_savepoint(name = nil) + exec_rollback_to_savepoint(name) + end + + def exec_rollback_to_savepoint(name = nil) #:nodoc: + end + + def default_sequence_name(table, column) + nil + end + + # Set the sequence to the max value of the table's column. + def reset_sequence!(table, column, sequence = nil) + # Do nothing by default. Implement for PostgreSQL, Oracle, ... + end + + # Inserts the given fixture into the table. Overridden in adapters that require + # something beyond a simple insert (eg. Oracle). + def insert_fixture(fixture, table_name) + fixture = fixture.stringify_keys + columns = schema_cache.columns_hash(table_name) + + key_list = [] + value_list = fixture.map do |name, value| + if column = columns[name] + key_list << quote_column_name(name) + quote(value, column) + else + raise Fixture::FixtureError, %(table "#{table_name}" has no column named #{name.inspect}.) + end + end + + execute "INSERT INTO #{quote_table_name(table_name)} (#{key_list.join(', ')}) VALUES (#{value_list.join(', ')})", 'Fixture Insert' + end + + def empty_insert_statement_value + "DEFAULT VALUES" + end + + # Sanitizes the given LIMIT parameter in order to prevent SQL injection. + # + # The +limit+ may be anything that can evaluate to a string via #to_s. It + # should look like an integer, or a comma-delimited list of integers, or + # an Arel SQL literal. + # + # Returns Integer and Arel::Nodes::SqlLiteral limits as is. + # Returns the sanitized limit parameter, either as an integer, or as a + # string which contains a comma-delimited list of integers. + def sanitize_limit(limit) + if limit.is_a?(Integer) || limit.is_a?(Arel::Nodes::SqlLiteral) + limit + elsif limit.to_s.include?(',') + Arel.sql limit.to_s.split(',').map{ |i| Integer(i) }.join(',') + else + Integer(limit) + end + end + + # The default strategy for an UPDATE with joins is to use a subquery. This doesn't work + # on MySQL (even when aliasing the tables), but MySQL allows using JOIN directly in + # an UPDATE statement, so in the MySQL adapters we redefine this to do that. + def join_to_update(update, select) #:nodoc: + key = update.key + subselect = subquery_for(key, select) + + update.where key.in(subselect) + end + + def join_to_delete(delete, select, key) #:nodoc: + subselect = subquery_for(key, select) + + delete.where key.in(subselect) + end + + protected + + # Returns a subquery for the given key using the join information. + def subquery_for(key, select) + subselect = select.clone + subselect.projections = [key] + subselect + end + + # Returns an ActiveRecord::Result instance. + def select(sql, name = nil, binds = []) + exec_query(sql, name, binds) + end + + + # Returns the last auto-generated ID from the affected table. + def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) + execute(sql, name) + id_value + end + + # Executes the update statement and returns the number of rows affected. + def update_sql(sql, name = nil) + execute(sql, name) + end + + # Executes the delete statement and returns the number of rows affected. + def delete_sql(sql, name = nil) + update_sql(sql, name) + end + + def sql_for_insert(sql, pk, id_value, sequence_name, binds) + [sql, binds] + end + + def last_inserted_id(result) + row = result.rows.first + row && row.first + end + + def binds_from_relation(relation, binds) + if relation.is_a?(Relation) && binds.empty? + relation, binds = relation.arel, relation.bind_values + end + [relation, binds] + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/abstract/query_cache.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/abstract/query_cache.rb new file mode 100644 index 0000000..5e27cfe --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/abstract/query_cache.rb @@ -0,0 +1,95 @@ +module ActiveRecord + module ConnectionAdapters # :nodoc: + module QueryCache + class << self + def included(base) #:nodoc: + dirties_query_cache base, :insert, :update, :delete, :rollback_to_savepoint, :rollback_db_transaction + end + + def dirties_query_cache(base, *method_names) + method_names.each do |method_name| + base.class_eval <<-end_code, __FILE__, __LINE__ + 1 + def #{method_name}(*) + clear_query_cache if @query_cache_enabled + super + end + end_code + end + end + end + + attr_reader :query_cache, :query_cache_enabled + + def initialize(*) + super + @query_cache = Hash.new { |h,sql| h[sql] = {} } + @query_cache_enabled = false + end + + # Enable the query cache within the block. + def cache + old, @query_cache_enabled = @query_cache_enabled, true + yield + ensure + @query_cache_enabled = old + clear_query_cache unless @query_cache_enabled + end + + def enable_query_cache! + @query_cache_enabled = true + end + + def disable_query_cache! + @query_cache_enabled = false + end + + # Disable the query cache within the block. + def uncached + old, @query_cache_enabled = @query_cache_enabled, false + yield + ensure + @query_cache_enabled = old + end + + # Clears the query cache. + # + # One reason you may wish to call this method explicitly is between queries + # that ask the database to randomize results. Otherwise the cache would see + # the same SQL query and repeatedly return the same result each time, silently + # undermining the randomness you were expecting. + def clear_query_cache + @query_cache.clear + end + + def select_all(arel, name = nil, binds = []) + if @query_cache_enabled && !locked?(arel) + arel, binds = binds_from_relation arel, binds + sql = to_sql(arel, binds) + cache_sql(sql, binds) { super(sql, name, binds) } + else + super + end + end + + private + + def cache_sql(sql, binds) + result = + if @query_cache[sql].key?(binds) + ActiveSupport::Notifications.instrument("sql.active_record", + :sql => sql, :binds => binds, :name => "CACHE", :connection_id => object_id) + @query_cache[sql][binds] + else + @query_cache[sql][binds] = yield + end + result.dup + end + + # If arel is locked this is a SELECT ... FOR UPDATE or somesuch. Such + # queries should not be cached. + def locked?(arel) + arel.respond_to?(:locked) && arel.locked + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/abstract/quoting.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/abstract/quoting.rb new file mode 100644 index 0000000..679878d --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/abstract/quoting.rb @@ -0,0 +1,133 @@ +require 'active_support/core_ext/big_decimal/conversions' + +module ActiveRecord + module ConnectionAdapters # :nodoc: + module Quoting + # Quotes the column value to help prevent + # {SQL injection attacks}[http://en.wikipedia.org/wiki/SQL_injection]. + def quote(value, column = nil) + # records are quoted as their primary key + return value.quoted_id if value.respond_to?(:quoted_id) + + if column + value = column.cast_type.type_cast_for_database(value) + end + + _quote(value) + end + + # Cast a +value+ to a type that the database understands. For example, + # SQLite does not understand dates, so this method will convert a Date + # to a String. + def type_cast(value, column) + if value.respond_to?(:quoted_id) && value.respond_to?(:id) + return value.id + end + + if column + value = column.cast_type.type_cast_for_database(value) + end + + _type_cast(value) + rescue TypeError + to_type = column ? " to #{column.type}" : "" + raise TypeError, "can't cast #{value.class}#{to_type}" + end + + # Quotes a string, escaping any ' (single quote) and \ (backslash) + # characters. + def quote_string(s) + s.gsub(/\\/, '\&\&').gsub(/'/, "''") # ' (for ruby-mode) + end + + # Quotes the column name. Defaults to no quoting. + def quote_column_name(column_name) + column_name + end + + # Quotes the table name. Defaults to column name quoting. + def quote_table_name(table_name) + quote_column_name(table_name) + end + + # Override to return the quoted table name for assignment. Defaults to + # table quoting. + # + # This works for mysql and mysql2 where table.column can be used to + # resolve ambiguity. + # + # We override this in the sqlite3 and postgresql adapters to use only + # the column name (as per syntax requirements). + def quote_table_name_for_assignment(table, attr) + quote_table_name("#{table}.#{attr}") + end + + def quoted_true + "'t'" + end + + def unquoted_true + 't' + end + + def quoted_false + "'f'" + end + + def unquoted_false + 'f' + end + + def quoted_date(value) + if value.acts_like?(:time) + zone_conversion_method = ActiveRecord::Base.default_timezone == :utc ? :getutc : :getlocal + + if value.respond_to?(zone_conversion_method) + value = value.send(zone_conversion_method) + end + end + + value.to_s(:db) + end + + private + + def types_which_need_no_typecasting + [nil, Numeric, String] + end + + def _quote(value) + case value + when String, ActiveSupport::Multibyte::Chars, Type::Binary::Data + "'#{quote_string(value.to_s)}'" + when true then quoted_true + when false then quoted_false + when nil then "NULL" + # BigDecimals need to be put in a non-normalized form and quoted. + when BigDecimal then value.to_s('F') + when Numeric, ActiveSupport::Duration then value.to_s + when Date, Time then "'#{quoted_date(value)}'" + when Symbol then "'#{quote_string(value.to_s)}'" + when Class then "'#{value}'" + else + "'#{quote_string(YAML.dump(value))}'" + end + end + + def _type_cast(value) + case value + when Symbol, ActiveSupport::Multibyte::Chars, Type::Binary::Data + value.to_s + when true then unquoted_true + when false then unquoted_false + # BigDecimals need to be put in a non-normalized form and quoted. + when BigDecimal then value.to_s('F') + when Date, Time then quoted_date(value) + when *types_which_need_no_typecasting + value + else raise TypeError + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/abstract/savepoints.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/abstract/savepoints.rb new file mode 100644 index 0000000..c0662f8 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/abstract/savepoints.rb @@ -0,0 +1,21 @@ +module ActiveRecord + module ConnectionAdapters + module Savepoints #:nodoc: + def supports_savepoints? + true + end + + def create_savepoint(name = current_savepoint_name) + execute("SAVEPOINT #{name}") + end + + def exec_rollback_to_savepoint(name = current_savepoint_name) + execute("ROLLBACK TO SAVEPOINT #{name}") + end + + def release_savepoint(name = current_savepoint_name) + execute("RELEASE SAVEPOINT #{name}") + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/abstract/schema_creation.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/abstract/schema_creation.rb new file mode 100644 index 0000000..792d49d --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/abstract/schema_creation.rb @@ -0,0 +1,125 @@ +require 'active_support/core_ext/string/strip' + +module ActiveRecord + module ConnectionAdapters + class AbstractAdapter + class SchemaCreation # :nodoc: + def initialize(conn) + @conn = conn + @cache = {} + end + + def accept(o) + m = @cache[o.class] ||= "visit_#{o.class.name.split('::').last}" + send m, o + end + + def visit_AddColumn(o) + "ADD #{accept(o)}" + end + + private + + def visit_AlterTable(o) + sql = "ALTER TABLE #{quote_table_name(o.name)} " + sql << o.adds.map { |col| visit_AddColumn col }.join(' ') + sql << o.foreign_key_adds.map { |fk| visit_AddForeignKey fk }.join(' ') + sql << o.foreign_key_drops.map { |fk| visit_DropForeignKey fk }.join(' ') + end + + def visit_ColumnDefinition(o) + sql_type = type_to_sql(o.type, o.limit, o.precision, o.scale) + column_sql = "#{quote_column_name(o.name)} #{sql_type}" + add_column_options!(column_sql, column_options(o)) unless o.primary_key? + column_sql + end + + def visit_TableDefinition(o) + create_sql = "CREATE#{' TEMPORARY' if o.temporary} TABLE " + create_sql << "#{quote_table_name(o.name)} " + create_sql << "(#{o.columns.map { |c| accept c }.join(', ')}) " unless o.as + create_sql << "#{o.options}" + create_sql << " AS #{@conn.to_sql(o.as)}" if o.as + create_sql + end + + def visit_AddForeignKey(o) + sql = <<-SQL.strip_heredoc + ADD CONSTRAINT #{quote_column_name(o.name)} + FOREIGN KEY (#{quote_column_name(o.column)}) + REFERENCES #{quote_table_name(o.to_table)} (#{quote_column_name(o.primary_key)}) + SQL + sql << " #{action_sql('DELETE', o.on_delete)}" if o.on_delete + sql << " #{action_sql('UPDATE', o.on_update)}" if o.on_update + sql + end + + def visit_DropForeignKey(name) + "DROP CONSTRAINT #{quote_column_name(name)}" + end + + def column_options(o) + column_options = {} + column_options[:null] = o.null unless o.null.nil? + column_options[:default] = o.default unless o.default.nil? + column_options[:column] = o + column_options[:first] = o.first + column_options[:after] = o.after + column_options + end + + def quote_column_name(name) + @conn.quote_column_name name + end + + def quote_table_name(name) + @conn.quote_table_name name + end + + def type_to_sql(type, limit, precision, scale) + @conn.type_to_sql type.to_sym, limit, precision, scale + end + + def add_column_options!(sql, options) + sql << " DEFAULT #{quote_value(options[:default], options[:column])}" if options_include_default?(options) + # must explicitly check for :null to allow change_column to work on migrations + if options[:null] == false + sql << " NOT NULL" + end + if options[:auto_increment] == true + sql << " AUTO_INCREMENT" + end + sql + end + + def quote_value(value, column) + column.sql_type ||= type_to_sql(column.type, column.limit, column.precision, column.scale) + column.cast_type ||= type_for_column(column) + + @conn.quote(value, column) + end + + def options_include_default?(options) + options.include?(:default) && !(options[:null] == false && options[:default].nil?) + end + + def action_sql(action, dependency) + case dependency + when :nullify then "ON #{action} SET NULL" + when :cascade then "ON #{action} CASCADE" + when :restrict then "ON #{action} RESTRICT" + else + raise ArgumentError, <<-MSG.strip_heredoc + '#{dependency}' is not supported for :on_update or :on_delete. + Supported values are: :nullify, :cascade, :restrict + MSG + end + end + + def type_for_column(column) + @conn.lookup_cast_type(column.sql_type) + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/abstract/schema_definitions.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/abstract/schema_definitions.rb new file mode 100644 index 0000000..82fe12b --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/abstract/schema_definitions.rb @@ -0,0 +1,584 @@ +require 'date' +require 'set' +require 'bigdecimal' +require 'bigdecimal/util' + +module ActiveRecord + module ConnectionAdapters #:nodoc: + # Abstract representation of an index definition on a table. Instances of + # this type are typically created and returned by methods in database + # adapters. e.g. ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter#indexes + class IndexDefinition < Struct.new(:table, :name, :unique, :columns, :lengths, :orders, :where, :type, :using) #:nodoc: + end + + # Abstract representation of a column definition. Instances of this type + # are typically created by methods in TableDefinition, and added to the + # +columns+ attribute of said TableDefinition object, in order to be used + # for generating a number of table creation or table changing SQL statements. + class ColumnDefinition < Struct.new(:name, :type, :limit, :precision, :scale, :default, :null, :first, :after, :primary_key, :sql_type, :cast_type) #:nodoc: + + def primary_key? + primary_key || type.to_sym == :primary_key + end + end + + class ChangeColumnDefinition < Struct.new(:column, :type, :options) #:nodoc: + end + + class ForeignKeyDefinition < Struct.new(:from_table, :to_table, :options) #:nodoc: + def name + options[:name] + end + + def column + options[:column] + end + + def primary_key + options[:primary_key] || default_primary_key + end + + def on_delete + options[:on_delete] + end + + def on_update + options[:on_update] + end + + def custom_primary_key? + options[:primary_key] != default_primary_key + end + + private + def default_primary_key + "id" + end + end + + module TimestampDefaultDeprecation # :nodoc: + def emit_warning_if_null_unspecified(sym, options) + return if options.key?(:null) + + ActiveSupport::Deprecation.warn(<<-MSG.squish) + `##{sym}` was called without specifying an option for `null`. In Rails 5, + this behavior will change to `null: false`. You should manually specify + `null: true` to prevent the behavior of your existing migrations from changing. + MSG + end + end + + # Represents the schema of an SQL table in an abstract way. This class + # provides methods for manipulating the schema representation. + # + # Inside migration files, the +t+ object in +create_table+ + # is actually of this type: + # + # class SomeMigration < ActiveRecord::Migration + # def up + # create_table :foo do |t| + # puts t.class # => "ActiveRecord::ConnectionAdapters::TableDefinition" + # end + # end + # + # def down + # ... + # end + # end + # + # The table definitions + # The Columns are stored as a ColumnDefinition in the +columns+ attribute. + class TableDefinition + include TimestampDefaultDeprecation + + # An array of ColumnDefinition objects, representing the column changes + # that have been defined. + attr_accessor :indexes + attr_reader :name, :temporary, :options, :as, :foreign_keys + + def initialize(types, name, temporary, options, as = nil) + @columns_hash = {} + @indexes = {} + @foreign_keys = [] + @native = types + @temporary = temporary + @options = options + @as = as + @name = name + end + + def columns; @columns_hash.values; end + + # Appends a primary key definition to the table definition. + # Can be called multiple times, but this is probably not a good idea. + def primary_key(name, type = :primary_key, options = {}) + column(name, type, options.merge(:primary_key => true)) + end + + # Returns a ColumnDefinition for the column with name +name+. + def [](name) + @columns_hash[name.to_s] + end + + # Instantiates a new column for the table. + # The +type+ parameter is normally one of the migrations native types, + # which is one of the following: + # :primary_key, :string, :text, + # :integer, :float, :decimal, + # :datetime, :time, :date, + # :binary, :boolean. + # + # You may use a type not in this list as long as it is supported by your + # database (for example, "polygon" in MySQL), but this will not be database + # agnostic and should usually be avoided. + # + # Available options are (none of these exists by default): + # * :limit - + # Requests a maximum column length. This is number of characters for :string and + # :text columns and number of bytes for :binary and :integer columns. + # * :default - + # The column's default value. Use nil for NULL. + # * :null - + # Allows or disallows +NULL+ values in the column. This option could + # have been named :null_allowed. + # * :precision - + # Specifies the precision for a :decimal column. + # * :scale - + # Specifies the scale for a :decimal column. + # * :index - + # Create an index for the column. Can be either true or an options hash. + # + # Note: The precision is the total number of significant digits + # and the scale is the number of digits that can be stored following + # the decimal point. For example, the number 123.45 has a precision of 5 + # and a scale of 2. A decimal with a precision of 5 and a scale of 2 can + # range from -999.99 to 999.99. + # + # Please be aware of different RDBMS implementations behavior with + # :decimal columns: + # * The SQL standard says the default scale should be 0, :scale <= + # :precision, and makes no comments about the requirements of + # :precision. + # * MySQL: :precision [1..63], :scale [0..30]. + # Default is (10,0). + # * PostgreSQL: :precision [1..infinity], + # :scale [0..infinity]. No default. + # * SQLite2: Any :precision and :scale may be used. + # Internal storage as strings. No default. + # * SQLite3: No restrictions on :precision and :scale, + # but the maximum supported :precision is 16. No default. + # * Oracle: :precision [1..38], :scale [-84..127]. + # Default is (38,0). + # * DB2: :precision [1..63], :scale [0..62]. + # Default unknown. + # * SqlServer?: :precision [1..38], :scale [0..38]. + # Default (38,0). + # + # This method returns self. + # + # == Examples + # # Assuming +td+ is an instance of TableDefinition + # td.column(:granted, :boolean) + # # granted BOOLEAN + # + # td.column(:picture, :binary, limit: 2.megabytes) + # # => picture BLOB(2097152) + # + # td.column(:sales_stage, :string, limit: 20, default: 'new', null: false) + # # => sales_stage VARCHAR(20) DEFAULT 'new' NOT NULL + # + # td.column(:bill_gates_money, :decimal, precision: 15, scale: 2) + # # => bill_gates_money DECIMAL(15,2) + # + # td.column(:sensor_reading, :decimal, precision: 30, scale: 20) + # # => sensor_reading DECIMAL(30,20) + # + # # While :scale defaults to zero on most databases, it + # # probably wouldn't hurt to include it. + # td.column(:huge_integer, :decimal, precision: 30) + # # => huge_integer DECIMAL(30) + # + # # Defines a column with a database-specific type. + # td.column(:foo, 'polygon') + # # => foo polygon + # + # == Short-hand examples + # + # Instead of calling +column+ directly, you can also work with the short-hand definitions for the default types. + # They use the type as the method name instead of as a parameter and allow for multiple columns to be defined + # in a single statement. + # + # What can be written like this with the regular calls to column: + # + # create_table :products do |t| + # t.column :shop_id, :integer + # t.column :creator_id, :integer + # t.column :item_number, :string + # t.column :name, :string, default: "Untitled" + # t.column :value, :string, default: "Untitled" + # t.column :created_at, :datetime + # t.column :updated_at, :datetime + # end + # add_index :products, :item_number + # + # can also be written as follows using the short-hand: + # + # create_table :products do |t| + # t.integer :shop_id, :creator_id + # t.string :item_number, index: true + # t.string :name, :value, default: "Untitled" + # t.timestamps null: false + # end + # + # There's a short-hand method for each of the type values declared at the top. And then there's + # TableDefinition#timestamps that'll add +created_at+ and +updated_at+ as datetimes. + # + # TableDefinition#references will add an appropriately-named _id column, plus a corresponding _type + # column if the :polymorphic option is supplied. If :polymorphic is a hash of + # options, these will be used when creating the _type column. The :index option + # will also create an index, similar to calling add_index. So what can be written like this: + # + # create_table :taggings do |t| + # t.integer :tag_id, :tagger_id, :taggable_id + # t.string :tagger_type + # t.string :taggable_type, default: 'Photo' + # end + # add_index :taggings, :tag_id, name: 'index_taggings_on_tag_id' + # add_index :taggings, [:tagger_id, :tagger_type] + # + # Can also be written as follows using references: + # + # create_table :taggings do |t| + # t.references :tag, index: { name: 'index_taggings_on_tag_id' } + # t.references :tagger, polymorphic: true, index: true + # t.references :taggable, polymorphic: { default: 'Photo' } + # end + def column(name, type, options = {}) + name = name.to_s + type = type.to_sym + options = options.dup + + if @columns_hash[name] && @columns_hash[name].primary_key? + raise ArgumentError, "you can't redefine the primary key column '#{name}'. To define a custom primary key, pass { id: false } to create_table." + end + + index_options = options.delete(:index) + index(name, index_options.is_a?(Hash) ? index_options : {}) if index_options + @columns_hash[name] = new_column_definition(name, type, options) + self + end + + def remove_column(name) + @columns_hash.delete name.to_s + end + + [:string, :text, :integer, :bigint, :float, :decimal, :datetime, :timestamp, :time, :date, :binary, :boolean].each do |column_type| + define_method column_type do |*args| + options = args.extract_options! + column_names = args + column_names.each { |name| column(name, column_type, options) } + end + end + + # Adds index options to the indexes hash, keyed by column name + # This is primarily used to track indexes that need to be created after the table + # + # index(:account_id, name: 'index_projects_on_account_id') + def index(column_name, options = {}) + indexes[column_name] = options + end + + def foreign_key(table_name, options = {}) # :nodoc: + foreign_keys.push([table_name, options]) + end + + # Appends :datetime columns :created_at and + # :updated_at to the table. See SchemaStatements#add_timestamps + # + # t.timestamps null: false + def timestamps(*args) + options = args.extract_options! + emit_warning_if_null_unspecified(:timestamps, options) + column(:created_at, :datetime, options) + column(:updated_at, :datetime, options) + end + + # Adds a reference. + # + # t.references(:user) + # t.belongs_to(:supplier, foreign_key: true) + # + # See SchemaStatements#add_reference for details of the options you can use. + def references(*args) + options = args.extract_options! + polymorphic = options.delete(:polymorphic) + index_options = options.delete(:index) + foreign_key_options = options.delete(:foreign_key) + type = options.delete(:type) || :integer + + if polymorphic && foreign_key_options + raise ArgumentError, "Cannot add a foreign key on a polymorphic relation" + end + + args.each do |col| + column("#{col}_id", type, options) + column("#{col}_type", :string, polymorphic.is_a?(Hash) ? polymorphic : options) if polymorphic + index(polymorphic ? %w(type id).map { |t| "#{col}_#{t}" } : "#{col}_id", index_options.is_a?(Hash) ? index_options : {}) if index_options + if foreign_key_options + to_table = Base.pluralize_table_names ? col.to_s.pluralize : col.to_s + foreign_key(to_table, foreign_key_options.is_a?(Hash) ? foreign_key_options : {}) + end + end + end + alias :belongs_to :references + + def new_column_definition(name, type, options) # :nodoc: + type = aliased_types(type.to_s, type) + column = create_column_definition name, type + limit = options.fetch(:limit) do + native[type][:limit] if native[type].is_a?(Hash) + end + + column.limit = limit + column.precision = options[:precision] + column.scale = options[:scale] + column.default = options[:default] + column.null = options[:null] + column.first = options[:first] + column.after = options[:after] + column.primary_key = type == :primary_key || options[:primary_key] + column + end + + private + def create_column_definition(name, type) + ColumnDefinition.new name, type + end + + def native + @native + end + + def aliased_types(name, fallback) + 'timestamp' == name ? :datetime : fallback + end + end + + class AlterTable # :nodoc: + attr_reader :adds + attr_reader :foreign_key_adds + attr_reader :foreign_key_drops + + def initialize(td) + @td = td + @adds = [] + @foreign_key_adds = [] + @foreign_key_drops = [] + end + + def name; @td.name; end + + def add_foreign_key(to_table, options) + @foreign_key_adds << ForeignKeyDefinition.new(name, to_table, options) + end + + def drop_foreign_key(name) + @foreign_key_drops << name + end + + def add_column(name, type, options) + name = name.to_s + type = type.to_sym + @adds << @td.new_column_definition(name, type, options) + end + end + + # Represents an SQL table in an abstract way for updating a table. + # Also see TableDefinition and SchemaStatements#create_table + # + # Available transformations are: + # + # change_table :table do |t| + # t.column + # t.index + # t.rename_index + # t.timestamps + # t.change + # t.change_default + # t.rename + # t.references + # t.belongs_to + # t.string + # t.text + # t.integer + # t.float + # t.decimal + # t.datetime + # t.timestamp + # t.time + # t.date + # t.binary + # t.boolean + # t.remove + # t.remove_references + # t.remove_belongs_to + # t.remove_index + # t.remove_timestamps + # end + # + class Table + attr_reader :name + + def initialize(table_name, base) + @name = table_name + @base = base + end + + # Adds a new column to the named table. + # See TableDefinition#column for details of the options you can use. + # + # ====== Creating a simple column + # t.column(:name, :string) + def column(column_name, type, options = {}) + @base.add_column(name, column_name, type, options) + end + + # Checks to see if a column exists. See SchemaStatements#column_exists? + def column_exists?(column_name, type = nil, options = {}) + @base.column_exists?(name, column_name, type, options) + end + + # Adds a new index to the table. +column_name+ can be a single Symbol, or + # an Array of Symbols. See SchemaStatements#add_index + # + # ====== Creating a simple index + # t.index(:name) + # ====== Creating a unique index + # t.index([:branch_id, :party_id], unique: true) + # ====== Creating a named index + # t.index([:branch_id, :party_id], unique: true, name: 'by_branch_party') + def index(column_name, options = {}) + @base.add_index(name, column_name, options) + end + + # Checks to see if an index exists. See SchemaStatements#index_exists? + def index_exists?(column_name, options = {}) + @base.index_exists?(name, column_name, options) + end + + # Renames the given index on the table. + # + # t.rename_index(:user_id, :account_id) + def rename_index(index_name, new_index_name) + @base.rename_index(name, index_name, new_index_name) + end + + # Adds timestamps (+created_at+ and +updated_at+) columns to the table. See SchemaStatements#add_timestamps + # + # t.timestamps null: false + def timestamps(options = {}) + @base.add_timestamps(name, options) + end + + # Changes the column's definition according to the new options. + # See TableDefinition#column for details of the options you can use. + # + # t.change(:name, :string, limit: 80) + # t.change(:description, :text) + def change(column_name, type, options = {}) + @base.change_column(name, column_name, type, options) + end + + # Sets a new default value for a column. See SchemaStatements#change_column_default + # + # t.change_default(:qualification, 'new') + # t.change_default(:authorized, 1) + def change_default(column_name, default) + @base.change_column_default(name, column_name, default) + end + + # Removes the column(s) from the table definition. + # + # t.remove(:qualification) + # t.remove(:qualification, :experience) + def remove(*column_names) + @base.remove_columns(name, *column_names) + end + + # Removes the given index from the table. + # + # ====== Remove the index_table_name_on_column in the table_name table + # t.remove_index :column + # ====== Remove the index named index_table_name_on_branch_id in the table_name table + # t.remove_index column: :branch_id + # ====== Remove the index named index_table_name_on_branch_id_and_party_id in the table_name table + # t.remove_index column: [:branch_id, :party_id] + # ====== Remove the index named by_branch_party in the table_name table + # t.remove_index name: :by_branch_party + def remove_index(options = {}) + @base.remove_index(name, options) + end + + # Removes the timestamp columns (+created_at+ and +updated_at+) from the table. + # + # t.remove_timestamps + def remove_timestamps(options = {}) + @base.remove_timestamps(name, options) + end + + # Renames a column. + # + # t.rename(:description, :name) + def rename(column_name, new_column_name) + @base.rename_column(name, column_name, new_column_name) + end + + # Adds a reference. + # + # t.references(:user) + # t.belongs_to(:supplier, foreign_key: true) + # + # See SchemaStatements#add_reference for details of the options you can use. + def references(*args) + options = args.extract_options! + args.each do |ref_name| + @base.add_reference(name, ref_name, options) + end + end + alias :belongs_to :references + + # Removes a reference. Optionally removes a +type+ column. + # remove_references and remove_belongs_to are acceptable. + # + # t.remove_references(:user) + # t.remove_belongs_to(:supplier, polymorphic: true) + # + # See SchemaStatements#remove_reference + def remove_references(*args) + options = args.extract_options! + args.each do |ref_name| + @base.remove_reference(name, ref_name, options) + end + end + alias :remove_belongs_to :remove_references + + # Adds a column or columns of a specified type + # + # t.string(:goat) + # t.string(:goat, :sheep) + [:string, :text, :integer, :float, :decimal, :datetime, :timestamp, :time, :date, :binary, :boolean].each do |column_type| + define_method column_type do |*args| + options = args.extract_options! + args.each do |column_name| + @base.add_column(name, column_name, column_type, options) + end + end + end + + private + def native + @base.native_database_types + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/abstract/schema_dumper.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/abstract/schema_dumper.rb new file mode 100644 index 0000000..6eab11b --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/abstract/schema_dumper.rb @@ -0,0 +1,50 @@ +module ActiveRecord + module ConnectionAdapters # :nodoc: + # The goal of this module is to move Adapter specific column + # definitions to the Adapter instead of having it in the schema + # dumper itself. This code represents the normal case. + # We can then redefine how certain data types may be handled in the schema dumper on the + # Adapter level by over-writing this code inside the database specific adapters + module ColumnDumper + def column_spec(column, types) + spec = prepare_column_options(column, types) + (spec.keys - [:name, :type]).each{ |k| spec[k].insert(0, "#{k}: ")} + spec + end + + # This can be overridden on a Adapter level basis to support other + # extended datatypes (Example: Adding an array option in the + # PostgreSQLAdapter) + def prepare_column_options(column, types) + spec = {} + spec[:name] = column.name.inspect + spec[:type] = column.type.to_s + spec[:null] = 'false' unless column.null + + limit = column.limit || types[column.type][:limit] + spec[:limit] = limit.inspect if limit + spec[:precision] = column.precision.inspect if column.precision + spec[:scale] = column.scale.inspect if column.scale + + default = schema_default(column) if column.has_default? + spec[:default] = default unless default.nil? + + spec + end + + # Lists the valid migration options + def migration_keys + [:name, :limit, :precision, :scale, :default, :null] + end + + private + + def schema_default(column) + default = column.type_cast_from_database(column.default) + unless default.nil? + column.type_cast_for_schema(default) + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/abstract/schema_statements.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/abstract/schema_statements.rb new file mode 100644 index 0000000..167683c --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/abstract/schema_statements.rb @@ -0,0 +1,1055 @@ +require 'active_record/migration/join_table' +require 'active_support/core_ext/string/access' +require 'digest' + +module ActiveRecord + module ConnectionAdapters # :nodoc: + module SchemaStatements + include ActiveRecord::Migration::JoinTable + + # Returns a hash of mappings from the abstract data types to the native + # database types. See TableDefinition#column for details on the recognized + # abstract data types. + def native_database_types + {} + end + + # Truncates a table alias according to the limits of the current adapter. + def table_alias_for(table_name) + table_name[0...table_alias_length].tr('.', '_') + end + + # Returns the relation names useable to back Active Record models. + # For most adapters this means all tables and views. + def data_sources + tables + end + + # Checks to see if the data source +name+ exists on the database. + # + # data_source_exists?(:ebooks) + # + def data_source_exists?(name) + data_sources.include?(name.to_s) + end + + # Checks to see if the table +table_name+ exists on the database. + # + # table_exists?(:developers) + # + def table_exists?(table_name) + tables.include?(table_name.to_s) + end + + # Returns an array of indexes for the given table. + # def indexes(table_name, name = nil) end + + # Checks to see if an index exists on a table for a given index definition. + # + # # Check an index exists + # index_exists?(:suppliers, :company_id) + # + # # Check an index on multiple columns exists + # index_exists?(:suppliers, [:company_id, :company_type]) + # + # # Check a unique index exists + # index_exists?(:suppliers, :company_id, unique: true) + # + # # Check an index with a custom name exists + # index_exists?(:suppliers, :company_id, name: "idx_company_id") + # + def index_exists?(table_name, column_name, options = {}) + column_names = Array(column_name).map(&:to_s) + index_name = options.key?(:name) ? options[:name].to_s : index_name(table_name, column: column_names) + checks = [] + checks << lambda { |i| i.name == index_name } + checks << lambda { |i| i.columns == column_names } + checks << lambda { |i| i.unique } if options[:unique] + + indexes(table_name).any? { |i| checks.all? { |check| check[i] } } + end + + # Returns an array of Column objects for the table specified by +table_name+. + # See the concrete implementation for details on the expected parameter values. + def columns(table_name) end + + # Checks to see if a column exists in a given table. + # + # # Check a column exists + # column_exists?(:suppliers, :name) + # + # # Check a column exists of a particular type + # column_exists?(:suppliers, :name, :string) + # + # # Check a column exists with a specific definition + # column_exists?(:suppliers, :name, :string, limit: 100) + # column_exists?(:suppliers, :name, :string, default: 'default') + # column_exists?(:suppliers, :name, :string, null: false) + # column_exists?(:suppliers, :tax, :decimal, precision: 8, scale: 2) + # + def column_exists?(table_name, column_name, type = nil, options = {}) + column_name = column_name.to_s + columns(table_name).any?{ |c| c.name == column_name && + (!type || c.type == type) && + (!options.key?(:limit) || c.limit == options[:limit]) && + (!options.key?(:precision) || c.precision == options[:precision]) && + (!options.key?(:scale) || c.scale == options[:scale]) && + (!options.key?(:default) || c.default == options[:default]) && + (!options.key?(:null) || c.null == options[:null]) } + end + + # Creates a new table with the name +table_name+. +table_name+ may either + # be a String or a Symbol. + # + # There are two ways to work with +create_table+. You can use the block + # form or the regular form, like this: + # + # === Block form + # + # # create_table() passes a TableDefinition object to the block. + # # This form will not only create the table, but also columns for the + # # table. + # + # create_table(:suppliers) do |t| + # t.column :name, :string, limit: 60 + # # Other fields here + # end + # + # === Block form, with shorthand + # + # # You can also use the column types as method calls, rather than calling the column method. + # create_table(:suppliers) do |t| + # t.string :name, limit: 60 + # # Other fields here + # end + # + # === Regular form + # + # # Creates a table called 'suppliers' with no columns. + # create_table(:suppliers) + # # Add a column to 'suppliers'. + # add_column(:suppliers, :name, :string, {limit: 60}) + # + # The +options+ hash can include the following keys: + # [:id] + # Whether to automatically add a primary key column. Defaults to true. + # Join tables for +has_and_belongs_to_many+ should set it to false. + # [:primary_key] + # The name of the primary key, if one is to be added automatically. + # Defaults to +id+. If :id is false this option is ignored. + # + # Note that Active Record models will automatically detect their + # primary key. This can be avoided by using +self.primary_key=+ on the model + # to define the key explicitly. + # + # [:options] + # Any extra options you want appended to the table definition. + # [:temporary] + # Make a temporary table. + # [:force] + # Set to true to drop the table before creating it. + # Set to +:cascade+ to drop dependent objects as well. + # Defaults to false. + # [:as] + # SQL to use to generate the table. When this option is used, the block is + # ignored, as are the :id and :primary_key options. + # + # ====== Add a backend specific option to the generated SQL (MySQL) + # + # create_table(:suppliers, options: 'ENGINE=InnoDB DEFAULT CHARSET=utf8') + # + # generates: + # + # CREATE TABLE suppliers ( + # id int(11) DEFAULT NULL auto_increment PRIMARY KEY + # ) ENGINE=InnoDB DEFAULT CHARSET=utf8 + # + # ====== Rename the primary key column + # + # create_table(:objects, primary_key: 'guid') do |t| + # t.column :name, :string, limit: 80 + # end + # + # generates: + # + # CREATE TABLE objects ( + # guid int(11) DEFAULT NULL auto_increment PRIMARY KEY, + # name varchar(80) + # ) + # + # ====== Do not add a primary key column + # + # create_table(:categories_suppliers, id: false) do |t| + # t.column :category_id, :integer + # t.column :supplier_id, :integer + # end + # + # generates: + # + # CREATE TABLE categories_suppliers ( + # category_id int, + # supplier_id int + # ) + # + # ====== Create a temporary table based on a query + # + # create_table(:long_query, temporary: true, + # as: "SELECT * FROM orders INNER JOIN line_items ON order_id=orders.id") + # + # generates: + # + # CREATE TEMPORARY TABLE long_query AS + # SELECT * FROM orders INNER JOIN line_items ON order_id=orders.id + # + # See also TableDefinition#column for details on how to create columns. + def create_table(table_name, options = {}) + td = create_table_definition table_name, options[:temporary], options[:options], options[:as] + + if options[:id] != false && !options[:as] + pk = options.fetch(:primary_key) do + Base.get_primary_key table_name.to_s.singularize + end + + td.primary_key pk, options.fetch(:id, :primary_key), options + end + + yield td if block_given? + + if options[:force] && table_exists?(table_name) + drop_table(table_name, options) + end + + result = execute schema_creation.accept td + + unless supports_indexes_in_create? + td.indexes.each_pair do |column_name, index_options| + add_index(table_name, column_name, index_options) + end + end + + td.foreign_keys.each do |other_table_name, foreign_key_options| + add_foreign_key(table_name, other_table_name, foreign_key_options) + end + + result + end + + # Creates a new join table with the name created using the lexical order of the first two + # arguments. These arguments can be a String or a Symbol. + # + # # Creates a table called 'assemblies_parts' with no id. + # create_join_table(:assemblies, :parts) + # + # You can pass a +options+ hash can include the following keys: + # [:table_name] + # Sets the table name overriding the default + # [:column_options] + # Any extra options you want appended to the columns definition. + # [:options] + # Any extra options you want appended to the table definition. + # [:temporary] + # Make a temporary table. + # [:force] + # Set to true to drop the table before creating it. + # Defaults to false. + # + # Note that +create_join_table+ does not create any indices by default; you can use + # its block form to do so yourself: + # + # create_join_table :products, :categories do |t| + # t.index :product_id + # t.index :category_id + # end + # + # ====== Add a backend specific option to the generated SQL (MySQL) + # + # create_join_table(:assemblies, :parts, options: 'ENGINE=InnoDB DEFAULT CHARSET=utf8') + # + # generates: + # + # CREATE TABLE assemblies_parts ( + # assembly_id int NOT NULL, + # part_id int NOT NULL, + # ) ENGINE=InnoDB DEFAULT CHARSET=utf8 + # + def create_join_table(table_1, table_2, options = {}) + join_table_name = find_join_table_name(table_1, table_2, options) + + column_options = options.delete(:column_options) || {} + column_options.reverse_merge!(null: false) + + t1_column, t2_column = [table_1, table_2].map{ |t| t.to_s.singularize.foreign_key } + + create_table(join_table_name, options.merge!(id: false)) do |td| + td.integer t1_column, column_options + td.integer t2_column, column_options + yield td if block_given? + end + end + + # Drops the join table specified by the given arguments. + # See +create_join_table+ for details. + # + # Although this command ignores the block if one is given, it can be helpful + # to provide one in a migration's +change+ method so it can be reverted. + # In that case, the block will be used by create_join_table. + def drop_join_table(table_1, table_2, options = {}) + join_table_name = find_join_table_name(table_1, table_2, options) + drop_table(join_table_name) + end + + # A block for changing columns in +table+. + # + # # change_table() yields a Table instance + # change_table(:suppliers) do |t| + # t.column :name, :string, limit: 60 + # # Other column alterations here + # end + # + # The +options+ hash can include the following keys: + # [:bulk] + # Set this to true to make this a bulk alter query, such as + # + # ALTER TABLE `users` ADD COLUMN age INT(11), ADD COLUMN birthdate DATETIME ... + # + # Defaults to false. + # + # ====== Add a column + # + # change_table(:suppliers) do |t| + # t.column :name, :string, limit: 60 + # end + # + # ====== Add 2 integer columns + # + # change_table(:suppliers) do |t| + # t.integer :width, :height, null: false, default: 0 + # end + # + # ====== Add created_at/updated_at columns + # + # change_table(:suppliers) do |t| + # t.timestamps + # end + # + # ====== Add a foreign key column + # + # change_table(:suppliers) do |t| + # t.references :company + # end + # + # Creates a company_id(integer) column. + # + # ====== Add a polymorphic foreign key column + # + # change_table(:suppliers) do |t| + # t.belongs_to :company, polymorphic: true + # end + # + # Creates company_type(varchar) and company_id(integer) columns. + # + # ====== Remove a column + # + # change_table(:suppliers) do |t| + # t.remove :company + # end + # + # ====== Remove several columns + # + # change_table(:suppliers) do |t| + # t.remove :company_id + # t.remove :width, :height + # end + # + # ====== Remove an index + # + # change_table(:suppliers) do |t| + # t.remove_index :company_id + # end + # + # See also Table for details on all of the various column transformation. + def change_table(table_name, options = {}) + if supports_bulk_alter? && options[:bulk] + recorder = ActiveRecord::Migration::CommandRecorder.new(self) + yield update_table_definition(table_name, recorder) + bulk_change_table(table_name, recorder.commands) + else + yield update_table_definition(table_name, self) + end + end + + # Renames a table. + # + # rename_table('octopuses', 'octopi') + # + def rename_table(table_name, new_name) + raise NotImplementedError, "rename_table is not implemented" + end + + # Drops a table from the database. + # + # [:force] + # Set to +:cascade+ to drop dependent objects as well. + # Defaults to false. + # + # Although this command ignores most +options+ and the block if one is given, + # it can be helpful to provide these in a migration's +change+ method so it can be reverted. + # In that case, +options+ and the block will be used by create_table. + def drop_table(table_name, options = {}) + execute "DROP TABLE #{quote_table_name(table_name)}" + end + + # Adds a new column to the named table. + # See TableDefinition#column for details of the options you can use. + def add_column(table_name, column_name, type, options = {}) + at = create_alter_table table_name + at.add_column(column_name, type, options) + execute schema_creation.accept at + end + + # Removes the given columns from the table definition. + # + # remove_columns(:suppliers, :qualification, :experience) + # + def remove_columns(table_name, *column_names) + raise ArgumentError.new("You must specify at least one column name. Example: remove_columns(:people, :first_name)") if column_names.empty? + column_names.each do |column_name| + remove_column(table_name, column_name) + end + end + + # Removes the column from the table definition. + # + # remove_column(:suppliers, :qualification) + # + # The +type+ and +options+ parameters will be ignored if present. It can be helpful + # to provide these in a migration's +change+ method so it can be reverted. + # In that case, +type+ and +options+ will be used by add_column. + def remove_column(table_name, column_name, type = nil, options = {}) + execute "ALTER TABLE #{quote_table_name(table_name)} DROP #{quote_column_name(column_name)}" + end + + # Changes the column's definition according to the new options. + # See TableDefinition#column for details of the options you can use. + # + # change_column(:suppliers, :name, :string, limit: 80) + # change_column(:accounts, :description, :text) + # + def change_column(table_name, column_name, type, options = {}) + raise NotImplementedError, "change_column is not implemented" + end + + # Sets a new default value for a column: + # + # change_column_default(:suppliers, :qualification, 'new') + # change_column_default(:accounts, :authorized, 1) + # + # Setting the default to +nil+ effectively drops the default: + # + # change_column_default(:users, :email, nil) + # + def change_column_default(table_name, column_name, default) + raise NotImplementedError, "change_column_default is not implemented" + end + + # Sets or removes a +NOT NULL+ constraint on a column. The +null+ flag + # indicates whether the value can be +NULL+. For example + # + # change_column_null(:users, :nickname, false) + # + # says nicknames cannot be +NULL+ (adds the constraint), whereas + # + # change_column_null(:users, :nickname, true) + # + # allows them to be +NULL+ (drops the constraint). + # + # The method accepts an optional fourth argument to replace existing + # +NULL+s with some other value. Use that one when enabling the + # constraint if needed, since otherwise those rows would not be valid. + # + # Please note the fourth argument does not set a column's default. + def change_column_null(table_name, column_name, null, default = nil) + raise NotImplementedError, "change_column_null is not implemented" + end + + # Renames a column. + # + # rename_column(:suppliers, :description, :name) + # + def rename_column(table_name, column_name, new_column_name) + raise NotImplementedError, "rename_column is not implemented" + end + + # Adds a new index to the table. +column_name+ can be a single Symbol, or + # an Array of Symbols. + # + # The index will be named after the table and the column name(s), unless + # you pass :name as an option. + # + # ====== Creating a simple index + # + # add_index(:suppliers, :name) + # + # generates: + # + # CREATE INDEX suppliers_name_index ON suppliers(name) + # + # ====== Creating a unique index + # + # add_index(:accounts, [:branch_id, :party_id], unique: true) + # + # generates: + # + # CREATE UNIQUE INDEX accounts_branch_id_party_id_index ON accounts(branch_id, party_id) + # + # ====== Creating a named index + # + # add_index(:accounts, [:branch_id, :party_id], unique: true, name: 'by_branch_party') + # + # generates: + # + # CREATE UNIQUE INDEX by_branch_party ON accounts(branch_id, party_id) + # + # ====== Creating an index with specific key length + # + # add_index(:accounts, :name, name: 'by_name', length: 10) + # + # generates: + # + # CREATE INDEX by_name ON accounts(name(10)) + # + # add_index(:accounts, [:name, :surname], name: 'by_name_surname', length: {name: 10, surname: 15}) + # + # generates: + # + # CREATE INDEX by_name_surname ON accounts(name(10), surname(15)) + # + # Note: SQLite doesn't support index length. + # + # ====== Creating an index with a sort order (desc or asc, asc is the default) + # + # add_index(:accounts, [:branch_id, :party_id, :surname], order: {branch_id: :desc, party_id: :asc}) + # + # generates: + # + # CREATE INDEX by_branch_desc_party ON accounts(branch_id DESC, party_id ASC, surname) + # + # Note: MySQL doesn't yet support index order (it accepts the syntax but ignores it). + # + # ====== Creating a partial index + # + # add_index(:accounts, [:branch_id, :party_id], unique: true, where: "active") + # + # generates: + # + # CREATE UNIQUE INDEX index_accounts_on_branch_id_and_party_id ON accounts(branch_id, party_id) WHERE active + # + # Note: Partial indexes are only supported for PostgreSQL and SQLite 3.8.0+. + # + # ====== Creating an index with a specific method + # + # add_index(:developers, :name, using: 'btree') + # + # generates: + # + # CREATE INDEX index_developers_on_name ON developers USING btree (name) -- PostgreSQL + # CREATE INDEX index_developers_on_name USING btree ON developers (name) -- MySQL + # + # Note: only supported by PostgreSQL and MySQL + # + # ====== Creating an index with a specific type + # + # add_index(:developers, :name, type: :fulltext) + # + # generates: + # + # CREATE FULLTEXT INDEX index_developers_on_name ON developers (name) -- MySQL + # + # Note: only supported by MySQL. Supported: :fulltext and :spatial on MyISAM tables. + def add_index(table_name, column_name, options = {}) + index_name, index_type, index_columns, index_options = add_index_options(table_name, column_name, options) + execute "CREATE #{index_type} INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)} (#{index_columns})#{index_options}" + end + + # Removes the given index from the table. + # + # Removes the +index_accounts_on_column+ in the +accounts+ table. + # + # remove_index :accounts, :column + # + # Removes the index named +index_accounts_on_branch_id+ in the +accounts+ table. + # + # remove_index :accounts, column: :branch_id + # + # Removes the index named +index_accounts_on_branch_id_and_party_id+ in the +accounts+ table. + # + # remove_index :accounts, column: [:branch_id, :party_id] + # + # Removes the index named +by_branch_party+ in the +accounts+ table. + # + # remove_index :accounts, name: :by_branch_party + # + def remove_index(table_name, options = {}) + remove_index!(table_name, index_name_for_remove(table_name, options)) + end + + def remove_index!(table_name, index_name) #:nodoc: + execute "DROP INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)}" + end + + # Renames an index. + # + # Rename the +index_people_on_last_name+ index to +index_users_on_last_name+: + # + # rename_index :people, 'index_people_on_last_name', 'index_users_on_last_name' + # + def rename_index(table_name, old_name, new_name) + validate_index_length!(table_name, new_name) + + # this is a naive implementation; some DBs may support this more efficiently (Postgres, for instance) + old_index_def = indexes(table_name).detect { |i| i.name == old_name } + return unless old_index_def + add_index(table_name, old_index_def.columns, name: new_name, unique: old_index_def.unique) + remove_index(table_name, name: old_name) + end + + def index_name(table_name, options) #:nodoc: + if Hash === options + if options[:column] + "index_#{table_name}_on_#{Array(options[:column]) * '_and_'}" + elsif options[:name] + options[:name] + else + raise ArgumentError, "You must specify the index name" + end + else + index_name(table_name, :column => options) + end + end + + # Verifies the existence of an index with a given name. + # + # The default argument is returned if the underlying implementation does not define the indexes method, + # as there's no way to determine the correct answer in that case. + def index_name_exists?(table_name, index_name, default) + return default unless respond_to?(:indexes) + index_name = index_name.to_s + indexes(table_name).detect { |i| i.name == index_name } + end + + # Adds a reference. The reference column is an integer by default, + # the :type option can be used to specify a different type. + # Optionally adds a +_type+ column, if :polymorphic option is provided. + # add_reference and add_belongs_to are acceptable. + # + # The +options+ hash can include the following keys: + # [:type] + # The reference column type. Defaults to +:integer+. + # [:index] + # Add an appropriate index. Defaults to false. + # [:foreign_key] + # Add an appropriate foreign key. Defaults to false. + # [:polymorphic] + # Wether an additional +_type+ column should be added. Defaults to false. + # + # ====== Create a user_id integer column + # + # add_reference(:products, :user) + # + # ====== Create a user_id string column + # + # add_reference(:products, :user, type: :string) + # + # ====== Create supplier_id, supplier_type columns and appropriate index + # + # add_reference(:products, :supplier, polymorphic: true, index: true) + # + def add_reference(table_name, ref_name, options = {}) + polymorphic = options.delete(:polymorphic) + index_options = options.delete(:index) + type = options.delete(:type) || :integer + foreign_key_options = options.delete(:foreign_key) + + if polymorphic && foreign_key_options + raise ArgumentError, "Cannot add a foreign key to a polymorphic relation" + end + + add_column(table_name, "#{ref_name}_id", type, options) + add_column(table_name, "#{ref_name}_type", :string, polymorphic.is_a?(Hash) ? polymorphic : options) if polymorphic + add_index(table_name, polymorphic ? %w[type id].map{ |t| "#{ref_name}_#{t}" } : "#{ref_name}_id", index_options.is_a?(Hash) ? index_options : {}) if index_options + if foreign_key_options + to_table = Base.pluralize_table_names ? ref_name.to_s.pluralize : ref_name + add_foreign_key(table_name, to_table, foreign_key_options.is_a?(Hash) ? foreign_key_options : {}) + end + end + alias :add_belongs_to :add_reference + + # Removes the reference(s). Also removes a +type+ column if one exists. + # remove_reference, remove_references and remove_belongs_to are acceptable. + # + # ====== Remove the reference + # + # remove_reference(:products, :user, index: true) + # + # ====== Remove polymorphic reference + # + # remove_reference(:products, :supplier, polymorphic: true) + # + # ====== Remove the reference with a foreign key + # + # remove_reference(:products, :user, index: true, foreign_key: true) + # + def remove_reference(table_name, ref_name, options = {}) + if options[:foreign_key] + to_table = Base.pluralize_table_names ? ref_name.to_s.pluralize : ref_name + remove_foreign_key(table_name, to_table) + end + + remove_column(table_name, "#{ref_name}_id") + remove_column(table_name, "#{ref_name}_type") if options[:polymorphic] + end + alias :remove_belongs_to :remove_reference + + # Returns an array of foreign keys for the given table. + # The foreign keys are represented as +ForeignKeyDefinition+ objects. + def foreign_keys(table_name) + raise NotImplementedError, "foreign_keys is not implemented" + end + + # Adds a new foreign key. +from_table+ is the table with the key column, + # +to_table+ contains the referenced primary key. + # + # The foreign key will be named after the following pattern: fk_rails_. + # +identifier+ is a 10 character long string which is deterministically generated from the + # +from_table+ and +column+. A custom name can be specified with the :name option. + # + # ====== Creating a simple foreign key + # + # add_foreign_key :articles, :authors + # + # generates: + # + # ALTER TABLE "articles" ADD CONSTRAINT articles_author_id_fk FOREIGN KEY ("author_id") REFERENCES "authors" ("id") + # + # ====== Creating a foreign key on a specific column + # + # add_foreign_key :articles, :users, column: :author_id, primary_key: :lng_id + # + # generates: + # + # ALTER TABLE "articles" ADD CONSTRAINT fk_rails_58ca3d3a82 FOREIGN KEY ("author_id") REFERENCES "users" ("lng_id") + # + # ====== Creating a cascading foreign key + # + # add_foreign_key :articles, :authors, on_delete: :cascade + # + # generates: + # + # ALTER TABLE "articles" ADD CONSTRAINT articles_author_id_fk FOREIGN KEY ("author_id") REFERENCES "authors" ("id") ON DELETE CASCADE + # + # The +options+ hash can include the following keys: + # [:column] + # The foreign key column name on +from_table+. Defaults to to_table.singularize + "_id" + # [:primary_key] + # The primary key column name on +to_table+. Defaults to +id+. + # [:name] + # The constraint name. Defaults to fk_rails_. + # [:on_delete] + # Action that happens ON DELETE. Valid values are +:nullify+, +:cascade:+ and +:restrict+ + # [:on_update] + # Action that happens ON UPDATE. Valid values are +:nullify+, +:cascade:+ and +:restrict+ + def add_foreign_key(from_table, to_table, options = {}) + return unless supports_foreign_keys? + + options[:column] ||= foreign_key_column_for(to_table) + + options = { + column: options[:column], + primary_key: options[:primary_key], + name: foreign_key_name(from_table, options), + on_delete: options[:on_delete], + on_update: options[:on_update] + } + at = create_alter_table from_table + at.add_foreign_key to_table, options + + execute schema_creation.accept(at) + end + + # Removes the given foreign key from the table. + # + # Removes the foreign key on +accounts.branch_id+. + # + # remove_foreign_key :accounts, :branches + # + # Removes the foreign key on +accounts.owner_id+. + # + # remove_foreign_key :accounts, column: :owner_id + # + # Removes the foreign key named +special_fk_name+ on the +accounts+ table. + # + # remove_foreign_key :accounts, name: :special_fk_name + # + def remove_foreign_key(from_table, options_or_to_table = {}) + return unless supports_foreign_keys? + + if options_or_to_table.is_a?(Hash) + options = options_or_to_table + else + options = { column: foreign_key_column_for(options_or_to_table) } + end + + fk_name_to_delete = options.fetch(:name) do + fk_to_delete = foreign_keys(from_table).detect {|fk| fk.column == options[:column].to_s } + + if fk_to_delete + fk_to_delete.name + else + raise ArgumentError, "Table '#{from_table}' has no foreign key on column '#{options[:column]}'" + end + end + + at = create_alter_table from_table + at.drop_foreign_key fk_name_to_delete + + execute schema_creation.accept(at) + end + + def foreign_key_column_for(table_name) # :nodoc: + prefix = Base.table_name_prefix + suffix = Base.table_name_suffix + name = table_name.to_s =~ /#{prefix}(.+)#{suffix}/ ? $1 : table_name.to_s + "#{name.singularize}_id" + end + + def dump_schema_information #:nodoc: + sm_table = ActiveRecord::Migrator.schema_migrations_table_name + + ActiveRecord::SchemaMigration.order('version').map { |sm| + "INSERT INTO #{sm_table} (version) VALUES ('#{sm.version}');" + }.join "\n\n" + end + + # Should not be called normally, but this operation is non-destructive. + # The migrations module handles this automatically. + def initialize_schema_migrations_table + ActiveRecord::SchemaMigration.create_table + end + + def assume_migrated_upto_version(version, migrations_paths = ActiveRecord::Migrator.migrations_paths) + migrations_paths = Array(migrations_paths) + version = version.to_i + sm_table = quote_table_name(ActiveRecord::Migrator.schema_migrations_table_name) + + migrated = select_values("SELECT version FROM #{sm_table}").map { |v| v.to_i } + paths = migrations_paths.map {|p| "#{p}/[0-9]*_*.rb" } + versions = Dir[*paths].map do |filename| + filename.split('/').last.split('_').first.to_i + end + + unless migrated.include?(version) + execute "INSERT INTO #{sm_table} (version) VALUES ('#{version}')" + end + + inserted = Set.new + (versions - migrated).each do |v| + if inserted.include?(v) + raise "Duplicate migration #{v}. Please renumber your migrations to resolve the conflict." + elsif v < version + execute "INSERT INTO #{sm_table} (version) VALUES ('#{v}')" + inserted << v + end + end + end + + def type_to_sql(type, limit = nil, precision = nil, scale = nil) #:nodoc: + if native = native_database_types[type.to_sym] + column_type_sql = (native.is_a?(Hash) ? native[:name] : native).dup + + if type == :decimal # ignore limit, use precision and scale + scale ||= native[:scale] + + if precision ||= native[:precision] + if scale + column_type_sql << "(#{precision},#{scale})" + else + column_type_sql << "(#{precision})" + end + elsif scale + raise ArgumentError, "Error adding decimal column: precision cannot be empty if scale is specified" + end + + elsif (type != :primary_key) && (limit ||= native.is_a?(Hash) && native[:limit]) + column_type_sql << "(#{limit})" + end + + column_type_sql + else + type.to_s + end + end + + # Given a set of columns and an ORDER BY clause, returns the columns for a SELECT DISTINCT. + # PostgreSQL, MySQL, and Oracle overrides this for custom DISTINCT syntax - they + # require the order columns appear in the SELECT. + # + # columns_for_distinct("posts.id", ["posts.created_at desc"]) + # + def columns_for_distinct(columns, orders) # :nodoc: + columns + end + + include TimestampDefaultDeprecation + # Adds timestamps (+created_at+ and +updated_at+) columns to +table_name+. + # Additional options (like null: false) are forwarded to #add_column. + # + # add_timestamps(:suppliers, null: false) + # + def add_timestamps(table_name, options = {}) + emit_warning_if_null_unspecified(:add_timestamps, options) + add_column table_name, :created_at, :datetime, options + add_column table_name, :updated_at, :datetime, options + end + + # Removes the timestamp columns (+created_at+ and +updated_at+) from the table definition. + # + # remove_timestamps(:suppliers) + # + def remove_timestamps(table_name, options = {}) + remove_column table_name, :updated_at + remove_column table_name, :created_at + end + + def update_table_definition(table_name, base) #:nodoc: + Table.new(table_name, base) + end + + def add_index_options(table_name, column_name, options = {}) #:nodoc: + column_names = Array(column_name) + index_name = index_name(table_name, column: column_names) + + options.assert_valid_keys(:unique, :order, :name, :where, :length, :internal, :using, :algorithm, :type) + + index_type = options[:unique] ? "UNIQUE" : "" + index_type = options[:type].to_s if options.key?(:type) + index_name = options[:name].to_s if options.key?(:name) + max_index_length = options.fetch(:internal, false) ? index_name_length : allowed_index_name_length + + if options.key?(:algorithm) + algorithm = index_algorithms.fetch(options[:algorithm]) { + raise ArgumentError.new("Algorithm must be one of the following: #{index_algorithms.keys.map(&:inspect).join(', ')}") + } + end + + using = "USING #{options[:using]}" if options[:using].present? + + if supports_partial_index? + index_options = options[:where] ? " WHERE #{options[:where]}" : "" + end + + if index_name.length > max_index_length + raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' is too long; the limit is #{max_index_length} characters" + end + if table_exists?(table_name) && index_name_exists?(table_name, index_name, false) + raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' already exists" + end + index_columns = quoted_columns_for_index(column_names, options).join(", ") + + [index_name, index_type, index_columns, index_options, algorithm, using] + end + + protected + def add_index_sort_order(option_strings, column_names, options = {}) + if options.is_a?(Hash) && order = options[:order] + case order + when Hash + column_names.each {|name| option_strings[name] += " #{order[name].upcase}" if order.has_key?(name)} + when String + column_names.each {|name| option_strings[name] += " #{order.upcase}"} + end + end + + return option_strings + end + + # Overridden by the MySQL adapter for supporting index lengths + def quoted_columns_for_index(column_names, options = {}) + option_strings = Hash[column_names.map {|name| [name, '']}] + + # add index sort order if supported + if supports_index_sort_order? + option_strings = add_index_sort_order(option_strings, column_names, options) + end + + column_names.map {|name| quote_column_name(name) + option_strings[name]} + end + + def options_include_default?(options) + options.include?(:default) && !(options[:null] == false && options[:default].nil?) + end + + def index_name_for_remove(table_name, options = {}) + index_name = index_name(table_name, options) + + unless index_name_exists?(table_name, index_name, true) + if options.is_a?(Hash) && options.has_key?(:name) + options_without_column = options.dup + options_without_column.delete :column + index_name_without_column = index_name(table_name, options_without_column) + + return index_name_without_column if index_name_exists?(table_name, index_name_without_column, false) + end + + raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' does not exist" + end + + index_name + end + + def rename_table_indexes(table_name, new_name) + indexes(new_name).each do |index| + generated_index_name = index_name(table_name, column: index.columns) + if generated_index_name == index.name + rename_index new_name, generated_index_name, index_name(new_name, column: index.columns) + end + end + end + + def rename_column_indexes(table_name, column_name, new_column_name) + column_name, new_column_name = column_name.to_s, new_column_name.to_s + indexes(table_name).each do |index| + next unless index.columns.include?(new_column_name) + old_columns = index.columns.dup + old_columns[old_columns.index(new_column_name)] = column_name + generated_index_name = index_name(table_name, column: old_columns) + if generated_index_name == index.name + rename_index table_name, generated_index_name, index_name(table_name, column: index.columns) + end + end + end + + private + def create_table_definition(name, temporary, options, as = nil) + TableDefinition.new native_database_types, name, temporary, options, as + end + + def create_alter_table(name) + AlterTable.new create_table_definition(name, false, {}) + end + + def foreign_key_name(table_name, options) # :nodoc: + identifier = "#{table_name}_#{options.fetch(:column)}_fk" + hashed_identifier = Digest::SHA256.hexdigest(identifier).first(10) + options.fetch(:name) do + "fk_rails_#{hashed_identifier}" + end + end + + def validate_index_length!(table_name, new_name) + if new_name.length > allowed_index_name_length + raise ArgumentError, "Index name '#{new_name}' on table '#{table_name}' is too long; the limit is #{allowed_index_name_length} characters" + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/abstract/transaction.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/abstract/transaction.rb new file mode 100644 index 0000000..2b0496e --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/abstract/transaction.rb @@ -0,0 +1,215 @@ +module ActiveRecord + module ConnectionAdapters + class TransactionState + attr_reader :parent + + VALID_STATES = Set.new([:committed, :rolledback, nil]) + + def initialize(state = nil) + @state = state + @parent = nil + end + + def finalized? + @state + end + + def committed? + @state == :committed + end + + def rolledback? + @state == :rolledback + end + + def completed? + committed? || rolledback? + end + + def set_state(state) + if !VALID_STATES.include?(state) + raise ArgumentError, "Invalid transaction state: #{state}" + end + @state = state + end + end + + class NullTransaction #:nodoc: + def initialize; end + def closed?; true; end + def open?; false; end + def joinable?; false; end + def add_record(record); end + end + + class Transaction #:nodoc: + + attr_reader :connection, :state, :records, :savepoint_name + attr_writer :joinable + + def initialize(connection, options) + @connection = connection + @state = TransactionState.new + @records = [] + @joinable = options.fetch(:joinable, true) + end + + def add_record(record) + records << record + end + + def rollback + @state.set_state(:rolledback) + end + + def rollback_records + ite = records.uniq + while record = ite.shift + begin + record.rolledback! full_rollback? + rescue => e + raise if ActiveRecord::Base.raise_in_transactional_callbacks + record.logger.error(e) if record.respond_to?(:logger) && record.logger + end + end + ensure + ite.each do |i| + i.rolledback!(full_rollback?, false) + end + end + + def commit + @state.set_state(:committed) + end + + def commit_records + ite = records.uniq + while record = ite.shift + begin + record.committed! + rescue => e + raise if ActiveRecord::Base.raise_in_transactional_callbacks + record.logger.error(e) if record.respond_to?(:logger) && record.logger + end + end + ensure + ite.each do |i| + i.committed!(false) + end + end + + def full_rollback?; true; end + def joinable?; @joinable; end + def closed?; false; end + def open?; !closed?; end + end + + class SavepointTransaction < Transaction + + def initialize(connection, savepoint_name, options) + super(connection, options) + if options[:isolation] + raise ActiveRecord::TransactionIsolationError, "cannot set transaction isolation in a nested transaction" + end + connection.create_savepoint(@savepoint_name = savepoint_name) + end + + def rollback + connection.rollback_to_savepoint(savepoint_name) + super + rollback_records + end + + def commit + connection.release_savepoint(savepoint_name) + super + parent = connection.transaction_manager.current_transaction + records.each { |r| parent.add_record(r) } + end + + def full_rollback?; false; end + end + + class RealTransaction < Transaction + + def initialize(connection, options) + super + if options[:isolation] + connection.begin_isolated_db_transaction(options[:isolation]) + else + connection.begin_db_transaction + end + end + + def rollback + connection.rollback_db_transaction + super + rollback_records + end + + def commit + connection.commit_db_transaction + super + commit_records + end + end + + class TransactionManager #:nodoc: + def initialize(connection) + @stack = [] + @connection = connection + end + + def begin_transaction(options = {}) + transaction = + if @stack.empty? + RealTransaction.new(@connection, options) + else + SavepointTransaction.new(@connection, "active_record_#{@stack.size}", options) + end + @stack.push(transaction) + transaction + end + + def commit_transaction + @stack.pop.commit + end + + def rollback_transaction + @stack.pop.rollback + end + + def within_new_transaction(options = {}) + transaction = begin_transaction options + yield + rescue Exception => error + rollback_transaction if transaction + raise + ensure + unless error + if Thread.current.status == 'aborting' + rollback_transaction if transaction + else + begin + commit_transaction + rescue Exception + transaction.rollback unless transaction.state.completed? + raise + end + end + end + end + + def open_transactions + @stack.size + end + + def current_transaction + @stack.last || NULL_TRANSACTION + end + + private + NULL_TRANSACTION = NullTransaction.new + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/abstract_adapter.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/abstract_adapter.rb new file mode 100644 index 0000000..91b2118 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/abstract_adapter.rb @@ -0,0 +1,493 @@ +require 'date' +require 'bigdecimal' +require 'bigdecimal/util' +require 'active_record/type' +require 'active_support/core_ext/benchmark' +require 'active_record/connection_adapters/schema_cache' +require 'active_record/connection_adapters/abstract/schema_dumper' +require 'active_record/connection_adapters/abstract/schema_creation' +require 'monitor' +require 'arel/collectors/bind' +require 'arel/collectors/sql_string' + +module ActiveRecord + module ConnectionAdapters # :nodoc: + extend ActiveSupport::Autoload + + autoload :Column + autoload :ConnectionSpecification + + autoload_at 'active_record/connection_adapters/abstract/schema_definitions' do + autoload :IndexDefinition + autoload :ColumnDefinition + autoload :ChangeColumnDefinition + autoload :TableDefinition + autoload :Table + autoload :AlterTable + autoload :TimestampDefaultDeprecation + end + + autoload_at 'active_record/connection_adapters/abstract/connection_pool' do + autoload :ConnectionHandler + autoload :ConnectionManagement + end + + autoload_under 'abstract' do + autoload :SchemaStatements + autoload :DatabaseStatements + autoload :DatabaseLimits + autoload :Quoting + autoload :ConnectionPool + autoload :QueryCache + autoload :Savepoints + end + + autoload_at 'active_record/connection_adapters/abstract/transaction' do + autoload :TransactionManager + autoload :NullTransaction + autoload :RealTransaction + autoload :SavepointTransaction + autoload :TransactionState + end + + # Active Record supports multiple database systems. AbstractAdapter and + # related classes form the abstraction layer which makes this possible. + # An AbstractAdapter represents a connection to a database, and provides an + # abstract interface for database-specific functionality such as establishing + # a connection, escaping values, building the right SQL fragments for ':offset' + # and ':limit' options, etc. + # + # All the concrete database adapters follow the interface laid down in this class. + # ActiveRecord::Base.connection returns an AbstractAdapter object, which + # you can use. + # + # Most of the methods in the adapter are useful during migrations. Most + # notably, the instance methods provided by SchemaStatement are very useful. + class AbstractAdapter + ADAPTER_NAME = 'Abstract'.freeze + include Quoting, DatabaseStatements, SchemaStatements + include DatabaseLimits + include QueryCache + include ActiveSupport::Callbacks + include MonitorMixin + include ColumnDumper + + SIMPLE_INT = /\A\d+\z/ + + define_callbacks :checkout, :checkin + + attr_accessor :visitor, :pool + attr_reader :schema_cache, :owner, :logger + alias :in_use? :owner + + def self.type_cast_config_to_integer(config) + if config =~ SIMPLE_INT + config.to_i + else + config + end + end + + def self.type_cast_config_to_boolean(config) + if config == "false" + false + else + config + end + end + + attr_reader :prepared_statements + + def initialize(connection, logger = nil, pool = nil) #:nodoc: + super() + + @connection = connection + @owner = nil + @instrumenter = ActiveSupport::Notifications.instrumenter + @logger = logger + @pool = pool + @schema_cache = SchemaCache.new self + @visitor = nil + @prepared_statements = false + end + + class BindCollector < Arel::Collectors::Bind + def compile(bvs, conn) + super(bvs.map { |bv| conn.quote(*bv.reverse) }) + end + end + + class SQLString < Arel::Collectors::SQLString + def compile(bvs, conn) + super(bvs) + end + end + + def collector + if prepared_statements + SQLString.new + else + BindCollector.new + end + end + + def valid_type?(type) + true + end + + def schema_creation + SchemaCreation.new self + end + + def lease + synchronize do + unless in_use? + @owner = Thread.current + end + end + end + + def schema_cache=(cache) + cache.connection = self + @schema_cache = cache + end + + def expire + @owner = nil + end + + def unprepared_statement + old_prepared_statements, @prepared_statements = @prepared_statements, false + yield + ensure + @prepared_statements = old_prepared_statements + end + + # Returns the human-readable name of the adapter. Use mixed case - one + # can always use downcase if needed. + def adapter_name + self.class::ADAPTER_NAME + end + + # Does this adapter support migrations? + def supports_migrations? + false + end + + # Can this adapter determine the primary key for tables not attached + # to an Active Record class, such as join tables? + def supports_primary_key? + false + end + + # Does this adapter support DDL rollbacks in transactions? That is, would + # CREATE TABLE or ALTER TABLE get rolled back by a transaction? + def supports_ddl_transactions? + false + end + + def supports_bulk_alter? + false + end + + # Does this adapter support savepoints? + def supports_savepoints? + false + end + + # Should primary key values be selected from their corresponding + # sequence before the insert statement? If true, next_sequence_value + # is called before each insert to set the record's primary key. + def prefetch_primary_key?(table_name = nil) + false + end + + # Does this adapter support index sort order? + def supports_index_sort_order? + false + end + + # Does this adapter support partial indices? + def supports_partial_index? + false + end + + # Does this adapter support explain? + def supports_explain? + false + end + + # Does this adapter support setting the isolation level for a transaction? + def supports_transaction_isolation? + false + end + + # Does this adapter support database extensions? + def supports_extensions? + false + end + + # Does this adapter support creating indexes in the same statement as + # creating the table? + def supports_indexes_in_create? + false + end + + # Does this adapter support creating foreign key constraints? + def supports_foreign_keys? + false + end + + # Does this adapter support views? + def supports_views? + false + end + + # This is meant to be implemented by the adapters that support extensions + def disable_extension(name) + end + + # This is meant to be implemented by the adapters that support extensions + def enable_extension(name) + end + + # A list of extensions, to be filled in by adapters that support them. + def extensions + [] + end + + # A list of index algorithms, to be filled by adapters that support them. + def index_algorithms + {} + end + + # QUOTING ================================================== + + # Returns a bind substitution value given a bind +column+ + # NOTE: The column param is currently being used by the sqlserver-adapter + def substitute_at(column, _unused = 0) + Arel::Nodes::BindParam.new + end + + # REFERENTIAL INTEGRITY ==================================== + + # Override to turn off referential integrity while executing &block. + def disable_referential_integrity + yield + end + + # CONNECTION MANAGEMENT ==================================== + + # Checks whether the connection to the database is still active. This includes + # checking whether the database is actually capable of responding, i.e. whether + # the connection isn't stale. + def active? + end + + # Disconnects from the database if already connected, and establishes a + # new connection with the database. Implementors should call super if they + # override the default implementation. + def reconnect! + clear_cache! + reset_transaction + end + + # Disconnects from the database if already connected. Otherwise, this + # method does nothing. + def disconnect! + clear_cache! + reset_transaction + end + + # Reset the state of this connection, directing the DBMS to clear + # transactions and other connection-related server-side state. Usually a + # database-dependent operation. + # + # The default implementation does nothing; the implementation should be + # overridden by concrete adapters. + def reset! + # this should be overridden by concrete adapters + end + + ### + # Clear any caching the database adapter may be doing, for example + # clearing the prepared statement cache. This is database specific. + def clear_cache! + # this should be overridden by concrete adapters + end + + # Returns true if its required to reload the connection between requests for development mode. + def requires_reloading? + false + end + + # Checks whether the connection to the database is still active (i.e. not stale). + # This is done under the hood by calling active?. If the connection + # is no longer active, then this method will reconnect to the database. + def verify!(*ignored) + reconnect! unless active? + end + + # Provides access to the underlying database driver for this adapter. For + # example, this method returns a Mysql object in case of MysqlAdapter, + # and a PGconn object in case of PostgreSQLAdapter. + # + # This is useful for when you need to call a proprietary method such as + # PostgreSQL's lo_* methods. + def raw_connection + @connection + end + + def create_savepoint(name = nil) + end + + def release_savepoint(name = nil) + end + + def case_sensitive_modifier(node, table_attribute) + node + end + + def case_sensitive_comparison(table, attribute, column, value) + table_attr = table[attribute] + value = case_sensitive_modifier(value, table_attr) unless value.nil? + table_attr.eq(value) + end + + def case_insensitive_comparison(table, attribute, column, value) + table[attribute].lower.eq(table.lower(value)) + end + + def current_savepoint_name + current_transaction.savepoint_name + end + + # Check the connection back in to the connection pool + def close + pool.checkin self + end + + def type_map # :nodoc: + @type_map ||= Type::TypeMap.new.tap do |mapping| + initialize_type_map(mapping) + end + end + + def new_column(name, default, cast_type, sql_type = nil, null = true) + Column.new(name, default, cast_type, sql_type, null) + end + + def lookup_cast_type(sql_type) # :nodoc: + type_map.lookup(sql_type) + end + + def column_name_for_operation(operation, node) # :nodoc: + visitor.accept(node, collector).value + end + + protected + + def initialize_type_map(m) # :nodoc: + register_class_with_limit m, %r(boolean)i, Type::Boolean + register_class_with_limit m, %r(char)i, Type::String + register_class_with_limit m, %r(binary)i, Type::Binary + register_class_with_limit m, %r(text)i, Type::Text + register_class_with_limit m, %r(date)i, Type::Date + register_class_with_limit m, %r(time)i, Type::Time + register_class_with_limit m, %r(datetime)i, Type::DateTime + register_class_with_limit m, %r(float)i, Type::Float + register_class_with_limit m, %r(int)i, Type::Integer + + m.alias_type %r(blob)i, 'binary' + m.alias_type %r(clob)i, 'text' + m.alias_type %r(timestamp)i, 'datetime' + m.alias_type %r(numeric)i, 'decimal' + m.alias_type %r(number)i, 'decimal' + m.alias_type %r(double)i, 'float' + + m.register_type(%r(decimal)i) do |sql_type| + scale = extract_scale(sql_type) + precision = extract_precision(sql_type) + + if scale == 0 + # FIXME: Remove this class as well + Type::DecimalWithoutScale.new(precision: precision) + else + Type::Decimal.new(precision: precision, scale: scale) + end + end + end + + def reload_type_map # :nodoc: + type_map.clear + initialize_type_map(type_map) + end + + def register_class_with_limit(mapping, key, klass) # :nodoc: + mapping.register_type(key) do |*args| + limit = extract_limit(args.last) + klass.new(limit: limit) + end + end + + def extract_scale(sql_type) # :nodoc: + case sql_type + when /\((\d+)\)/ then 0 + when /\((\d+)(,(\d+))\)/ then $3.to_i + end + end + + def extract_precision(sql_type) # :nodoc: + $1.to_i if sql_type =~ /\((\d+)(,\d+)?\)/ + end + + def extract_limit(sql_type) # :nodoc: + case sql_type + when /^bigint/i + 8 + when /\((.*)\)/ + $1.to_i + end + end + + def translate_exception_class(e, sql) + begin + message = "#{e.class.name}: #{e.message}: #{sql}" + rescue Encoding::CompatibilityError + message = "#{e.class.name}: #{e.message.force_encoding sql.encoding}: #{sql}" + end + + exception = translate_exception(e, message) + exception.set_backtrace e.backtrace + exception + end + + def log(sql, name = "SQL", binds = [], statement_name = nil) + @instrumenter.instrument( + "sql.active_record", + :sql => sql, + :name => name, + :connection_id => object_id, + :statement_name => statement_name, + :binds => binds) { yield } + rescue => e + raise translate_exception_class(e, sql) + end + + def translate_exception(exception, message) + # override in derived class + ActiveRecord::StatementInvalid.new(message, exception) + end + + def without_prepared_statement?(binds) + !prepared_statements || binds.empty? + end + + def column_for(table_name, column_name) # :nodoc: + column_name = column_name.to_s + columns(table_name).detect { |c| c.name == column_name } || + raise(ActiveRecordError, "No such column: #{table_name}.#{column_name}") + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/abstract_mysql_adapter.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/abstract_mysql_adapter.rb new file mode 100644 index 0000000..497bc63 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/abstract_mysql_adapter.rb @@ -0,0 +1,934 @@ +require 'arel/visitors/bind_visitor' +require 'active_support/core_ext/string/strip' + +module ActiveRecord + module ConnectionAdapters + class AbstractMysqlAdapter < AbstractAdapter + include Savepoints + + class SchemaCreation < AbstractAdapter::SchemaCreation + def visit_AddColumn(o) + add_column_position!(super, column_options(o)) + end + + private + + def visit_DropForeignKey(name) + "DROP FOREIGN KEY #{name}" + end + + def visit_TableDefinition(o) + name = o.name + create_sql = "CREATE#{' TEMPORARY' if o.temporary} TABLE #{quote_table_name(name)} " + + statements = o.columns.map { |c| accept c } + statements.concat(o.indexes.map { |column_name, options| index_in_create(name, column_name, options) }) + + create_sql << "(#{statements.join(', ')}) " if statements.present? + create_sql << "#{o.options}" + create_sql << " AS #{@conn.to_sql(o.as)}" if o.as + create_sql + end + + def visit_ChangeColumnDefinition(o) + column = o.column + options = o.options + sql_type = type_to_sql(o.type, options[:limit], options[:precision], options[:scale]) + change_column_sql = "CHANGE #{quote_column_name(column.name)} #{quote_column_name(options[:name])} #{sql_type}" + add_column_options!(change_column_sql, options.merge(column: column)) + add_column_position!(change_column_sql, options) + end + + def add_column_position!(sql, options) + if options[:first] + sql << " FIRST" + elsif options[:after] + sql << " AFTER #{quote_column_name(options[:after])}" + end + sql + end + + def index_in_create(table_name, column_name, options) + index_name, index_type, index_columns, index_options, index_algorithm, index_using = @conn.add_index_options(table_name, column_name, options) + "#{index_type} INDEX #{quote_column_name(index_name)} #{index_using} (#{index_columns})#{index_options} #{index_algorithm}" + end + end + + def schema_creation + SchemaCreation.new self + end + + def prepare_column_options(column, types) # :nodoc: + spec = super + spec.delete(:limit) if :boolean === column.type + spec + end + + class Column < ConnectionAdapters::Column # :nodoc: + attr_reader :collation, :strict, :extra + + def initialize(name, default, cast_type, sql_type = nil, null = true, collation = nil, strict = false, extra = "") + @strict = strict + @collation = collation + @extra = extra + super(name, default, cast_type, sql_type, null) + assert_valid_default(default) + extract_default + end + + def extract_default + if blob_or_text_column? + @default = null || strict ? nil : '' + elsif missing_default_forged_as_empty_string?(@default) + @default = nil + end + end + + def has_default? + return false if blob_or_text_column? # MySQL forbids defaults on blob and text columns + super + end + + def blob_or_text_column? + sql_type =~ /blob/i || type == :text + end + + def case_sensitive? + collation && !collation.match(/_ci$/) + end + + def ==(other) + super && + collation == other.collation && + strict == other.strict && + extra == other.extra + end + + private + + # MySQL misreports NOT NULL column default when none is given. + # We can't detect this for columns which may have a legitimate '' + # default (string) but we can for others (integer, datetime, boolean, + # and the rest). + # + # Test whether the column has default '', is not null, and is not + # a type allowing default ''. + def missing_default_forged_as_empty_string?(default) + type != :string && !null && default == '' + end + + def assert_valid_default(default) + if blob_or_text_column? && default.present? + raise ArgumentError, "#{type} columns cannot have a default value: #{default.inspect}" + end + end + + def attributes_for_hash + super + [collation, strict, extra] + end + end + + ## + # :singleton-method: + # By default, the MysqlAdapter will consider all columns of type tinyint(1) + # as boolean. If you wish to disable this emulation (which was the default + # behavior in versions 0.13.1 and earlier) you can add the following line + # to your application.rb file: + # + # ActiveRecord::ConnectionAdapters::Mysql[2]Adapter.emulate_booleans = false + class_attribute :emulate_booleans + self.emulate_booleans = true + + LOST_CONNECTION_ERROR_MESSAGES = [ + "Server shutdown in progress", + "Broken pipe", + "Lost connection to MySQL server during query", + "MySQL server has gone away" ] + + QUOTED_TRUE, QUOTED_FALSE = '1', '0' + + NATIVE_DATABASE_TYPES = { + :primary_key => "int(11) auto_increment PRIMARY KEY", + :string => { :name => "varchar", :limit => 255 }, + :text => { :name => "text" }, + :integer => { :name => "int", :limit => 4 }, + :float => { :name => "float" }, + :decimal => { :name => "decimal" }, + :datetime => { :name => "datetime" }, + :time => { :name => "time" }, + :date => { :name => "date" }, + :binary => { :name => "blob" }, + :boolean => { :name => "tinyint", :limit => 1 } + } + + INDEX_TYPES = [:fulltext, :spatial] + INDEX_USINGS = [:btree, :hash] + + # FIXME: Make the first parameter more similar for the two adapters + def initialize(connection, logger, connection_options, config) + super(connection, logger) + @connection_options, @config = connection_options, config + @quoted_column_names, @quoted_table_names = {}, {} + + @visitor = Arel::Visitors::MySQL.new self + + if self.class.type_cast_config_to_boolean(config.fetch(:prepared_statements) { true }) + @prepared_statements = true + else + @prepared_statements = false + end + end + + # Returns true, since this connection adapter supports migrations. + def supports_migrations? + true + end + + def supports_primary_key? + true + end + + def supports_bulk_alter? #:nodoc: + true + end + + # Technically MySQL allows to create indexes with the sort order syntax + # but at the moment (5.5) it doesn't yet implement them + def supports_index_sort_order? + true + end + + # MySQL 4 technically support transaction isolation, but it is affected by a bug + # where the transaction level gets persisted for the whole session: + # + # http://bugs.mysql.com/bug.php?id=39170 + def supports_transaction_isolation? + version[0] >= 5 + end + + def supports_indexes_in_create? + true + end + + def supports_foreign_keys? + true + end + + def supports_views? + version[0] >= 5 + end + + def native_database_types + NATIVE_DATABASE_TYPES + end + + def index_algorithms + { default: 'ALGORITHM = DEFAULT', copy: 'ALGORITHM = COPY', inplace: 'ALGORITHM = INPLACE' } + end + + # HELPER METHODS =========================================== + + # The two drivers have slightly different ways of yielding hashes of results, so + # this method must be implemented to provide a uniform interface. + def each_hash(result) # :nodoc: + raise NotImplementedError + end + + def new_column(field, default, cast_type, sql_type = nil, null = true, collation = "", extra = "") # :nodoc: + Column.new(field, default, cast_type, sql_type, null, collation, strict_mode?, extra) + end + + # Must return the MySQL error number from the exception, if the exception has an + # error number. + def error_number(exception) # :nodoc: + raise NotImplementedError + end + + # QUOTING ================================================== + + def _quote(value) # :nodoc: + if value.is_a?(Type::Binary::Data) + "x'#{value.hex}'" + else + super + end + end + + def quote_column_name(name) #:nodoc: + @quoted_column_names[name] ||= "`#{name.to_s.gsub('`', '``')}`" + end + + def quote_table_name(name) #:nodoc: + @quoted_table_names[name] ||= quote_column_name(name).gsub('.', '`.`') + end + + def quoted_true + QUOTED_TRUE + end + + def unquoted_true + 1 + end + + def quoted_false + QUOTED_FALSE + end + + def unquoted_false + 0 + end + + # REFERENTIAL INTEGRITY ==================================== + + def disable_referential_integrity #:nodoc: + old = select_value("SELECT @@FOREIGN_KEY_CHECKS") + + begin + update("SET FOREIGN_KEY_CHECKS = 0") + yield + ensure + update("SET FOREIGN_KEY_CHECKS = #{old}") + end + end + + #-- + # DATABASE STATEMENTS ====================================== + #++ + + def clear_cache! + super + reload_type_map + end + + # Executes the SQL statement in the context of this connection. + def execute(sql, name = nil) + log(sql, name) { @connection.query(sql) } + end + + # MysqlAdapter has to free a result after using it, so we use this method to write + # stuff in an abstract way without concerning ourselves about whether it needs to be + # explicitly freed or not. + def execute_and_free(sql, name = nil) #:nodoc: + yield execute(sql, name) + end + + def update_sql(sql, name = nil) #:nodoc: + super + @connection.affected_rows + end + + def begin_db_transaction + execute "BEGIN" + end + + def begin_isolated_db_transaction(isolation) + execute "SET TRANSACTION ISOLATION LEVEL #{transaction_isolation_levels.fetch(isolation)}" + begin_db_transaction + end + + def commit_db_transaction #:nodoc: + execute "COMMIT" + end + + def exec_rollback_db_transaction #:nodoc: + execute "ROLLBACK" + end + + # In the simple case, MySQL allows us to place JOINs directly into the UPDATE + # query. However, this does not allow for LIMIT, OFFSET and ORDER. To support + # these, we must use a subquery. + def join_to_update(update, select) #:nodoc: + if select.limit || select.offset || select.orders.any? + super + else + update.table select.source + update.wheres = select.constraints + end + end + + def empty_insert_statement_value + "VALUES ()" + end + + # SCHEMA STATEMENTS ======================================== + + # Drops the database specified on the +name+ attribute + # and creates it again using the provided +options+. + def recreate_database(name, options = {}) + drop_database(name) + sql = create_database(name, options) + reconnect! + sql + end + + # Create a new MySQL database with optional :charset and :collation. + # Charset defaults to utf8. + # + # Example: + # create_database 'charset_test', charset: 'latin1', collation: 'latin1_bin' + # create_database 'matt_development' + # create_database 'matt_development', charset: :big5 + def create_database(name, options = {}) + if options[:collation] + execute "CREATE DATABASE `#{name}` DEFAULT CHARACTER SET `#{options[:charset] || 'utf8'}` COLLATE `#{options[:collation]}`" + else + execute "CREATE DATABASE `#{name}` DEFAULT CHARACTER SET `#{options[:charset] || 'utf8'}`" + end + end + + # Drops a MySQL database. + # + # Example: + # drop_database('sebastian_development') + def drop_database(name) #:nodoc: + execute "DROP DATABASE IF EXISTS `#{name}`" + end + + def current_database + select_value 'SELECT DATABASE() as db' + end + + # Returns the database character set. + def charset + show_variable 'character_set_database' + end + + # Returns the database collation strategy. + def collation + show_variable 'collation_database' + end + + def tables(name = nil, database = nil, like = nil) #:nodoc: + sql = "SHOW TABLES " + sql << "IN #{quote_table_name(database)} " if database + sql << "LIKE #{quote(like)}" if like + + execute_and_free(sql, 'SCHEMA') do |result| + result.collect { |field| field.first } + end + end + alias data_sources tables + + def truncate(table_name, name = nil) + execute "TRUNCATE TABLE #{quote_table_name(table_name)}", name + end + + def table_exists?(name) + return false unless name.present? + return true if tables(nil, nil, name).any? + + name = name.to_s + schema, table = name.split('.', 2) + + unless table # A table was provided without a schema + table = schema + schema = nil + end + + tables(nil, schema, table).any? + end + alias data_source_exists? table_exists? + + # Returns an array of indexes for the given table. + def indexes(table_name, name = nil) #:nodoc: + indexes = [] + current_index = nil + execute_and_free("SHOW KEYS FROM #{quote_table_name(table_name)}", 'SCHEMA') do |result| + each_hash(result) do |row| + if current_index != row[:Key_name] + next if row[:Key_name] == 'PRIMARY' # skip the primary key + current_index = row[:Key_name] + + mysql_index_type = row[:Index_type].downcase.to_sym + index_type = INDEX_TYPES.include?(mysql_index_type) ? mysql_index_type : nil + index_using = INDEX_USINGS.include?(mysql_index_type) ? mysql_index_type : nil + indexes << IndexDefinition.new(row[:Table], row[:Key_name], row[:Non_unique].to_i == 0, [], [], nil, nil, index_type, index_using) + end + + indexes.last.columns << row[:Column_name] + indexes.last.lengths << row[:Sub_part] + end + end + + indexes + end + + # Returns an array of +Column+ objects for the table specified by +table_name+. + def columns(table_name)#:nodoc: + sql = "SHOW FULL FIELDS FROM #{quote_table_name(table_name)}" + execute_and_free(sql, 'SCHEMA') do |result| + each_hash(result).map do |field| + field_name = set_field_encoding(field[:Field]) + sql_type = field[:Type] + cast_type = lookup_cast_type(sql_type) + new_column(field_name, field[:Default], cast_type, sql_type, field[:Null] == "YES", field[:Collation], field[:Extra]) + end + end + end + + def create_table(table_name, options = {}) #:nodoc: + super(table_name, options.reverse_merge(:options => "ENGINE=InnoDB")) + end + + def bulk_change_table(table_name, operations) #:nodoc: + sqls = operations.flat_map do |command, args| + table, arguments = args.shift, args + method = :"#{command}_sql" + + if respond_to?(method, true) + send(method, table, *arguments) + else + raise "Unknown method called : #{method}(#{arguments.inspect})" + end + end.join(", ") + + execute("ALTER TABLE #{quote_table_name(table_name)} #{sqls}") + end + + # Renames a table. + # + # Example: + # rename_table('octopuses', 'octopi') + def rename_table(table_name, new_name) + execute "RENAME TABLE #{quote_table_name(table_name)} TO #{quote_table_name(new_name)}" + rename_table_indexes(table_name, new_name) + end + + def drop_table(table_name, options = {}) + execute "DROP#{' TEMPORARY' if options[:temporary]} TABLE #{quote_table_name(table_name)}#{' CASCADE' if options[:force] == :cascade}" + end + + def rename_index(table_name, old_name, new_name) + if supports_rename_index? + validate_index_length!(table_name, new_name) + + execute "ALTER TABLE #{quote_table_name(table_name)} RENAME INDEX #{quote_table_name(old_name)} TO #{quote_table_name(new_name)}" + else + super + end + end + + def change_column_default(table_name, column_name, default) #:nodoc: + column = column_for(table_name, column_name) + change_column table_name, column_name, column.sql_type, :default => default + end + + def change_column_null(table_name, column_name, null, default = nil) + column = column_for(table_name, column_name) + + unless null || default.nil? + execute("UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote(default)} WHERE #{quote_column_name(column_name)} IS NULL") + end + + change_column table_name, column_name, column.sql_type, :null => null + end + + def change_column(table_name, column_name, type, options = {}) #:nodoc: + execute("ALTER TABLE #{quote_table_name(table_name)} #{change_column_sql(table_name, column_name, type, options)}") + end + + def rename_column(table_name, column_name, new_column_name) #:nodoc: + execute("ALTER TABLE #{quote_table_name(table_name)} #{rename_column_sql(table_name, column_name, new_column_name)}") + rename_column_indexes(table_name, column_name, new_column_name) + end + + def add_index(table_name, column_name, options = {}) #:nodoc: + index_name, index_type, index_columns, index_options, index_algorithm, index_using = add_index_options(table_name, column_name, options) + execute "CREATE #{index_type} INDEX #{quote_column_name(index_name)} #{index_using} ON #{quote_table_name(table_name)} (#{index_columns})#{index_options} #{index_algorithm}" + end + + def foreign_keys(table_name) + fk_info = select_all <<-SQL.strip_heredoc + SELECT fk.referenced_table_name as 'to_table' + ,fk.referenced_column_name as 'primary_key' + ,fk.column_name as 'column' + ,fk.constraint_name as 'name' + FROM information_schema.key_column_usage fk + WHERE fk.referenced_column_name is not null + AND fk.table_schema = '#{@config[:database]}' + AND fk.table_name = '#{table_name}' + SQL + + create_table_info = select_one("SHOW CREATE TABLE #{quote_table_name(table_name)}")["Create Table"] + + fk_info.map do |row| + options = { + column: row['column'], + name: row['name'], + primary_key: row['primary_key'] + } + + options[:on_update] = extract_foreign_key_action(create_table_info, row['name'], "UPDATE") + options[:on_delete] = extract_foreign_key_action(create_table_info, row['name'], "DELETE") + + ForeignKeyDefinition.new(table_name, row['to_table'], options) + end + end + + # Maps logical Rails types to MySQL-specific data types. + def type_to_sql(type, limit = nil, precision = nil, scale = nil) + case type.to_s + when 'binary' + case limit + when 0..0xfff; "varbinary(#{limit})" + when nil; "blob" + when 0x1000..0xffffffff; "blob(#{limit})" + else raise(ActiveRecordError, "No binary type has character length #{limit}") + end + when 'integer' + case limit + when 1; 'tinyint' + when 2; 'smallint' + when 3; 'mediumint' + when nil, 4, 11; 'int(11)' # compatibility with MySQL default + when 5..8; 'bigint' + else raise(ActiveRecordError, "No integer type has byte size #{limit}") + end + when 'text' + case limit + when 0..0xff; 'tinytext' + when nil, 0x100..0xffff; 'text' + when 0x10000..0xffffff; 'mediumtext' + when 0x1000000..0xffffffff; 'longtext' + else raise(ActiveRecordError, "No text type has character length #{limit}") + end + when 'datetime' + return super unless precision + + case precision + when 0..6; "datetime(#{precision})" + else raise(ActiveRecordError, "No datetime type has precision of #{precision}. The allowed range of precision is from 0 to 6.") + end + else + super + end + end + + # SHOW VARIABLES LIKE 'name' + def show_variable(name) + variables = select_all("select @@#{name} as 'Value'", 'SCHEMA') + variables.first['Value'] unless variables.empty? + rescue ActiveRecord::StatementInvalid + nil + end + + # Returns a table's primary key and belonging sequence. + def pk_and_sequence_for(table) + execute_and_free("SHOW CREATE TABLE #{quote_table_name(table)}", 'SCHEMA') do |result| + create_table = each_hash(result).first[:"Create Table"] + if create_table.to_s =~ /PRIMARY KEY\s+(?:USING\s+\w+\s+)?\((.+)\)/ + keys = $1.split(",").map { |key| key.delete('`"') } + keys.length == 1 ? [keys.first, nil] : nil + else + nil + end + end + end + + # Returns just a table's primary key + def primary_key(table) + pk_and_sequence = pk_and_sequence_for(table) + pk_and_sequence && pk_and_sequence.first + end + + def case_sensitive_modifier(node, table_attribute) + node = Arel::Nodes.build_quoted node, table_attribute + Arel::Nodes::Bin.new(node) + end + + def case_sensitive_comparison(table, attribute, column, value) + if column.case_sensitive? + table[attribute].eq(value) + else + super + end + end + + def case_insensitive_comparison(table, attribute, column, value) + if column.case_sensitive? + super + else + table[attribute].eq(value) + end + end + + # In MySQL 5.7.5 and up, ONLY_FULL_GROUP_BY affects handling of queries that use + # DISTINCT and ORDER BY. It requires the ORDER BY columns in the select list for + # distinct queries, and requires that the ORDER BY include the distinct column. + # See https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html + def columns_for_distinct(columns, orders) # :nodoc: + order_columns = orders.reject(&:blank?).map { |s| + # Convert Arel node to string + s = s.to_sql unless s.is_a?(String) + # Remove any ASC/DESC modifiers + s.gsub(/\s+(?:ASC|DESC)\b/i, '') + }.reject(&:blank?).map.with_index { |column, i| "#{column} AS alias_#{i}" } + + [super, *order_columns].join(', ') + end + + def strict_mode? + self.class.type_cast_config_to_boolean(@config.fetch(:strict, true)) + end + + def valid_type?(type) + !native_database_types[type].nil? + end + + protected + + def initialize_type_map(m) # :nodoc: + super + + register_class_with_limit m, %r(char)i, MysqlString + + m.register_type %r(tinytext)i, Type::Text.new(limit: 2**8 - 1) + m.register_type %r(tinyblob)i, Type::Binary.new(limit: 2**8 - 1) + m.register_type %r(text)i, Type::Text.new(limit: 2**16 - 1) + m.register_type %r(blob)i, Type::Binary.new(limit: 2**16 - 1) + m.register_type %r(mediumtext)i, Type::Text.new(limit: 2**24 - 1) + m.register_type %r(mediumblob)i, Type::Binary.new(limit: 2**24 - 1) + m.register_type %r(longtext)i, Type::Text.new(limit: 2**32 - 1) + m.register_type %r(longblob)i, Type::Binary.new(limit: 2**32 - 1) + m.register_type %r(^float)i, Type::Float.new(limit: 24) + m.register_type %r(^double)i, Type::Float.new(limit: 53) + + register_integer_type m, %r(^bigint)i, limit: 8 + register_integer_type m, %r(^int)i, limit: 4 + register_integer_type m, %r(^mediumint)i, limit: 3 + register_integer_type m, %r(^smallint)i, limit: 2 + register_integer_type m, %r(^tinyint)i, limit: 1 + + m.alias_type %r(tinyint\(1\))i, 'boolean' if emulate_booleans + m.alias_type %r(set)i, 'varchar' + m.alias_type %r(year)i, 'integer' + m.alias_type %r(bit)i, 'binary' + + m.register_type(%r(datetime)i) do |sql_type| + precision = extract_precision(sql_type) + MysqlDateTime.new(precision: precision) + end + + m.register_type(%r(enum)i) do |sql_type| + limit = sql_type[/^enum\((.+)\)/i, 1] + .split(',').map{|enum| enum.strip.length - 2}.max + MysqlString.new(limit: limit) + end + end + + def register_integer_type(mapping, key, options) # :nodoc: + mapping.register_type(key) do |sql_type| + if /unsigned/i =~ sql_type + Type::UnsignedInteger.new(options) + else + Type::Integer.new(options) + end + end + end + + # MySQL is too stupid to create a temporary table for use subquery, so we have + # to give it some prompting in the form of a subsubquery. Ugh! + def subquery_for(key, select) + subsubselect = select.clone + subsubselect.projections = [key] + + # Materialize subquery by adding distinct + # to work with MySQL 5.7.6 which sets optimizer_switch='derived_merge=on' + subsubselect.distinct unless select.limit || select.offset || select.orders.any? + + subselect = Arel::SelectManager.new(select.engine) + subselect.project Arel.sql(key.name) + subselect.from subsubselect.as('__active_record_temp') + end + + def add_index_length(option_strings, column_names, options = {}) + if options.is_a?(Hash) && length = options[:length] + case length + when Hash + column_names.each {|name| option_strings[name] += "(#{length[name]})" if length.has_key?(name) && length[name].present?} + when Fixnum + column_names.each {|name| option_strings[name] += "(#{length})"} + end + end + + return option_strings + end + + def quoted_columns_for_index(column_names, options = {}) + option_strings = Hash[column_names.map {|name| [name, '']}] + + # add index length + option_strings = add_index_length(option_strings, column_names, options) + + # add index sort order + option_strings = add_index_sort_order(option_strings, column_names, options) + + column_names.map {|name| quote_column_name(name) + option_strings[name]} + end + + def translate_exception(exception, message) + case error_number(exception) + when 1062 + RecordNotUnique.new(message, exception) + when 1452 + InvalidForeignKey.new(message, exception) + else + super + end + end + + def add_column_sql(table_name, column_name, type, options = {}) + td = create_table_definition table_name, options[:temporary], options[:options] + cd = td.new_column_definition(column_name, type, options) + schema_creation.visit_AddColumn cd + end + + def change_column_sql(table_name, column_name, type, options = {}) + column = column_for(table_name, column_name) + + unless options_include_default?(options) + options[:default] = column.default + end + + unless options.has_key?(:null) + options[:null] = column.null + end + + options[:name] = column.name + schema_creation.accept ChangeColumnDefinition.new column, type, options + end + + def rename_column_sql(table_name, column_name, new_column_name) + column = column_for(table_name, column_name) + options = { + name: new_column_name, + default: column.default, + null: column.null, + auto_increment: column.extra == "auto_increment" + } + + current_type = select_one("SHOW COLUMNS FROM #{quote_table_name(table_name)} LIKE '#{column_name}'", 'SCHEMA')["Type"] + schema_creation.accept ChangeColumnDefinition.new column, current_type, options + end + + def remove_column_sql(table_name, column_name, type = nil, options = {}) + "DROP #{quote_column_name(column_name)}" + end + + def remove_columns_sql(table_name, *column_names) + column_names.map {|column_name| remove_column_sql(table_name, column_name) } + end + + def add_index_sql(table_name, column_name, options = {}) + index_name, index_type, index_columns = add_index_options(table_name, column_name, options) + "ADD #{index_type} INDEX #{index_name} (#{index_columns})" + end + + def remove_index_sql(table_name, options = {}) + index_name = index_name_for_remove(table_name, options) + "DROP INDEX #{index_name}" + end + + def add_timestamps_sql(table_name, options = {}) + [add_column_sql(table_name, :created_at, :datetime, options), add_column_sql(table_name, :updated_at, :datetime, options)] + end + + def remove_timestamps_sql(table_name, options = {}) + [remove_column_sql(table_name, :updated_at), remove_column_sql(table_name, :created_at)] + end + + private + + def version + @version ||= full_version.scan(/^(\d+)\.(\d+)\.(\d+)/).flatten.map { |v| v.to_i } + end + + def mariadb? + full_version =~ /mariadb/i + end + + def supports_rename_index? + mariadb? ? false : (version[0] == 5 && version[1] >= 7) || version[0] >= 6 + end + + def configure_connection + variables = @config.fetch(:variables, {}).stringify_keys + + # By default, MySQL 'where id is null' selects the last inserted id. + # Turn this off. http://dev.rubyonrails.org/ticket/6778 + variables['sql_auto_is_null'] = 0 + + # Increase timeout so the server doesn't disconnect us. + wait_timeout = @config[:wait_timeout] + wait_timeout = 2147483 unless wait_timeout.is_a?(Fixnum) + variables['wait_timeout'] = self.class.type_cast_config_to_integer(wait_timeout) + + # Make MySQL reject illegal values rather than truncating or blanking them, see + # http://dev.mysql.com/doc/refman/5.0/en/server-sql-mode.html#sqlmode_strict_all_tables + # If the user has provided another value for sql_mode, don't replace it. + unless variables.has_key?('sql_mode') + variables['sql_mode'] = strict_mode? ? 'STRICT_ALL_TABLES' : '' + end + + # NAMES does not have an equals sign, see + # http://dev.mysql.com/doc/refman/5.0/en/set-statement.html#id944430 + # (trailing comma because variable_assignments will always have content) + if @config[:encoding] + encoding = "NAMES #{@config[:encoding]}" + encoding << " COLLATE #{@config[:collation]}" if @config[:collation] + encoding << ", " + end + + # Gather up all of the SET variables... + variable_assignments = variables.map do |k, v| + if v == ':default' || v == :default + "@@SESSION.#{k} = DEFAULT" # Sets the value to the global or compile default + elsif !v.nil? + "@@SESSION.#{k} = #{quote(v)}" + end + # or else nil; compact to clear nils out + end.compact.join(', ') + + # ...and send them all in one query + @connection.query "SET #{encoding} #{variable_assignments}" + end + + def extract_foreign_key_action(structure, name, action) # :nodoc: + if structure =~ /CONSTRAINT #{quote_column_name(name)} FOREIGN KEY .* REFERENCES .* ON #{action} (CASCADE|SET NULL|RESTRICT)/ + case $1 + when 'CASCADE'; :cascade + when 'SET NULL'; :nullify + end + end + end + + class MysqlDateTime < Type::DateTime # :nodoc: + private + + def has_precision? + precision || 0 + end + end + + class MysqlString < Type::String # :nodoc: + def type_cast_for_database(value) + case value + when true then "1" + when false then "0" + else super + end + end + + private + + def cast_value(value) + case value + when true then "1" + when false then "0" + else super + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/column.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/column.rb new file mode 100644 index 0000000..4037e31 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/column.rb @@ -0,0 +1,82 @@ +require 'set' + +module ActiveRecord + # :stopdoc: + module ConnectionAdapters + # An abstract definition of a column in a table. + class Column + TRUE_VALUES = [true, 1, '1', 't', 'T', 'true', 'TRUE', 'on', 'ON'].to_set + FALSE_VALUES = [false, 0, '0', 'f', 'F', 'false', 'FALSE', 'off', 'OFF'].to_set + + module Format + ISO_DATE = /\A(\d{4})-(\d\d)-(\d\d)\z/ + ISO_DATETIME = /\A(\d{4})-(\d\d)-(\d\d) (\d\d):(\d\d):(\d\d)(\.\d+)?\z/ + end + + attr_reader :name, :cast_type, :null, :sql_type, :default, :default_function + + delegate :type, :precision, :scale, :limit, :klass, :accessor, + :text?, :number?, :binary?, :changed?, + :type_cast_from_user, :type_cast_from_database, :type_cast_for_database, + :type_cast_for_schema, + to: :cast_type + + # Instantiates a new column in the table. + # + # +name+ is the column's name, such as supplier_id in supplier_id int(11). + # +default+ is the type-casted default value, such as +new+ in sales_stage varchar(20) default 'new'. + # +cast_type+ is the object used for type casting and type information. + # +sql_type+ is used to extract the column's length, if necessary. For example +60+ in + # company_name varchar(60). + # It will be mapped to one of the standard Rails SQL types in the type attribute. + # +null+ determines if this column allows +NULL+ values. + def initialize(name, default, cast_type, sql_type = nil, null = true) + @name = name.freeze + @cast_type = cast_type + @sql_type = sql_type + @null = null + @default = default + @default_function = nil + end + + def has_default? + !default.nil? + end + + # Returns the human name of the column name. + # + # ===== Examples + # Column.new('sales_stage', ...).human_name # => 'Sales stage' + def human_name + Base.human_attribute_name(@name) + end + + def with_type(type) + dup.tap do |clone| + clone.instance_variable_set('@cast_type', type) + end + end + + def ==(other) + other.name == name && + other.default == default && + other.cast_type == cast_type && + other.sql_type == sql_type && + other.null == null && + other.default_function == default_function + end + alias :eql? :== + + def hash + attributes_for_hash.hash + end + + private + + def attributes_for_hash + [self.class, name, default, cast_type, sql_type, null, default_function] + end + end + end + # :startdoc: +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/connection_specification.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/connection_specification.rb new file mode 100644 index 0000000..e54e319 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/connection_specification.rb @@ -0,0 +1,275 @@ +require 'uri' +require 'active_support/core_ext/string/filters' + +module ActiveRecord + module ConnectionAdapters + class ConnectionSpecification #:nodoc: + attr_reader :config, :adapter_method + + def initialize(config, adapter_method) + @config, @adapter_method = config, adapter_method + end + + def initialize_dup(original) + @config = original.config.dup + end + + # Expands a connection string into a hash. + class ConnectionUrlResolver # :nodoc: + + # == Example + # + # url = "postgresql://foo:bar@localhost:9000/foo_test?pool=5&timeout=3000" + # ConnectionUrlResolver.new(url).to_hash + # # => { + # "adapter" => "postgresql", + # "host" => "localhost", + # "port" => 9000, + # "database" => "foo_test", + # "username" => "foo", + # "password" => "bar", + # "pool" => "5", + # "timeout" => "3000" + # } + def initialize(url) + raise "Database URL cannot be empty" if url.blank? + @uri = uri_parser.parse(url) + @adapter = @uri.scheme.tr('-', '_') + @adapter = "postgresql" if @adapter == "postgres" + + if @uri.opaque + @uri.opaque, @query = @uri.opaque.split('?', 2) + else + @query = @uri.query + end + end + + # Converts the given URL to a full connection hash. + def to_hash + config = raw_config.reject { |_,value| value.blank? } + config.map { |key,value| config[key] = uri_parser.unescape(value) if value.is_a? String } + config + end + + private + + def uri + @uri + end + + def uri_parser + @uri_parser ||= URI::Parser.new + end + + # Converts the query parameters of the URI into a hash. + # + # "localhost?pool=5&reaping_frequency=2" + # # => { "pool" => "5", "reaping_frequency" => "2" } + # + # returns empty hash if no query present. + # + # "localhost" + # # => {} + def query_hash + Hash[(@query || '').split("&").map { |pair| pair.split("=") }] + end + + def raw_config + if uri.opaque + query_hash.merge({ + "adapter" => @adapter, + "database" => uri.opaque }) + else + query_hash.merge({ + "adapter" => @adapter, + "username" => uri.user, + "password" => uri.password, + "port" => uri.port, + "database" => database_from_path, + "host" => uri.hostname }) + end + end + + # Returns name of the database. + def database_from_path + if @adapter == 'sqlite3' + # 'sqlite3:/foo' is absolute, because that makes sense. The + # corresponding relative version, 'sqlite3:foo', is handled + # elsewhere, as an "opaque". + + uri.path + else + # Only SQLite uses a filename as the "database" name; for + # anything else, a leading slash would be silly. + + uri.path.sub(%r{^/}, "") + end + end + end + + ## + # Builds a ConnectionSpecification from user input. + class Resolver # :nodoc: + attr_reader :configurations + + # Accepts a hash two layers deep, keys on the first layer represent + # environments such as "production". Keys must be strings. + def initialize(configurations) + @configurations = configurations + end + + # Returns a hash with database connection information. + # + # == Examples + # + # Full hash Configuration. + # + # configurations = { "production" => { "host" => "localhost", "database" => "foo", "adapter" => "sqlite3" } } + # Resolver.new(configurations).resolve(:production) + # # => { "host" => "localhost", "database" => "foo", "adapter" => "sqlite3"} + # + # Initialized with URL configuration strings. + # + # configurations = { "production" => "postgresql://localhost/foo" } + # Resolver.new(configurations).resolve(:production) + # # => { "host" => "localhost", "database" => "foo", "adapter" => "postgresql" } + # + def resolve(config) + if config + resolve_connection config + elsif env = ActiveRecord::ConnectionHandling::RAILS_ENV.call + resolve_symbol_connection env.to_sym + else + raise AdapterNotSpecified + end + end + + # Expands each key in @configurations hash into fully resolved hash + def resolve_all + config = configurations.dup + config.each do |key, value| + config[key] = resolve(value) if value + end + config + end + + # Returns an instance of ConnectionSpecification for a given adapter. + # Accepts a hash one layer deep that contains all connection information. + # + # == Example + # + # config = { "production" => { "host" => "localhost", "database" => "foo", "adapter" => "sqlite3" } } + # spec = Resolver.new(config).spec(:production) + # spec.adapter_method + # # => "sqlite3_connection" + # spec.config + # # => { "host" => "localhost", "database" => "foo", "adapter" => "sqlite3" } + # + def spec(config) + spec = resolve(config).symbolize_keys + + raise(AdapterNotSpecified, "database configuration does not specify adapter") unless spec.key?(:adapter) + + path_to_adapter = "active_record/connection_adapters/#{spec[:adapter]}_adapter" + begin + require path_to_adapter + rescue Gem::LoadError => e + raise Gem::LoadError, "Specified '#{spec[:adapter]}' for database adapter, but the gem is not loaded. Add `gem '#{e.name}'` to your Gemfile (and ensure its version is at the minimum required by ActiveRecord)." + rescue LoadError => e + raise LoadError, "Could not load '#{path_to_adapter}'. Make sure that the adapter in config/database.yml is valid. If you use an adapter other than 'mysql', 'mysql2', 'postgresql' or 'sqlite3' add the necessary adapter gem to the Gemfile.", e.backtrace + end + + adapter_method = "#{spec[:adapter]}_connection" + ConnectionSpecification.new(spec, adapter_method) + end + + private + + # Returns fully resolved connection, accepts hash, string or symbol. + # Always returns a hash. + # + # == Examples + # + # Symbol representing current environment. + # + # Resolver.new("production" => {}).resolve_connection(:production) + # # => {} + # + # One layer deep hash of connection values. + # + # Resolver.new({}).resolve_connection("adapter" => "sqlite3") + # # => { "adapter" => "sqlite3" } + # + # Connection URL. + # + # Resolver.new({}).resolve_connection("postgresql://localhost/foo") + # # => { "host" => "localhost", "database" => "foo", "adapter" => "postgresql" } + # + def resolve_connection(spec) + case spec + when Symbol + resolve_symbol_connection spec + when String + resolve_string_connection spec + when Hash + resolve_hash_connection spec + end + end + + def resolve_string_connection(spec) + # Rails has historically accepted a string to mean either + # an environment key or a URL spec, so we have deprecated + # this ambiguous behaviour and in the future this function + # can be removed in favor of resolve_url_connection. + if configurations.key?(spec) || spec !~ /:/ + ActiveSupport::Deprecation.warn(<<-MSG.squish) + Passing a string to ActiveRecord::Base.establish_connection for a + configuration lookup is deprecated, please pass a symbol + (#{spec.to_sym.inspect}) instead. + MSG + + resolve_symbol_connection(spec) + else + resolve_url_connection(spec) + end + end + + # Takes the environment such as +:production+ or +:development+. + # This requires that the @configurations was initialized with a key that + # matches. + # + # Resolver.new("production" => {}).resolve_symbol_connection(:production) + # # => {} + # + def resolve_symbol_connection(spec) + if config = configurations[spec.to_s] + resolve_connection(config) + else + raise(AdapterNotSpecified, "'#{spec}' database is not configured. Available: #{configurations.keys.inspect}") + end + end + + # Accepts a hash. Expands the "url" key that contains a + # URL database connection to a full connection + # hash and merges with the rest of the hash. + # Connection details inside of the "url" key win any merge conflicts + def resolve_hash_connection(spec) + if spec["url"] && spec["url"] !~ /^jdbc:/ + connection_hash = resolve_url_connection(spec.delete("url")) + spec.merge!(connection_hash) + end + spec + end + + # Takes a connection URL. + # + # Resolver.new({}).resolve_url_connection("postgresql://localhost/foo") + # # => { "host" => "localhost", "database" => "foo", "adapter" => "postgresql" } + # + def resolve_url_connection(url) + ConnectionUrlResolver.new(url).to_hash + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/mysql2_adapter.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/mysql2_adapter.rb new file mode 100644 index 0000000..8bf1464 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/mysql2_adapter.rb @@ -0,0 +1,282 @@ +require 'active_record/connection_adapters/abstract_mysql_adapter' + +gem 'mysql2', '>= 0.3.13', '< 0.5' +require 'mysql2' + +module ActiveRecord + module ConnectionHandling # :nodoc: + # Establishes a connection to the database that's used by all Active Record objects. + def mysql2_connection(config) + config = config.symbolize_keys + + config[:username] = 'root' if config[:username].nil? + + if Mysql2::Client.const_defined? :FOUND_ROWS + config[:flags] = Mysql2::Client::FOUND_ROWS + end + + client = Mysql2::Client.new(config) + options = [config[:host], config[:username], config[:password], config[:database], config[:port], config[:socket], 0] + ConnectionAdapters::Mysql2Adapter.new(client, logger, options, config) + rescue Mysql2::Error => error + if error.message.include?("Unknown database") + raise ActiveRecord::NoDatabaseError.new(error.message, error) + else + raise + end + end + end + + module ConnectionAdapters + class Mysql2Adapter < AbstractMysqlAdapter + ADAPTER_NAME = 'Mysql2'.freeze + + def initialize(connection, logger, connection_options, config) + super + @prepared_statements = false + configure_connection + end + + MAX_INDEX_LENGTH_FOR_UTF8MB4 = 191 + def initialize_schema_migrations_table + if charset == 'utf8mb4' + ActiveRecord::SchemaMigration.create_table(MAX_INDEX_LENGTH_FOR_UTF8MB4) + else + ActiveRecord::SchemaMigration.create_table + end + end + + def supports_explain? + true + end + + # HELPER METHODS =========================================== + + def each_hash(result) # :nodoc: + if block_given? + result.each(:as => :hash, :symbolize_keys => true) do |row| + yield row + end + else + to_enum(:each_hash, result) + end + end + + def error_number(exception) + exception.error_number if exception.respond_to?(:error_number) + end + + #-- + # QUOTING ================================================== + #++ + + def quote_string(string) + @connection.escape(string) + end + + def quoted_date(value) + if value.acts_like?(:time) && value.respond_to?(:usec) + "#{super}.#{sprintf("%06d", value.usec)}" + else + super + end + end + + #-- + # CONNECTION MANAGEMENT ==================================== + #++ + + def active? + return false unless @connection + @connection.ping + end + + def reconnect! + super + disconnect! + connect + end + alias :reset! :reconnect! + + # Disconnects from the database if already connected. + # Otherwise, this method does nothing. + def disconnect! + super + unless @connection.nil? + @connection.close + @connection = nil + end + end + + #-- + # DATABASE STATEMENTS ====================================== + #++ + + def explain(arel, binds = []) + sql = "EXPLAIN #{to_sql(arel, binds.dup)}" + start = Time.now + result = exec_query(sql, 'EXPLAIN', binds) + elapsed = Time.now - start + + ExplainPrettyPrinter.new.pp(result, elapsed) + end + + class ExplainPrettyPrinter # :nodoc: + # Pretty prints the result of a EXPLAIN in a way that resembles the output of the + # MySQL shell: + # + # +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+ + # | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | + # +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+ + # | 1 | SIMPLE | users | const | PRIMARY | PRIMARY | 4 | const | 1 | | + # | 1 | SIMPLE | posts | ALL | NULL | NULL | NULL | NULL | 1 | Using where | + # +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+ + # 2 rows in set (0.00 sec) + # + # This is an exercise in Ruby hyperrealism :). + def pp(result, elapsed) + widths = compute_column_widths(result) + separator = build_separator(widths) + + pp = [] + + pp << separator + pp << build_cells(result.columns, widths) + pp << separator + + result.rows.each do |row| + pp << build_cells(row, widths) + end + + pp << separator + pp << build_footer(result.rows.length, elapsed) + + pp.join("\n") + "\n" + end + + private + + def compute_column_widths(result) + [].tap do |widths| + result.columns.each_with_index do |column, i| + cells_in_column = [column] + result.rows.map {|r| r[i].nil? ? 'NULL' : r[i].to_s} + widths << cells_in_column.map(&:length).max + end + end + end + + def build_separator(widths) + padding = 1 + '+' + widths.map {|w| '-' * (w + (padding*2))}.join('+') + '+' + end + + def build_cells(items, widths) + cells = [] + items.each_with_index do |item, i| + item = 'NULL' if item.nil? + justifier = item.is_a?(Numeric) ? 'rjust' : 'ljust' + cells << item.to_s.send(justifier, widths[i]) + end + '| ' + cells.join(' | ') + ' |' + end + + def build_footer(nrows, elapsed) + rows_label = nrows == 1 ? 'row' : 'rows' + "#{nrows} #{rows_label} in set (%.2f sec)" % elapsed + end + end + + # FIXME: re-enable the following once a "better" query_cache solution is in core + # + # The overrides below perform much better than the originals in AbstractAdapter + # because we're able to take advantage of mysql2's lazy-loading capabilities + # + # # Returns a record hash with the column names as keys and column values + # # as values. + # def select_one(sql, name = nil) + # result = execute(sql, name) + # result.each(as: :hash) do |r| + # return r + # end + # end + # + # # Returns a single value from a record + # def select_value(sql, name = nil) + # result = execute(sql, name) + # if first = result.first + # first.first + # end + # end + # + # # Returns an array of the values of the first column in a select: + # # select_values("SELECT id FROM companies LIMIT 3") => [1,2,3] + # def select_values(sql, name = nil) + # execute(sql, name).map { |row| row.first } + # end + + # Returns an array of arrays containing the field values. + # Order is the same as that returned by +columns+. + def select_rows(sql, name = nil, binds = []) + execute(sql, name).to_a + end + + # Executes the SQL statement in the context of this connection. + def execute(sql, name = nil) + if @connection + # make sure we carry over any changes to ActiveRecord::Base.default_timezone that have been + # made since we established the connection + @connection.query_options[:database_timezone] = ActiveRecord::Base.default_timezone + end + + super + end + + def exec_query(sql, name = 'SQL', binds = []) + result = execute(sql, name) + ActiveRecord::Result.new(result.fields, result.to_a) + end + + alias exec_without_stmt exec_query + + def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) + super + id_value || @connection.last_id + end + alias :create :insert_sql + + def exec_insert(sql, name, binds, pk = nil, sequence_name = nil) + execute to_sql(sql, binds), name + end + + def exec_delete(sql, name, binds) + execute to_sql(sql, binds), name + @connection.affected_rows + end + alias :exec_update :exec_delete + + def last_inserted_id(result) + @connection.last_id + end + + private + + def connect + @connection = Mysql2::Client.new(@config) + configure_connection + end + + def configure_connection + @connection.query_options.merge!(:as => :array) + super + end + + def full_version + @full_version ||= @connection.server_info[:version] + end + + def set_field_encoding field_name + field_name + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/mysql_adapter.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/mysql_adapter.rb new file mode 100644 index 0000000..1e2b218 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/mysql_adapter.rb @@ -0,0 +1,491 @@ +require 'active_record/connection_adapters/abstract_mysql_adapter' +require 'active_record/connection_adapters/statement_pool' +require 'active_support/core_ext/hash/keys' + +gem 'mysql', '~> 2.9' +require 'mysql' + +class Mysql + class Time + def to_date + Date.new(year, month, day) + end + end + class Stmt; include Enumerable end + class Result; include Enumerable end +end + +module ActiveRecord + module ConnectionHandling # :nodoc: + # Establishes a connection to the database that's used by all Active Record objects. + def mysql_connection(config) + config = config.symbolize_keys + host = config[:host] + port = config[:port] + socket = config[:socket] + username = config[:username] ? config[:username].to_s : 'root' + password = config[:password].to_s + database = config[:database] + + mysql = Mysql.init + mysql.ssl_set(config[:sslkey], config[:sslcert], config[:sslca], config[:sslcapath], config[:sslcipher]) if config[:sslca] || config[:sslkey] + + default_flags = Mysql.const_defined?(:CLIENT_MULTI_RESULTS) ? Mysql::CLIENT_MULTI_RESULTS : 0 + default_flags |= Mysql::CLIENT_FOUND_ROWS if Mysql.const_defined?(:CLIENT_FOUND_ROWS) + options = [host, username, password, database, port, socket, default_flags] + ConnectionAdapters::MysqlAdapter.new(mysql, logger, options, config) + rescue Mysql::Error => error + if error.message.include?("Unknown database") + raise ActiveRecord::NoDatabaseError.new(error.message, error) + else + raise + end + end + end + + module ConnectionAdapters + # The MySQL adapter will work with both Ruby/MySQL, which is a Ruby-based MySQL adapter that comes bundled with Active Record, and with + # the faster C-based MySQL/Ruby adapter (available both as a gem and from http://www.tmtm.org/en/mysql/ruby/). + # + # Options: + # + # * :host - Defaults to "localhost". + # * :port - Defaults to 3306. + # * :socket - Defaults to "/tmp/mysql.sock". + # * :username - Defaults to "root" + # * :password - Defaults to nothing. + # * :database - The name of the database. No default, must be provided. + # * :encoding - (Optional) Sets the client encoding by executing "SET NAMES " after connection. + # * :reconnect - Defaults to false (See MySQL documentation: http://dev.mysql.com/doc/refman/5.0/en/auto-reconnect.html). + # * :strict - Defaults to true. Enable STRICT_ALL_TABLES. (See MySQL documentation: http://dev.mysql.com/doc/refman/5.0/en/sql-mode.html) + # * :variables - (Optional) A hash session variables to send as SET @@SESSION.key = value on each database connection. Use the value +:default+ to set a variable to its DEFAULT value. (See MySQL documentation: http://dev.mysql.com/doc/refman/5.0/en/set-statement.html). + # * :sslca - Necessary to use MySQL with an SSL connection. + # * :sslkey - Necessary to use MySQL with an SSL connection. + # * :sslcert - Necessary to use MySQL with an SSL connection. + # * :sslcapath - Necessary to use MySQL with an SSL connection. + # * :sslcipher - Necessary to use MySQL with an SSL connection. + # + class MysqlAdapter < AbstractMysqlAdapter + ADAPTER_NAME = 'MySQL'.freeze + + class StatementPool < ConnectionAdapters::StatementPool + def initialize(connection, max = 1000) + super + @cache = Hash.new { |h,pid| h[pid] = {} } + end + + def each(&block); cache.each(&block); end + def key?(key); cache.key?(key); end + def [](key); cache[key]; end + def length; cache.length; end + def delete(key); cache.delete(key); end + + def []=(sql, key) + while @max <= cache.size + cache.shift.last[:stmt].close + end + cache[sql] = key + end + + def clear + cache.each_value do |hash| + hash[:stmt].close + end + cache.clear + end + + private + def cache + @cache[Process.pid] + end + end + + def initialize(connection, logger, connection_options, config) + super + @statements = StatementPool.new(@connection, + self.class.type_cast_config_to_integer(config.fetch(:statement_limit) { 1000 })) + @client_encoding = nil + connect + end + + # Returns true, since this connection adapter supports prepared statement + # caching. + def supports_statement_cache? + true + end + + # HELPER METHODS =========================================== + + def each_hash(result) # :nodoc: + if block_given? + result.each_hash do |row| + row.symbolize_keys! + yield row + end + else + to_enum(:each_hash, result) + end + end + + def error_number(exception) # :nodoc: + exception.errno if exception.respond_to?(:errno) + end + + # QUOTING ================================================== + + def quote_string(string) #:nodoc: + @connection.quote(string) + end + + #-- + # CONNECTION MANAGEMENT ==================================== + #++ + + def active? + if @connection.respond_to?(:stat) + @connection.stat + else + @connection.query 'select 1' + end + + # mysql-ruby doesn't raise an exception when stat fails. + if @connection.respond_to?(:errno) + @connection.errno.zero? + else + true + end + rescue Mysql::Error + false + end + + def reconnect! + super + disconnect! + connect + end + + # Disconnects from the database if already connected. Otherwise, this + # method does nothing. + def disconnect! + super + @connection.close rescue nil + end + + def reset! + if @connection.respond_to?(:change_user) + # See http://bugs.mysql.com/bug.php?id=33540 -- the workaround way to + # reset the connection is to change the user to the same user. + @connection.change_user(@config[:username], @config[:password], @config[:database]) + configure_connection + end + end + + #-- + # DATABASE STATEMENTS ====================================== + #++ + + def select_rows(sql, name = nil, binds = []) + @connection.query_with_result = true + rows = exec_query(sql, name, binds).rows + @connection.more_results && @connection.next_result # invoking stored procedures with CLIENT_MULTI_RESULTS requires this to tidy up else connection will be dropped + rows + end + + # Clears the prepared statements cache. + def clear_cache! + super + @statements.clear + end + + # Taken from here: + # https://github.com/tmtm/ruby-mysql/blob/master/lib/mysql/charset.rb + # Author: TOMITA Masahiro + ENCODINGS = { + "armscii8" => nil, + "ascii" => Encoding::US_ASCII, + "big5" => Encoding::Big5, + "binary" => Encoding::ASCII_8BIT, + "cp1250" => Encoding::Windows_1250, + "cp1251" => Encoding::Windows_1251, + "cp1256" => Encoding::Windows_1256, + "cp1257" => Encoding::Windows_1257, + "cp850" => Encoding::CP850, + "cp852" => Encoding::CP852, + "cp866" => Encoding::IBM866, + "cp932" => Encoding::Windows_31J, + "dec8" => nil, + "eucjpms" => Encoding::EucJP_ms, + "euckr" => Encoding::EUC_KR, + "gb2312" => Encoding::EUC_CN, + "gbk" => Encoding::GBK, + "geostd8" => nil, + "greek" => Encoding::ISO_8859_7, + "hebrew" => Encoding::ISO_8859_8, + "hp8" => nil, + "keybcs2" => nil, + "koi8r" => Encoding::KOI8_R, + "koi8u" => Encoding::KOI8_U, + "latin1" => Encoding::ISO_8859_1, + "latin2" => Encoding::ISO_8859_2, + "latin5" => Encoding::ISO_8859_9, + "latin7" => Encoding::ISO_8859_13, + "macce" => Encoding::MacCentEuro, + "macroman" => Encoding::MacRoman, + "sjis" => Encoding::SHIFT_JIS, + "swe7" => nil, + "tis620" => Encoding::TIS_620, + "ucs2" => Encoding::UTF_16BE, + "ujis" => Encoding::EucJP_ms, + "utf8" => Encoding::UTF_8, + "utf8mb4" => Encoding::UTF_8, + } + + # Get the client encoding for this database + def client_encoding + return @client_encoding if @client_encoding + + result = exec_query( + "select @@character_set_client", + 'SCHEMA') + @client_encoding = ENCODINGS[result.rows.last.last] + end + + def exec_query(sql, name = 'SQL', binds = []) + if without_prepared_statement?(binds) + result_set, affected_rows = exec_without_stmt(sql, name) + else + result_set, affected_rows = exec_stmt(sql, name, binds) + end + + yield affected_rows if block_given? + + result_set + end + + def last_inserted_id(result) + @connection.insert_id + end + + module Fields # :nodoc: + class DateTime < Type::DateTime # :nodoc: + def cast_value(value) + if Mysql::Time === value + new_time( + value.year, + value.month, + value.day, + value.hour, + value.minute, + value.second, + value.second_part) + else + super + end + end + end + + class Time < Type::Time # :nodoc: + def cast_value(value) + if Mysql::Time === value + new_time( + 2000, + 01, + 01, + value.hour, + value.minute, + value.second, + value.second_part) + else + super + end + end + end + + class << self + TYPES = Type::HashLookupTypeMap.new # :nodoc: + + delegate :register_type, :alias_type, to: :TYPES + + def find_type(field) + if field.type == Mysql::Field::TYPE_TINY && field.length > 1 + TYPES.lookup(Mysql::Field::TYPE_LONG) + else + TYPES.lookup(field.type) + end + end + end + + register_type Mysql::Field::TYPE_TINY, Type::Boolean.new + register_type Mysql::Field::TYPE_LONG, Type::Integer.new + alias_type Mysql::Field::TYPE_LONGLONG, Mysql::Field::TYPE_LONG + alias_type Mysql::Field::TYPE_NEWDECIMAL, Mysql::Field::TYPE_LONG + + register_type Mysql::Field::TYPE_DATE, Type::Date.new + register_type Mysql::Field::TYPE_DATETIME, Fields::DateTime.new + register_type Mysql::Field::TYPE_TIME, Fields::Time.new + register_type Mysql::Field::TYPE_FLOAT, Type::Float.new + end + + def initialize_type_map(m) # :nodoc: + super + m.register_type %r(datetime)i, Fields::DateTime.new + m.register_type %r(time)i, Fields::Time.new + end + + def exec_without_stmt(sql, name = 'SQL') # :nodoc: + # Some queries, like SHOW CREATE TABLE don't work through the prepared + # statement API. For those queries, we need to use this method. :'( + log(sql, name) do + result = @connection.query(sql) + affected_rows = @connection.affected_rows + + if result + types = {} + fields = [] + result.fetch_fields.each { |field| + field_name = field.name + fields << field_name + + if field.decimals > 0 + types[field_name] = Type::Decimal.new + else + types[field_name] = Fields.find_type field + end + } + + result_set = ActiveRecord::Result.new(fields, result.to_a, types) + result.free + else + result_set = ActiveRecord::Result.new([], []) + end + + [result_set, affected_rows] + end + end + + def execute_and_free(sql, name = nil) # :nodoc: + result = execute(sql, name) + ret = yield result + result.free + ret + end + + def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) #:nodoc: + super sql, name + id_value || @connection.insert_id + end + alias :create :insert_sql + + def exec_delete(sql, name, binds) # :nodoc: + affected_rows = 0 + + exec_query(sql, name, binds) do |n| + affected_rows = n + end + + affected_rows + end + alias :exec_update :exec_delete + + def begin_db_transaction #:nodoc: + exec_query "BEGIN" + end + + private + + def exec_stmt(sql, name, binds) + cache = {} + type_casted_binds = binds.map { |col, val| + [col, type_cast(val, col)] + } + + log(sql, name, type_casted_binds) do + if binds.empty? + stmt = @connection.prepare(sql) + else + cache = @statements[sql] ||= { + :stmt => @connection.prepare(sql) + } + stmt = cache[:stmt] + end + + begin + stmt.execute(*type_casted_binds.map { |_, val| val }) + rescue Mysql::Error => e + # Older versions of MySQL leave the prepared statement in a bad + # place when an error occurs. To support older MySQL versions, we + # need to close the statement and delete the statement from the + # cache. + stmt.close + @statements.delete sql + raise e + end + + cols = nil + if metadata = stmt.result_metadata + cols = cache[:cols] ||= metadata.fetch_fields.map { |field| + field.name + } + metadata.free + end + + result_set = ActiveRecord::Result.new(cols, stmt.to_a) if cols + affected_rows = stmt.affected_rows + + stmt.free_result + stmt.close if binds.empty? + + [result_set, affected_rows] + end + end + + def connect + encoding = @config[:encoding] + if encoding + @connection.options(Mysql::SET_CHARSET_NAME, encoding) rescue nil + end + + if @config[:sslca] || @config[:sslkey] + @connection.ssl_set(@config[:sslkey], @config[:sslcert], @config[:sslca], @config[:sslcapath], @config[:sslcipher]) + end + + @connection.options(Mysql::OPT_CONNECT_TIMEOUT, @config[:connect_timeout]) if @config[:connect_timeout] + @connection.options(Mysql::OPT_READ_TIMEOUT, @config[:read_timeout]) if @config[:read_timeout] + @connection.options(Mysql::OPT_WRITE_TIMEOUT, @config[:write_timeout]) if @config[:write_timeout] + + @connection.real_connect(*@connection_options) + + # reconnect must be set after real_connect is called, because real_connect sets it to false internally + @connection.reconnect = !!@config[:reconnect] if @connection.respond_to?(:reconnect=) + + configure_connection + end + + # Many Rails applications monkey-patch a replacement of the configure_connection method + # and don't call 'super', so leave this here even though it looks superfluous. + def configure_connection + super + end + + def select(sql, name = nil, binds = []) + @connection.query_with_result = true + rows = super + @connection.more_results && @connection.next_result # invoking stored procedures with CLIENT_MULTI_RESULTS requires this to tidy up else connection will be dropped + rows + end + + # Returns the full version of the connected MySQL server. + def full_version + @full_version ||= @connection.server_info + end + + def set_field_encoding field_name + field_name.force_encoding(client_encoding) + if internal_enc = Encoding.default_internal + field_name = field_name.encode!(internal_enc) + end + field_name + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/array_parser.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/array_parser.rb new file mode 100644 index 0000000..1b74c03 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/array_parser.rb @@ -0,0 +1,93 @@ +module ActiveRecord + module ConnectionAdapters + module PostgreSQL + module ArrayParser # :nodoc: + + DOUBLE_QUOTE = '"' + BACKSLASH = "\\" + COMMA = ',' + BRACKET_OPEN = '{' + BRACKET_CLOSE = '}' + + def parse_pg_array(string) # :nodoc: + local_index = 0 + array = [] + while(local_index < string.length) + case string[local_index] + when BRACKET_OPEN + local_index,array = parse_array_contents(array, string, local_index + 1) + when BRACKET_CLOSE + return array + end + local_index += 1 + end + + array + end + + private + + def parse_array_contents(array, string, index) + is_escaping = false + is_quoted = false + was_quoted = false + current_item = '' + + local_index = index + while local_index + token = string[local_index] + if is_escaping + current_item << token + is_escaping = false + else + if is_quoted + case token + when DOUBLE_QUOTE + is_quoted = false + was_quoted = true + when BACKSLASH + is_escaping = true + else + current_item << token + end + else + case token + when BACKSLASH + is_escaping = true + when COMMA + add_item_to_array(array, current_item, was_quoted) + current_item = '' + was_quoted = false + when DOUBLE_QUOTE + is_quoted = true + when BRACKET_OPEN + internal_items = [] + local_index,internal_items = parse_array_contents(internal_items, string, local_index + 1) + array.push(internal_items) + when BRACKET_CLOSE + add_item_to_array(array, current_item, was_quoted) + return local_index,array + else + current_item << token + end + end + end + + local_index += 1 + end + return local_index,array + end + + def add_item_to_array(array, current_item, quoted) + return if !quoted && current_item.length == 0 + + if !quoted && current_item == 'NULL' + array.push nil + else + array.push current_item + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/column.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/column.rb new file mode 100644 index 0000000..37e5c38 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/column.rb @@ -0,0 +1,20 @@ +module ActiveRecord + module ConnectionAdapters + # PostgreSQL-specific extensions to column definitions in a table. + class PostgreSQLColumn < Column #:nodoc: + attr_accessor :array + + def initialize(name, default, cast_type, sql_type = nil, null = true, default_function = nil) + if sql_type =~ /\[\]$/ + @array = true + super(name, default, cast_type, sql_type[0..sql_type.length - 3], null) + else + @array = false + super(name, default, cast_type, sql_type, null) + end + + @default_function = default_function + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/database_statements.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/database_statements.rb new file mode 100644 index 0000000..11d3f53 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/database_statements.rb @@ -0,0 +1,232 @@ +module ActiveRecord + module ConnectionAdapters + module PostgreSQL + module DatabaseStatements + def explain(arel, binds = []) + sql = "EXPLAIN #{to_sql(arel, binds)}" + ExplainPrettyPrinter.new.pp(exec_query(sql, 'EXPLAIN', binds)) + end + + class ExplainPrettyPrinter # :nodoc: + # Pretty prints the result of a EXPLAIN in a way that resembles the output of the + # PostgreSQL shell: + # + # QUERY PLAN + # ------------------------------------------------------------------------------ + # Nested Loop Left Join (cost=0.00..37.24 rows=8 width=0) + # Join Filter: (posts.user_id = users.id) + # -> Index Scan using users_pkey on users (cost=0.00..8.27 rows=1 width=4) + # Index Cond: (id = 1) + # -> Seq Scan on posts (cost=0.00..28.88 rows=8 width=4) + # Filter: (posts.user_id = 1) + # (6 rows) + # + def pp(result) + header = result.columns.first + lines = result.rows.map(&:first) + + # We add 2 because there's one char of padding at both sides, note + # the extra hyphens in the example above. + width = [header, *lines].map(&:length).max + 2 + + pp = [] + + pp << header.center(width).rstrip + pp << '-' * width + + pp += lines.map {|line| " #{line}"} + + nrows = result.rows.length + rows_label = nrows == 1 ? 'row' : 'rows' + pp << "(#{nrows} #{rows_label})" + + pp.join("\n") + "\n" + end + end + + def select_value(arel, name = nil, binds = []) + arel, binds = binds_from_relation arel, binds + sql = to_sql(arel, binds) + execute_and_clear(sql, name, binds) do |result| + result.getvalue(0, 0) if result.ntuples > 0 && result.nfields > 0 + end + end + + def select_values(arel, name = nil) + arel, binds = binds_from_relation arel, [] + sql = to_sql(arel, binds) + execute_and_clear(sql, name, binds) do |result| + if result.nfields > 0 + result.column_values(0) + else + [] + end + end + end + + # Executes a SELECT query and returns an array of rows. Each row is an + # array of field values. + def select_rows(sql, name = nil, binds = []) + execute_and_clear(sql, name, binds) do |result| + result.values + end + end + + # Executes an INSERT query and returns the new record's ID + def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) + unless pk + # Extract the table from the insert sql. Yuck. + table_ref = extract_table_ref_from_insert_sql(sql) + pk = primary_key(table_ref) if table_ref + end + + if pk && use_insert_returning? + select_value("#{sql} RETURNING #{quote_column_name(pk)}") + elsif pk + super + last_insert_id_value(sequence_name || default_sequence_name(table_ref, pk)) + else + super + end + end + + def create + super.insert + end + + # The internal PostgreSQL identifier of the money data type. + MONEY_COLUMN_TYPE_OID = 790 #:nodoc: + # The internal PostgreSQL identifier of the BYTEA data type. + BYTEA_COLUMN_TYPE_OID = 17 #:nodoc: + + # create a 2D array representing the result set + def result_as_array(res) #:nodoc: + # check if we have any binary column and if they need escaping + ftypes = Array.new(res.nfields) do |i| + [i, res.ftype(i)] + end + + rows = res.values + return rows unless ftypes.any? { |_, x| + x == BYTEA_COLUMN_TYPE_OID || x == MONEY_COLUMN_TYPE_OID + } + + typehash = ftypes.group_by { |_, type| type } + binaries = typehash[BYTEA_COLUMN_TYPE_OID] || [] + monies = typehash[MONEY_COLUMN_TYPE_OID] || [] + + rows.each do |row| + # unescape string passed BYTEA field (OID == 17) + binaries.each do |index, _| + row[index] = unescape_bytea(row[index]) + end + + # If this is a money type column and there are any currency symbols, + # then strip them off. Indeed it would be prettier to do this in + # PostgreSQLColumn.string_to_decimal but would break form input + # fields that call value_before_type_cast. + monies.each do |index, _| + data = row[index] + # Because money output is formatted according to the locale, there are two + # cases to consider (note the decimal separators): + # (1) $12,345,678.12 + # (2) $12.345.678,12 + case data + when /^-?\D+[\d,]+\.\d{2}$/ # (1) + data.gsub!(/[^-\d.]/, '') + when /^-?\D+[\d.]+,\d{2}$/ # (2) + data.gsub!(/[^-\d,]/, '').sub!(/,/, '.') + end + end + end + end + + # Queries the database and returns the results in an Array-like object + def query(sql, name = nil) #:nodoc: + log(sql, name) do + result_as_array @connection.async_exec(sql) + end + end + + # Executes an SQL statement, returning a PGresult object on success + # or raising a PGError exception otherwise. + def execute(sql, name = nil) + log(sql, name) do + @connection.async_exec(sql) + end + end + + def exec_query(sql, name = 'SQL', binds = []) + execute_and_clear(sql, name, binds) do |result| + types = {} + fields = result.fields + fields.each_with_index do |fname, i| + ftype = result.ftype i + fmod = result.fmod i + types[fname] = get_oid_type(ftype, fmod, fname) + end + ActiveRecord::Result.new(fields, result.values, types) + end + end + + def exec_delete(sql, name = 'SQL', binds = []) + execute_and_clear(sql, name, binds) {|result| result.cmd_tuples } + end + alias :exec_update :exec_delete + + def sql_for_insert(sql, pk, id_value, sequence_name, binds) + unless pk + # Extract the table from the insert sql. Yuck. + table_ref = extract_table_ref_from_insert_sql(sql) + pk = primary_key(table_ref) if table_ref + end + + if pk && use_insert_returning? + sql = "#{sql} RETURNING #{quote_column_name(pk)}" + end + + [sql, binds] + end + + def exec_insert(sql, name, binds, pk = nil, sequence_name = nil) + val = exec_query(sql, name, binds) + if !use_insert_returning? && pk + unless sequence_name + table_ref = extract_table_ref_from_insert_sql(sql) + sequence_name = default_sequence_name(table_ref, pk) + return val unless sequence_name + end + last_insert_id_result(sequence_name) + else + val + end + end + + # Executes an UPDATE query and returns the number of affected tuples. + def update_sql(sql, name = nil) + super.cmd_tuples + end + + # Begins a transaction. + def begin_db_transaction + execute "BEGIN" + end + + def begin_isolated_db_transaction(isolation) + begin_db_transaction + execute "SET TRANSACTION ISOLATION LEVEL #{transaction_isolation_levels.fetch(isolation)}" + end + + # Commits a transaction. + def commit_db_transaction + execute "COMMIT" + end + + # Aborts a transaction. + def exec_rollback_db_transaction + execute "ROLLBACK" + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid.rb new file mode 100644 index 0000000..d28a2b4 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid.rb @@ -0,0 +1,36 @@ +require 'active_record/connection_adapters/postgresql/oid/infinity' + +require 'active_record/connection_adapters/postgresql/oid/array' +require 'active_record/connection_adapters/postgresql/oid/bit' +require 'active_record/connection_adapters/postgresql/oid/bit_varying' +require 'active_record/connection_adapters/postgresql/oid/bytea' +require 'active_record/connection_adapters/postgresql/oid/cidr' +require 'active_record/connection_adapters/postgresql/oid/date' +require 'active_record/connection_adapters/postgresql/oid/date_time' +require 'active_record/connection_adapters/postgresql/oid/decimal' +require 'active_record/connection_adapters/postgresql/oid/enum' +require 'active_record/connection_adapters/postgresql/oid/float' +require 'active_record/connection_adapters/postgresql/oid/hstore' +require 'active_record/connection_adapters/postgresql/oid/inet' +require 'active_record/connection_adapters/postgresql/oid/integer' +require 'active_record/connection_adapters/postgresql/oid/json' +require 'active_record/connection_adapters/postgresql/oid/jsonb' +require 'active_record/connection_adapters/postgresql/oid/money' +require 'active_record/connection_adapters/postgresql/oid/point' +require 'active_record/connection_adapters/postgresql/oid/range' +require 'active_record/connection_adapters/postgresql/oid/specialized_string' +require 'active_record/connection_adapters/postgresql/oid/time' +require 'active_record/connection_adapters/postgresql/oid/uuid' +require 'active_record/connection_adapters/postgresql/oid/vector' +require 'active_record/connection_adapters/postgresql/oid/xml' + +require 'active_record/connection_adapters/postgresql/oid/type_map_initializer' + +module ActiveRecord + module ConnectionAdapters + module PostgreSQL + module OID # :nodoc: + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/array.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/array.rb new file mode 100644 index 0000000..e5f8cea --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/array.rb @@ -0,0 +1,99 @@ +module ActiveRecord + module ConnectionAdapters + module PostgreSQL + module OID # :nodoc: + class Array < Type::Value # :nodoc: + include Type::Mutable + + # Loads pg_array_parser if available. String parsing can be + # performed quicker by a native extension, which will not create + # a large amount of Ruby objects that will need to be garbage + # collected. pg_array_parser has a C and Java extension + begin + require 'pg_array_parser' + include PgArrayParser + rescue LoadError + require 'active_record/connection_adapters/postgresql/array_parser' + include PostgreSQL::ArrayParser + end + + attr_reader :subtype, :delimiter + delegate :type, :limit, to: :subtype + + def initialize(subtype, delimiter = ',') + @subtype = subtype + @delimiter = delimiter + end + + def type_cast_from_database(value) + if value.is_a?(::String) + type_cast_array(parse_pg_array(value), :type_cast_from_database) + else + super + end + end + + def type_cast_from_user(value) + if value.is_a?(::String) + value = parse_pg_array(value) + end + type_cast_array(value, :type_cast_from_user) + end + + def type_cast_for_database(value) + if value.is_a?(::Array) + cast_value_for_database(value) + else + super + end + end + + private + + def type_cast_array(value, method) + if value.is_a?(::Array) + value.map { |item| type_cast_array(item, method) } + else + @subtype.public_send(method, value) + end + end + + def cast_value_for_database(value) + if value.is_a?(::Array) + casted_values = value.map { |item| cast_value_for_database(item) } + "{#{casted_values.join(delimiter)}}" + else + quote_and_escape(subtype.type_cast_for_database(value)) + end + end + + ARRAY_ESCAPE = "\\" * 2 * 2 # escape the backslash twice for PG arrays + + def quote_and_escape(value) + case value + when ::String + if string_requires_quoting?(value) + value = value.gsub(/\\/, ARRAY_ESCAPE) + value.gsub!(/"/,"\\\"") + %("#{value}") + else + value + end + when nil then "NULL" + else value + end + end + + # See http://www.postgresql.org/docs/9.2/static/arrays.html#ARRAYS-IO + # for a list of all cases in which strings will be quoted. + def string_requires_quoting?(string) + string.empty? || + string == "NULL" || + string =~ /[\{\}"\\\s]/ || + string.include?(delimiter) + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/bit.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/bit.rb new file mode 100644 index 0000000..1dbb40c --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/bit.rb @@ -0,0 +1,52 @@ +module ActiveRecord + module ConnectionAdapters + module PostgreSQL + module OID # :nodoc: + class Bit < Type::Value # :nodoc: + def type + :bit + end + + def type_cast(value) + if ::String === value + case value + when /^0x/i + value[2..-1].hex.to_s(2) # Hexadecimal notation + else + value # Bit-string notation + end + else + value + end + end + + def type_cast_for_database(value) + Data.new(super) if value + end + + class Data + def initialize(value) + @value = value + end + + def to_s + value + end + + def binary? + /\A[01]*\Z/ === value + end + + def hex? + /\A[0-9A-F]*\Z/i === value + end + + protected + + attr_reader :value + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb new file mode 100644 index 0000000..4c21097 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb @@ -0,0 +1,13 @@ +module ActiveRecord + module ConnectionAdapters + module PostgreSQL + module OID # :nodoc: + class BitVarying < OID::Bit # :nodoc: + def type + :bit_varying + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/bytea.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/bytea.rb new file mode 100644 index 0000000..6bd1b8e --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/bytea.rb @@ -0,0 +1,15 @@ +module ActiveRecord + module ConnectionAdapters + module PostgreSQL + module OID # :nodoc: + class Bytea < Type::Binary # :nodoc: + def type_cast_from_database(value) + return if value.nil? + return value.to_s if value.is_a?(Type::Binary::Data) + PGconn.unescape_bytea(super) + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/cidr.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/cidr.rb new file mode 100644 index 0000000..222f10f --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/cidr.rb @@ -0,0 +1,46 @@ +module ActiveRecord + module ConnectionAdapters + module PostgreSQL + module OID # :nodoc: + class Cidr < Type::Value # :nodoc: + def type + :cidr + end + + def type_cast_for_schema(value) + subnet_mask = value.instance_variable_get(:@mask_addr) + + # If the subnet mask is equal to /32, don't output it + if subnet_mask == (2**32 - 1) + "\"#{value}\"" + else + "\"#{value}/#{subnet_mask.to_s(2).count('1')}\"" + end + end + + def type_cast_for_database(value) + if IPAddr === value + "#{value}/#{value.instance_variable_get(:@mask_addr).to_s(2).count('1')}" + else + value + end + end + + def cast_value(value) + if value.nil? + nil + elsif String === value + begin + IPAddr.new(value) + rescue ArgumentError + nil + end + else + value + end + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/date.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/date.rb new file mode 100644 index 0000000..1d8d264 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/date.rb @@ -0,0 +1,11 @@ +module ActiveRecord + module ConnectionAdapters + module PostgreSQL + module OID # :nodoc: + class Date < Type::Date # :nodoc: + include Infinity + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/date_time.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/date_time.rb new file mode 100644 index 0000000..2fe61ee --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/date_time.rb @@ -0,0 +1,36 @@ +module ActiveRecord + module ConnectionAdapters + module PostgreSQL + module OID # :nodoc: + class DateTime < Type::DateTime # :nodoc: + include Infinity + + def type_cast_for_database(value) + if has_precision? && value.acts_like?(:time) && value.year <= 0 + bce_year = format("%04d", -value.year + 1) + super.sub(/^-?\d+/, bce_year) + " BC" + else + super + end + end + + def cast_value(value) + if value.is_a?(::String) + case value + when 'infinity' then ::Float::INFINITY + when '-infinity' then -::Float::INFINITY + when / BC$/ + astronomical_year = format("%04d", -value[/^\d+/].to_i + 1) + super(value.sub(/ BC$/, "").sub(/^\d+/, astronomical_year)) + else + super + end + else + value + end + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/decimal.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/decimal.rb new file mode 100644 index 0000000..43d22c8 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/decimal.rb @@ -0,0 +1,13 @@ +module ActiveRecord + module ConnectionAdapters + module PostgreSQL + module OID # :nodoc: + class Decimal < Type::Decimal # :nodoc: + def infinity(options = {}) + BigDecimal.new("Infinity") * (options[:negative] ? -1 : 1) + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/enum.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/enum.rb new file mode 100644 index 0000000..91d339f --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/enum.rb @@ -0,0 +1,19 @@ +module ActiveRecord + module ConnectionAdapters + module PostgreSQL + module OID # :nodoc: + class Enum < Type::Value # :nodoc: + def type + :enum + end + + private + + def cast_value(value) + value.to_s + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/float.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/float.rb new file mode 100644 index 0000000..78ef94b --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/float.rb @@ -0,0 +1,21 @@ +module ActiveRecord + module ConnectionAdapters + module PostgreSQL + module OID # :nodoc: + class Float < Type::Float # :nodoc: + include Infinity + + def cast_value(value) + case value + when ::Float then value + when 'Infinity' then ::Float::INFINITY + when '-Infinity' then -::Float::INFINITY + when 'NaN' then ::Float::NAN + else value.to_f + end + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/hstore.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/hstore.rb new file mode 100644 index 0000000..be4525c --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/hstore.rb @@ -0,0 +1,59 @@ +module ActiveRecord + module ConnectionAdapters + module PostgreSQL + module OID # :nodoc: + class Hstore < Type::Value # :nodoc: + include Type::Mutable + + def type + :hstore + end + + def type_cast_from_database(value) + if value.is_a?(::String) + ::Hash[value.scan(HstorePair).map { |k, v| + v = v.upcase == 'NULL' ? nil : v.gsub(/\A"(.*)"\Z/m,'\1').gsub(/\\(.)/, '\1') + k = k.gsub(/\A"(.*)"\Z/m,'\1').gsub(/\\(.)/, '\1') + [k, v] + }] + else + value + end + end + + def type_cast_for_database(value) + if value.is_a?(::Hash) + value.map { |k, v| "#{escape_hstore(k)}=>#{escape_hstore(v)}" }.join(', ') + else + value + end + end + + def accessor + ActiveRecord::Store::StringKeyedHashAccessor + end + + private + + HstorePair = begin + quoted_string = /"[^"\\]*(?:\\.[^"\\]*)*"/ + unquoted_string = /(?:\\.|[^\s,])[^\s=,\\]*(?:\\.[^\s=,\\]*|=[^,>])*/ + /(#{quoted_string}|#{unquoted_string})\s*=>\s*(#{quoted_string}|#{unquoted_string})/ + end + + def escape_hstore(value) + if value.nil? + 'NULL' + else + if value == "" + '""' + else + '"%s"' % value.to_s.gsub(/(["\\])/, '\\\\\1') + end + end + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/inet.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/inet.rb new file mode 100644 index 0000000..96486fa --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/inet.rb @@ -0,0 +1,13 @@ +module ActiveRecord + module ConnectionAdapters + module PostgreSQL + module OID # :nodoc: + class Inet < Cidr # :nodoc: + def type + :inet + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/infinity.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/infinity.rb new file mode 100644 index 0000000..e477803 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/infinity.rb @@ -0,0 +1,13 @@ +module ActiveRecord + module ConnectionAdapters + module PostgreSQL + module OID # :nodoc: + module Infinity # :nodoc: + def infinity(options = {}) + options[:negative] ? -::Float::INFINITY : ::Float::INFINITY + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/integer.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/integer.rb new file mode 100644 index 0000000..59abdc0 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/integer.rb @@ -0,0 +1,11 @@ +module ActiveRecord + module ConnectionAdapters + module PostgreSQL + module OID # :nodoc: + class Integer < Type::Integer # :nodoc: + include Infinity + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/json.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/json.rb new file mode 100644 index 0000000..7dadc09 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/json.rb @@ -0,0 +1,35 @@ +module ActiveRecord + module ConnectionAdapters + module PostgreSQL + module OID # :nodoc: + class Json < Type::Value # :nodoc: + include Type::Mutable + + def type + :json + end + + def type_cast_from_database(value) + if value.is_a?(::String) + ::ActiveSupport::JSON.decode(value) rescue nil + else + super + end + end + + def type_cast_for_database(value) + if value.is_a?(::Array) || value.is_a?(::Hash) + ::ActiveSupport::JSON.encode(value) + else + super + end + end + + def accessor + ActiveRecord::Store::StringKeyedHashAccessor + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb new file mode 100644 index 0000000..380c50f --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb @@ -0,0 +1,23 @@ +module ActiveRecord + module ConnectionAdapters + module PostgreSQL + module OID # :nodoc: + class Jsonb < Json # :nodoc: + def type + :jsonb + end + + def changed_in_place?(raw_old_value, new_value) + # Postgres does not preserve insignificant whitespaces when + # roundtripping jsonb columns. This causes some false positives for + # the comparison here. Therefore, we need to parse and re-dump the + # raw value here to ensure the insignificant whitespaces are + # consistent with our encoder's output. + raw_old_value = type_cast_for_database(type_cast_from_database(raw_old_value)) + super(raw_old_value, new_value) + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/money.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/money.rb new file mode 100644 index 0000000..df890c2 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/money.rb @@ -0,0 +1,43 @@ +module ActiveRecord + module ConnectionAdapters + module PostgreSQL + module OID # :nodoc: + class Money < Type::Decimal # :nodoc: + include Infinity + + class_attribute :precision + + def type + :money + end + + def scale + 2 + end + + def cast_value(value) + return value unless ::String === value + + # Because money output is formatted according to the locale, there are two + # cases to consider (note the decimal separators): + # (1) $12,345,678.12 + # (2) $12.345.678,12 + # Negative values are represented as follows: + # (3) -$2.55 + # (4) ($2.55) + + value.sub!(/^\((.+)\)$/, '-\1') # (4) + case value + when /^-?\D+[\d,]+\.\d{2}$/ # (1) + value.gsub!(/[^-\d.]/, '') + when /^-?\D+[\d.]+,\d{2}$/ # (2) + value.gsub!(/[^-\d,]/, '').sub!(/,/, '.') + end + + super(value) + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/point.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/point.rb new file mode 100644 index 0000000..bac8b01 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/point.rb @@ -0,0 +1,43 @@ +module ActiveRecord + module ConnectionAdapters + module PostgreSQL + module OID # :nodoc: + class Point < Type::Value # :nodoc: + include Type::Mutable + + def type + :point + end + + def type_cast(value) + case value + when ::String + if value[0] == '(' && value[-1] == ')' + value = value[1...-1] + end + type_cast(value.split(',')) + when ::Array + value.map { |v| Float(v) } + else + value + end + end + + def type_cast_for_database(value) + if value.is_a?(::Array) + "(#{number_for_point(value[0])},#{number_for_point(value[1])})" + else + super + end + end + + private + + def number_for_point(number) + number.to_s.gsub(/\.0$/, '') + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/range.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/range.rb new file mode 100644 index 0000000..961e622 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/range.rb @@ -0,0 +1,79 @@ +require 'active_support/core_ext/string/filters' + +module ActiveRecord + module ConnectionAdapters + module PostgreSQL + module OID # :nodoc: + class Range < Type::Value # :nodoc: + attr_reader :subtype, :type + + def initialize(subtype, type) + @subtype = subtype + @type = type + end + + def type_cast_for_schema(value) + value.inspect.gsub('Infinity', '::Float::INFINITY') + end + + def cast_value(value) + return if value == 'empty' + return value if value.is_a?(::Range) + + extracted = extract_bounds(value) + from = type_cast_single extracted[:from] + to = type_cast_single extracted[:to] + + if !infinity?(from) && extracted[:exclude_start] + if from.respond_to?(:succ) + from = from.succ + ActiveSupport::Deprecation.warn(<<-MSG.squish) + Excluding the beginning of a Range is only partialy supported + through `#succ`. This is not reliable and will be removed in + the future. + MSG + else + raise ArgumentError, "The Ruby Range object does not support excluding the beginning of a Range. (unsupported value: '#{value}')" + end + end + ::Range.new(from, to, extracted[:exclude_end]) + end + + def type_cast_for_database(value) + if value.is_a?(::Range) + from = type_cast_single_for_database(value.begin) + to = type_cast_single_for_database(value.end) + "[#{from},#{to}#{value.exclude_end? ? ')' : ']'}" + else + super + end + end + + private + + def type_cast_single(value) + infinity?(value) ? value : @subtype.type_cast_from_database(value) + end + + def type_cast_single_for_database(value) + infinity?(value) ? '' : @subtype.type_cast_for_database(value) + end + + def extract_bounds(value) + from, to = value[1..-2].split(',') + { + from: (value[1] == ',' || from == '-infinity') ? @subtype.infinity(negative: true) : from, + to: (value[-2] == ',' || to == 'infinity') ? @subtype.infinity : to, + exclude_start: (value[0] == '('), + exclude_end: (value[-1] == ')') + } + end + + def infinity?(value) + value.respond_to?(:infinite?) && value.infinite? + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb new file mode 100644 index 0000000..b2a42e9 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb @@ -0,0 +1,19 @@ +module ActiveRecord + module ConnectionAdapters + module PostgreSQL + module OID # :nodoc: + class SpecializedString < Type::String # :nodoc: + attr_reader :type + + def initialize(type) + @type = type + end + + def text? + false + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/time.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/time.rb new file mode 100644 index 0000000..8f0246e --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/time.rb @@ -0,0 +1,11 @@ +module ActiveRecord + module ConnectionAdapters + module PostgreSQL + module OID # :nodoc: + class Time < Type::Time # :nodoc: + include Infinity + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb new file mode 100644 index 0000000..6155e53 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb @@ -0,0 +1,109 @@ +module ActiveRecord + module ConnectionAdapters + module PostgreSQL + module OID # :nodoc: + # This class uses the data from PostgreSQL pg_type table to build + # the OID -> Type mapping. + # - OID is an integer representing the type. + # - Type is an OID::Type object. + # This class has side effects on the +store+ passed during initialization. + class TypeMapInitializer # :nodoc: + def initialize(store) + @store = store + end + + def run(records) + nodes = records.reject { |row| @store.key? row['oid'].to_i } + mapped, nodes = nodes.partition { |row| @store.key? row['typname'] } + ranges, nodes = nodes.partition { |row| row['typtype'] == 'r'.freeze } + enums, nodes = nodes.partition { |row| row['typtype'] == 'e'.freeze } + domains, nodes = nodes.partition { |row| row['typtype'] == 'd'.freeze } + arrays, nodes = nodes.partition { |row| row['typinput'] == 'array_in'.freeze } + composites, nodes = nodes.partition { |row| row['typelem'].to_i != 0 } + + mapped.each { |row| register_mapped_type(row) } + enums.each { |row| register_enum_type(row) } + domains.each { |row| register_domain_type(row) } + arrays.each { |row| register_array_type(row) } + ranges.each { |row| register_range_type(row) } + composites.each { |row| register_composite_type(row) } + end + + def query_conditions_for_initial_load(type_map) + known_type_names = type_map.keys.map { |n| "'#{n}'" } + known_type_types = %w('r' 'e' 'd') + <<-SQL % [known_type_names.join(", "), known_type_types.join(", ")] + WHERE + t.typname IN (%s) + OR t.typtype IN (%s) + OR t.typinput = 'array_in(cstring,oid,integer)'::regprocedure + OR t.typelem != 0 + SQL + end + + private + def register_mapped_type(row) + alias_type row['oid'], row['typname'] + end + + def register_enum_type(row) + register row['oid'], OID::Enum.new + end + + def register_array_type(row) + register_with_subtype(row['oid'], row['typelem'].to_i) do |subtype| + OID::Array.new(subtype, row['typdelim']) + end + end + + def register_range_type(row) + register_with_subtype(row['oid'], row['rngsubtype'].to_i) do |subtype| + OID::Range.new(subtype, row['typname'].to_sym) + end + end + + def register_domain_type(row) + if base_type = @store.lookup(row["typbasetype"].to_i) + register row['oid'], base_type + else + warn "unknown base type (OID: #{row["typbasetype"]}) for domain #{row["typname"]}." + end + end + + def register_composite_type(row) + if subtype = @store.lookup(row['typelem'].to_i) + register row['oid'], OID::Vector.new(row['typdelim'], subtype) + end + end + + def register(oid, oid_type = nil, &block) + oid = assert_valid_registration(oid, oid_type || block) + if block_given? + @store.register_type(oid, &block) + else + @store.register_type(oid, oid_type) + end + end + + def alias_type(oid, target) + oid = assert_valid_registration(oid, target) + @store.alias_type(oid, target) + end + + def register_with_subtype(oid, target_oid) + if @store.key?(target_oid) + register(oid) do |_, *args| + yield @store.lookup(target_oid, *args) + end + end + end + + def assert_valid_registration(oid, oid_type) + raise ArgumentError, "can't register nil type for OID #{oid}" if oid_type.nil? + oid.to_i + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/uuid.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/uuid.rb new file mode 100644 index 0000000..97b4fd3 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/uuid.rb @@ -0,0 +1,21 @@ +module ActiveRecord + module ConnectionAdapters + module PostgreSQL + module OID # :nodoc: + class Uuid < Type::Value # :nodoc: + ACCEPTABLE_UUID = %r{\A\{?([a-fA-F0-9]{4}-?){8}\}?\z}x + + alias_method :type_cast_for_database, :type_cast_from_database + + def type + :uuid + end + + def type_cast(value) + value.to_s[ACCEPTABLE_UUID, 0] + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/vector.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/vector.rb new file mode 100644 index 0000000..de4187b --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/vector.rb @@ -0,0 +1,26 @@ +module ActiveRecord + module ConnectionAdapters + module PostgreSQL + module OID # :nodoc: + class Vector < Type::Value # :nodoc: + attr_reader :delim, :subtype + + # +delim+ corresponds to the `typdelim` column in the pg_types + # table. +subtype+ is derived from the `typelem` column in the + # pg_types table. + def initialize(delim, subtype) + @delim = delim + @subtype = subtype + end + + # FIXME: this should probably split on +delim+ and use +subtype+ + # to cast the values. Unfortunately, the current Rails behavior + # is to just return the string. + def type_cast(value) + value + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/xml.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/xml.rb new file mode 100644 index 0000000..334af7c --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/oid/xml.rb @@ -0,0 +1,28 @@ +module ActiveRecord + module ConnectionAdapters + module PostgreSQL + module OID # :nodoc: + class Xml < Type::String # :nodoc: + def type + :xml + end + + def type_cast_for_database(value) + return unless value + Data.new(super) + end + + class Data # :nodoc: + def initialize(value) + @value = value + end + + def to_s + @value + end + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/quoting.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/quoting.rb new file mode 100644 index 0000000..991c413 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/quoting.rb @@ -0,0 +1,108 @@ +module ActiveRecord + module ConnectionAdapters + module PostgreSQL + module Quoting + # Escapes binary strings for bytea input to the database. + def escape_bytea(value) + @connection.escape_bytea(value) if value + end + + # Unescapes bytea output from a database to the binary string it represents. + # NOTE: This is NOT an inverse of escape_bytea! This is only to be used + # on escaped binary output from database drive. + def unescape_bytea(value) + @connection.unescape_bytea(value) if value + end + + # Quotes strings for use in SQL input. + def quote_string(s) #:nodoc: + @connection.escape(s) + end + + # Checks the following cases: + # + # - table_name + # - "table.name" + # - schema_name.table_name + # - schema_name."table.name" + # - "schema.name".table_name + # - "schema.name"."table.name" + def quote_table_name(name) + Utils.extract_schema_qualified_name(name.to_s).quoted + end + + def quote_table_name_for_assignment(table, attr) + quote_column_name(attr) + end + + # Quotes column names for use in SQL queries. + def quote_column_name(name) #:nodoc: + PGconn.quote_ident(name.to_s) + end + + # Quote date/time values for use in SQL input. Includes microseconds + # if the value is a Time responding to usec. + def quoted_date(value) #:nodoc: + result = super + if value.acts_like?(:time) && value.respond_to?(:usec) + result = "#{result}.#{sprintf("%06d", value.usec)}" + end + + if value.year <= 0 + bce_year = format("%04d", -value.year + 1) + result = result.sub(/^-?\d+/, bce_year) + " BC" + end + result + end + + # Does not quote function default values for UUID columns + def quote_default_value(value, column) #:nodoc: + if column.type == :uuid && value =~ /\(\)/ + value + else + quote(value, column) + end + end + + private + + def _quote(value) + case value + when Type::Binary::Data + "'#{escape_bytea(value.to_s)}'" + when OID::Xml::Data + "xml '#{quote_string(value.to_s)}'" + when OID::Bit::Data + if value.binary? + "B'#{value}'" + elsif value.hex? + "X'#{value}'" + end + when Float + if value.infinite? || value.nan? + "'#{value}'" + else + super + end + else + super + end + end + + def _type_cast(value) + case value + when Type::Binary::Data + # Return a bind param hash with format as binary. + # See http://deveiate.org/code/pg/PGconn.html#method-i-exec_prepared-doc + # for more information + { value: value.to_s, format: 1 } + when OID::Xml::Data, OID::Bit::Data + value.to_s + else + super + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/referential_integrity.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/referential_integrity.rb new file mode 100644 index 0000000..52b307c --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/referential_integrity.rb @@ -0,0 +1,30 @@ +module ActiveRecord + module ConnectionAdapters + module PostgreSQL + module ReferentialIntegrity # :nodoc: + def supports_disable_referential_integrity? # :nodoc: + true + end + + def disable_referential_integrity # :nodoc: + if supports_disable_referential_integrity? + begin + execute(tables.collect { |name| "ALTER TABLE #{quote_table_name(name)} DISABLE TRIGGER ALL" }.join(";")) + rescue + execute(tables.collect { |name| "ALTER TABLE #{quote_table_name(name)} DISABLE TRIGGER USER" }.join(";")) + end + end + yield + ensure + if supports_disable_referential_integrity? + begin + execute(tables.collect { |name| "ALTER TABLE #{quote_table_name(name)} ENABLE TRIGGER ALL" }.join(";")) + rescue + execute(tables.collect { |name| "ALTER TABLE #{quote_table_name(name)} ENABLE TRIGGER USER" }.join(";")) + end + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/schema_definitions.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/schema_definitions.rb new file mode 100644 index 0000000..42e99bd --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/schema_definitions.rb @@ -0,0 +1,152 @@ +module ActiveRecord + module ConnectionAdapters + module PostgreSQL + module ColumnMethods + def xml(*args) + options = args.extract_options! + column(args[0], :xml, options) + end + + def tsvector(*args) + options = args.extract_options! + column(args[0], :tsvector, options) + end + + def int4range(name, options = {}) + column(name, :int4range, options) + end + + def int8range(name, options = {}) + column(name, :int8range, options) + end + + def tsrange(name, options = {}) + column(name, :tsrange, options) + end + + def tstzrange(name, options = {}) + column(name, :tstzrange, options) + end + + def numrange(name, options = {}) + column(name, :numrange, options) + end + + def daterange(name, options = {}) + column(name, :daterange, options) + end + + def hstore(name, options = {}) + column(name, :hstore, options) + end + + def ltree(name, options = {}) + column(name, :ltree, options) + end + + def inet(name, options = {}) + column(name, :inet, options) + end + + def cidr(name, options = {}) + column(name, :cidr, options) + end + + def macaddr(name, options = {}) + column(name, :macaddr, options) + end + + def uuid(name, options = {}) + column(name, :uuid, options) + end + + def json(name, options = {}) + column(name, :json, options) + end + + def jsonb(name, options = {}) + column(name, :jsonb, options) + end + + def citext(name, options = {}) + column(name, :citext, options) + end + + def point(name, options = {}) + column(name, :point, options) + end + + def bit(name, options = {}) + column(name, :bit, options) + end + + def bit_varying(name, options = {}) + column(name, :bit_varying, options) + end + + def money(name, options = {}) + column(name, :money, options) + end + end + + class ColumnDefinition < ActiveRecord::ConnectionAdapters::ColumnDefinition + attr_accessor :array + end + + class TableDefinition < ActiveRecord::ConnectionAdapters::TableDefinition + include ColumnMethods + + # Defines the primary key field. + # Use of the native PostgreSQL UUID type is supported, and can be used + # by defining your tables as such: + # + # create_table :stuffs, id: :uuid do |t| + # t.string :content + # t.timestamps + # end + # + # By default, this will use the +uuid_generate_v4()+ function from the + # +uuid-ossp+ extension, which MUST be enabled on your database. To enable + # the +uuid-ossp+ extension, you can use the +enable_extension+ method in your + # migrations. To use a UUID primary key without +uuid-ossp+ enabled, you can + # set the +:default+ option to +nil+: + # + # create_table :stuffs, id: false do |t| + # t.primary_key :id, :uuid, default: nil + # t.uuid :foo_id + # t.timestamps + # end + # + # You may also pass a different UUID generation function from +uuid-ossp+ + # or another library. + # + # Note that setting the UUID primary key default value to +nil+ will + # require you to assure that you always provide a UUID value before saving + # a record (as primary keys cannot be +nil+). This might be done via the + # +SecureRandom.uuid+ method and a +before_save+ callback, for instance. + def primary_key(name, type = :primary_key, options = {}) + return super unless type == :uuid + options[:default] = options.fetch(:default, 'uuid_generate_v4()') + options[:primary_key] = true + column name, type, options + end + + def new_column_definition(name, type, options) # :nodoc: + column = super + column.array = options[:array] + column + end + + private + + def create_column_definition(name, type) + PostgreSQL::ColumnDefinition.new name, type + end + end + + class Table < ActiveRecord::ConnectionAdapters::Table + include ColumnMethods + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/schema_statements.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/schema_statements.rb new file mode 100644 index 0000000..2f92926 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/schema_statements.rb @@ -0,0 +1,596 @@ +module ActiveRecord + module ConnectionAdapters + module PostgreSQL + class SchemaCreation < AbstractAdapter::SchemaCreation + private + + def visit_ColumnDefinition(o) + sql = super + if o.primary_key? && o.type != :primary_key + sql << " PRIMARY KEY " + add_column_options!(sql, column_options(o)) + end + sql + end + + def add_column_options!(sql, options) + if options[:array] || options[:column].try(:array) + sql << '[]' + end + + column = options.fetch(:column) { return super } + if column.type == :uuid && options[:default] =~ /\(\)/ + sql << " DEFAULT #{options[:default]}" + else + super + end + end + + def type_for_column(column) + if column.array + @conn.lookup_cast_type("#{column.sql_type}[]") + else + super + end + end + end + + module SchemaStatements + # Drops the database specified on the +name+ attribute + # and creates it again using the provided +options+. + def recreate_database(name, options = {}) #:nodoc: + drop_database(name) + create_database(name, options) + end + + # Create a new PostgreSQL database. Options include :owner, :template, + # :encoding (defaults to utf8), :collation, :ctype, + # :tablespace, and :connection_limit (note that MySQL uses + # :charset while PostgreSQL uses :encoding). + # + # Example: + # create_database config[:database], config + # create_database 'foo_development', encoding: 'unicode' + def create_database(name, options = {}) + options = { encoding: 'utf8' }.merge!(options.symbolize_keys) + + option_string = options.inject("") do |memo, (key, value)| + memo += case key + when :owner + " OWNER = \"#{value}\"" + when :template + " TEMPLATE = \"#{value}\"" + when :encoding + " ENCODING = '#{value}'" + when :collation + " LC_COLLATE = '#{value}'" + when :ctype + " LC_CTYPE = '#{value}'" + when :tablespace + " TABLESPACE = \"#{value}\"" + when :connection_limit + " CONNECTION LIMIT = #{value}" + else + "" + end + end + + execute "CREATE DATABASE #{quote_table_name(name)}#{option_string}" + end + + # Drops a PostgreSQL database. + # + # Example: + # drop_database 'matt_development' + def drop_database(name) #:nodoc: + execute "DROP DATABASE IF EXISTS #{quote_table_name(name)}" + end + + # Returns the list of all tables in the schema search path. + def tables(name = nil) + query(<<-SQL, 'SCHEMA').map { |row| row[0] } + SELECT tablename + FROM pg_tables + WHERE schemaname = ANY (current_schemas(false)) + SQL + end + + def data_sources # :nodoc + select_values(<<-SQL, 'SCHEMA') + SELECT c.relname + FROM pg_class c + LEFT JOIN pg_namespace n ON n.oid = c.relnamespace + WHERE c.relkind IN ('r', 'v','m') -- (r)elation/table, (v)iew, (m)aterialized view + AND n.nspname = ANY (current_schemas(false)) + SQL + end + + # Returns true if table exists. + # If the schema is not specified as part of +name+ then it will only find tables within + # the current schema search path (regardless of permissions to access tables in other schemas) + def table_exists?(name) + name = Utils.extract_schema_qualified_name(name.to_s) + return false unless name.identifier + + exec_query(<<-SQL, 'SCHEMA').rows.first[0].to_i > 0 + SELECT COUNT(*) + FROM pg_class c + LEFT JOIN pg_namespace n ON n.oid = c.relnamespace + WHERE c.relkind IN ('r','v','m') -- (r)elation/table, (v)iew, (m)aterialized view + AND c.relname = '#{name.identifier}' + AND n.nspname = #{name.schema ? "'#{name.schema}'" : 'ANY (current_schemas(false))'} + SQL + end + alias data_source_exists? table_exists? + + def drop_table(table_name, options = {}) + execute "DROP TABLE #{quote_table_name(table_name)}#{' CASCADE' if options[:force] == :cascade}" + end + + # Returns true if schema exists. + def schema_exists?(name) + exec_query(<<-SQL, 'SCHEMA').rows.first[0].to_i > 0 + SELECT COUNT(*) + FROM pg_namespace + WHERE nspname = '#{name}' + SQL + end + + def index_name_exists?(table_name, index_name, default) + exec_query(<<-SQL, 'SCHEMA').rows.first[0].to_i > 0 + SELECT COUNT(*) + FROM pg_class t + INNER JOIN pg_index d ON t.oid = d.indrelid + INNER JOIN pg_class i ON d.indexrelid = i.oid + WHERE i.relkind = 'i' + AND i.relname = '#{index_name}' + AND t.relname = '#{table_name}' + AND i.relnamespace IN (SELECT oid FROM pg_namespace WHERE nspname = ANY (current_schemas(false)) ) + SQL + end + + # Returns an array of indexes for the given table. + def indexes(table_name, name = nil) + result = query(<<-SQL, 'SCHEMA') + SELECT distinct i.relname, d.indisunique, d.indkey, pg_get_indexdef(d.indexrelid), t.oid + FROM pg_class t + INNER JOIN pg_index d ON t.oid = d.indrelid + INNER JOIN pg_class i ON d.indexrelid = i.oid + WHERE i.relkind = 'i' + AND d.indisprimary = 'f' + AND t.relname = '#{table_name}' + AND i.relnamespace IN (SELECT oid FROM pg_namespace WHERE nspname = ANY (current_schemas(false)) ) + ORDER BY i.relname + SQL + + result.map do |row| + index_name = row[0] + unique = row[1] == 't' + indkey = row[2].split(" ") + inddef = row[3] + oid = row[4] + + columns = Hash[query(<<-SQL, "SCHEMA")] + SELECT a.attnum, a.attname + FROM pg_attribute a + WHERE a.attrelid = #{oid} + AND a.attnum IN (#{indkey.join(",")}) + SQL + + column_names = columns.values_at(*indkey).compact + + unless column_names.empty? + # add info on sort order for columns (only desc order is explicitly specified, asc is the default) + desc_order_columns = inddef.scan(/(\w+) DESC/).flatten + orders = desc_order_columns.any? ? Hash[desc_order_columns.map {|order_column| [order_column, :desc]}] : {} + where = inddef.scan(/WHERE (.+)$/).flatten[0] + using = inddef.scan(/USING (.+?) /).flatten[0].to_sym + + IndexDefinition.new(table_name, index_name, unique, column_names, [], orders, where, nil, using) + end + end.compact + end + + # Returns the list of all column definitions for a table. + def columns(table_name) + # Limit, precision, and scale are all handled by the superclass. + column_definitions(table_name).map do |column_name, type, default, notnull, oid, fmod| + oid = get_oid_type(oid.to_i, fmod.to_i, column_name, type) + default_value = extract_value_from_default(oid, default) + default_function = extract_default_function(default_value, default) + new_column(column_name, default_value, oid, type, notnull == 'f', default_function) + end + end + + def new_column(name, default, cast_type, sql_type = nil, null = true, default_function = nil) # :nodoc: + PostgreSQLColumn.new(name, default, cast_type, sql_type, null, default_function) + end + + # Returns the current database name. + def current_database + query('select current_database()', 'SCHEMA')[0][0] + end + + # Returns the current schema name. + def current_schema + query('SELECT current_schema', 'SCHEMA')[0][0] + end + + # Returns the current database encoding format. + def encoding + query(<<-end_sql, 'SCHEMA')[0][0] + SELECT pg_encoding_to_char(pg_database.encoding) FROM pg_database + WHERE pg_database.datname LIKE '#{current_database}' + end_sql + end + + # Returns the current database collation. + def collation + query(<<-end_sql, 'SCHEMA')[0][0] + SELECT pg_database.datcollate FROM pg_database WHERE pg_database.datname LIKE '#{current_database}' + end_sql + end + + # Returns the current database ctype. + def ctype + query(<<-end_sql, 'SCHEMA')[0][0] + SELECT pg_database.datctype FROM pg_database WHERE pg_database.datname LIKE '#{current_database}' + end_sql + end + + # Returns an array of schema names. + def schema_names + query(<<-SQL, 'SCHEMA').flatten + SELECT nspname + FROM pg_namespace + WHERE nspname !~ '^pg_.*' + AND nspname NOT IN ('information_schema') + ORDER by nspname; + SQL + end + + # Creates a schema for the given schema name. + def create_schema schema_name + execute "CREATE SCHEMA #{schema_name}" + end + + # Drops the schema for the given schema name. + def drop_schema schema_name + execute "DROP SCHEMA #{schema_name} CASCADE" + end + + # Sets the schema search path to a string of comma-separated schema names. + # Names beginning with $ have to be quoted (e.g. $user => '$user'). + # See: http://www.postgresql.org/docs/current/static/ddl-schemas.html + # + # This should be not be called manually but set in database.yml. + def schema_search_path=(schema_csv) + if schema_csv + execute("SET search_path TO #{schema_csv}", 'SCHEMA') + @schema_search_path = schema_csv + end + end + + # Returns the active schema search path. + def schema_search_path + @schema_search_path ||= query('SHOW search_path', 'SCHEMA')[0][0] + end + + # Returns the current client message level. + def client_min_messages + query('SHOW client_min_messages', 'SCHEMA')[0][0] + end + + # Set the client message level. + def client_min_messages=(level) + execute("SET client_min_messages TO '#{level}'", 'SCHEMA') + end + + # Returns the sequence name for a table's primary key or some other specified key. + def default_sequence_name(table_name, pk = nil) #:nodoc: + result = serial_sequence(table_name, pk || 'id') + return nil unless result + Utils.extract_schema_qualified_name(result).to_s + rescue ActiveRecord::StatementInvalid + PostgreSQL::Name.new(nil, "#{table_name}_#{pk || 'id'}_seq").to_s + end + + def serial_sequence(table, column) + result = exec_query(<<-eosql, 'SCHEMA') + SELECT pg_get_serial_sequence('#{table}', '#{column}') + eosql + result.rows.first.first + end + + # Sets the sequence of a table's primary key to the specified value. + def set_pk_sequence!(table, value) #:nodoc: + pk, sequence = pk_and_sequence_for(table) + + if pk + if sequence + quoted_sequence = quote_table_name(sequence) + + select_value <<-end_sql, 'SCHEMA' + SELECT setval('#{quoted_sequence}', #{value}) + end_sql + else + @logger.warn "#{table} has primary key #{pk} with no default sequence" if @logger + end + end + end + + # Resets the sequence of a table's primary key to the maximum value. + def reset_pk_sequence!(table, pk = nil, sequence = nil) #:nodoc: + unless pk and sequence + default_pk, default_sequence = pk_and_sequence_for(table) + + pk ||= default_pk + sequence ||= default_sequence + end + + if @logger && pk && !sequence + @logger.warn "#{table} has primary key #{pk} with no default sequence" + end + + if pk && sequence + quoted_sequence = quote_table_name(sequence) + + select_value <<-end_sql, 'SCHEMA' + SELECT setval('#{quoted_sequence}', (SELECT COALESCE(MAX(#{quote_column_name pk})+(SELECT increment_by FROM #{quoted_sequence}), (SELECT min_value FROM #{quoted_sequence})) FROM #{quote_table_name(table)}), false) + end_sql + end + end + + # Returns a table's primary key and belonging sequence. + def pk_and_sequence_for(table) #:nodoc: + # First try looking for a sequence with a dependency on the + # given table's primary key. + result = query(<<-end_sql, 'SCHEMA')[0] + SELECT attr.attname, nsp.nspname, seq.relname + FROM pg_class seq, + pg_attribute attr, + pg_depend dep, + pg_constraint cons, + pg_namespace nsp + WHERE seq.oid = dep.objid + AND seq.relkind = 'S' + AND attr.attrelid = dep.refobjid + AND attr.attnum = dep.refobjsubid + AND attr.attrelid = cons.conrelid + AND attr.attnum = cons.conkey[1] + AND seq.relnamespace = nsp.oid + AND cons.contype = 'p' + AND dep.classid = 'pg_class'::regclass + AND dep.refobjid = '#{quote_table_name(table)}'::regclass + end_sql + + if result.nil? or result.empty? + result = query(<<-end_sql, 'SCHEMA')[0] + SELECT attr.attname, nsp.nspname, + CASE + WHEN pg_get_expr(def.adbin, def.adrelid) !~* 'nextval' THEN NULL + WHEN split_part(pg_get_expr(def.adbin, def.adrelid), '''', 2) ~ '.' THEN + substr(split_part(pg_get_expr(def.adbin, def.adrelid), '''', 2), + strpos(split_part(pg_get_expr(def.adbin, def.adrelid), '''', 2), '.')+1) + ELSE split_part(pg_get_expr(def.adbin, def.adrelid), '''', 2) + END + FROM pg_class t + JOIN pg_attribute attr ON (t.oid = attrelid) + JOIN pg_attrdef def ON (adrelid = attrelid AND adnum = attnum) + JOIN pg_constraint cons ON (conrelid = adrelid AND adnum = conkey[1]) + JOIN pg_namespace nsp ON (t.relnamespace = nsp.oid) + WHERE t.oid = '#{quote_table_name(table)}'::regclass + AND cons.contype = 'p' + AND pg_get_expr(def.adbin, def.adrelid) ~* 'nextval|uuid_generate' + end_sql + end + + pk = result.shift + if result.last + [pk, PostgreSQL::Name.new(*result)] + else + [pk, nil] + end + rescue + nil + end + + # Returns just a table's primary key + def primary_key(table) + pks = exec_query(<<-end_sql, 'SCHEMA').rows + SELECT attr.attname + FROM pg_attribute attr + INNER JOIN pg_constraint cons ON attr.attrelid = cons.conrelid AND attr.attnum = any(cons.conkey) + WHERE cons.contype = 'p' + AND cons.conrelid = '#{quote_table_name(table)}'::regclass + end_sql + return nil unless pks.count == 1 + pks[0][0] + end + + # Renames a table. + # Also renames a table's primary key sequence if the sequence name exists and + # matches the Active Record default. + # + # Example: + # rename_table('octopuses', 'octopi') + def rename_table(table_name, new_name) + clear_cache! + execute "ALTER TABLE #{quote_table_name(table_name)} RENAME TO #{quote_table_name(new_name)}" + pk, seq = pk_and_sequence_for(new_name) + if seq && seq.identifier == "#{table_name}_#{pk}_seq" + new_seq = "#{new_name}_#{pk}_seq" + idx = "#{table_name}_pkey" + new_idx = "#{new_name}_pkey" + execute "ALTER TABLE #{quote_table_name(seq)} RENAME TO #{quote_table_name(new_seq)}" + execute "ALTER INDEX #{quote_table_name(idx)} RENAME TO #{quote_table_name(new_idx)}" + end + + rename_table_indexes(table_name, new_name) + end + + def add_column(table_name, column_name, type, options = {}) #:nodoc: + clear_cache! + super + end + + # Changes the column of a table. + def change_column(table_name, column_name, type, options = {}) + clear_cache! + quoted_table_name = quote_table_name(table_name) + sql_type = type_to_sql(type, options[:limit], options[:precision], options[:scale]) + sql_type << "[]" if options[:array] + sql = "ALTER TABLE #{quoted_table_name} ALTER COLUMN #{quote_column_name(column_name)} TYPE #{sql_type}" + sql << " USING #{options[:using]}" if options[:using] + if options[:cast_as] + sql << " USING CAST(#{quote_column_name(column_name)} AS #{type_to_sql(options[:cast_as], options[:limit], options[:precision], options[:scale])})" + end + execute sql + + change_column_default(table_name, column_name, options[:default]) if options_include_default?(options) + change_column_null(table_name, column_name, options[:null], options[:default]) if options.key?(:null) + end + + # Changes the default value of a table column. + def change_column_default(table_name, column_name, default) + clear_cache! + column = column_for(table_name, column_name) + return unless column + + alter_column_query = "ALTER TABLE #{quote_table_name(table_name)} ALTER COLUMN #{quote_column_name(column_name)} %s" + if default.nil? + # DEFAULT NULL results in the same behavior as DROP DEFAULT. However, PostgreSQL will + # cast the default to the columns type, which leaves us with a default like "default NULL::character varying". + execute alter_column_query % "DROP DEFAULT" + else + execute alter_column_query % "SET DEFAULT #{quote_default_value(default, column)}" + end + end + + def change_column_null(table_name, column_name, null, default = nil) + clear_cache! + unless null || default.nil? + column = column_for(table_name, column_name) + execute("UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote_default_value(default, column)} WHERE #{quote_column_name(column_name)} IS NULL") if column + end + execute("ALTER TABLE #{quote_table_name(table_name)} ALTER #{quote_column_name(column_name)} #{null ? 'DROP' : 'SET'} NOT NULL") + end + + # Renames a column in a table. + def rename_column(table_name, column_name, new_column_name) #:nodoc: + clear_cache! + execute "ALTER TABLE #{quote_table_name(table_name)} RENAME COLUMN #{quote_column_name(column_name)} TO #{quote_column_name(new_column_name)}" + rename_column_indexes(table_name, column_name, new_column_name) + end + + def add_index(table_name, column_name, options = {}) #:nodoc: + index_name, index_type, index_columns, index_options, index_algorithm, index_using = add_index_options(table_name, column_name, options) + execute "CREATE #{index_type} INDEX #{index_algorithm} #{quote_column_name(index_name)} ON #{quote_table_name(table_name)} #{index_using} (#{index_columns})#{index_options}" + end + + def remove_index!(table_name, index_name) #:nodoc: + execute "DROP INDEX #{quote_table_name(index_name)}" + end + + def rename_index(table_name, old_name, new_name) + validate_index_length!(table_name, new_name) + + execute "ALTER INDEX #{quote_column_name(old_name)} RENAME TO #{quote_table_name(new_name)}" + end + + def foreign_keys(table_name) + fk_info = select_all <<-SQL.strip_heredoc + SELECT t2.oid::regclass::text AS to_table, a1.attname AS column, a2.attname AS primary_key, c.conname AS name, c.confupdtype AS on_update, c.confdeltype AS on_delete + FROM pg_constraint c + JOIN pg_class t1 ON c.conrelid = t1.oid + JOIN pg_class t2 ON c.confrelid = t2.oid + JOIN pg_attribute a1 ON a1.attnum = c.conkey[1] AND a1.attrelid = t1.oid + JOIN pg_attribute a2 ON a2.attnum = c.confkey[1] AND a2.attrelid = t2.oid + JOIN pg_namespace t3 ON c.connamespace = t3.oid + WHERE c.contype = 'f' + AND t1.relname = #{quote(table_name)} + AND t3.nspname = ANY (current_schemas(false)) + ORDER BY c.conname + SQL + + fk_info.map do |row| + options = { + column: row['column'], + name: row['name'], + primary_key: row['primary_key'] + } + + options[:on_delete] = extract_foreign_key_action(row['on_delete']) + options[:on_update] = extract_foreign_key_action(row['on_update']) + + ForeignKeyDefinition.new(table_name, row['to_table'], options) + end + end + + def extract_foreign_key_action(specifier) # :nodoc: + case specifier + when 'c'; :cascade + when 'n'; :nullify + when 'r'; :restrict + end + end + + def index_name_length + 63 + end + + # Maps logical Rails types to PostgreSQL-specific data types. + def type_to_sql(type, limit = nil, precision = nil, scale = nil) + case type.to_s + when 'binary' + # PostgreSQL doesn't support limits on binary (bytea) columns. + # The hard limit is 1Gb, because of a 32-bit size field, and TOAST. + case limit + when nil, 0..0x3fffffff; super(type) + else raise(ActiveRecordError, "No binary type has byte size #{limit}.") + end + when 'text' + # PostgreSQL doesn't support limits on text columns. + # The hard limit is 1Gb, according to section 8.3 in the manual. + case limit + when nil, 0..0x3fffffff; super(type) + else raise(ActiveRecordError, "The limit on text can be at most 1GB - 1byte.") + end + when 'integer' + return 'integer' unless limit + + case limit + when 1, 2; 'smallint' + when 3, 4; 'integer' + when 5..8; 'bigint' + else raise(ActiveRecordError, "No integer type has byte size #{limit}. Use a numeric with precision 0 instead.") + end + when 'datetime' + return super unless precision + + case precision + when 0..6; "timestamp(#{precision})" + else raise(ActiveRecordError, "No timestamp type has precision of #{precision}. The allowed range of precision is from 0 to 6") + end + else + super + end + end + + # PostgreSQL requires the ORDER BY columns in the select list for distinct queries, and + # requires that the ORDER BY include the distinct column. + def columns_for_distinct(columns, orders) #:nodoc: + order_columns = orders.reject(&:blank?).map{ |s| + # Convert Arel node to string + s = s.to_sql unless s.is_a?(String) + # Remove any ASC/DESC modifiers + s.gsub(/\s+(?:ASC|DESC)\b/i, '') + .gsub(/\s+NULLS\s+(?:FIRST|LAST)\b/i, '') + }.reject(&:blank?).map.with_index { |column, i| "#{column} AS alias_#{i}" } + + [super, *order_columns].join(', ') + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/utils.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/utils.rb new file mode 100644 index 0000000..9a0b80d --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql/utils.rb @@ -0,0 +1,77 @@ +module ActiveRecord + module ConnectionAdapters + module PostgreSQL + # Value Object to hold a schema qualified name. + # This is usually the name of a PostgreSQL relation but it can also represent + # schema qualified type names. +schema+ and +identifier+ are unquoted to prevent + # double quoting. + class Name # :nodoc: + SEPARATOR = "." + attr_reader :schema, :identifier + + def initialize(schema, identifier) + @schema, @identifier = unquote(schema), unquote(identifier) + end + + def to_s + parts.join SEPARATOR + end + + def quoted + if schema + PGconn.quote_ident(schema) << SEPARATOR << PGconn.quote_ident(identifier) + else + PGconn.quote_ident(identifier) + end + end + + def ==(o) + o.class == self.class && o.parts == parts + end + alias_method :eql?, :== + + def hash + parts.hash + end + + protected + def unquote(part) + if part && part.start_with?('"') + part[1..-2] + else + part + end + end + + def parts + @parts ||= [@schema, @identifier].compact + end + end + + module Utils # :nodoc: + extend self + + # Returns an instance of ActiveRecord::ConnectionAdapters::PostgreSQL::Name + # extracted from +string+. + # +schema+ is nil if not specified in +string+. + # +schema+ and +identifier+ exclude surrounding quotes (regardless of whether provided in +string+) + # +string+ supports the range of schema/table references understood by PostgreSQL, for example: + # + # * table_name + # * "table.name" + # * schema_name.table_name + # * schema_name."table.name" + # * "schema_name".table_name + # * "schema.name"."table name" + def extract_schema_qualified_name(string) + schema, table = string.scan(/[^".\s]+|"[^"]*"/) + if table.nil? + table = schema + schema = nil + end + PostgreSQL::Name.new(schema, table) + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql_adapter.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql_adapter.rb new file mode 100644 index 0000000..051cda6 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -0,0 +1,754 @@ +require 'active_record/connection_adapters/abstract_adapter' +require 'active_record/connection_adapters/statement_pool' + +require 'active_record/connection_adapters/postgresql/utils' +require 'active_record/connection_adapters/postgresql/column' +require 'active_record/connection_adapters/postgresql/oid' +require 'active_record/connection_adapters/postgresql/quoting' +require 'active_record/connection_adapters/postgresql/referential_integrity' +require 'active_record/connection_adapters/postgresql/schema_definitions' +require 'active_record/connection_adapters/postgresql/schema_statements' +require 'active_record/connection_adapters/postgresql/database_statements' + +require 'arel/visitors/bind_visitor' + +# Make sure we're using pg high enough for PGResult#values +gem 'pg', '~> 0.15' +require 'pg' + +require 'ipaddr' + +module ActiveRecord + module ConnectionHandling # :nodoc: + VALID_CONN_PARAMS = [:host, :hostaddr, :port, :dbname, :user, :password, :connect_timeout, + :client_encoding, :options, :application_name, :fallback_application_name, + :keepalives, :keepalives_idle, :keepalives_interval, :keepalives_count, + :tty, :sslmode, :requiressl, :sslcompression, :sslcert, :sslkey, + :sslrootcert, :sslcrl, :requirepeer, :krbsrvname, :gsslib, :service] + + # Establishes a connection to the database that's used by all Active Record objects + def postgresql_connection(config) + conn_params = config.symbolize_keys + + conn_params.delete_if { |_, v| v.nil? } + + # Map ActiveRecords param names to PGs. + conn_params[:user] = conn_params.delete(:username) if conn_params[:username] + conn_params[:dbname] = conn_params.delete(:database) if conn_params[:database] + + # Forward only valid config params to PGconn.connect. + conn_params.keep_if { |k, _| VALID_CONN_PARAMS.include?(k) } + + # The postgres drivers don't allow the creation of an unconnected PGconn object, + # so just pass a nil connection object for the time being. + ConnectionAdapters::PostgreSQLAdapter.new(nil, logger, conn_params, config) + end + end + + module ConnectionAdapters + # The PostgreSQL adapter works with the native C (https://bitbucket.org/ged/ruby-pg) driver. + # + # Options: + # + # * :host - Defaults to a Unix-domain socket in /tmp. On machines without Unix-domain sockets, + # the default is to connect to localhost. + # * :port - Defaults to 5432. + # * :username - Defaults to be the same as the operating system name of the user running the application. + # * :password - Password to be used if the server demands password authentication. + # * :database - Defaults to be the same as the user name. + # * :schema_search_path - An optional schema search path for the connection given + # as a string of comma-separated schema names. This is backward-compatible with the :schema_order option. + # * :encoding - An optional client encoding that is used in a SET client_encoding TO + # call on the connection. + # * :min_messages - An optional client min messages that is used in a + # SET client_min_messages TO call on the connection. + # * :variables - An optional hash of additional parameters that + # will be used in SET SESSION key = val calls on the connection. + # * :insert_returning - An optional boolean to control the use of RETURNING for INSERT statements + # defaults to true. + # + # Any further options are used as connection parameters to libpq. See + # http://www.postgresql.org/docs/9.1/static/libpq-connect.html for the + # list of parameters. + # + # In addition, default connection parameters of libpq can be set per environment variables. + # See http://www.postgresql.org/docs/9.1/static/libpq-envars.html . + class PostgreSQLAdapter < AbstractAdapter + ADAPTER_NAME = 'PostgreSQL'.freeze + + NATIVE_DATABASE_TYPES = { + primary_key: "serial primary key", + bigserial: "bigserial", + string: { name: "character varying" }, + text: { name: "text" }, + integer: { name: "integer" }, + float: { name: "float" }, + decimal: { name: "decimal" }, + datetime: { name: "timestamp" }, + time: { name: "time" }, + date: { name: "date" }, + daterange: { name: "daterange" }, + numrange: { name: "numrange" }, + tsrange: { name: "tsrange" }, + tstzrange: { name: "tstzrange" }, + int4range: { name: "int4range" }, + int8range: { name: "int8range" }, + binary: { name: "bytea" }, + boolean: { name: "boolean" }, + bigint: { name: "bigint" }, + xml: { name: "xml" }, + tsvector: { name: "tsvector" }, + hstore: { name: "hstore" }, + inet: { name: "inet" }, + cidr: { name: "cidr" }, + macaddr: { name: "macaddr" }, + uuid: { name: "uuid" }, + json: { name: "json" }, + jsonb: { name: "jsonb" }, + ltree: { name: "ltree" }, + citext: { name: "citext" }, + point: { name: "point" }, + bit: { name: "bit" }, + bit_varying: { name: "bit varying" }, + money: { name: "money" }, + } + + OID = PostgreSQL::OID #:nodoc: + + include PostgreSQL::Quoting + include PostgreSQL::ReferentialIntegrity + include PostgreSQL::SchemaStatements + include PostgreSQL::DatabaseStatements + include Savepoints + + def schema_creation # :nodoc: + PostgreSQL::SchemaCreation.new self + end + + # Adds +:array+ option to the default set provided by the + # AbstractAdapter + def prepare_column_options(column, types) # :nodoc: + spec = super + spec[:array] = 'true' if column.respond_to?(:array) && column.array + spec[:default] = "\"#{column.default_function}\"" if column.default_function + spec + end + + # Adds +:array+ as a valid migration key + def migration_keys + super + [:array] + end + + # Returns +true+, since this connection adapter supports prepared statement + # caching. + def supports_statement_cache? + true + end + + def supports_index_sort_order? + true + end + + def supports_partial_index? + true + end + + def supports_transaction_isolation? + true + end + + def supports_foreign_keys? + true + end + + def supports_views? + true + end + + def index_algorithms + { concurrently: 'CONCURRENTLY' } + end + + class StatementPool < ConnectionAdapters::StatementPool + def initialize(connection, max) + super + @counter = 0 + @cache = Hash.new { |h,pid| h[pid] = {} } + end + + def each(&block); cache.each(&block); end + def key?(key); cache.key?(key); end + def [](key); cache[key]; end + def length; cache.length; end + + def next_key + "a#{@counter + 1}" + end + + def []=(sql, key) + while @max <= cache.size + dealloc(cache.shift.last) + end + @counter += 1 + cache[sql] = key + end + + def clear + cache.each_value do |stmt_key| + dealloc stmt_key + end + cache.clear + end + + def delete(sql_key) + dealloc cache[sql_key] + cache.delete sql_key + end + + private + + def cache + @cache[Process.pid] + end + + def dealloc(key) + @connection.query "DEALLOCATE #{key}" if connection_active? + end + + def connection_active? + @connection.status == PGconn::CONNECTION_OK + rescue PGError + false + end + end + + # Initializes and connects a PostgreSQL adapter. + def initialize(connection, logger, connection_parameters, config) + super(connection, logger) + + @visitor = Arel::Visitors::PostgreSQL.new self + if self.class.type_cast_config_to_boolean(config.fetch(:prepared_statements) { true }) + @prepared_statements = true + else + @prepared_statements = false + end + + @connection_parameters, @config = connection_parameters, config + + # @local_tz is initialized as nil to avoid warnings when connect tries to use it + @local_tz = nil + @table_alias_length = nil + + connect + @statements = StatementPool.new @connection, + self.class.type_cast_config_to_integer(config.fetch(:statement_limit) { 1000 }) + + if postgresql_version < 80200 + raise "Your version of PostgreSQL (#{postgresql_version}) is too old, please upgrade!" + end + + @type_map = Type::HashLookupTypeMap.new + initialize_type_map(type_map) + @local_tz = execute('SHOW TIME ZONE', 'SCHEMA').first["TimeZone"] + @use_insert_returning = @config.key?(:insert_returning) ? self.class.type_cast_config_to_boolean(@config[:insert_returning]) : true + end + + # Clears the prepared statements cache. + def clear_cache! + @statements.clear + end + + def truncate(table_name, name = nil) + exec_query "TRUNCATE TABLE #{quote_table_name(table_name)}", name, [] + end + + # Is this connection alive and ready for queries? + def active? + @connection.query 'SELECT 1' + true + rescue PGError + false + end + + # Close then reopen the connection. + def reconnect! + super + @connection.reset + configure_connection + end + + def reset! + clear_cache! + reset_transaction + unless @connection.transaction_status == ::PG::PQTRANS_IDLE + @connection.query 'ROLLBACK' + end + @connection.query 'DISCARD ALL' + configure_connection + end + + # Disconnects from the database if already connected. Otherwise, this + # method does nothing. + def disconnect! + super + @connection.close rescue nil + end + + def native_database_types #:nodoc: + NATIVE_DATABASE_TYPES + end + + # Returns true, since this connection adapter supports migrations. + def supports_migrations? + true + end + + # Does PostgreSQL support finding primary key on non-Active Record tables? + def supports_primary_key? #:nodoc: + true + end + + def set_standard_conforming_strings + execute('SET standard_conforming_strings = on', 'SCHEMA') + end + + def supports_ddl_transactions? + true + end + + def supports_explain? + true + end + + # Returns true if pg > 9.1 + def supports_extensions? + postgresql_version >= 90100 + end + + # Range datatypes weren't introduced until PostgreSQL 9.2 + def supports_ranges? + postgresql_version >= 90200 + end + + def supports_materialized_views? + postgresql_version >= 90300 + end + + def enable_extension(name) + exec_query("CREATE EXTENSION IF NOT EXISTS \"#{name}\"").tap { + reload_type_map + } + end + + def disable_extension(name) + exec_query("DROP EXTENSION IF EXISTS \"#{name}\" CASCADE").tap { + reload_type_map + } + end + + def extension_enabled?(name) + if supports_extensions? + res = exec_query "SELECT EXISTS(SELECT * FROM pg_available_extensions WHERE name = '#{name}' AND installed_version IS NOT NULL) as enabled", + 'SCHEMA' + res.cast_values.first + end + end + + def extensions + if supports_extensions? + exec_query("SELECT extname from pg_extension", "SCHEMA").cast_values + else + super + end + end + + # Returns the configured supported identifier length supported by PostgreSQL + def table_alias_length + @table_alias_length ||= query('SHOW max_identifier_length', 'SCHEMA')[0][0].to_i + end + + # Set the authorized user for this session + def session_auth=(user) + clear_cache! + exec_query "SET SESSION AUTHORIZATION #{user}" + end + + def use_insert_returning? + @use_insert_returning + end + + def valid_type?(type) + !native_database_types[type].nil? + end + + def update_table_definition(table_name, base) #:nodoc: + PostgreSQL::Table.new(table_name, base) + end + + def lookup_cast_type(sql_type) # :nodoc: + oid = execute("SELECT #{quote(sql_type)}::regtype::oid", "SCHEMA").first['oid'].to_i + super(oid) + end + + def column_name_for_operation(operation, node) # :nodoc: + OPERATION_ALIASES.fetch(operation) { operation.downcase } + end + + OPERATION_ALIASES = { # :nodoc: + "maximum" => "max", + "minimum" => "min", + "average" => "avg", + } + + protected + + # Returns the version of the connected PostgreSQL server. + def postgresql_version + @connection.server_version + end + + # See http://www.postgresql.org/docs/9.1/static/errcodes-appendix.html + FOREIGN_KEY_VIOLATION = "23503" + UNIQUE_VIOLATION = "23505" + + def translate_exception(exception, message) + return exception unless exception.respond_to?(:result) + + case exception.result.try(:error_field, PGresult::PG_DIAG_SQLSTATE) + when UNIQUE_VIOLATION + RecordNotUnique.new(message, exception) + when FOREIGN_KEY_VIOLATION + InvalidForeignKey.new(message, exception) + else + super + end + end + + private + + def get_oid_type(oid, fmod, column_name, sql_type = '') # :nodoc: + if !type_map.key?(oid) + load_additional_types(type_map, [oid]) + end + + type_map.fetch(oid, fmod, sql_type) { + warn "unknown OID #{oid}: failed to recognize type of '#{column_name}'. It will be treated as String." + Type::Value.new.tap do |cast_type| + type_map.register_type(oid, cast_type) + end + } + end + + def initialize_type_map(m) # :nodoc: + register_class_with_limit m, 'int2', OID::Integer + register_class_with_limit m, 'int4', OID::Integer + register_class_with_limit m, 'int8', OID::Integer + m.alias_type 'oid', 'int2' + m.register_type 'float4', OID::Float.new + m.alias_type 'float8', 'float4' + m.register_type 'text', Type::Text.new + register_class_with_limit m, 'varchar', Type::String + m.alias_type 'char', 'varchar' + m.alias_type 'name', 'varchar' + m.alias_type 'bpchar', 'varchar' + m.register_type 'bool', Type::Boolean.new + register_class_with_limit m, 'bit', OID::Bit + register_class_with_limit m, 'varbit', OID::BitVarying + m.alias_type 'timestamptz', 'timestamp' + m.register_type 'date', OID::Date.new + m.register_type 'time', OID::Time.new + + m.register_type 'money', OID::Money.new + m.register_type 'bytea', OID::Bytea.new + m.register_type 'point', OID::Point.new + m.register_type 'hstore', OID::Hstore.new + m.register_type 'json', OID::Json.new + m.register_type 'jsonb', OID::Jsonb.new + m.register_type 'cidr', OID::Cidr.new + m.register_type 'inet', OID::Inet.new + m.register_type 'uuid', OID::Uuid.new + m.register_type 'xml', OID::Xml.new + m.register_type 'tsvector', OID::SpecializedString.new(:tsvector) + m.register_type 'macaddr', OID::SpecializedString.new(:macaddr) + m.register_type 'citext', OID::SpecializedString.new(:citext) + m.register_type 'ltree', OID::SpecializedString.new(:ltree) + + # FIXME: why are we keeping these types as strings? + m.alias_type 'interval', 'varchar' + m.alias_type 'path', 'varchar' + m.alias_type 'line', 'varchar' + m.alias_type 'polygon', 'varchar' + m.alias_type 'circle', 'varchar' + m.alias_type 'lseg', 'varchar' + m.alias_type 'box', 'varchar' + + m.register_type 'timestamp' do |_, _, sql_type| + precision = extract_precision(sql_type) + OID::DateTime.new(precision: precision) + end + + m.register_type 'numeric' do |_, fmod, sql_type| + precision = extract_precision(sql_type) + scale = extract_scale(sql_type) + + # The type for the numeric depends on the width of the field, + # so we'll do something special here. + # + # When dealing with decimal columns: + # + # places after decimal = fmod - 4 & 0xffff + # places before decimal = (fmod - 4) >> 16 & 0xffff + if fmod && (fmod - 4 & 0xffff).zero? + # FIXME: Remove this class, and the second argument to + # lookups on PG + Type::DecimalWithoutScale.new(precision: precision) + else + OID::Decimal.new(precision: precision, scale: scale) + end + end + + load_additional_types(m) + end + + def extract_limit(sql_type) # :nodoc: + case sql_type + when /^bigint/i, /^int8/i + 8 + when /^smallint/i + 2 + else + super + end + end + + # Extracts the value from a PostgreSQL column default definition. + def extract_value_from_default(oid, default) # :nodoc: + case default + # Quoted types + when /\A[\(B]?'(.*)'::/m + $1.gsub(/''/, "'") + # Boolean types + when 'true', 'false' + default + # Numeric types + when /\A\(?(-?\d+(\.\d*)?)\)?(::bigint)?\z/ + $1 + # Object identifier types + when /\A-?\d+\z/ + $1 + else + # Anything else is blank, some user type, or some function + # and we can't know the value of that, so return nil. + nil + end + end + + def extract_default_function(default_value, default) # :nodoc: + default if has_default_function?(default_value, default) + end + + def has_default_function?(default_value, default) # :nodoc: + !default_value && (%r{\w+\(.*\)} === default) + end + + def load_additional_types(type_map, oids = nil) # :nodoc: + initializer = OID::TypeMapInitializer.new(type_map) + + if supports_ranges? + query = <<-SQL + SELECT t.oid, t.typname, t.typelem, t.typdelim, t.typinput, r.rngsubtype, t.typtype, t.typbasetype + FROM pg_type as t + LEFT JOIN pg_range as r ON oid = rngtypid + SQL + else + query = <<-SQL + SELECT t.oid, t.typname, t.typelem, t.typdelim, t.typinput, t.typtype, t.typbasetype + FROM pg_type as t + SQL + end + + if oids + query += "WHERE t.oid::integer IN (%s)" % oids.join(", ") + else + query += initializer.query_conditions_for_initial_load(type_map) + end + + execute_and_clear(query, 'SCHEMA', []) do |records| + initializer.run(records) + end + end + + FEATURE_NOT_SUPPORTED = "0A000" #:nodoc: + + def execute_and_clear(sql, name, binds) + result = without_prepared_statement?(binds) ? exec_no_cache(sql, name, binds) : + exec_cache(sql, name, binds) + ret = yield result + result.clear + ret + end + + def exec_no_cache(sql, name, binds) + log(sql, name, binds) { @connection.async_exec(sql, []) } + end + + def exec_cache(sql, name, binds) + stmt_key = prepare_statement(sql) + type_casted_binds = binds.map { |col, val| + [col, type_cast(val, col)] + } + + log(sql, name, type_casted_binds, stmt_key) do + @connection.exec_prepared(stmt_key, type_casted_binds.map { |_, val| val }) + end + rescue ActiveRecord::StatementInvalid => e + pgerror = e.original_exception + + # Get the PG code for the failure. Annoyingly, the code for + # prepared statements whose return value may have changed is + # FEATURE_NOT_SUPPORTED. Check here for more details: + # http://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/backend/utils/cache/plancache.c#l573 + begin + code = pgerror.result.result_error_field(PGresult::PG_DIAG_SQLSTATE) + rescue + raise e + end + if FEATURE_NOT_SUPPORTED == code + @statements.delete sql_key(sql) + retry + else + raise e + end + end + + # Returns the statement identifier for the client side cache + # of statements + def sql_key(sql) + "#{schema_search_path}-#{sql}" + end + + # Prepare the statement if it hasn't been prepared, return + # the statement key. + def prepare_statement(sql) + sql_key = sql_key(sql) + unless @statements.key? sql_key + nextkey = @statements.next_key + begin + @connection.prepare nextkey, sql + rescue => e + raise translate_exception_class(e, sql) + end + # Clear the queue + @connection.get_last_result + @statements[sql_key] = nextkey + end + @statements[sql_key] + end + + # Connects to a PostgreSQL server and sets up the adapter depending on the + # connected server's characteristics. + def connect + @connection = PGconn.connect(@connection_parameters) + + # Money type has a fixed precision of 10 in PostgreSQL 8.2 and below, and as of + # PostgreSQL 8.3 it has a fixed precision of 19. PostgreSQLColumn.extract_precision + # should know about this but can't detect it there, so deal with it here. + OID::Money.precision = (postgresql_version >= 80300) ? 19 : 10 + + configure_connection + rescue ::PG::Error => error + if error.message.include?("does not exist") + raise ActiveRecord::NoDatabaseError.new(error.message, error) + else + raise + end + end + + # Configures the encoding, verbosity, schema search path, and time zone of the connection. + # This is called by #connect and should not be called manually. + def configure_connection + if @config[:encoding] + @connection.set_client_encoding(@config[:encoding]) + end + self.client_min_messages = @config[:min_messages] || 'warning' + self.schema_search_path = @config[:schema_search_path] || @config[:schema_order] + + # Use standard-conforming strings so we don't have to do the E'...' dance. + set_standard_conforming_strings + + # If using Active Record's time zone support configure the connection to return + # TIMESTAMP WITH ZONE types in UTC. + # (SET TIME ZONE does not use an equals sign like other SET variables) + if ActiveRecord::Base.default_timezone == :utc + execute("SET time zone 'UTC'", 'SCHEMA') + elsif @local_tz + execute("SET time zone '#{@local_tz}'", 'SCHEMA') + end + + # SET statements from :variables config hash + # http://www.postgresql.org/docs/8.3/static/sql-set.html + variables = @config[:variables] || {} + variables.map do |k, v| + if v == ':default' || v == :default + # Sets the value to the global or compile default + execute("SET SESSION #{k} TO DEFAULT", 'SCHEMA') + elsif !v.nil? + execute("SET SESSION #{k} TO #{quote(v)}", 'SCHEMA') + end + end + end + + # Returns the current ID of a table's sequence. + def last_insert_id(sequence_name) #:nodoc: + Integer(last_insert_id_value(sequence_name)) + end + + def last_insert_id_value(sequence_name) + last_insert_id_result(sequence_name).rows.first.first + end + + def last_insert_id_result(sequence_name) #:nodoc: + exec_query("SELECT currval('#{sequence_name}')", 'SQL') + end + + # Returns the list of a table's column names, data types, and default values. + # + # The underlying query is roughly: + # SELECT column.name, column.type, default.value + # FROM column LEFT JOIN default + # ON column.table_id = default.table_id + # AND column.num = default.column_num + # WHERE column.table_id = get_table_id('table_name') + # AND column.num > 0 + # AND NOT column.is_dropped + # ORDER BY column.num + # + # If the table name is not prefixed with a schema, the database will + # take the first match from the schema search path. + # + # Query implementation notes: + # - format_type includes the column size constraint, e.g. varchar(50) + # - ::regclass is a function that gives the id for a table name + def column_definitions(table_name) # :nodoc: + exec_query(<<-end_sql, 'SCHEMA').rows + SELECT a.attname, format_type(a.atttypid, a.atttypmod), + pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod + FROM pg_attribute a LEFT JOIN pg_attrdef d + ON a.attrelid = d.adrelid AND a.attnum = d.adnum + WHERE a.attrelid = '#{quote_table_name(table_name)}'::regclass + AND a.attnum > 0 AND NOT a.attisdropped + ORDER BY a.attnum + end_sql + end + + def extract_table_ref_from_insert_sql(sql) # :nodoc: + sql[/into\s+([^\(]*).*values\s*\(/im] + $1.strip if $1 + end + + def create_table_definition(name, temporary, options, as = nil) # :nodoc: + PostgreSQL::TableDefinition.new native_database_types, name, temporary, options, as + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/schema_cache.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/schema_cache.rb new file mode 100644 index 0000000..a10ce33 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/schema_cache.rb @@ -0,0 +1,94 @@ +module ActiveRecord + module ConnectionAdapters + class SchemaCache + attr_reader :version + attr_accessor :connection + + def initialize(conn) + @connection = conn + + @columns = {} + @columns_hash = {} + @primary_keys = {} + @tables = {} + end + + def primary_keys(table_name) + @primary_keys[table_name] ||= table_exists?(table_name) ? connection.primary_key(table_name) : nil + end + + # A cached lookup for table existence. + def table_exists?(name) + prepare_tables if @tables.empty? + return @tables[name] if @tables.key? name + + @tables[name] = connection.table_exists?(name) + end + + # Add internal cache for table with +table_name+. + def add(table_name) + if table_exists?(table_name) + primary_keys(table_name) + columns(table_name) + columns_hash(table_name) + end + end + + def tables(name) + @tables[name] + end + + # Get the columns for a table + def columns(table_name) + @columns[table_name] ||= connection.columns(table_name) + end + + # Get the columns for a table as a hash, key is the column name + # value is the column object. + def columns_hash(table_name) + @columns_hash[table_name] ||= Hash[columns(table_name).map { |col| + [col.name, col] + }] + end + + # Clears out internal caches + def clear! + @columns.clear + @columns_hash.clear + @primary_keys.clear + @tables.clear + @version = nil + end + + def size + [@columns, @columns_hash, @primary_keys, @tables].map { |x| + x.size + }.inject :+ + end + + # Clear out internal caches for table with +table_name+. + def clear_table_cache!(table_name) + @columns.delete table_name + @columns_hash.delete table_name + @primary_keys.delete table_name + @tables.delete table_name + end + + def marshal_dump + # if we get current version during initialization, it happens stack over flow. + @version = ActiveRecord::Migrator.current_version + [@version, @columns, @columns_hash, @primary_keys, @tables] + end + + def marshal_load(array) + @version, @columns, @columns_hash, @primary_keys, @tables = array + end + + private + + def prepare_tables + connection.tables.each { |table| @tables[table] = true } + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/sqlite3_adapter.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/sqlite3_adapter.rb new file mode 100644 index 0000000..0f48d12 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/sqlite3_adapter.rb @@ -0,0 +1,624 @@ +require 'active_record/connection_adapters/abstract_adapter' +require 'active_record/connection_adapters/statement_pool' +require 'arel/visitors/bind_visitor' + +gem 'sqlite3', '~> 1.3.6' +require 'sqlite3' + +module ActiveRecord + module ConnectionHandling # :nodoc: + # sqlite3 adapter reuses sqlite_connection. + def sqlite3_connection(config) + # Require database. + unless config[:database] + raise ArgumentError, "No database file specified. Missing argument: database" + end + + # Allow database path relative to Rails.root, but only if the database + # path is not the special path that tells sqlite to build a database only + # in memory. + if ':memory:' != config[:database] + config[:database] = File.expand_path(config[:database], Rails.root) if defined?(Rails.root) + dirname = File.dirname(config[:database]) + Dir.mkdir(dirname) unless File.directory?(dirname) + end + + db = SQLite3::Database.new( + config[:database].to_s, + :results_as_hash => true + ) + + db.busy_timeout(ConnectionAdapters::SQLite3Adapter.type_cast_config_to_integer(config[:timeout])) if config[:timeout] + + ConnectionAdapters::SQLite3Adapter.new(db, logger, nil, config) + rescue Errno::ENOENT => error + if error.message.include?("No such file or directory") + raise ActiveRecord::NoDatabaseError.new(error.message, error) + else + raise + end + end + end + + module ConnectionAdapters #:nodoc: + class SQLite3Binary < Type::Binary # :nodoc: + def cast_value(value) + if value.encoding != Encoding::ASCII_8BIT + value = value.force_encoding(Encoding::ASCII_8BIT) + end + value + end + end + + # The SQLite3 adapter works SQLite 3.6.16 or newer + # with the sqlite3-ruby drivers (available as gem from https://rubygems.org/gems/sqlite3). + # + # Options: + # + # * :database - Path to the database file. + class SQLite3Adapter < AbstractAdapter + ADAPTER_NAME = 'SQLite'.freeze + include Savepoints + + NATIVE_DATABASE_TYPES = { + primary_key: 'INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL', + string: { name: "varchar" }, + text: { name: "text" }, + integer: { name: "integer" }, + float: { name: "float" }, + decimal: { name: "decimal" }, + datetime: { name: "datetime" }, + time: { name: "time" }, + date: { name: "date" }, + binary: { name: "blob" }, + boolean: { name: "boolean" } + } + + class Version + include Comparable + + def initialize(version_string) + @version = version_string.split('.').map { |v| v.to_i } + end + + def <=>(version_string) + @version <=> version_string.split('.').map { |v| v.to_i } + end + end + + class StatementPool < ConnectionAdapters::StatementPool + def initialize(connection, max) + super + @cache = Hash.new { |h,pid| h[pid] = {} } + end + + def each(&block); cache.each(&block); end + def key?(key); cache.key?(key); end + def [](key); cache[key]; end + def length; cache.length; end + + def []=(sql, key) + while @max <= cache.size + dealloc(cache.shift.last[:stmt]) + end + cache[sql] = key + end + + def clear + cache.each_value do |hash| + dealloc hash[:stmt] + end + cache.clear + end + + private + def cache + @cache[$$] + end + + def dealloc(stmt) + stmt.close unless stmt.closed? + end + end + + def initialize(connection, logger, connection_options, config) + super(connection, logger) + + @active = nil + @statements = StatementPool.new(@connection, + self.class.type_cast_config_to_integer(config.fetch(:statement_limit) { 1000 })) + @config = config + + @visitor = Arel::Visitors::SQLite.new self + + if self.class.type_cast_config_to_boolean(config.fetch(:prepared_statements) { true }) + @prepared_statements = true + else + @prepared_statements = false + end + end + + def supports_ddl_transactions? + true + end + + def supports_savepoints? + true + end + + def supports_partial_index? + sqlite_version >= '3.8.0' + end + + # Returns true, since this connection adapter supports prepared statement + # caching. + def supports_statement_cache? + true + end + + # Returns true, since this connection adapter supports migrations. + def supports_migrations? #:nodoc: + true + end + + def supports_primary_key? #:nodoc: + true + end + + def requires_reloading? + true + end + + def supports_views? + true + end + + def active? + @active != false + end + + # Disconnects from the database if already connected. Otherwise, this + # method does nothing. + def disconnect! + super + @active = false + @connection.close rescue nil + end + + # Clears the prepared statements cache. + def clear_cache! + @statements.clear + end + + def supports_index_sort_order? + true + end + + # Returns 62. SQLite supports index names up to 64 + # characters. The rest is used by rails internally to perform + # temporary rename operations + def allowed_index_name_length + index_name_length - 2 + end + + def native_database_types #:nodoc: + NATIVE_DATABASE_TYPES + end + + # Returns the current database encoding format as a string, eg: 'UTF-8' + def encoding + @connection.encoding.to_s + end + + def supports_explain? + true + end + + # QUOTING ================================================== + + def _quote(value) # :nodoc: + case value + when Type::Binary::Data + "x'#{value.hex}'" + else + super + end + end + + def _type_cast(value) # :nodoc: + case value + when BigDecimal + value.to_f + when String + if value.encoding == Encoding::ASCII_8BIT + super(value.encode(Encoding::UTF_8)) + else + super + end + else + super + end + end + + def quote_string(s) #:nodoc: + @connection.class.quote(s) + end + + def quote_table_name_for_assignment(table, attr) + quote_column_name(attr) + end + + def quote_column_name(name) #:nodoc: + %Q("#{name.to_s.gsub('"', '""')}") + end + + # Quote date/time values for use in SQL input. Includes microseconds + # if the value is a Time responding to usec. + def quoted_date(value) #:nodoc: + if value.respond_to?(:usec) + "#{super}.#{sprintf("%06d", value.usec)}" + else + super + end + end + + #-- + # DATABASE STATEMENTS ====================================== + #++ + + def explain(arel, binds = []) + sql = "EXPLAIN QUERY PLAN #{to_sql(arel, binds)}" + ExplainPrettyPrinter.new.pp(exec_query(sql, 'EXPLAIN', [])) + end + + class ExplainPrettyPrinter + # Pretty prints the result of a EXPLAIN QUERY PLAN in a way that resembles + # the output of the SQLite shell: + # + # 0|0|0|SEARCH TABLE users USING INTEGER PRIMARY KEY (rowid=?) (~1 rows) + # 0|1|1|SCAN TABLE posts (~100000 rows) + # + def pp(result) # :nodoc: + result.rows.map do |row| + row.join('|') + end.join("\n") + "\n" + end + end + + def exec_query(sql, name = nil, binds = []) + type_casted_binds = binds.map { |col, val| + [col, type_cast(val, col)] + } + + log(sql, name, type_casted_binds) do + # Don't cache statements if they are not prepared + if without_prepared_statement?(binds) + stmt = @connection.prepare(sql) + begin + cols = stmt.columns + records = stmt.to_a + ensure + stmt.close + end + stmt = records + else + cache = @statements[sql] ||= { + :stmt => @connection.prepare(sql) + } + stmt = cache[:stmt] + cols = cache[:cols] ||= stmt.columns + stmt.reset! + stmt.bind_params type_casted_binds.map { |_, val| val } + end + + ActiveRecord::Result.new(cols, stmt.to_a) + end + end + + def exec_delete(sql, name = 'SQL', binds = []) + exec_query(sql, name, binds) + @connection.changes + end + alias :exec_update :exec_delete + + def last_inserted_id(result) + @connection.last_insert_row_id + end + + def execute(sql, name = nil) #:nodoc: + log(sql, name) { @connection.execute(sql) } + end + + def update_sql(sql, name = nil) #:nodoc: + super + @connection.changes + end + + def delete_sql(sql, name = nil) #:nodoc: + sql += " WHERE 1=1" unless sql =~ /WHERE/i + super sql, name + end + + def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) #:nodoc: + super + id_value || @connection.last_insert_row_id + end + alias :create :insert_sql + + def select_rows(sql, name = nil, binds = []) + exec_query(sql, name, binds).rows + end + + def begin_db_transaction #:nodoc: + log('begin transaction',nil) { @connection.transaction } + end + + def commit_db_transaction #:nodoc: + log('commit transaction',nil) { @connection.commit } + end + + def exec_rollback_db_transaction #:nodoc: + log('rollback transaction',nil) { @connection.rollback } + end + + # SCHEMA STATEMENTS ======================================== + + def tables(name = nil, table_name = nil) #:nodoc: + sql = <<-SQL + SELECT name + FROM sqlite_master + WHERE (type = 'table' OR type = 'view') AND NOT name = 'sqlite_sequence' + SQL + sql << " AND name = #{quote_table_name(table_name)}" if table_name + + exec_query(sql, 'SCHEMA').map do |row| + row['name'] + end + end + alias data_sources tables + + def table_exists?(table_name) + table_name && tables(nil, table_name).any? + end + alias data_source_exists? table_exists? + + # Returns an array of +Column+ objects for the table specified by +table_name+. + def columns(table_name) #:nodoc: + table_structure(table_name).map do |field| + case field["dflt_value"] + when /^null$/i + field["dflt_value"] = nil + when /^'(.*)'$/m + field["dflt_value"] = $1.gsub("''", "'") + when /^"(.*)"$/m + field["dflt_value"] = $1.gsub('""', '"') + end + + sql_type = field['type'] + cast_type = lookup_cast_type(sql_type) + new_column(field['name'], field['dflt_value'], cast_type, sql_type, field['notnull'].to_i == 0) + end + end + + # Returns an array of indexes for the given table. + def indexes(table_name, name = nil) #:nodoc: + exec_query("PRAGMA index_list(#{quote_table_name(table_name)})", 'SCHEMA').map do |row| + sql = <<-SQL + SELECT sql + FROM sqlite_master + WHERE name=#{quote(row['name'])} AND type='index' + UNION ALL + SELECT sql + FROM sqlite_temp_master + WHERE name=#{quote(row['name'])} AND type='index' + SQL + index_sql = exec_query(sql).first['sql'] + match = /\sWHERE\s+(.+)$/i.match(index_sql) + where = match[1] if match + IndexDefinition.new( + table_name, + row['name'], + row['unique'] != 0, + exec_query("PRAGMA index_info('#{row['name']}')", "SCHEMA").map { |col| + col['name'] + }, nil, nil, where) + end + end + + def primary_key(table_name) #:nodoc: + pks = table_structure(table_name).select { |f| f['pk'] > 0 } + return nil unless pks.count == 1 + pks[0]['name'] + end + + def remove_index!(table_name, index_name) #:nodoc: + exec_query "DROP INDEX #{quote_column_name(index_name)}" + end + + # Renames a table. + # + # Example: + # rename_table('octopuses', 'octopi') + def rename_table(table_name, new_name) + exec_query "ALTER TABLE #{quote_table_name(table_name)} RENAME TO #{quote_table_name(new_name)}" + rename_table_indexes(table_name, new_name) + end + + # See: http://www.sqlite.org/lang_altertable.html + # SQLite has an additional restriction on the ALTER TABLE statement + def valid_alter_table_type?(type) + type.to_sym != :primary_key + end + + def add_column(table_name, column_name, type, options = {}) #:nodoc: + if valid_alter_table_type?(type) + super(table_name, column_name, type, options) + else + alter_table(table_name) do |definition| + definition.column(column_name, type, options) + end + end + end + + def remove_column(table_name, column_name, type = nil, options = {}) #:nodoc: + alter_table(table_name) do |definition| + definition.remove_column column_name + end + end + + def change_column_default(table_name, column_name, default) #:nodoc: + alter_table(table_name) do |definition| + definition[column_name].default = default + end + end + + def change_column_null(table_name, column_name, null, default = nil) + unless null || default.nil? + exec_query("UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote(default)} WHERE #{quote_column_name(column_name)} IS NULL") + end + alter_table(table_name) do |definition| + definition[column_name].null = null + end + end + + def change_column(table_name, column_name, type, options = {}) #:nodoc: + alter_table(table_name) do |definition| + include_default = options_include_default?(options) + definition[column_name].instance_eval do + self.type = type + self.limit = options[:limit] if options.include?(:limit) + self.default = options[:default] if include_default + self.null = options[:null] if options.include?(:null) + self.precision = options[:precision] if options.include?(:precision) + self.scale = options[:scale] if options.include?(:scale) + end + end + end + + def rename_column(table_name, column_name, new_column_name) #:nodoc: + column = column_for(table_name, column_name) + alter_table(table_name, rename: {column.name => new_column_name.to_s}) + rename_column_indexes(table_name, column.name, new_column_name) + end + + protected + + def initialize_type_map(m) + super + m.register_type(/binary/i, SQLite3Binary.new) + end + + def table_structure(table_name) + structure = exec_query("PRAGMA table_info(#{quote_table_name(table_name)})", 'SCHEMA').to_hash + raise(ActiveRecord::StatementInvalid, "Could not find table '#{table_name}'") if structure.empty? + structure + end + + def alter_table(table_name, options = {}) #:nodoc: + altered_table_name = "a#{table_name}" + caller = lambda {|definition| yield definition if block_given?} + + transaction do + move_table(table_name, altered_table_name, + options.merge(:temporary => true)) + move_table(altered_table_name, table_name, &caller) + end + end + + def move_table(from, to, options = {}, &block) #:nodoc: + copy_table(from, to, options, &block) + drop_table(from) + end + + def copy_table(from, to, options = {}) #:nodoc: + from_primary_key = primary_key(from) + options[:id] = false + create_table(to, options) do |definition| + @definition = definition + @definition.primary_key(from_primary_key) if from_primary_key.present? + columns(from).each do |column| + column_name = options[:rename] ? + (options[:rename][column.name] || + options[:rename][column.name.to_sym] || + column.name) : column.name + next if column_name == from_primary_key + + @definition.column(column_name, column.type, + :limit => column.limit, :default => column.default, + :precision => column.precision, :scale => column.scale, + :null => column.null) + end + yield @definition if block_given? + end + copy_table_indexes(from, to, options[:rename] || {}) + copy_table_contents(from, to, + @definition.columns.map {|column| column.name}, + options[:rename] || {}) + end + + def copy_table_indexes(from, to, rename = {}) #:nodoc: + indexes(from).each do |index| + name = index.name + if to == "a#{from}" + name = "t#{name}" + elsif from == "a#{to}" + name = name[1..-1] + end + + to_column_names = columns(to).map { |c| c.name } + columns = index.columns.map {|c| rename[c] || c }.select do |column| + to_column_names.include?(column) + end + + unless columns.empty? + # index name can't be the same + opts = { name: name.gsub(/(^|_)(#{from})_/, "\\1#{to}_"), internal: true } + opts[:unique] = true if index.unique + add_index(to, columns, opts) + end + end + end + + def copy_table_contents(from, to, columns, rename = {}) #:nodoc: + column_mappings = Hash[columns.map {|name| [name, name]}] + rename.each { |a| column_mappings[a.last] = a.first } + from_columns = columns(from).collect {|col| col.name} + columns = columns.find_all{|col| from_columns.include?(column_mappings[col])} + quoted_columns = columns.map { |col| quote_column_name(col) } * ',' + + quoted_to = quote_table_name(to) + + raw_column_mappings = Hash[columns(from).map { |c| [c.name, c] }] + + exec_query("SELECT * FROM #{quote_table_name(from)}").each do |row| + sql = "INSERT INTO #{quoted_to} (#{quoted_columns}) VALUES (" + + column_values = columns.map do |col| + quote(row[column_mappings[col]], raw_column_mappings[col]) + end + + sql << column_values * ', ' + sql << ')' + exec_query sql + end + end + + def sqlite_version + @sqlite_version ||= SQLite3Adapter::Version.new(select_value('select sqlite_version(*)')) + end + + def translate_exception(exception, message) + case exception.message + # SQLite 3.8.2 returns a newly formatted error message: + # UNIQUE constraint failed: *table_name*.*column_name* + # Older versions of SQLite return: + # column *column_name* is not unique + when /column(s)? .* (is|are) not unique/, /UNIQUE constraint failed: .*/ + RecordNotUnique.new(message, exception) + else + super + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/statement_pool.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/statement_pool.rb new file mode 100644 index 0000000..c6b1bc8 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/statement_pool.rb @@ -0,0 +1,40 @@ +module ActiveRecord + module ConnectionAdapters + class StatementPool + include Enumerable + + def initialize(connection, max = 1000) + @connection = connection + @max = max + end + + def each + raise NotImplementedError + end + + def key?(key) + raise NotImplementedError + end + + def [](key) + raise NotImplementedError + end + + def length + raise NotImplementedError + end + + def []=(sql, key) + raise NotImplementedError + end + + def clear + raise NotImplementedError + end + + def delete(key) + raise NotImplementedError + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_handling.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_handling.rb new file mode 100644 index 0000000..984af79 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_handling.rb @@ -0,0 +1,132 @@ +module ActiveRecord + module ConnectionHandling + RAILS_ENV = -> { (Rails.env if defined?(Rails.env)) || ENV["RAILS_ENV"] || ENV["RACK_ENV"] } + DEFAULT_ENV = -> { RAILS_ENV.call || "default_env" } + + # Establishes the connection to the database. Accepts a hash as input where + # the :adapter key must be specified with the name of a database adapter (in lower-case) + # example for regular databases (MySQL, Postgresql, etc): + # + # ActiveRecord::Base.establish_connection( + # adapter: "mysql", + # host: "localhost", + # username: "myuser", + # password: "mypass", + # database: "somedatabase" + # ) + # + # Example for SQLite database: + # + # ActiveRecord::Base.establish_connection( + # adapter: "sqlite3", + # database: "path/to/dbfile" + # ) + # + # Also accepts keys as strings (for parsing from YAML for example): + # + # ActiveRecord::Base.establish_connection( + # "adapter" => "sqlite3", + # "database" => "path/to/dbfile" + # ) + # + # Or a URL: + # + # ActiveRecord::Base.establish_connection( + # "postgres://myuser:mypass@localhost/somedatabase" + # ) + # + # In case ActiveRecord::Base.configurations is set (Rails + # automatically loads the contents of config/database.yml into it), + # a symbol can also be given as argument, representing a key in the + # configuration hash: + # + # ActiveRecord::Base.establish_connection(:production) + # + # The exceptions AdapterNotSpecified, AdapterNotFound and ArgumentError + # may be returned on an error. + def establish_connection(spec = nil) + spec ||= DEFAULT_ENV.call.to_sym + resolver = ConnectionAdapters::ConnectionSpecification::Resolver.new configurations + spec = resolver.spec(spec) + + unless respond_to?(spec.adapter_method) + raise AdapterNotFound, "database configuration specifies nonexistent #{spec.config[:adapter]} adapter" + end + + remove_connection + connection_handler.establish_connection self, spec + end + + class MergeAndResolveDefaultUrlConfig # :nodoc: + def initialize(raw_configurations) + @raw_config = raw_configurations.dup + @env = DEFAULT_ENV.call.to_s + end + + # Returns fully resolved connection hashes. + # Merges connection information from `ENV['DATABASE_URL']` if available. + def resolve + ConnectionAdapters::ConnectionSpecification::Resolver.new(config).resolve_all + end + + private + def config + @raw_config.dup.tap do |cfg| + if url = ENV['DATABASE_URL'] + cfg[@env] ||= {} + cfg[@env]["url"] ||= url + end + end + end + end + + # Returns the connection currently associated with the class. This can + # also be used to "borrow" the connection to do database work unrelated + # to any of the specific Active Records. + def connection + retrieve_connection + end + + def connection_id + ActiveRecord::RuntimeRegistry.connection_id + end + + def connection_id=(connection_id) + ActiveRecord::RuntimeRegistry.connection_id = connection_id + end + + # Returns the configuration of the associated connection as a hash: + # + # ActiveRecord::Base.connection_config + # # => {pool: 5, timeout: 5000, database: "db/development.sqlite3", adapter: "sqlite3"} + # + # Please use only for reading. + def connection_config + connection_pool.spec.config + end + + def connection_pool + connection_handler.retrieve_connection_pool(self) or raise ConnectionNotEstablished + end + + def retrieve_connection + connection_handler.retrieve_connection(self) + end + + # Returns +true+ if Active Record is connected. + def connected? + connection_handler.connected?(self) + end + + def remove_connection(klass = self) + connection_handler.remove_connection(klass) + end + + def clear_cache! # :nodoc: + connection.schema_cache.clear! + end + + delegate :clear_active_connections!, :clear_reloadable_connections!, + :clear_all_connections!, :to => :connection_handler + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/core.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/core.rb new file mode 100644 index 0000000..de411c5 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/core.rb @@ -0,0 +1,579 @@ +require 'thread' +require 'active_support/core_ext/hash/indifferent_access' +require 'active_support/core_ext/object/duplicable' +require 'active_support/core_ext/string/filters' + +module ActiveRecord + module Core + extend ActiveSupport::Concern + + included do + ## + # :singleton-method: + # + # Accepts a logger conforming to the interface of Log4r which is then + # passed on to any new database connections made and which can be + # retrieved on both a class and instance level by calling +logger+. + mattr_accessor :logger, instance_writer: false + + ## + # Contains the database configuration - as is typically stored in config/database.yml - + # as a Hash. + # + # For example, the following database.yml... + # + # development: + # adapter: sqlite3 + # database: db/development.sqlite3 + # + # production: + # adapter: sqlite3 + # database: db/production.sqlite3 + # + # ...would result in ActiveRecord::Base.configurations to look like this: + # + # { + # 'development' => { + # 'adapter' => 'sqlite3', + # 'database' => 'db/development.sqlite3' + # }, + # 'production' => { + # 'adapter' => 'sqlite3', + # 'database' => 'db/production.sqlite3' + # } + # } + def self.configurations=(config) + @@configurations = ActiveRecord::ConnectionHandling::MergeAndResolveDefaultUrlConfig.new(config).resolve + end + self.configurations = {} + + # Returns fully resolved configurations hash + def self.configurations + @@configurations + end + + ## + # :singleton-method: + # Determines whether to use Time.utc (using :utc) or Time.local (using :local) when pulling + # dates and times from the database. This is set to :utc by default. + mattr_accessor :default_timezone, instance_writer: false + self.default_timezone = :utc + + ## + # :singleton-method: + # Specifies the format to use when dumping the database schema with Rails' + # Rakefile. If :sql, the schema is dumped as (potentially database- + # specific) SQL statements. If :ruby, the schema is dumped as an + # ActiveRecord::Schema file which can be loaded into any database that + # supports migrations. Use :ruby if you want to have different database + # adapters for, e.g., your development and test environments. + mattr_accessor :schema_format, instance_writer: false + self.schema_format = :ruby + + ## + # :singleton-method: + # Specify whether or not to use timestamps for migration versions + mattr_accessor :timestamped_migrations, instance_writer: false + self.timestamped_migrations = true + + ## + # :singleton-method: + # Specify whether schema dump should happen at the end of the + # db:migrate rake task. This is true by default, which is useful for the + # development environment. This should ideally be false in the production + # environment where dumping schema is rarely needed. + mattr_accessor :dump_schema_after_migration, instance_writer: false + self.dump_schema_after_migration = true + + mattr_accessor :maintain_test_schema, instance_accessor: false + + def self.disable_implicit_join_references=(value) + ActiveSupport::Deprecation.warn(<<-MSG.squish) + Implicit join references were removed with Rails 4.1. + Make sure to remove this configuration because it does nothing. + MSG + end + + class_attribute :default_connection_handler, instance_writer: false + class_attribute :find_by_statement_cache + + def self.connection_handler + ActiveRecord::RuntimeRegistry.connection_handler || default_connection_handler + end + + def self.connection_handler=(handler) + ActiveRecord::RuntimeRegistry.connection_handler = handler + end + + self.default_connection_handler = ConnectionAdapters::ConnectionHandler.new + end + + module ClassMethods + def allocate + define_attribute_methods + super + end + + def initialize_find_by_cache # :nodoc: + self.find_by_statement_cache = {}.extend(Mutex_m) + end + + def inherited(child_class) # :nodoc: + child_class.initialize_find_by_cache + super + end + + def find(*ids) # :nodoc: + # We don't have cache keys for this stuff yet + return super unless ids.length == 1 + # Allow symbols to super to maintain compatibility for deprecated finders until Rails 5 + return super if ids.first.kind_of?(Symbol) + return super if block_given? || + primary_key.nil? || + default_scopes.any? || + current_scope || + columns_hash.include?(inheritance_column) || + ids.first.kind_of?(Array) + + id = ids.first + if ActiveRecord::Base === id + id = id.id + ActiveSupport::Deprecation.warn(<<-MSG.squish) + You are passing an instance of ActiveRecord::Base to `find`. + Please pass the id of the object by calling `.id` + MSG + end + key = primary_key + + s = find_by_statement_cache[key] || find_by_statement_cache.synchronize { + find_by_statement_cache[key] ||= StatementCache.create(connection) { |params| + where(key => params.bind).limit(1) + } + } + record = s.execute([id], self, connection).first + unless record + raise RecordNotFound, "Couldn't find #{name} with '#{primary_key}'=#{id}" + end + record + rescue RangeError + raise RecordNotFound, "Couldn't find #{name} with an out of range value for '#{primary_key}'" + end + + def find_by(*args) # :nodoc: + return super if current_scope || !(Hash === args.first) || reflect_on_all_aggregations.any? + return super if default_scopes.any? + + hash = args.first + + return super if hash.values.any? { |v| + v.nil? || Array === v || Hash === v + } + + # We can't cache Post.find_by(author: david) ...yet + return super unless hash.keys.all? { |k| columns_hash.has_key?(k.to_s) } + + key = hash.keys + + klass = self + s = find_by_statement_cache[key] || find_by_statement_cache.synchronize { + find_by_statement_cache[key] ||= StatementCache.create(connection) { |params| + wheres = key.each_with_object({}) { |param,o| + o[param] = params.bind + } + klass.where(wheres).limit(1) + } + } + begin + s.execute(hash.values, self, connection).first + rescue TypeError => e + raise ActiveRecord::StatementInvalid.new(e.message, e) + rescue RangeError + nil + end + end + + def find_by!(*args) # :nodoc: + find_by(*args) or raise RecordNotFound.new("Couldn't find #{name}") + end + + def initialize_generated_modules # :nodoc: + generated_association_methods + end + + def generated_association_methods + @generated_association_methods ||= begin + mod = const_set(:GeneratedAssociationMethods, Module.new) + include mod + mod + end + end + + # Returns a string like 'Post(id:integer, title:string, body:text)' + def inspect + if self == Base + super + elsif abstract_class? + "#{super}(abstract)" + elsif !connected? + "#{super} (call '#{super}.connection' to establish a connection)" + elsif table_exists? + attr_list = columns.map { |c| "#{c.name}: #{c.type}" } * ', ' + "#{super}(#{attr_list})" + else + "#{super}(Table doesn't exist)" + end + end + + # Overwrite the default class equality method to provide support for association proxies. + def ===(object) + object.is_a?(self) + end + + # Returns an instance of Arel::Table loaded with the current table name. + # + # class Post < ActiveRecord::Base + # scope :published_and_commented, -> { published.and(self.arel_table[:comments_count].gt(0)) } + # end + def arel_table # :nodoc: + @arel_table ||= Arel::Table.new(table_name, arel_engine) + end + + # Returns the Arel engine. + def arel_engine # :nodoc: + @arel_engine ||= + if Base == self || connection_handler.retrieve_connection_pool(self) + self + else + superclass.arel_engine + end + end + + private + + def relation #:nodoc: + relation = Relation.create(self, arel_table) + + if finder_needs_type_condition? + relation.where(type_condition).create_with(inheritance_column.to_sym => sti_name) + else + relation + end + end + end + + # New objects can be instantiated as either empty (pass no construction parameter) or pre-set with + # attributes but not yet saved (pass a hash with key names matching the associated table column names). + # In both instances, valid attribute keys are determined by the column names of the associated table -- + # hence you can't have attributes that aren't part of the table columns. + # + # ==== Example: + # # Instantiates a single new object + # User.new(first_name: 'Jamie') + def initialize(attributes = nil, options = {}) + @attributes = self.class._default_attributes.dup + self.class.define_attribute_methods + + init_internals + initialize_internals_callback + + # +options+ argument is only needed to make protected_attributes gem easier to hook. + # Remove it when we drop support to this gem. + init_attributes(attributes, options) if attributes + + yield self if block_given? + _run_initialize_callbacks + end + + # Initialize an empty model object from +coder+. +coder+ should be + # the result of previously encoding an Active Record model, using + # `encode_with` + # + # class Post < ActiveRecord::Base + # end + # + # old_post = Post.new(title: "hello world") + # coder = {} + # old_post.encode_with(coder) + # + # post = Post.allocate + # post.init_with(coder) + # post.title # => 'hello world' + def init_with(coder) + coder = LegacyYamlAdapter.convert(self.class, coder) + @attributes = coder['attributes'] + + init_internals + + @new_record = coder['new_record'] + + self.class.define_attribute_methods + + _run_find_callbacks + _run_initialize_callbacks + + self + end + + ## + # :method: clone + # Identical to Ruby's clone method. This is a "shallow" copy. Be warned that your attributes are not copied. + # That means that modifying attributes of the clone will modify the original, since they will both point to the + # same attributes hash. If you need a copy of your attributes hash, please use the #dup method. + # + # user = User.first + # new_user = user.clone + # user.name # => "Bob" + # new_user.name = "Joe" + # user.name # => "Joe" + # + # user.object_id == new_user.object_id # => false + # user.name.object_id == new_user.name.object_id # => true + # + # user.name.object_id == user.dup.name.object_id # => false + + ## + # :method: dup + # Duped objects have no id assigned and are treated as new records. Note + # that this is a "shallow" copy as it copies the object's attributes + # only, not its associations. The extent of a "deep" copy is application + # specific and is therefore left to the application to implement according + # to its need. + # The dup method does not preserve the timestamps (created|updated)_(at|on). + + ## + def initialize_dup(other) # :nodoc: + @attributes = @attributes.dup + @attributes.reset(self.class.primary_key) + + _run_initialize_callbacks + + @aggregation_cache = {} + @association_cache = {} + + @new_record = true + @destroyed = false + + super + end + + # Populate +coder+ with attributes about this record that should be + # serialized. The structure of +coder+ defined in this method is + # guaranteed to match the structure of +coder+ passed to the +init_with+ + # method. + # + # Example: + # + # class Post < ActiveRecord::Base + # end + # coder = {} + # Post.new.encode_with(coder) + # coder # => {"attributes" => {"id" => nil, ... }} + def encode_with(coder) + # FIXME: Remove this when we better serialize attributes + coder['raw_attributes'] = attributes_before_type_cast + coder['attributes'] = @attributes + coder['new_record'] = new_record? + coder['active_record_yaml_version'] = 0 + end + + # Returns true if +comparison_object+ is the same exact object, or +comparison_object+ + # is of the same type and +self+ has an ID and it is equal to +comparison_object.id+. + # + # Note that new records are different from any other record by definition, unless the + # other record is the receiver itself. Besides, if you fetch existing records with + # +select+ and leave the ID out, you're on your own, this predicate will return false. + # + # Note also that destroying a record preserves its ID in the model instance, so deleted + # models are still comparable. + def ==(comparison_object) + super || + comparison_object.instance_of?(self.class) && + !id.nil? && + comparison_object.id == id + end + alias :eql? :== + + # Delegates to id in order to allow two records of the same type and id to work with something like: + # [ Person.find(1), Person.find(2), Person.find(3) ] & [ Person.find(1), Person.find(4) ] # => [ Person.find(1) ] + def hash + if id + id.hash + else + super + end + end + + # Clone and freeze the attributes hash such that associations are still + # accessible, even on destroyed records, but cloned models will not be + # frozen. + def freeze + @attributes = @attributes.clone.freeze + self + end + + # Returns +true+ if the attributes hash has been frozen. + def frozen? + @attributes.frozen? + end + + # Allows sort on objects + def <=>(other_object) + if other_object.is_a?(self.class) + self.to_key <=> other_object.to_key + else + super + end + end + + # Returns +true+ if the record is read only. Records loaded through joins with piggy-back + # attributes will be marked as read only since they cannot be saved. + def readonly? + @readonly + end + + # Marks this record as read only. + def readonly! + @readonly = true + end + + def connection_handler + self.class.connection_handler + end + + # Returns the contents of the record as a nicely formatted string. + def inspect + # We check defined?(@attributes) not to issue warnings if the object is + # allocated but not initialized. + inspection = if defined?(@attributes) && @attributes + self.class.column_names.collect { |name| + if has_attribute?(name) + "#{name}: #{attribute_for_inspect(name)}" + end + }.compact.join(", ") + else + "not initialized" + end + "#<#{self.class} #{inspection}>" + end + + # Takes a PP and prettily prints this record to it, allowing you to get a nice result from `pp record` + # when pp is required. + def pretty_print(pp) + return super if custom_inspect_method_defined? + pp.object_address_group(self) do + if defined?(@attributes) && @attributes + column_names = self.class.column_names.select { |name| has_attribute?(name) || new_record? } + pp.seplist(column_names, proc { pp.text ',' }) do |column_name| + column_value = read_attribute(column_name) + pp.breakable ' ' + pp.group(1) do + pp.text column_name + pp.text ':' + pp.breakable + pp.pp column_value + end + end + else + pp.breakable ' ' + pp.text 'not initialized' + end + end + end + + # Returns a hash of the given methods with their names as keys and returned values as values. + def slice(*methods) + Hash[methods.map! { |method| [method, public_send(method)] }].with_indifferent_access + end + + private + + def set_transaction_state(state) # :nodoc: + @transaction_state = state + end + + def has_transactional_callbacks? # :nodoc: + !_rollback_callbacks.empty? || !_commit_callbacks.empty? + end + + # Updates the attributes on this particular ActiveRecord object so that + # if it is associated with a transaction, then the state of the AR object + # will be updated to reflect the current state of the transaction + # + # The @transaction_state variable stores the states of the associated + # transaction. This relies on the fact that a transaction can only be in + # one rollback or commit (otherwise a list of states would be required) + # Each AR object inside of a transaction carries that transaction's + # TransactionState. + # + # This method checks to see if the ActiveRecord object's state reflects + # the TransactionState, and rolls back or commits the ActiveRecord object + # as appropriate. + # + # Since ActiveRecord objects can be inside multiple transactions, this + # method recursively goes through the parent of the TransactionState and + # checks if the ActiveRecord object reflects the state of the object. + def sync_with_transaction_state + update_attributes_from_transaction_state(@transaction_state, 0) + end + + def update_attributes_from_transaction_state(transaction_state, depth) + @reflects_state = [false] if depth == 0 + + if transaction_state && transaction_state.finalized? && !has_transactional_callbacks? + unless @reflects_state[depth] + restore_transaction_record_state if transaction_state.rolledback? + clear_transaction_record_state + @reflects_state[depth] = true + end + + if transaction_state.parent && !@reflects_state[depth+1] + update_attributes_from_transaction_state(transaction_state.parent, depth+1) + end + end + end + + # Under Ruby 1.9, Array#flatten will call #to_ary (recursively) on each of the elements + # of the array, and then rescues from the possible NoMethodError. If those elements are + # ActiveRecord::Base's, then this triggers the various method_missing's that we have, + # which significantly impacts upon performance. + # + # So we can avoid the method_missing hit by explicitly defining #to_ary as nil here. + # + # See also http://tenderlovemaking.com/2011/06/28/til-its-ok-to-return-nil-from-to_ary.html + def to_ary # :nodoc: + nil + end + + def init_internals + @aggregation_cache = {} + @association_cache = {} + @readonly = false + @destroyed = false + @marked_for_destruction = false + @destroyed_by_association = nil + @new_record = true + @txn = nil + @_start_transaction_state = {} + @transaction_state = nil + end + + def initialize_internals_callback + end + + # This method is needed to make protected_attributes gem easier to hook. + # Remove it when we drop support to this gem. + def init_attributes(attributes, options) + assign_attributes(attributes) + end + + def thaw + if frozen? + @attributes = @attributes.dup + end + end + + def custom_inspect_method_defined? + self.class.instance_method(:inspect).owner != ActiveRecord::Base.instance_method(:inspect).owner + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/counter_cache.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/counter_cache.rb new file mode 100644 index 0000000..fd2e6d5 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/counter_cache.rb @@ -0,0 +1,175 @@ +module ActiveRecord + # = Active Record Counter Cache + module CounterCache + extend ActiveSupport::Concern + + module ClassMethods + # Resets one or more counter caches to their correct value using an SQL + # count query. This is useful when adding new counter caches, or if the + # counter has been corrupted or modified directly by SQL. + # + # ==== Parameters + # + # * +id+ - The id of the object you wish to reset a counter on. + # * +counters+ - One or more association counters to reset. Association name or counter name can be given. + # + # ==== Examples + # + # # For Post with id #1 records reset the comments_count + # Post.reset_counters(1, :comments) + def reset_counters(id, *counters) + object = find(id) + counters.each do |counter_association| + has_many_association = _reflect_on_association(counter_association) + unless has_many_association + has_many = reflect_on_all_associations(:has_many) + has_many_association = has_many.find { |association| association.counter_cache_column && association.counter_cache_column.to_sym == counter_association.to_sym } + counter_association = has_many_association.plural_name if has_many_association + end + raise ArgumentError, "'#{self.name}' has no association called '#{counter_association}'" unless has_many_association + + if has_many_association.is_a? ActiveRecord::Reflection::ThroughReflection + has_many_association = has_many_association.through_reflection + end + + foreign_key = has_many_association.foreign_key.to_s + child_class = has_many_association.klass + reflection = child_class._reflections.values.find { |e| e.belongs_to? && e.foreign_key.to_s == foreign_key && e.options[:counter_cache].present? } + counter_name = reflection.counter_cache_column + + stmt = unscoped.where(arel_table[primary_key].eq(object.id)).arel.compile_update({ + arel_table[counter_name] => object.send(counter_association).count(:all) + }, primary_key) + connection.update stmt + end + return true + end + + # A generic "counter updater" implementation, intended primarily to be + # used by increment_counter and decrement_counter, but which may also + # be useful on its own. It simply does a direct SQL update for the record + # with the given ID, altering the given hash of counters by the amount + # given by the corresponding value: + # + # ==== Parameters + # + # * +id+ - The id of the object you wish to update a counter on or an Array of ids. + # * +counters+ - A Hash containing the names of the fields + # to update as keys and the amount to update the field by as values. + # + # ==== Examples + # + # # For the Post with id of 5, decrement the comment_count by 1, and + # # increment the action_count by 1 + # Post.update_counters 5, comment_count: -1, action_count: 1 + # # Executes the following SQL: + # # UPDATE posts + # # SET comment_count = COALESCE(comment_count, 0) - 1, + # # action_count = COALESCE(action_count, 0) + 1 + # # WHERE id = 5 + # + # # For the Posts with id of 10 and 15, increment the comment_count by 1 + # Post.update_counters [10, 15], comment_count: 1 + # # Executes the following SQL: + # # UPDATE posts + # # SET comment_count = COALESCE(comment_count, 0) + 1 + # # WHERE id IN (10, 15) + def update_counters(id, counters) + updates = counters.map do |counter_name, value| + operator = value < 0 ? '-' : '+' + quoted_column = connection.quote_column_name(counter_name) + "#{quoted_column} = COALESCE(#{quoted_column}, 0) #{operator} #{value.abs}" + end + + unscoped.where(primary_key => id).update_all updates.join(', ') + end + + # Increment a numeric field by one, via a direct SQL update. + # + # This method is used primarily for maintaining counter_cache columns that are + # used to store aggregate values. For example, a DiscussionBoard may cache + # posts_count and comments_count to avoid running an SQL query to calculate the + # number of posts and comments there are, each time it is displayed. + # + # ==== Parameters + # + # * +counter_name+ - The name of the field that should be incremented. + # * +id+ - The id of the object that should be incremented or an Array of ids. + # + # ==== Examples + # + # # Increment the post_count column for the record with an id of 5 + # DiscussionBoard.increment_counter(:post_count, 5) + def increment_counter(counter_name, id) + update_counters(id, counter_name => 1) + end + + # Decrement a numeric field by one, via a direct SQL update. + # + # This works the same as increment_counter but reduces the column value by + # 1 instead of increasing it. + # + # ==== Parameters + # + # * +counter_name+ - The name of the field that should be decremented. + # * +id+ - The id of the object that should be decremented or an Array of ids. + # + # ==== Examples + # + # # Decrement the post_count column for the record with an id of 5 + # DiscussionBoard.decrement_counter(:post_count, 5) + def decrement_counter(counter_name, id) + update_counters(id, counter_name => -1) + end + end + + protected + + def actually_destroyed? + @_actually_destroyed + end + + def clear_destroy_state + @_actually_destroyed = nil + end + + private + + def _create_record(*) + id = super + + each_counter_cached_associations do |association| + if send(association.reflection.name) + association.increment_counters + @_after_create_counter_called = true + end + end + + id + end + + def destroy_row + affected_rows = super + + if affected_rows > 0 + each_counter_cached_associations do |association| + foreign_key = association.reflection.foreign_key.to_sym + unless destroyed_by_association && destroyed_by_association.foreign_key.to_sym == foreign_key + if send(association.reflection.name) + association.decrement_counters + end + end + end + end + + affected_rows + end + + def each_counter_cached_associations + _reflections.each do |name, reflection| + yield association(name.to_sym) if reflection.belongs_to? && reflection.counter_cache_column + end + end + + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/dynamic_matchers.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/dynamic_matchers.rb new file mode 100644 index 0000000..e94b740 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/dynamic_matchers.rb @@ -0,0 +1,140 @@ +module ActiveRecord + module DynamicMatchers #:nodoc: + # This code in this file seems to have a lot of indirection, but the indirection + # is there to provide extension points for the activerecord-deprecated_finders + # gem. When we stop supporting activerecord-deprecated_finders (from Rails 5), + # then we can remove the indirection. + + def respond_to?(name, include_private = false) + if self == Base + super + else + match = Method.match(self, name) + match && match.valid? || super + end + end + + private + + def method_missing(name, *arguments, &block) + match = Method.match(self, name) + + if match && match.valid? + match.define + send(name, *arguments, &block) + else + super + end + end + + class Method + @matchers = [] + + class << self + attr_reader :matchers + + def match(model, name) + klass = matchers.find { |k| name =~ k.pattern } + klass.new(model, name) if klass + end + + def pattern + @pattern ||= /\A#{prefix}_([_a-zA-Z]\w*)#{suffix}\Z/ + end + + def prefix + raise NotImplementedError + end + + def suffix + '' + end + end + + attr_reader :model, :name, :attribute_names + + def initialize(model, name) + @model = model + @name = name.to_s + @attribute_names = @name.match(self.class.pattern)[1].split('_and_') + @attribute_names.map! { |n| @model.attribute_aliases[n] || n } + end + + def valid? + attribute_names.all? { |name| model.columns_hash[name] || model.reflect_on_aggregation(name.to_sym) } + end + + def define + model.class_eval <<-CODE, __FILE__, __LINE__ + 1 + def self.#{name}(#{signature}) + #{body} + end + CODE + end + + def body + raise NotImplementedError + end + end + + module Finder + # Extended in activerecord-deprecated_finders + def body + result + end + + # Extended in activerecord-deprecated_finders + def result + "#{finder}(#{attributes_hash})" + end + + # The parameters in the signature may have reserved Ruby words, in order + # to prevent errors, we start each param name with `_`. + # + # Extended in activerecord-deprecated_finders + def signature + attribute_names.map { |name| "_#{name}" }.join(', ') + end + + # Given that the parameters starts with `_`, the finder needs to use the + # same parameter name. + def attributes_hash + "{" + attribute_names.map { |name| ":#{name} => _#{name}" }.join(',') + "}" + end + + def finder + raise NotImplementedError + end + end + + class FindBy < Method + Method.matchers << self + include Finder + + def self.prefix + "find_by" + end + + def finder + "find_by" + end + end + + class FindByBang < Method + Method.matchers << self + include Finder + + def self.prefix + "find_by" + end + + def self.suffix + "!" + end + + def finder + "find_by!" + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/enum.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/enum.rb new file mode 100644 index 0000000..7887991 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/enum.rb @@ -0,0 +1,197 @@ +require 'active_support/core_ext/object/deep_dup' + +module ActiveRecord + # Declare an enum attribute where the values map to integers in the database, + # but can be queried by name. Example: + # + # class Conversation < ActiveRecord::Base + # enum status: [ :active, :archived ] + # end + # + # # conversation.update! status: 0 + # conversation.active! + # conversation.active? # => true + # conversation.status # => "active" + # + # # conversation.update! status: 1 + # conversation.archived! + # conversation.archived? # => true + # conversation.status # => "archived" + # + # # conversation.status = 1 + # conversation.status = "archived" + # + # conversation.status = nil + # conversation.status.nil? # => true + # conversation.status # => nil + # + # Scopes based on the allowed values of the enum field will be provided + # as well. With the above example: + # + # Conversation.active + # Conversation.archived + # + # You can set the default value from the database declaration, like: + # + # create_table :conversations do |t| + # t.column :status, :integer, default: 0 + # end + # + # Good practice is to let the first declared status be the default. + # + # Finally, it's also possible to explicitly map the relation between attribute and + # database integer with a +Hash+: + # + # class Conversation < ActiveRecord::Base + # enum status: { active: 0, archived: 1 } + # end + # + # Note that when an +Array+ is used, the implicit mapping from the values to database + # integers is derived from the order the values appear in the array. In the example, + # :active is mapped to +0+ as it's the first element, and :archived + # is mapped to +1+. In general, the +i+-th element is mapped to i-1 in the + # database. + # + # Therefore, once a value is added to the enum array, its position in the array must + # be maintained, and new values should only be added to the end of the array. To + # remove unused values, the explicit +Hash+ syntax should be used. + # + # In rare circumstances you might need to access the mapping directly. + # The mappings are exposed through a class method with the pluralized attribute + # name: + # + # Conversation.statuses # => { "active" => 0, "archived" => 1 } + # + # Use that class method when you need to know the ordinal value of an enum: + # + # Conversation.where("status <> ?", Conversation.statuses[:archived]) + # + # Where conditions on an enum attribute must use the ordinal value of an enum. + module Enum + def self.extended(base) # :nodoc: + base.class_attribute(:defined_enums, instance_writer: false) + base.defined_enums = {} + end + + def inherited(base) # :nodoc: + base.defined_enums = defined_enums.deep_dup + super + end + + def enum(definitions) + klass = self + definitions.each do |name, values| + # statuses = { } + enum_values = ActiveSupport::HashWithIndifferentAccess.new + name = name.to_sym + + # def self.statuses statuses end + detect_enum_conflict!(name, name.to_s.pluralize, true) + klass.singleton_class.send(:define_method, name.to_s.pluralize) { enum_values } + + _enum_methods_module.module_eval do + # def status=(value) self[:status] = statuses[value] end + klass.send(:detect_enum_conflict!, name, "#{name}=") + define_method("#{name}=") { |value| + if enum_values.has_key?(value) || value.blank? + self[name] = enum_values[value] + elsif enum_values.has_value?(value) + # Assigning a value directly is not a end-user feature, hence it's not documented. + # This is used internally to make building objects from the generated scopes work + # as expected, i.e. +Conversation.archived.build.archived?+ should be true. + self[name] = value + else + raise ArgumentError, "'#{value}' is not a valid #{name}" + end + } + + # def status() statuses.key self[:status] end + klass.send(:detect_enum_conflict!, name, name) + define_method(name) { enum_values.key self[name] } + + # def status_before_type_cast() statuses.key self[:status] end + klass.send(:detect_enum_conflict!, name, "#{name}_before_type_cast") + define_method("#{name}_before_type_cast") { enum_values.key self[name] } + + pairs = values.respond_to?(:each_pair) ? values.each_pair : values.each_with_index + pairs.each do |value, i| + enum_values[value] = i + + # def active?() status == 0 end + klass.send(:detect_enum_conflict!, name, "#{value}?") + define_method("#{value}?") { self[name] == i } + + # def active!() update! status: :active end + klass.send(:detect_enum_conflict!, name, "#{value}!") + define_method("#{value}!") { update! name => value } + + # scope :active, -> { where status: 0 } + klass.send(:detect_enum_conflict!, name, value, true) + klass.scope value, -> { klass.where name => i } + end + end + defined_enums[name.to_s] = enum_values + end + end + + private + def _enum_methods_module + @_enum_methods_module ||= begin + mod = Module.new do + private + def save_changed_attribute(attr_name, old) + if (mapping = self.class.defined_enums[attr_name.to_s]) + value = _read_attribute(attr_name) + if attribute_changed?(attr_name) + if mapping[old] == value + clear_attribute_changes([attr_name]) + end + else + if old != value + set_attribute_was(attr_name, mapping.key(old)) + end + end + else + super + end + end + end + include mod + mod + end + end + + ENUM_CONFLICT_MESSAGE = \ + "You tried to define an enum named \"%{enum}\" on the model \"%{klass}\", but " \ + "this will generate a %{type} method \"%{method}\", which is already defined " \ + "by %{source}." + + def detect_enum_conflict!(enum_name, method_name, klass_method = false) + if klass_method && dangerous_class_method?(method_name) + raise ArgumentError, ENUM_CONFLICT_MESSAGE % { + enum: enum_name, + klass: self.name, + type: 'class', + method: method_name, + source: 'Active Record' + } + elsif !klass_method && dangerous_attribute_method?(method_name) + raise ArgumentError, ENUM_CONFLICT_MESSAGE % { + enum: enum_name, + klass: self.name, + type: 'instance', + method: method_name, + source: 'Active Record' + } + elsif !klass_method && method_defined_within?(method_name, _enum_methods_module, Module) + raise ArgumentError, ENUM_CONFLICT_MESSAGE % { + enum: enum_name, + klass: self.name, + type: 'instance', + method: method_name, + source: 'another enum' + } + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/errors.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/errors.rb new file mode 100644 index 0000000..b3575f3 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/errors.rb @@ -0,0 +1,253 @@ +module ActiveRecord + + # = Active Record Errors + # + # Generic Active Record exception class. + class ActiveRecordError < StandardError + end + + # Raised when the single-table inheritance mechanism fails to locate the subclass + # (for example due to improper usage of column that +inheritance_column+ points to). + class SubclassNotFound < ActiveRecordError #:nodoc: + end + + # Raised when an object assigned to an association has an incorrect type. + # + # class Ticket < ActiveRecord::Base + # has_many :patches + # end + # + # class Patch < ActiveRecord::Base + # belongs_to :ticket + # end + # + # # Comments are not patches, this assignment raises AssociationTypeMismatch. + # @ticket.patches << Comment.new(content: "Please attach tests to your patch.") + class AssociationTypeMismatch < ActiveRecordError + end + + # Raised when unserialized object's type mismatches one specified for serializable field. + class SerializationTypeMismatch < ActiveRecordError + end + + # Raised when adapter not specified on connection (or configuration file + # +config/database.yml+ misses adapter field). + class AdapterNotSpecified < ActiveRecordError + end + + # Raised when Active Record cannot find database adapter specified in + # +config/database.yml+ or programmatically. + class AdapterNotFound < ActiveRecordError + end + + # Raised when connection to the database could not been established (for + # example when +connection=+ is given a nil object). + class ConnectionNotEstablished < ActiveRecordError + end + + # Raised when Active Record cannot find record by given id or set of ids. + class RecordNotFound < ActiveRecordError + end + + # Raised by ActiveRecord::Base.save! and ActiveRecord::Base.create! methods when record cannot be + # saved because record is invalid. + class RecordNotSaved < ActiveRecordError + attr_reader :record + + def initialize(message, record = nil) + @record = record + super(message) + end + end + + # Raised by ActiveRecord::Base.destroy! when a call to destroy would return false. + # + # begin + # complex_operation_that_internally_calls_destroy! + # rescue ActiveRecord::RecordNotDestroyed => invalid + # puts invalid.record.errors + # end + # + class RecordNotDestroyed < ActiveRecordError + attr_reader :record + + def initialize(message, record = nil) + @record = record + super(message) + end + end + + # Superclass for all database execution errors. + # + # Wraps the underlying database error as +original_exception+. + class StatementInvalid < ActiveRecordError + attr_reader :original_exception + + def initialize(message, original_exception = nil) + super(message) + @original_exception = original_exception + end + end + + # Defunct wrapper class kept for compatibility. + # +StatementInvalid+ wraps the original exception now. + class WrappedDatabaseException < StatementInvalid + end + + # Raised when a record cannot be inserted because it would violate a uniqueness constraint. + class RecordNotUnique < WrappedDatabaseException + end + + # Raised when a record cannot be inserted or updated because it references a non-existent record. + class InvalidForeignKey < WrappedDatabaseException + end + + # Raised when number of bind variables in statement given to +:condition+ key + # (for example, when using +find+ method) does not match number of expected + # values supplied. + # + # For example, when there are two placeholders with only one value supplied: + # + # Location.where("lat = ? AND lng = ?", 53.7362) + class PreparedStatementInvalid < ActiveRecordError + end + + # Raised when a given database does not exist. + class NoDatabaseError < StatementInvalid + end + + # Raised on attempt to save stale record. Record is stale when it's being saved in another query after + # instantiation, for example, when two users edit the same wiki page and one starts editing and saves + # the page before the other. + # + # Read more about optimistic locking in ActiveRecord::Locking module + # documentation. + class StaleObjectError < ActiveRecordError + attr_reader :record, :attempted_action + + def initialize(record, attempted_action) + super("Attempted to #{attempted_action} a stale object: #{record.class.name}") + @record = record + @attempted_action = attempted_action + end + + end + + # Raised when association is being configured improperly or user tries to use + # offset and limit together with +has_many+ or +has_and_belongs_to_many+ + # associations. + class ConfigurationError < ActiveRecordError + end + + # Raised on attempt to update record that is instantiated as read only. + class ReadOnlyRecord < ActiveRecordError + end + + # ActiveRecord::Transactions::ClassMethods.transaction uses this exception + # to distinguish a deliberate rollback from other exceptional situations. + # Normally, raising an exception will cause the +transaction+ method to rollback + # the database transaction *and* pass on the exception. But if you raise an + # ActiveRecord::Rollback exception, then the database transaction will be rolled back, + # without passing on the exception. + # + # For example, you could do this in your controller to rollback a transaction: + # + # class BooksController < ActionController::Base + # def create + # Book.transaction do + # book = Book.new(params[:book]) + # book.save! + # if today_is_friday? + # # The system must fail on Friday so that our support department + # # won't be out of job. We silently rollback this transaction + # # without telling the user. + # raise ActiveRecord::Rollback, "Call tech support!" + # end + # end + # # ActiveRecord::Rollback is the only exception that won't be passed on + # # by ActiveRecord::Base.transaction, so this line will still be reached + # # even on Friday. + # redirect_to root_url + # end + # end + class Rollback < ActiveRecordError + end + + # Raised when attribute has a name reserved by Active Record (when attribute + # has name of one of Active Record instance methods). + class DangerousAttributeError < ActiveRecordError + end + + # Raised when unknown attributes are supplied via mass assignment. + class UnknownAttributeError < NoMethodError + + attr_reader :record, :attribute + + def initialize(record, attribute) + @record = record + @attribute = attribute.to_s + super("unknown attribute '#{attribute}' for #{@record.class}.") + end + + end + + # Raised when an error occurred while doing a mass assignment to an attribute through the + # +attributes=+ method. The exception has an +attribute+ property that is the name of the + # offending attribute. + class AttributeAssignmentError < ActiveRecordError + attr_reader :exception, :attribute + + def initialize(message, exception, attribute) + super(message) + @exception = exception + @attribute = attribute + end + end + + # Raised when there are multiple errors while doing a mass assignment through the +attributes+ + # method. The exception has an +errors+ property that contains an array of AttributeAssignmentError + # objects, each corresponding to the error while assigning to an attribute. + class MultiparameterAssignmentErrors < ActiveRecordError + attr_reader :errors + + def initialize(errors) + @errors = errors + end + end + + # Raised when a primary key is needed, but not specified in the schema or model. + class UnknownPrimaryKey < ActiveRecordError + attr_reader :model + + def initialize(model, description = nil) + message = "Unknown primary key for table #{model.table_name} in model #{model}." + message += "\n#{description}" if description + super(message) + @model = model + end + end + + # Raised when a relation cannot be mutated because it's already loaded. + # + # class Task < ActiveRecord::Base + # end + # + # relation = Task.all + # relation.loaded? # => true + # + # # Methods which try to mutate a loaded relation fail. + # relation.where!(title: 'TODO') # => ActiveRecord::ImmutableRelation + # relation.limit!(5) # => ActiveRecord::ImmutableRelation + class ImmutableRelation < ActiveRecordError + end + + # TransactionIsolationError will be raised under the following conditions: + # + # * The adapter does not support setting the isolation level + # * You are joining an existing open transaction + # * You are creating a nested (savepoint) transaction + # + # The mysql, mysql2 and postgresql adapters support setting the transaction isolation level. + class TransactionIsolationError < ActiveRecordError + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/explain.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/explain.rb new file mode 100644 index 0000000..727a9be --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/explain.rb @@ -0,0 +1,38 @@ +require 'active_support/lazy_load_hooks' +require 'active_record/explain_registry' + +module ActiveRecord + module Explain + # Executes the block with the collect flag enabled. Queries are collected + # asynchronously by the subscriber and returned. + def collecting_queries_for_explain # :nodoc: + ExplainRegistry.collect = true + yield + ExplainRegistry.queries + ensure + ExplainRegistry.reset + end + + # Makes the adapter execute EXPLAIN for the tuples of queries and bindings. + # Returns a formatted string ready to be logged. + def exec_explain(queries) # :nodoc: + str = queries.map do |sql, bind| + [].tap do |msg| + msg << "EXPLAIN for: #{sql}" + unless bind.empty? + bind_msg = bind.map {|col, val| [col.name, val]}.inspect + msg.last << " #{bind_msg}" + end + msg << connection.explain(sql, bind) + end.join("\n") + end.join("\n") + + # Overriding inspect to be more human readable, especially in the console. + def str.inspect + self + end + + str + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/explain_registry.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/explain_registry.rb new file mode 100644 index 0000000..f5cd57e --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/explain_registry.rb @@ -0,0 +1,30 @@ +require 'active_support/per_thread_registry' + +module ActiveRecord + # This is a thread locals registry for EXPLAIN. For example + # + # ActiveRecord::ExplainRegistry.queries + # + # returns the collected queries local to the current thread. + # + # See the documentation of ActiveSupport::PerThreadRegistry + # for further details. + class ExplainRegistry # :nodoc: + extend ActiveSupport::PerThreadRegistry + + attr_accessor :queries, :collect + + def initialize + reset + end + + def collect? + @collect + end + + def reset + @collect = false + @queries = [] + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/explain_subscriber.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/explain_subscriber.rb new file mode 100644 index 0000000..9adabd7 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/explain_subscriber.rb @@ -0,0 +1,29 @@ +require 'active_support/notifications' +require 'active_record/explain_registry' + +module ActiveRecord + class ExplainSubscriber # :nodoc: + def start(name, id, payload) + # unused + end + + def finish(name, id, payload) + if ExplainRegistry.collect? && !ignore_payload?(payload) + ExplainRegistry.queries << payload.values_at(:sql, :binds) + end + end + + # SCHEMA queries cannot be EXPLAINed, also we do not want to run EXPLAIN on + # our own EXPLAINs now matter how loopingly beautiful that would be. + # + # On the other hand, we want to monitor the performance of our real database + # queries, not the performance of the access to the query cache. + IGNORED_PAYLOADS = %w(SCHEMA EXPLAIN CACHE) + EXPLAINED_SQLS = /\A\s*(with|select|update|delete|insert)\b/i + def ignore_payload?(payload) + payload[:exception] || IGNORED_PAYLOADS.include?(payload[:name]) || payload[:sql] !~ EXPLAINED_SQLS + end + + ActiveSupport::Notifications.subscribe("sql.active_record", new) + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/fixture_set/file.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/fixture_set/file.rb new file mode 100644 index 0000000..8132310 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/fixture_set/file.rb @@ -0,0 +1,56 @@ +require 'erb' +require 'yaml' + +module ActiveRecord + class FixtureSet + class File # :nodoc: + include Enumerable + + ## + # Open a fixture file named +file+. When called with a block, the block + # is called with the filehandle and the filehandle is automatically closed + # when the block finishes. + def self.open(file) + x = new file + block_given? ? yield(x) : x + end + + def initialize(file) + @file = file + @rows = nil + end + + def each(&block) + rows.each(&block) + end + + + private + def rows + return @rows if @rows + + begin + data = YAML.load(render(IO.read(@file))) + rescue ArgumentError, Psych::SyntaxError => error + raise Fixture::FormatError, "a YAML error occurred parsing #{@file}. Please note that YAML must be consistently indented using spaces. Tabs are not allowed. Please have a look at http://www.yaml.org/faq.html\nThe exact error was:\n #{error.class}: #{error}", error.backtrace + end + @rows = data ? validate(data).to_a : [] + end + + def render(content) + context = ActiveRecord::FixtureSet::RenderContext.create_subclass.new + ERB.new(content).result(context.get_binding) + end + + # Validate our unmarshalled data. + def validate(data) + unless Hash === data || YAML::Omap === data + raise Fixture::FormatError, 'fixture is not a hash' + end + + raise Fixture::FormatError unless data.all? { |name, row| Hash === row } + data + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/fixtures.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/fixtures.rb new file mode 100644 index 0000000..15fb6c7 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/fixtures.rb @@ -0,0 +1,1009 @@ +require 'erb' +require 'yaml' +require 'zlib' +require 'active_support/dependencies' +require 'active_support/core_ext/digest/uuid' +require 'active_record/fixture_set/file' +require 'active_record/errors' + +module ActiveRecord + class FixtureClassNotFound < ActiveRecord::ActiveRecordError #:nodoc: + end + + # \Fixtures are a way of organizing data that you want to test against; in short, sample data. + # + # They are stored in YAML files, one file per model, which are placed in the directory + # appointed by ActiveSupport::TestCase.fixture_path=(path) (this is automatically + # configured for Rails, so you can just put your files in /test/fixtures/). + # The fixture file ends with the +.yml+ file extension, for example: + # /test/fixtures/web_sites.yml). + # + # The format of a fixture file looks like this: + # + # rubyonrails: + # id: 1 + # name: Ruby on Rails + # url: http://www.rubyonrails.org + # + # google: + # id: 2 + # name: Google + # url: http://www.google.com + # + # This fixture file includes two fixtures. Each YAML fixture (ie. record) is given a name and + # is followed by an indented list of key/value pairs in the "key: value" format. Records are + # separated by a blank line for your viewing pleasure. + # + # Note: Fixtures are unordered. If you want ordered fixtures, use the omap YAML type. + # See http://yaml.org/type/omap.html + # for the specification. You will need ordered fixtures when you have foreign key constraints + # on keys in the same table. This is commonly needed for tree structures. Example: + # + # --- !omap + # - parent: + # id: 1 + # parent_id: NULL + # title: Parent + # - child: + # id: 2 + # parent_id: 1 + # title: Child + # + # = Using Fixtures in Test Cases + # + # Since fixtures are a testing construct, we use them in our unit and functional tests. There + # are two ways to use the fixtures, but first let's take a look at a sample unit test: + # + # require 'test_helper' + # + # class WebSiteTest < ActiveSupport::TestCase + # test "web_site_count" do + # assert_equal 2, WebSite.count + # end + # end + # + # By default, +test_helper.rb+ will load all of your fixtures into your test + # database, so this test will succeed. + # + # The testing environment will automatically load the all fixtures into the database before each + # test. To ensure consistent data, the environment deletes the fixtures before running the load. + # + # In addition to being available in the database, the fixture's data may also be accessed by + # using a special dynamic method, which has the same name as the model, and accepts the + # name of the fixture to instantiate: + # + # test "find" do + # assert_equal "Ruby on Rails", web_sites(:rubyonrails).name + # end + # + # Alternatively, you may enable auto-instantiation of the fixture data. For instance, take the + # following tests: + # + # test "find_alt_method_1" do + # assert_equal "Ruby on Rails", @web_sites['rubyonrails']['name'] + # end + # + # test "find_alt_method_2" do + # assert_equal "Ruby on Rails", @rubyonrails.name + # end + # + # In order to use these methods to access fixtured data within your testcases, you must specify one of the + # following in your ActiveSupport::TestCase-derived class: + # + # - to fully enable instantiated fixtures (enable alternate methods #1 and #2 above) + # self.use_instantiated_fixtures = true + # + # - create only the hash for the fixtures, do not 'find' each instance (enable alternate method #1 only) + # self.use_instantiated_fixtures = :no_instances + # + # Using either of these alternate methods incurs a performance hit, as the fixtured data must be fully + # traversed in the database to create the fixture hash and/or instance variables. This is expensive for + # large sets of fixtured data. + # + # = Dynamic fixtures with ERB + # + # Some times you don't care about the content of the fixtures as much as you care about the volume. + # In these cases, you can mix ERB in with your YAML fixtures to create a bunch of fixtures for load + # testing, like: + # + # <% 1.upto(1000) do |i| %> + # fix_<%= i %>: + # id: <%= i %> + # name: guy_<%= 1 %> + # <% end %> + # + # This will create 1000 very simple fixtures. + # + # Using ERB, you can also inject dynamic values into your fixtures with inserts like + # <%= Date.today.strftime("%Y-%m-%d") %>. + # This is however a feature to be used with some caution. The point of fixtures are that they're + # stable units of predictable sample data. If you feel that you need to inject dynamic values, then + # perhaps you should reexamine whether your application is properly testable. Hence, dynamic values + # in fixtures are to be considered a code smell. + # + # Helper methods defined in a fixture will not be available in other fixtures, to prevent against + # unwanted inter-test dependencies. Methods used by multiple fixtures should be defined in a module + # that is included in ActiveRecord::FixtureSet.context_class. + # + # - define a helper method in `test_helper.rb` + # module FixtureFileHelpers + # def file_sha(path) + # Digest::SHA2.hexdigest(File.read(Rails.root.join('test/fixtures', path))) + # end + # end + # ActiveRecord::FixtureSet.context_class.send :include, FixtureFileHelpers + # + # - use the helper method in a fixture + # photo: + # name: kitten.png + # sha: <%= file_sha 'files/kitten.png' %> + # + # = Transactional Fixtures + # + # Test cases can use begin+rollback to isolate their changes to the database instead of having to + # delete+insert for every test case. + # + # class FooTest < ActiveSupport::TestCase + # self.use_transactional_fixtures = true + # + # test "godzilla" do + # assert !Foo.all.empty? + # Foo.destroy_all + # assert Foo.all.empty? + # end + # + # test "godzilla aftermath" do + # assert !Foo.all.empty? + # end + # end + # + # If you preload your test database with all fixture data (probably in the rake task) and use + # transactional fixtures, then you may omit all fixtures declarations in your test cases since + # all the data's already there and every case rolls back its changes. + # + # In order to use instantiated fixtures with preloaded data, set +self.pre_loaded_fixtures+ to + # true. This will provide access to fixture data for every table that has been loaded through + # fixtures (depending on the value of +use_instantiated_fixtures+). + # + # When *not* to use transactional fixtures: + # + # 1. You're testing whether a transaction works correctly. Nested transactions don't commit until + # all parent transactions commit, particularly, the fixtures transaction which is begun in setup + # and rolled back in teardown. Thus, you won't be able to verify + # the results of your transaction until Active Record supports nested transactions or savepoints (in progress). + # 2. Your database does not support transactions. Every Active Record database supports transactions except MySQL MyISAM. + # Use InnoDB, MaxDB, or NDB instead. + # + # = Advanced Fixtures + # + # Fixtures that don't specify an ID get some extra features: + # + # * Stable, autogenerated IDs + # * Label references for associations (belongs_to, has_one, has_many) + # * HABTM associations as inline lists + # + # There are some more advanced features available even if the id is specified: + # + # * Autofilled timestamp columns + # * Fixture label interpolation + # * Support for YAML defaults + # + # == Stable, Autogenerated IDs + # + # Here, have a monkey fixture: + # + # george: + # id: 1 + # name: George the Monkey + # + # reginald: + # id: 2 + # name: Reginald the Pirate + # + # Each of these fixtures has two unique identifiers: one for the database + # and one for the humans. Why don't we generate the primary key instead? + # Hashing each fixture's label yields a consistent ID: + # + # george: # generated id: 503576764 + # name: George the Monkey + # + # reginald: # generated id: 324201669 + # name: Reginald the Pirate + # + # Active Record looks at the fixture's model class, discovers the correct + # primary key, and generates it right before inserting the fixture + # into the database. + # + # The generated ID for a given label is constant, so we can discover + # any fixture's ID without loading anything, as long as we know the label. + # + # == Label references for associations (belongs_to, has_one, has_many) + # + # Specifying foreign keys in fixtures can be very fragile, not to + # mention difficult to read. Since Active Record can figure out the ID of + # any fixture from its label, you can specify FK's by label instead of ID. + # + # === belongs_to + # + # Let's break out some more monkeys and pirates. + # + # ### in pirates.yml + # + # reginald: + # id: 1 + # name: Reginald the Pirate + # monkey_id: 1 + # + # ### in monkeys.yml + # + # george: + # id: 1 + # name: George the Monkey + # pirate_id: 1 + # + # Add a few more monkeys and pirates and break this into multiple files, + # and it gets pretty hard to keep track of what's going on. Let's + # use labels instead of IDs: + # + # ### in pirates.yml + # + # reginald: + # name: Reginald the Pirate + # monkey: george + # + # ### in monkeys.yml + # + # george: + # name: George the Monkey + # pirate: reginald + # + # Pow! All is made clear. Active Record reflects on the fixture's model class, + # finds all the +belongs_to+ associations, and allows you to specify + # a target *label* for the *association* (monkey: george) rather than + # a target *id* for the *FK* (monkey_id: 1). + # + # ==== Polymorphic belongs_to + # + # Supporting polymorphic relationships is a little bit more complicated, since + # Active Record needs to know what type your association is pointing at. Something + # like this should look familiar: + # + # ### in fruit.rb + # + # belongs_to :eater, polymorphic: true + # + # ### in fruits.yml + # + # apple: + # id: 1 + # name: apple + # eater_id: 1 + # eater_type: Monkey + # + # Can we do better? You bet! + # + # apple: + # eater: george (Monkey) + # + # Just provide the polymorphic target type and Active Record will take care of the rest. + # + # === has_and_belongs_to_many + # + # Time to give our monkey some fruit. + # + # ### in monkeys.yml + # + # george: + # id: 1 + # name: George the Monkey + # + # ### in fruits.yml + # + # apple: + # id: 1 + # name: apple + # + # orange: + # id: 2 + # name: orange + # + # grape: + # id: 3 + # name: grape + # + # ### in fruits_monkeys.yml + # + # apple_george: + # fruit_id: 1 + # monkey_id: 1 + # + # orange_george: + # fruit_id: 2 + # monkey_id: 1 + # + # grape_george: + # fruit_id: 3 + # monkey_id: 1 + # + # Let's make the HABTM fixture go away. + # + # ### in monkeys.yml + # + # george: + # id: 1 + # name: George the Monkey + # fruits: apple, orange, grape + # + # ### in fruits.yml + # + # apple: + # name: apple + # + # orange: + # name: orange + # + # grape: + # name: grape + # + # Zap! No more fruits_monkeys.yml file. We've specified the list of fruits + # on George's fixture, but we could've just as easily specified a list + # of monkeys on each fruit. As with +belongs_to+, Active Record reflects on + # the fixture's model class and discovers the +has_and_belongs_to_many+ + # associations. + # + # == Autofilled Timestamp Columns + # + # If your table/model specifies any of Active Record's + # standard timestamp columns (+created_at+, +created_on+, +updated_at+, +updated_on+), + # they will automatically be set to Time.now. + # + # If you've set specific values, they'll be left alone. + # + # == Fixture label interpolation + # + # The label of the current fixture is always available as a column value: + # + # geeksomnia: + # name: Geeksomnia's Account + # subdomain: $LABEL + # email: $LABEL@email.com + # + # Also, sometimes (like when porting older join table fixtures) you'll need + # to be able to get a hold of the identifier for a given label. ERB + # to the rescue: + # + # george_reginald: + # monkey_id: <%= ActiveRecord::FixtureSet.identify(:reginald) %> + # pirate_id: <%= ActiveRecord::FixtureSet.identify(:george) %> + # + # == Support for YAML defaults + # + # You can set and reuse defaults in your fixtures YAML file. + # This is the same technique used in the +database.yml+ file to specify + # defaults: + # + # DEFAULTS: &DEFAULTS + # created_on: <%= 3.weeks.ago.to_s(:db) %> + # + # first: + # name: Smurf + # <<: *DEFAULTS + # + # second: + # name: Fraggle + # <<: *DEFAULTS + # + # Any fixture labeled "DEFAULTS" is safely ignored. + class FixtureSet + #-- + # An instance of FixtureSet is normally stored in a single YAML file and + # possibly in a folder with the same name. + #++ + + MAX_ID = 2 ** 30 - 1 + + @@all_cached_fixtures = Hash.new { |h,k| h[k] = {} } + + def self.default_fixture_model_name(fixture_set_name, config = ActiveRecord::Base) # :nodoc: + config.pluralize_table_names ? + fixture_set_name.singularize.camelize : + fixture_set_name.camelize + end + + def self.default_fixture_table_name(fixture_set_name, config = ActiveRecord::Base) # :nodoc: + "#{ config.table_name_prefix }"\ + "#{ fixture_set_name.tr('/', '_') }"\ + "#{ config.table_name_suffix }".to_sym + end + + def self.reset_cache + @@all_cached_fixtures.clear + end + + def self.cache_for_connection(connection) + @@all_cached_fixtures[connection] + end + + def self.fixture_is_cached?(connection, table_name) + cache_for_connection(connection)[table_name] + end + + def self.cached_fixtures(connection, keys_to_fetch = nil) + if keys_to_fetch + cache_for_connection(connection).values_at(*keys_to_fetch) + else + cache_for_connection(connection).values + end + end + + def self.cache_fixtures(connection, fixtures_map) + cache_for_connection(connection).update(fixtures_map) + end + + def self.instantiate_fixtures(object, fixture_set, load_instances = true) + if load_instances + fixture_set.each do |fixture_name, fixture| + begin + object.instance_variable_set "@#{fixture_name}", fixture.find + rescue FixtureClassNotFound + nil + end + end + end + end + + def self.instantiate_all_loaded_fixtures(object, load_instances = true) + all_loaded_fixtures.each_value do |fixture_set| + instantiate_fixtures(object, fixture_set, load_instances) + end + end + + cattr_accessor :all_loaded_fixtures + self.all_loaded_fixtures = {} + + class ClassCache + def initialize(class_names, config) + @class_names = class_names.stringify_keys + @config = config + + # Remove string values that aren't constants or subclasses of AR + @class_names.delete_if { |klass_name, klass| !insert_class(@class_names, klass_name, klass) } + end + + def [](fs_name) + @class_names.fetch(fs_name) { + klass = default_fixture_model(fs_name, @config).safe_constantize + insert_class(@class_names, fs_name, klass) + } + end + + private + + def insert_class(class_names, name, klass) + # We only want to deal with AR objects. + if klass && klass < ActiveRecord::Base + class_names[name] = klass + else + class_names[name] = nil + end + end + + def default_fixture_model(fs_name, config) + ActiveRecord::FixtureSet.default_fixture_model_name(fs_name, config) + end + end + + def self.create_fixtures(fixtures_directory, fixture_set_names, class_names = {}, config = ActiveRecord::Base) + fixture_set_names = Array(fixture_set_names).map(&:to_s) + class_names = ClassCache.new class_names, config + + # FIXME: Apparently JK uses this. + connection = block_given? ? yield : ActiveRecord::Base.connection + + files_to_read = fixture_set_names.reject { |fs_name| + fixture_is_cached?(connection, fs_name) + } + + unless files_to_read.empty? + connection.disable_referential_integrity do + fixtures_map = {} + + fixture_sets = files_to_read.map do |fs_name| + klass = class_names[fs_name] + conn = klass ? klass.connection : connection + fixtures_map[fs_name] = new( # ActiveRecord::FixtureSet.new + conn, + fs_name, + klass, + ::File.join(fixtures_directory, fs_name)) + end + + update_all_loaded_fixtures fixtures_map + + connection.transaction(:requires_new => true) do + fixture_sets.each do |fs| + conn = fs.model_class.respond_to?(:connection) ? fs.model_class.connection : connection + table_rows = fs.table_rows + + table_rows.each_key do |table| + conn.delete "DELETE FROM #{conn.quote_table_name(table)}", 'Fixture Delete' + end + + table_rows.each do |fixture_set_name, rows| + rows.each do |row| + conn.insert_fixture(row, fixture_set_name) + end + end + + # Cap primary key sequences to max(pk). + if conn.respond_to?(:reset_pk_sequence!) + conn.reset_pk_sequence!(fs.table_name) + end + end + end + + cache_fixtures(connection, fixtures_map) + end + end + cached_fixtures(connection, fixture_set_names) + end + + # Returns a consistent, platform-independent identifier for +label+. + # Integer identifiers are values less than 2^30. UUIDs are RFC 4122 version 5 SHA-1 hashes. + def self.identify(label, column_type = :integer) + if column_type == :uuid + Digest::UUID.uuid_v5(Digest::UUID::OID_NAMESPACE, label.to_s) + else + Zlib.crc32(label.to_s) % MAX_ID + end + end + + # Superclass for the evaluation contexts used by ERB fixtures. + def self.context_class + @context_class ||= Class.new + end + + def self.update_all_loaded_fixtures(fixtures_map) # :nodoc: + all_loaded_fixtures.update(fixtures_map) + end + + attr_reader :table_name, :name, :fixtures, :model_class, :config + + def initialize(connection, name, class_name, path, config = ActiveRecord::Base) + @name = name + @path = path + @config = config + @model_class = nil + + if class_name.is_a?(Class) # TODO: Should be an AR::Base type class, or any? + @model_class = class_name + else + @model_class = class_name.safe_constantize if class_name + end + + @connection = connection + + @table_name = ( model_class.respond_to?(:table_name) ? + model_class.table_name : + self.class.default_fixture_table_name(name, config) ) + + @fixtures = read_fixture_files path, @model_class + end + + def [](x) + fixtures[x] + end + + def []=(k,v) + fixtures[k] = v + end + + def each(&block) + fixtures.each(&block) + end + + def size + fixtures.size + end + + # Returns a hash of rows to be inserted. The key is the table, the value is + # a list of rows to insert to that table. + def table_rows + now = config.default_timezone == :utc ? Time.now.utc : Time.now + now = now.to_s(:db) + + # allow a standard key to be used for doing defaults in YAML + fixtures.delete('DEFAULTS') + + # track any join tables we need to insert later + rows = Hash.new { |h,table| h[table] = [] } + + rows[table_name] = fixtures.map do |label, fixture| + row = fixture.to_hash + + if model_class + # fill in timestamp columns if they aren't specified and the model is set to record_timestamps + if model_class.record_timestamps + timestamp_column_names.each do |c_name| + row[c_name] = now unless row.key?(c_name) + end + end + + # interpolate the fixture label + row.each do |key, value| + row[key] = value.gsub("$LABEL", label.to_s) if value.is_a?(String) + end + + # generate a primary key if necessary + if has_primary_key_column? && !row.include?(primary_key_name) + row[primary_key_name] = ActiveRecord::FixtureSet.identify(label, primary_key_type) + end + + # If STI is used, find the correct subclass for association reflection + reflection_class = + if row.include?(inheritance_column_name) + row[inheritance_column_name].constantize rescue model_class + else + model_class + end + + reflection_class._reflections.each_value do |association| + case association.macro + when :belongs_to + # Do not replace association name with association foreign key if they are named the same + fk_name = (association.options[:foreign_key] || "#{association.name}_id").to_s + + if association.name.to_s != fk_name && value = row.delete(association.name.to_s) + if association.polymorphic? && value.sub!(/\s*\(([^\)]*)\)\s*$/, "") + # support polymorphic belongs_to as "label (Type)" + row[association.foreign_type] = $1 + end + + fk_type = reflection_class.columns_hash[fk_name].type + row[fk_name] = ActiveRecord::FixtureSet.identify(value, fk_type) + end + when :has_many + if association.options[:through] + add_join_records(rows, row, HasManyThroughProxy.new(association)) + end + end + end + end + + row + end + rows + end + + class ReflectionProxy # :nodoc: + def initialize(association) + @association = association + end + + def join_table + @association.join_table + end + + def name + @association.name + end + + def primary_key_type + @association.klass.column_types[@association.klass.primary_key].type + end + end + + class HasManyThroughProxy < ReflectionProxy # :nodoc: + def rhs_key + @association.foreign_key + end + + def lhs_key + @association.through_reflection.foreign_key + end + + def join_table + @association.through_reflection.table_name + end + end + + private + def primary_key_name + @primary_key_name ||= model_class && model_class.primary_key + end + + def primary_key_type + @primary_key_type ||= model_class && model_class.column_types[model_class.primary_key].type + end + + def add_join_records(rows, row, association) + # This is the case when the join table has no fixtures file + if (targets = row.delete(association.name.to_s)) + table_name = association.join_table + column_type = association.primary_key_type + lhs_key = association.lhs_key + rhs_key = association.rhs_key + + targets = targets.is_a?(Array) ? targets : targets.split(/\s*,\s*/) + rows[table_name].concat targets.map { |target| + { lhs_key => row[primary_key_name], + rhs_key => ActiveRecord::FixtureSet.identify(target, column_type) } + } + end + end + + def has_primary_key_column? + @has_primary_key_column ||= primary_key_name && + model_class.columns.any? { |c| c.name == primary_key_name } + end + + def timestamp_column_names + @timestamp_column_names ||= + %w(created_at created_on updated_at updated_on) & column_names + end + + def inheritance_column_name + @inheritance_column_name ||= model_class && model_class.inheritance_column + end + + def column_names + @column_names ||= @connection.columns(@table_name).collect { |c| c.name } + end + + def read_fixture_files(path, model_class) + yaml_files = Dir["#{path}/{**,*}/*.yml"].select { |f| + ::File.file?(f) + } + [yaml_file_path(path)] + + yaml_files.each_with_object({}) do |file, fixtures| + FixtureSet::File.open(file) do |fh| + fh.each do |fixture_name, row| + fixtures[fixture_name] = ActiveRecord::Fixture.new(row, model_class) + end + end + end + end + + def yaml_file_path(path) + "#{path}.yml" + end + + end + + #-- + # Deprecate 'Fixtures' in favor of 'FixtureSet'. + #++ + # :nodoc: + Fixtures = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('ActiveRecord::Fixtures', 'ActiveRecord::FixtureSet') + + class Fixture #:nodoc: + include Enumerable + + class FixtureError < StandardError #:nodoc: + end + + class FormatError < FixtureError #:nodoc: + end + + attr_reader :model_class, :fixture + + def initialize(fixture, model_class) + @fixture = fixture + @model_class = model_class + end + + def class_name + model_class.name if model_class + end + + def each + fixture.each { |item| yield item } + end + + def [](key) + fixture[key] + end + + alias :to_hash :fixture + + def find + if model_class + model_class.unscoped do + model_class.find(fixture[model_class.primary_key]) + end + else + raise FixtureClassNotFound, "No class attached to find." + end + end + end +end + +module ActiveRecord + module TestFixtures + extend ActiveSupport::Concern + + def before_setup + setup_fixtures + super + end + + def after_teardown + super + teardown_fixtures + end + + included do + class_attribute :fixture_path, :instance_writer => false + class_attribute :fixture_table_names + class_attribute :fixture_class_names + class_attribute :use_transactional_fixtures + class_attribute :use_instantiated_fixtures # true, false, or :no_instances + class_attribute :pre_loaded_fixtures + class_attribute :config + + self.fixture_table_names = [] + self.use_transactional_fixtures = true + self.use_instantiated_fixtures = false + self.pre_loaded_fixtures = false + self.config = ActiveRecord::Base + + self.fixture_class_names = Hash.new do |h, fixture_set_name| + h[fixture_set_name] = ActiveRecord::FixtureSet.default_fixture_model_name(fixture_set_name, self.config) + end + end + + module ClassMethods + # Sets the model class for a fixture when the class name cannot be inferred from the fixture name. + # + # Examples: + # + # set_fixture_class some_fixture: SomeModel, + # 'namespaced/fixture' => Another::Model + # + # The keys must be the fixture names, that coincide with the short paths to the fixture files. + def set_fixture_class(class_names = {}) + self.fixture_class_names = self.fixture_class_names.merge(class_names.stringify_keys) + end + + def fixtures(*fixture_set_names) + if fixture_set_names.first == :all + fixture_set_names = Dir["#{fixture_path}/{**,*}/*.{yml}"] + fixture_set_names.map! { |f| f[(fixture_path.to_s.size + 1)..-5] } + else + fixture_set_names = fixture_set_names.flatten.map { |n| n.to_s } + end + + self.fixture_table_names |= fixture_set_names + setup_fixture_accessors(fixture_set_names) + end + + def setup_fixture_accessors(fixture_set_names = nil) + fixture_set_names = Array(fixture_set_names || fixture_table_names) + methods = Module.new do + fixture_set_names.each do |fs_name| + fs_name = fs_name.to_s + accessor_name = fs_name.tr('/', '_').to_sym + + define_method(accessor_name) do |*fixture_names| + force_reload = fixture_names.pop if fixture_names.last == true || fixture_names.last == :reload + + @fixture_cache[fs_name] ||= {} + + instances = fixture_names.map do |f_name| + f_name = f_name.to_s + @fixture_cache[fs_name].delete(f_name) if force_reload + + if @loaded_fixtures[fs_name][f_name] + @fixture_cache[fs_name][f_name] ||= @loaded_fixtures[fs_name][f_name].find + else + raise StandardError, "No fixture named '#{f_name}' found for fixture set '#{fs_name}'" + end + end + + instances.size == 1 ? instances.first : instances + end + private accessor_name + end + end + include methods + end + + def uses_transaction(*methods) + @uses_transaction = [] unless defined?(@uses_transaction) + @uses_transaction.concat methods.map { |m| m.to_s } + end + + def uses_transaction?(method) + @uses_transaction = [] unless defined?(@uses_transaction) + @uses_transaction.include?(method.to_s) + end + end + + def run_in_transaction? + use_transactional_fixtures && + !self.class.uses_transaction?(method_name) + end + + def setup_fixtures(config = ActiveRecord::Base) + if pre_loaded_fixtures && !use_transactional_fixtures + raise RuntimeError, 'pre_loaded_fixtures requires use_transactional_fixtures' + end + + @fixture_cache = {} + @fixture_connections = [] + @@already_loaded_fixtures ||= {} + + # Load fixtures once and begin transaction. + if run_in_transaction? + if @@already_loaded_fixtures[self.class] + @loaded_fixtures = @@already_loaded_fixtures[self.class] + else + @loaded_fixtures = load_fixtures(config) + @@already_loaded_fixtures[self.class] = @loaded_fixtures + end + @fixture_connections = enlist_fixture_connections + @fixture_connections.each do |connection| + connection.begin_transaction joinable: false + end + # Load fixtures for every test. + else + ActiveRecord::FixtureSet.reset_cache + @@already_loaded_fixtures[self.class] = nil + @loaded_fixtures = load_fixtures(config) + end + + # Instantiate fixtures for every test if requested. + instantiate_fixtures if use_instantiated_fixtures + end + + def teardown_fixtures + # Rollback changes if a transaction is active. + if run_in_transaction? + @fixture_connections.each do |connection| + connection.rollback_transaction if connection.transaction_open? + end + @fixture_connections.clear + else + ActiveRecord::FixtureSet.reset_cache + end + + ActiveRecord::Base.clear_active_connections! + end + + def enlist_fixture_connections + ActiveRecord::Base.connection_handler.connection_pool_list.map(&:connection) + end + + private + def load_fixtures(config) + fixtures = ActiveRecord::FixtureSet.create_fixtures(fixture_path, fixture_table_names, fixture_class_names, config) + Hash[fixtures.map { |f| [f.name, f] }] + end + + def instantiate_fixtures + if pre_loaded_fixtures + raise RuntimeError, 'Load fixtures before instantiating them.' if ActiveRecord::FixtureSet.all_loaded_fixtures.empty? + ActiveRecord::FixtureSet.instantiate_all_loaded_fixtures(self, load_instances?) + else + raise RuntimeError, 'Load fixtures before instantiating them.' if @loaded_fixtures.nil? + @loaded_fixtures.each_value do |fixture_set| + ActiveRecord::FixtureSet.instantiate_fixtures(self, fixture_set, load_instances?) + end + end + end + + def load_instances? + use_instantiated_fixtures != :no_instances + end + end +end + +class ActiveRecord::FixtureSet::RenderContext # :nodoc: + def self.create_subclass + Class.new ActiveRecord::FixtureSet.context_class do + def get_binding + binding() + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/gem_version.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/gem_version.rb new file mode 100644 index 0000000..222b420 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/gem_version.rb @@ -0,0 +1,15 @@ +module ActiveRecord + # Returns the version of the currently loaded Active Record as a Gem::Version + def self.gem_version + Gem::Version.new VERSION::STRING + end + + module VERSION + MAJOR = 4 + MINOR = 2 + TINY = 6 + PRE = nil + + STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".") + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/inheritance.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/inheritance.rb new file mode 100644 index 0000000..f58145a --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/inheritance.rb @@ -0,0 +1,247 @@ +require 'active_support/core_ext/hash/indifferent_access' + +module ActiveRecord + # == Single table inheritance + # + # Active Record allows inheritance by storing the name of the class in a column that by + # default is named "type" (can be changed by overwriting Base.inheritance_column). + # This means that an inheritance looking like this: + # + # class Company < ActiveRecord::Base; end + # class Firm < Company; end + # class Client < Company; end + # class PriorityClient < Client; end + # + # When you do Firm.create(name: "37signals"), this record will be saved in + # the companies table with type = "Firm". You can then fetch this row again using + # Company.where(name: '37signals').first and it will return a Firm object. + # + # Be aware that because the type column is an attribute on the record every new + # subclass will instantly be marked as dirty and the type column will be included + # in the list of changed attributes on the record. This is different from non + # STI classes: + # + # Company.new.changed? # => false + # Firm.new.changed? # => true + # Firm.new.changes # => {"type"=>["","Firm"]} + # + # If you don't have a type column defined in your table, single-table inheritance won't + # be triggered. In that case, it'll work just like normal subclasses with no special magic + # for differentiating between them or reloading the right type with find. + # + # Note, all the attributes for all the cases are kept in the same table. Read more: + # http://www.martinfowler.com/eaaCatalog/singleTableInheritance.html + # + module Inheritance + extend ActiveSupport::Concern + + included do + # Determines whether to store the full constant name including namespace when using STI. + class_attribute :store_full_sti_class, instance_writer: false + self.store_full_sti_class = true + end + + module ClassMethods + # Determines if one of the attributes passed in is the inheritance column, + # and if the inheritance column is attr accessible, it initializes an + # instance of the given subclass instead of the base class. + def new(*args, &block) + if abstract_class? || self == Base + raise NotImplementedError, "#{self} is an abstract class and cannot be instantiated." + end + + attrs = args.first + if subclass_from_attributes?(attrs) + subclass = subclass_from_attributes(attrs) + end + + if subclass + subclass.new(*args, &block) + else + super + end + end + + # Returns +true+ if this does not need STI type condition. Returns + # +false+ if STI type condition needs to be applied. + def descends_from_active_record? + if self == Base + false + elsif superclass.abstract_class? + superclass.descends_from_active_record? + else + superclass == Base || !columns_hash.include?(inheritance_column) + end + end + + def finder_needs_type_condition? #:nodoc: + # This is like this because benchmarking justifies the strange :false stuff + :true == (@finder_needs_type_condition ||= descends_from_active_record? ? :false : :true) + end + + def symbolized_base_class + ActiveSupport::Deprecation.warn('`ActiveRecord::Base.symbolized_base_class` is deprecated and will be removed without replacement.') + @symbolized_base_class ||= base_class.to_s.to_sym + end + + def symbolized_sti_name + ActiveSupport::Deprecation.warn('`ActiveRecord::Base.symbolized_sti_name` is deprecated and will be removed without replacement.') + @symbolized_sti_name ||= sti_name.present? ? sti_name.to_sym : symbolized_base_class + end + + # Returns the class descending directly from ActiveRecord::Base, or + # an abstract class, if any, in the inheritance hierarchy. + # + # If A extends AR::Base, A.base_class will return A. If B descends from A + # through some arbitrarily deep hierarchy, B.base_class will return A. + # + # If B < A and C < B and if A is an abstract_class then both B.base_class + # and C.base_class would return B as the answer since A is an abstract_class. + def base_class + unless self < Base + raise ActiveRecordError, "#{name} doesn't belong in a hierarchy descending from ActiveRecord" + end + + if superclass == Base || superclass.abstract_class? + self + else + superclass.base_class + end + end + + # Set this to true if this is an abstract class (see abstract_class?). + # If you are using inheritance with ActiveRecord and don't want child classes + # to utilize the implied STI table name of the parent class, this will need to be true. + # For example, given the following: + # + # class SuperClass < ActiveRecord::Base + # self.abstract_class = true + # end + # class Child < SuperClass + # self.table_name = 'the_table_i_really_want' + # end + # + # + # self.abstract_class = true is required to make Child<.find,.create, or any Arel method> use the_table_i_really_want instead of a table called super_classes + # + attr_accessor :abstract_class + + # Returns whether this class is an abstract class or not. + def abstract_class? + defined?(@abstract_class) && @abstract_class == true + end + + def sti_name + store_full_sti_class ? name : name.demodulize + end + + protected + + # Returns the class type of the record using the current module as a prefix. So descendants of + # MyApp::Business::Account would appear as MyApp::Business::AccountSubclass. + def compute_type(type_name) + if type_name.match(/^::/) + # If the type is prefixed with a scope operator then we assume that + # the type_name is an absolute reference. + ActiveSupport::Dependencies.constantize(type_name) + else + # Build a list of candidates to search for + candidates = [] + name.scan(/::|$/) { candidates.unshift "#{$`}::#{type_name}" } + candidates << type_name + + candidates.each do |candidate| + constant = ActiveSupport::Dependencies.safe_constantize(candidate) + return constant if candidate == constant.to_s + end + + raise NameError.new("uninitialized constant #{candidates.first}", candidates.first) + end + end + + private + + # Called by +instantiate+ to decide which class to use for a new + # record instance. For single-table inheritance, we check the record + # for a +type+ column and return the corresponding class. + def discriminate_class_for_record(record) + if using_single_table_inheritance?(record) + find_sti_class(record[inheritance_column]) + else + super + end + end + + def using_single_table_inheritance?(record) + record[inheritance_column].present? && columns_hash.include?(inheritance_column) + end + + def find_sti_class(type_name) + if store_full_sti_class + ActiveSupport::Dependencies.constantize(type_name) + else + compute_type(type_name) + end + rescue NameError + raise SubclassNotFound, + "The single-table inheritance mechanism failed to locate the subclass: '#{type_name}'. " + + "This error is raised because the column '#{inheritance_column}' is reserved for storing the class in case of inheritance. " + + "Please rename this column if you didn't intend it to be used for storing the inheritance class " + + "or overwrite #{name}.inheritance_column to use another column for that information." + end + + def type_condition(table = arel_table) + sti_column = table[inheritance_column] + sti_names = ([self] + descendants).map { |model| model.sti_name } + + sti_column.in(sti_names) + end + + # Detect the subclass from the inheritance column of attrs. If the inheritance column value + # is not self or a valid subclass, raises ActiveRecord::SubclassNotFound + # If this is a StrongParameters hash, and access to inheritance_column is not permitted, + # this will ignore the inheritance column and return nil + def subclass_from_attributes?(attrs) + columns_hash.include?(inheritance_column) && attrs.is_a?(Hash) + end + + def subclass_from_attributes(attrs) + subclass_name = attrs.with_indifferent_access[inheritance_column] + + if subclass_name.present? && subclass_name != self.name + subclass = subclass_name.safe_constantize + + unless descendants.include?(subclass) + raise ActiveRecord::SubclassNotFound.new("Invalid single-table inheritance type: #{subclass_name} is not a subclass of #{name}") + end + + subclass + end + end + end + + def initialize_dup(other) + super + ensure_proper_type + end + + private + + def initialize_internals_callback + super + ensure_proper_type + end + + # Sets the attribute used for single table inheritance to this class name if this is not the + # ActiveRecord::Base descendant. + # Considering the hierarchy Reply < Message < ActiveRecord::Base, this makes it possible to + # do Reply.new without having to set Reply[Reply.inheritance_column] = "Reply" yourself. + # No such attribute would be set for objects of the Message class in that example. + def ensure_proper_type + klass = self.class + if klass.finder_needs_type_condition? + write_attribute(klass.inheritance_column, klass.sti_name) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/integration.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/integration.rb new file mode 100644 index 0000000..15b2f65 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/integration.rb @@ -0,0 +1,113 @@ +require 'active_support/core_ext/string/filters' + +module ActiveRecord + module Integration + extend ActiveSupport::Concern + + included do + ## + # :singleton-method: + # Indicates the format used to generate the timestamp in the cache key. + # Accepts any of the symbols in Time::DATE_FORMATS. + # + # This is +:nsec+, by default. + class_attribute :cache_timestamp_format, :instance_writer => false + self.cache_timestamp_format = :nsec + end + + # Returns a String, which Action Pack uses for constructing an URL to this + # object. The default implementation returns this record's id as a String, + # or nil if this record's unsaved. + # + # For example, suppose that you have a User model, and that you have a + # resources :users route. Normally, +user_path+ will + # construct a path with the user object's 'id' in it: + # + # user = User.find_by(name: 'Phusion') + # user_path(user) # => "/users/1" + # + # You can override +to_param+ in your model to make +user_path+ construct + # a path using the user's name instead of the user's id: + # + # class User < ActiveRecord::Base + # def to_param # overridden + # name + # end + # end + # + # user = User.find_by(name: 'Phusion') + # user_path(user) # => "/users/Phusion" + def to_param + # We can't use alias_method here, because method 'id' optimizes itself on the fly. + id && id.to_s # Be sure to stringify the id for routes + end + + # Returns a cache key that can be used to identify this record. + # + # Product.new.cache_key # => "products/new" + # Product.find(5).cache_key # => "products/5" (updated_at not available) + # Person.find(5).cache_key # => "people/5-20071224150000" (updated_at available) + # + # You can also pass a list of named timestamps, and the newest in the list will be + # used to generate the key: + # + # Person.find(5).cache_key(:updated_at, :last_reviewed_at) + def cache_key(*timestamp_names) + case + when new_record? + "#{model_name.cache_key}/new" + when timestamp_names.any? + timestamp = max_updated_column_timestamp(timestamp_names) + timestamp = timestamp.utc.to_s(cache_timestamp_format) + "#{model_name.cache_key}/#{id}-#{timestamp}" + when timestamp = max_updated_column_timestamp + timestamp = timestamp.utc.to_s(cache_timestamp_format) + "#{model_name.cache_key}/#{id}-#{timestamp}" + else + "#{model_name.cache_key}/#{id}" + end + end + + module ClassMethods + # Defines your model's +to_param+ method to generate "pretty" URLs + # using +method_name+, which can be any attribute or method that + # responds to +to_s+. + # + # class User < ActiveRecord::Base + # to_param :name + # end + # + # user = User.find_by(name: 'Fancy Pants') + # user.id # => 123 + # user_path(user) # => "/users/123-fancy-pants" + # + # Values longer than 20 characters will be truncated. The value + # is truncated word by word. + # + # user = User.find_by(name: 'David HeinemeierHansson') + # user.id # => 125 + # user_path(user) # => "/users/125-david" + # + # Because the generated param begins with the record's +id+, it is + # suitable for passing to +find+. In a controller, for example: + # + # params[:id] # => "123-fancy-pants" + # User.find(params[:id]).id # => 123 + def to_param(method_name = nil) + if method_name.nil? + super() + else + define_method :to_param do + if (default = super()) && + (result = send(method_name).to_s).present? && + (param = result.squish.truncate(20, separator: /\s/, omission: nil).parameterize).present? + "#{default}-#{param}" + else + default + end + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/legacy_yaml_adapter.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/legacy_yaml_adapter.rb new file mode 100644 index 0000000..655cafe --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/legacy_yaml_adapter.rb @@ -0,0 +1,30 @@ +module ActiveRecord + module LegacyYamlAdapter + def self.convert(klass, coder) + return coder unless coder.is_a?(Psych::Coder) + + case coder["active_record_yaml_version"] + when 0 then coder + else + if coder["attributes"].is_a?(AttributeSet) + coder + else + Rails41.convert(klass, coder) + end + end + end + + module Rails41 + def self.convert(klass, coder) + attributes = klass.attributes_builder + .build_from_database(coder["attributes"]) + new_record = coder["attributes"][klass.primary_key].blank? + + { + "attributes" => attributes, + "new_record" => new_record, + } + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/locale/en.yml b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/locale/en.yml new file mode 100644 index 0000000..b1fbd38 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/locale/en.yml @@ -0,0 +1,47 @@ +en: + # Attributes names common to most models + #attributes: + #created_at: "Created at" + #updated_at: "Updated at" + + # Default error messages + errors: + messages: + taken: "has already been taken" + + # Active Record models configuration + activerecord: + errors: + messages: + record_invalid: "Validation failed: %{errors}" + restrict_dependent_destroy: + one: "Cannot delete record because a dependent %{record} exists" + many: "Cannot delete record because dependent %{record} exist" + # Append your own errors here or at the model/attributes scope. + + # You can define own errors for models or model attributes. + # The values :model, :attribute and :value are always available for interpolation. + # + # For example, + # models: + # user: + # blank: "This is a custom blank message for %{model}: %{attribute}" + # attributes: + # login: + # blank: "This is a custom blank message for User login" + # Will define custom blank validation message for User model and + # custom blank validation message for login attribute of User model. + #models: + + # Translate model names. Used in Model.human_name(). + #models: + # For example, + # user: "Dude" + # will translate User model name to "Dude" + + # Translate model attribute names. Used in Model.human_attribute_name(attribute). + #attributes: + # For example, + # user: + # login: "Handle" + # will translate User attribute "login" as "Handle" diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/locking/optimistic.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/locking/optimistic.rb new file mode 100644 index 0000000..bd28f59 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/locking/optimistic.rb @@ -0,0 +1,206 @@ +module ActiveRecord + module Locking + # == What is Optimistic Locking + # + # Optimistic locking allows multiple users to access the same record for edits, and assumes a minimum of + # conflicts with the data. It does this by checking whether another process has made changes to a record since + # it was opened, an ActiveRecord::StaleObjectError exception is thrown if that has occurred + # and the update is ignored. + # + # Check out ActiveRecord::Locking::Pessimistic for an alternative. + # + # == Usage + # + # Active Records support optimistic locking if the field +lock_version+ is present. Each update to the + # record increments the +lock_version+ column and the locking facilities ensure that records instantiated twice + # will let the last one saved raise a +StaleObjectError+ if the first was also updated. Example: + # + # p1 = Person.find(1) + # p2 = Person.find(1) + # + # p1.first_name = "Michael" + # p1.save + # + # p2.first_name = "should fail" + # p2.save # Raises a ActiveRecord::StaleObjectError + # + # Optimistic locking will also check for stale data when objects are destroyed. Example: + # + # p1 = Person.find(1) + # p2 = Person.find(1) + # + # p1.first_name = "Michael" + # p1.save + # + # p2.destroy # Raises a ActiveRecord::StaleObjectError + # + # You're then responsible for dealing with the conflict by rescuing the exception and either rolling back, merging, + # or otherwise apply the business logic needed to resolve the conflict. + # + # This locking mechanism will function inside a single Ruby process. To make it work across all + # web requests, the recommended approach is to add +lock_version+ as a hidden field to your form. + # + # This behavior can be turned off by setting ActiveRecord::Base.lock_optimistically = false. + # To override the name of the +lock_version+ column, set the locking_column class attribute: + # + # class Person < ActiveRecord::Base + # self.locking_column = :lock_person + # end + # + module Optimistic + extend ActiveSupport::Concern + + included do + class_attribute :lock_optimistically, instance_writer: false + self.lock_optimistically = true + end + + def locking_enabled? #:nodoc: + self.class.locking_enabled? + end + + private + def increment_lock + lock_col = self.class.locking_column + previous_lock_value = send(lock_col).to_i + send(lock_col + '=', previous_lock_value + 1) + end + + def _create_record(attribute_names = self.attribute_names, *) # :nodoc: + if locking_enabled? + # We always want to persist the locking version, even if we don't detect + # a change from the default, since the database might have no default + attribute_names |= [self.class.locking_column] + end + super + end + + def _update_record(attribute_names = self.attribute_names) #:nodoc: + return super unless locking_enabled? + return 0 if attribute_names.empty? + + lock_col = self.class.locking_column + previous_lock_value = send(lock_col).to_i + increment_lock + + attribute_names += [lock_col] + attribute_names.uniq! + + begin + relation = self.class.unscoped + + affected_rows = relation.where( + self.class.primary_key => id, + lock_col => previous_lock_value, + ).update_all( + Hash[attributes_for_update(attribute_names).map do |name| + [name, _read_attribute(name)] + end] + ) + + unless affected_rows == 1 + raise ActiveRecord::StaleObjectError.new(self, "update") + end + + affected_rows + + # If something went wrong, revert the version. + rescue Exception + send(lock_col + '=', previous_lock_value) + raise + end + end + + def destroy_row + affected_rows = super + + if locking_enabled? && affected_rows != 1 + raise ActiveRecord::StaleObjectError.new(self, "destroy") + end + + affected_rows + end + + def relation_for_destroy + relation = super + + if locking_enabled? + column_name = self.class.locking_column + column = self.class.columns_hash[column_name] + substitute = self.class.connection.substitute_at(column) + + relation = relation.where(self.class.arel_table[column_name].eq(substitute)) + relation.bind_values << [column, self[column_name].to_i] + end + + relation + end + + module ClassMethods + DEFAULT_LOCKING_COLUMN = 'lock_version' + + # Returns true if the +lock_optimistically+ flag is set to true + # (which it is, by default) and the table includes the + # +locking_column+ column (defaults to +lock_version+). + def locking_enabled? + lock_optimistically && columns_hash[locking_column] + end + + # Set the column to use for optimistic locking. Defaults to +lock_version+. + def locking_column=(value) + clear_caches_calculated_from_columns + @locking_column = value.to_s + end + + # The version column used for optimistic locking. Defaults to +lock_version+. + def locking_column + reset_locking_column unless defined?(@locking_column) + @locking_column + end + + # Reset the column used for optimistic locking back to the +lock_version+ default. + def reset_locking_column + self.locking_column = DEFAULT_LOCKING_COLUMN + end + + # Make sure the lock version column gets updated when counters are + # updated. + def update_counters(id, counters) + counters = counters.merge(locking_column => 1) if locking_enabled? + super + end + + private + + # We need to apply this decorator here, rather than on module inclusion. The closure + # created by the matcher would otherwise evaluate for `ActiveRecord::Base`, not the + # sub class being decorated. As such, changes to `lock_optimistically`, or + # `locking_column` would not be picked up. + def inherited(subclass) + subclass.class_eval do + is_lock_column = ->(name, _) { lock_optimistically && name == locking_column } + decorate_matching_attribute_types(is_lock_column, :_optimistic_locking) do |type| + LockingType.new(type) + end + end + super + end + end + end + + class LockingType < SimpleDelegator # :nodoc: + def type_cast_from_database(value) + # `nil` *should* be changed to 0 + super.to_i + end + + def init_with(coder) + __setobj__(coder['subtype']) + end + + def encode_with(coder) + coder['subtype'] = __getobj__ + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/locking/pessimistic.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/locking/pessimistic.rb new file mode 100644 index 0000000..ff7102d --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/locking/pessimistic.rb @@ -0,0 +1,77 @@ +module ActiveRecord + module Locking + # Locking::Pessimistic provides support for row-level locking using + # SELECT ... FOR UPDATE and other lock types. + # + # Chain ActiveRecord::Base#find to ActiveRecord::QueryMethods#lock to obtain an exclusive + # lock on the selected rows: + # # select * from accounts where id=1 for update + # Account.lock.find(1) + # + # Call lock('some locking clause') to use a database-specific locking clause + # of your own such as 'LOCK IN SHARE MODE' or 'FOR UPDATE NOWAIT'. Example: + # + # Account.transaction do + # # select * from accounts where name = 'shugo' limit 1 for update + # shugo = Account.where("name = 'shugo'").lock(true).first + # yuko = Account.where("name = 'yuko'").lock(true).first + # shugo.balance -= 100 + # shugo.save! + # yuko.balance += 100 + # yuko.save! + # end + # + # You can also use ActiveRecord::Base#lock! method to lock one record by id. + # This may be better if you don't need to lock every row. Example: + # + # Account.transaction do + # # select * from accounts where ... + # accounts = Account.where(...) + # account1 = accounts.detect { |account| ... } + # account2 = accounts.detect { |account| ... } + # # select * from accounts where id=? for update + # account1.lock! + # account2.lock! + # account1.balance -= 100 + # account1.save! + # account2.balance += 100 + # account2.save! + # end + # + # You can start a transaction and acquire the lock in one go by calling + # with_lock with a block. The block is called from within + # a transaction, the object is already locked. Example: + # + # account = Account.first + # account.with_lock do + # # This block is called within a transaction, + # # account is already locked. + # account.balance -= 100 + # account.save! + # end + # + # Database-specific information on row locking: + # MySQL: http://dev.mysql.com/doc/refman/5.1/en/innodb-locking-reads.html + # PostgreSQL: http://www.postgresql.org/docs/current/interactive/sql-select.html#SQL-FOR-UPDATE-SHARE + module Pessimistic + # Obtain a row lock on this record. Reloads the record to obtain the requested + # lock. Pass an SQL locking clause to append the end of the SELECT statement + # or pass true for "FOR UPDATE" (the default, an exclusive row lock). Returns + # the locked record. + def lock!(lock = true) + reload(:lock => lock) if persisted? + self + end + + # Wraps the passed block in a transaction, locking the object + # before yielding. You can pass the SQL locking clause + # as argument (see lock!). + def with_lock(lock = true) + transaction do + lock!(lock) + yield + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/log_subscriber.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/log_subscriber.rb new file mode 100644 index 0000000..eb64d19 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/log_subscriber.rb @@ -0,0 +1,75 @@ +module ActiveRecord + class LogSubscriber < ActiveSupport::LogSubscriber + IGNORE_PAYLOAD_NAMES = ["SCHEMA", "EXPLAIN"] + + def self.runtime=(value) + ActiveRecord::RuntimeRegistry.sql_runtime = value + end + + def self.runtime + ActiveRecord::RuntimeRegistry.sql_runtime ||= 0 + end + + def self.reset_runtime + rt, self.runtime = runtime, 0 + rt + end + + def initialize + super + @odd = false + end + + def render_bind(column, value) + if column + if column.binary? + # This specifically deals with the PG adapter that casts bytea columns into a Hash. + value = value[:value] if value.is_a?(Hash) + value = value ? "<#{value.bytesize} bytes of binary data>" : "" + end + + [column.name, value] + else + [nil, value] + end + end + + def sql(event) + self.class.runtime += event.duration + return unless logger.debug? + + payload = event.payload + + return if IGNORE_PAYLOAD_NAMES.include?(payload[:name]) + + name = "#{payload[:name]} (#{event.duration.round(1)}ms)" + sql = payload[:sql] + binds = nil + + unless (payload[:binds] || []).empty? + binds = " " + payload[:binds].map { |col,v| + render_bind(col, v) + }.inspect + end + + if odd? + name = color(name, CYAN, true) + sql = color(sql, nil, true) + else + name = color(name, MAGENTA, true) + end + + debug " #{name} #{sql}#{binds}" + end + + def odd? + @odd = !@odd + end + + def logger + ActiveRecord::Base.logger + end + end +end + +ActiveRecord::LogSubscriber.attach_to :active_record diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/migration.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/migration.rb new file mode 100644 index 0000000..a6bb97a --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/migration.rb @@ -0,0 +1,1054 @@ +require "active_support/core_ext/module/attribute_accessors" +require 'set' + +module ActiveRecord + class MigrationError < ActiveRecordError#:nodoc: + def initialize(message = nil) + message = "\n\n#{message}\n\n" if message + super + end + end + + # Exception that can be raised to stop migrations from going backwards. + class IrreversibleMigration < MigrationError + end + + class DuplicateMigrationVersionError < MigrationError#:nodoc: + def initialize(version) + super("Multiple migrations have the version number #{version}") + end + end + + class DuplicateMigrationNameError < MigrationError#:nodoc: + def initialize(name) + super("Multiple migrations have the name #{name}") + end + end + + class UnknownMigrationVersionError < MigrationError #:nodoc: + def initialize(version) + super("No migration with version number #{version}") + end + end + + class IllegalMigrationNameError < MigrationError#:nodoc: + def initialize(name) + super("Illegal name for migration file: #{name}\n\t(only lower case letters, numbers, and '_' allowed)") + end + end + + class PendingMigrationError < MigrationError#:nodoc: + def initialize + if defined?(Rails.env) + super("Migrations are pending. To resolve this issue, run:\n\n\tbin/rake db:migrate RAILS_ENV=#{::Rails.env}") + else + super("Migrations are pending. To resolve this issue, run:\n\n\tbin/rake db:migrate") + end + end + end + + # = Active Record Migrations + # + # Migrations can manage the evolution of a schema used by several physical + # databases. It's a solution to the common problem of adding a field to make + # a new feature work in your local database, but being unsure of how to + # push that change to other developers and to the production server. With + # migrations, you can describe the transformations in self-contained classes + # that can be checked into version control systems and executed against + # another database that might be one, two, or five versions behind. + # + # Example of a simple migration: + # + # class AddSsl < ActiveRecord::Migration + # def up + # add_column :accounts, :ssl_enabled, :boolean, default: true + # end + # + # def down + # remove_column :accounts, :ssl_enabled + # end + # end + # + # This migration will add a boolean flag to the accounts table and remove it + # if you're backing out of the migration. It shows how all migrations have + # two methods +up+ and +down+ that describes the transformations + # required to implement or remove the migration. These methods can consist + # of both the migration specific methods like +add_column+ and +remove_column+, + # but may also contain regular Ruby code for generating data needed for the + # transformations. + # + # Example of a more complex migration that also needs to initialize data: + # + # class AddSystemSettings < ActiveRecord::Migration + # def up + # create_table :system_settings do |t| + # t.string :name + # t.string :label + # t.text :value + # t.string :type + # t.integer :position + # end + # + # SystemSetting.create name: 'notice', + # label: 'Use notice?', + # value: 1 + # end + # + # def down + # drop_table :system_settings + # end + # end + # + # This migration first adds the +system_settings+ table, then creates the very + # first row in it using the Active Record model that relies on the table. It + # also uses the more advanced +create_table+ syntax where you can specify a + # complete table schema in one block call. + # + # == Available transformations + # + # * create_table(name, options): Creates a table called +name+ and + # makes the table object available to a block that can then add columns to it, + # following the same format as +add_column+. See example above. The options hash + # is for fragments like "DEFAULT CHARSET=UTF-8" that are appended to the create + # table definition. + # * drop_table(name): Drops the table called +name+. + # * change_table(name, options): Allows to make column alterations to + # the table called +name+. It makes the table object available to a block that + # can then add/remove columns, indexes or foreign keys to it. + # * rename_table(old_name, new_name): Renames the table called +old_name+ + # to +new_name+. + # * add_column(table_name, column_name, type, options): Adds a new column + # to the table called +table_name+ + # named +column_name+ specified to be one of the following types: + # :string, :text, :integer, :float, + # :decimal, :datetime, :timestamp, :time, + # :date, :binary, :boolean. A default value can be + # specified by passing an +options+ hash like { default: 11 }. + # Other options include :limit and :null (e.g. + # { limit: 50, null: false }) -- see + # ActiveRecord::ConnectionAdapters::TableDefinition#column for details. + # * rename_column(table_name, column_name, new_column_name): Renames + # a column but keeps the type and content. + # * change_column(table_name, column_name, type, options): Changes + # the column to a different type using the same parameters as add_column. + # * remove_column(table_name, column_name, type, options): Removes the column + # named +column_name+ from the table called +table_name+. + # * add_index(table_name, column_names, options): Adds a new index + # with the name of the column. Other options include + # :name, :unique (e.g. + # { name: 'users_name_index', unique: true }) and :order + # (e.g. { order: { name: :desc } }). + # * remove_index(table_name, column: column_name): Removes the index + # specified by +column_name+. + # * remove_index(table_name, name: index_name): Removes the index + # specified by +index_name+. + # + # == Irreversible transformations + # + # Some transformations are destructive in a manner that cannot be reversed. + # Migrations of that kind should raise an ActiveRecord::IrreversibleMigration + # exception in their +down+ method. + # + # == Running migrations from within Rails + # + # The Rails package has several tools to help create and apply migrations. + # + # To generate a new migration, you can use + # rails generate migration MyNewMigration + # + # where MyNewMigration is the name of your migration. The generator will + # create an empty migration file timestamp_my_new_migration.rb + # in the db/migrate/ directory where timestamp is the + # UTC formatted date and time that the migration was generated. + # + # There is a special syntactic shortcut to generate migrations that add fields to a table. + # + # rails generate migration add_fieldname_to_tablename fieldname:string + # + # This will generate the file timestamp_add_fieldname_to_tablename, which will look like this: + # class AddFieldnameToTablename < ActiveRecord::Migration + # def change + # add_column :tablenames, :field, :string + # end + # end + # + # To run migrations against the currently configured database, use + # rake db:migrate. This will update the database by running all of the + # pending migrations, creating the schema_migrations table + # (see "About the schema_migrations table" section below) if missing. It will also + # invoke the db:schema:dump task, which will update your db/schema.rb file + # to match the structure of your database. + # + # To roll the database back to a previous migration version, use + # rake db:migrate VERSION=X where X is the version to which + # you wish to downgrade. Alternatively, you can also use the STEP option if you + # wish to rollback last few migrations. rake db:migrate STEP=2 will rollback + # the latest two migrations. + # + # If any of the migrations throw an ActiveRecord::IrreversibleMigration exception, + # that step will fail and you'll have some manual work to do. + # + # == Database support + # + # Migrations are currently supported in MySQL, PostgreSQL, SQLite, + # SQL Server, and Oracle (all supported databases except DB2). + # + # == More examples + # + # Not all migrations change the schema. Some just fix the data: + # + # class RemoveEmptyTags < ActiveRecord::Migration + # def up + # Tag.all.each { |tag| tag.destroy if tag.pages.empty? } + # end + # + # def down + # # not much we can do to restore deleted data + # raise ActiveRecord::IrreversibleMigration, "Can't recover the deleted tags" + # end + # end + # + # Others remove columns when they migrate up instead of down: + # + # class RemoveUnnecessaryItemAttributes < ActiveRecord::Migration + # def up + # remove_column :items, :incomplete_items_count + # remove_column :items, :completed_items_count + # end + # + # def down + # add_column :items, :incomplete_items_count + # add_column :items, :completed_items_count + # end + # end + # + # And sometimes you need to do something in SQL not abstracted directly by migrations: + # + # class MakeJoinUnique < ActiveRecord::Migration + # def up + # execute "ALTER TABLE `pages_linked_pages` ADD UNIQUE `page_id_linked_page_id` (`page_id`,`linked_page_id`)" + # end + # + # def down + # execute "ALTER TABLE `pages_linked_pages` DROP INDEX `page_id_linked_page_id`" + # end + # end + # + # == Using a model after changing its table + # + # Sometimes you'll want to add a column in a migration and populate it + # immediately after. In that case, you'll need to make a call to + # Base#reset_column_information in order to ensure that the model has the + # latest column data from after the new column was added. Example: + # + # class AddPeopleSalary < ActiveRecord::Migration + # def up + # add_column :people, :salary, :integer + # Person.reset_column_information + # Person.all.each do |p| + # p.update_attribute :salary, SalaryCalculator.compute(p) + # end + # end + # end + # + # == Controlling verbosity + # + # By default, migrations will describe the actions they are taking, writing + # them to the console as they happen, along with benchmarks describing how + # long each step took. + # + # You can quiet them down by setting ActiveRecord::Migration.verbose = false. + # + # You can also insert your own messages and benchmarks by using the +say_with_time+ + # method: + # + # def up + # ... + # say_with_time "Updating salaries..." do + # Person.all.each do |p| + # p.update_attribute :salary, SalaryCalculator.compute(p) + # end + # end + # ... + # end + # + # The phrase "Updating salaries..." would then be printed, along with the + # benchmark for the block when the block completes. + # + # == About the schema_migrations table + # + # Rails versions 2.0 and prior used to create a table called + # schema_info when using migrations. This table contained the + # version of the schema as of the last applied migration. + # + # Starting with Rails 2.1, the schema_info table is + # (automatically) replaced by the schema_migrations table, which + # contains the version numbers of all the migrations applied. + # + # As a result, it is now possible to add migration files that are numbered + # lower than the current schema version: when migrating up, those + # never-applied "interleaved" migrations will be automatically applied, and + # when migrating down, never-applied "interleaved" migrations will be skipped. + # + # == Timestamped Migrations + # + # By default, Rails generates migrations that look like: + # + # 20080717013526_your_migration_name.rb + # + # The prefix is a generation timestamp (in UTC). + # + # If you'd prefer to use numeric prefixes, you can turn timestamped migrations + # off by setting: + # + # config.active_record.timestamped_migrations = false + # + # In application.rb. + # + # == Reversible Migrations + # + # Reversible migrations are migrations that know how to go +down+ for you. + # You simply supply the +up+ logic, and the Migration system figures out + # how to execute the down commands for you. + # + # To define a reversible migration, define the +change+ method in your + # migration like this: + # + # class TenderloveMigration < ActiveRecord::Migration + # def change + # create_table(:horses) do |t| + # t.column :content, :text + # t.column :remind_at, :datetime + # end + # end + # end + # + # This migration will create the horses table for you on the way up, and + # automatically figure out how to drop the table on the way down. + # + # Some commands like +remove_column+ cannot be reversed. If you care to + # define how to move up and down in these cases, you should define the +up+ + # and +down+ methods as before. + # + # If a command cannot be reversed, an + # ActiveRecord::IrreversibleMigration exception will be raised when + # the migration is moving down. + # + # For a list of commands that are reversible, please see + # ActiveRecord::Migration::CommandRecorder. + # + # == Transactional Migrations + # + # If the database adapter supports DDL transactions, all migrations will + # automatically be wrapped in a transaction. There are queries that you + # can't execute inside a transaction though, and for these situations + # you can turn the automatic transactions off. + # + # class ChangeEnum < ActiveRecord::Migration + # disable_ddl_transaction! + # + # def up + # execute "ALTER TYPE model_size ADD VALUE 'new_value'" + # end + # end + # + # Remember that you can still open your own transactions, even if you + # are in a Migration with self.disable_ddl_transaction!. + class Migration + autoload :CommandRecorder, 'active_record/migration/command_recorder' + + + # This class is used to verify that all migrations have been run before + # loading a web page if config.active_record.migration_error is set to :page_load + class CheckPending + def initialize(app) + @app = app + @last_check = 0 + end + + def call(env) + if connection.supports_migrations? + mtime = ActiveRecord::Migrator.last_migration.mtime.to_i + if @last_check < mtime + ActiveRecord::Migration.check_pending!(connection) + @last_check = mtime + end + end + @app.call(env) + end + + private + + def connection + ActiveRecord::Base.connection + end + end + + class << self + attr_accessor :delegate # :nodoc: + attr_accessor :disable_ddl_transaction # :nodoc: + + def check_pending!(connection = Base.connection) + raise ActiveRecord::PendingMigrationError if ActiveRecord::Migrator.needs_migration?(connection) + end + + def load_schema_if_pending! + if ActiveRecord::Migrator.needs_migration? || !ActiveRecord::Migrator.any_migrations? + # Roundrip to Rake to allow plugins to hook into database initialization. + FileUtils.cd Rails.root do + current_config = Base.connection_config + Base.clear_all_connections! + system("bin/rake db:test:prepare") + # Establish a new connection, the old database may be gone (db:test:prepare uses purge) + Base.establish_connection(current_config) + end + check_pending! + end + end + + def maintain_test_schema! # :nodoc: + if ActiveRecord::Base.maintain_test_schema + suppress_messages { load_schema_if_pending! } + end + end + + def method_missing(name, *args, &block) # :nodoc: + (delegate || superclass.delegate).send(name, *args, &block) + end + + def migrate(direction) + new.migrate direction + end + + # Disable the transaction wrapping this migration. + # You can still create your own transactions even after calling #disable_ddl_transaction! + # + # For more details read the {"Transactional Migrations" section above}[rdoc-ref:Migration]. + def disable_ddl_transaction! + @disable_ddl_transaction = true + end + end + + def disable_ddl_transaction # :nodoc: + self.class.disable_ddl_transaction + end + + cattr_accessor :verbose + attr_accessor :name, :version + + def initialize(name = self.class.name, version = nil) + @name = name + @version = version + @connection = nil + end + + self.verbose = true + # instantiate the delegate object after initialize is defined + self.delegate = new + + # Reverses the migration commands for the given block and + # the given migrations. + # + # The following migration will remove the table 'horses' + # and create the table 'apples' on the way up, and the reverse + # on the way down. + # + # class FixTLMigration < ActiveRecord::Migration + # def change + # revert do + # create_table(:horses) do |t| + # t.text :content + # t.datetime :remind_at + # end + # end + # create_table(:apples) do |t| + # t.string :variety + # end + # end + # end + # + # Or equivalently, if +TenderloveMigration+ is defined as in the + # documentation for Migration: + # + # require_relative '2012121212_tenderlove_migration' + # + # class FixupTLMigration < ActiveRecord::Migration + # def change + # revert TenderloveMigration + # + # create_table(:apples) do |t| + # t.string :variety + # end + # end + # end + # + # This command can be nested. + def revert(*migration_classes) + run(*migration_classes.reverse, revert: true) unless migration_classes.empty? + if block_given? + if @connection.respond_to? :revert + @connection.revert { yield } + else + recorder = CommandRecorder.new(@connection) + @connection = recorder + suppress_messages do + @connection.revert { yield } + end + @connection = recorder.delegate + recorder.commands.each do |cmd, args, block| + send(cmd, *args, &block) + end + end + end + end + + def reverting? + @connection.respond_to?(:reverting) && @connection.reverting + end + + class ReversibleBlockHelper < Struct.new(:reverting) # :nodoc: + def up + yield unless reverting + end + + def down + yield if reverting + end + end + + # Used to specify an operation that can be run in one direction or another. + # Call the methods +up+ and +down+ of the yielded object to run a block + # only in one given direction. + # The whole block will be called in the right order within the migration. + # + # In the following example, the looping on users will always be done + # when the three columns 'first_name', 'last_name' and 'full_name' exist, + # even when migrating down: + # + # class SplitNameMigration < ActiveRecord::Migration + # def change + # add_column :users, :first_name, :string + # add_column :users, :last_name, :string + # + # reversible do |dir| + # User.reset_column_information + # User.all.each do |u| + # dir.up { u.first_name, u.last_name = u.full_name.split(' ') } + # dir.down { u.full_name = "#{u.first_name} #{u.last_name}" } + # u.save + # end + # end + # + # revert { add_column :users, :full_name, :string } + # end + # end + def reversible + helper = ReversibleBlockHelper.new(reverting?) + execute_block{ yield helper } + end + + # Runs the given migration classes. + # Last argument can specify options: + # - :direction (default is :up) + # - :revert (default is false) + def run(*migration_classes) + opts = migration_classes.extract_options! + dir = opts[:direction] || :up + dir = (dir == :down ? :up : :down) if opts[:revert] + if reverting? + # If in revert and going :up, say, we want to execute :down without reverting, so + revert { run(*migration_classes, direction: dir, revert: true) } + else + migration_classes.each do |migration_class| + migration_class.new.exec_migration(@connection, dir) + end + end + end + + def up + self.class.delegate = self + return unless self.class.respond_to?(:up) + self.class.up + end + + def down + self.class.delegate = self + return unless self.class.respond_to?(:down) + self.class.down + end + + # Execute this migration in the named direction + def migrate(direction) + return unless respond_to?(direction) + + case direction + when :up then announce "migrating" + when :down then announce "reverting" + end + + time = nil + ActiveRecord::Base.connection_pool.with_connection do |conn| + time = Benchmark.measure do + exec_migration(conn, direction) + end + end + + case direction + when :up then announce "migrated (%.4fs)" % time.real; write + when :down then announce "reverted (%.4fs)" % time.real; write + end + end + + def exec_migration(conn, direction) + @connection = conn + if respond_to?(:change) + if direction == :down + revert { change } + else + change + end + else + send(direction) + end + ensure + @connection = nil + end + + def write(text="") + puts(text) if verbose + end + + def announce(message) + text = "#{version} #{name}: #{message}" + length = [0, 75 - text.length].max + write "== %s %s" % [text, "=" * length] + end + + def say(message, subitem=false) + write "#{subitem ? " ->" : "--"} #{message}" + end + + def say_with_time(message) + say(message) + result = nil + time = Benchmark.measure { result = yield } + say "%.4fs" % time.real, :subitem + say("#{result} rows", :subitem) if result.is_a?(Integer) + result + end + + def suppress_messages + save, self.verbose = verbose, false + yield + ensure + self.verbose = save + end + + def connection + @connection || ActiveRecord::Base.connection + end + + def method_missing(method, *arguments, &block) + arg_list = arguments.map{ |a| a.inspect } * ', ' + + say_with_time "#{method}(#{arg_list})" do + unless @connection.respond_to? :revert + unless arguments.empty? || [:execute, :enable_extension, :disable_extension].include?(method) + arguments[0] = proper_table_name(arguments.first, table_name_options) + if [:rename_table, :add_foreign_key].include?(method) || + (method == :remove_foreign_key && !arguments.second.is_a?(Hash)) + arguments[1] = proper_table_name(arguments.second, table_name_options) + end + end + end + return super unless connection.respond_to?(method) + connection.send(method, *arguments, &block) + end + end + + def copy(destination, sources, options = {}) + copied = [] + + FileUtils.mkdir_p(destination) unless File.exist?(destination) + + destination_migrations = ActiveRecord::Migrator.migrations(destination) + last = destination_migrations.last + sources.each do |scope, path| + source_migrations = ActiveRecord::Migrator.migrations(path) + + source_migrations.each do |migration| + source = File.binread(migration.filename) + inserted_comment = "# This migration comes from #{scope} (originally #{migration.version})\n" + if /\A#.*\b(?:en)?coding:\s*\S+/ =~ source + # If we have a magic comment in the original migration, + # insert our comment after the first newline(end of the magic comment line) + # so the magic keep working. + # Note that magic comments must be at the first line(except sh-bang). + source[/\n/] = "\n#{inserted_comment}" + else + source = "#{inserted_comment}#{source}" + end + + if duplicate = destination_migrations.detect { |m| m.name == migration.name } + if options[:on_skip] && duplicate.scope != scope.to_s + options[:on_skip].call(scope, migration) + end + next + end + + migration.version = next_migration_number(last ? last.version + 1 : 0).to_i + new_path = File.join(destination, "#{migration.version}_#{migration.name.underscore}.#{scope}.rb") + old_path, migration.filename = migration.filename, new_path + last = migration + + File.binwrite(migration.filename, source) + copied << migration + options[:on_copy].call(scope, migration, old_path) if options[:on_copy] + destination_migrations << migration + end + end + + copied + end + + # Finds the correct table name given an Active Record object. + # Uses the Active Record object's own table_name, or pre/suffix from the + # options passed in. + def proper_table_name(name, options = {}) + if name.respond_to? :table_name + name.table_name + else + "#{options[:table_name_prefix]}#{name}#{options[:table_name_suffix]}" + end + end + + # Determines the version number of the next migration. + def next_migration_number(number) + if ActiveRecord::Base.timestamped_migrations + [Time.now.utc.strftime("%Y%m%d%H%M%S"), "%.14d" % number].max + else + SchemaMigration.normalize_migration_number(number) + end + end + + def table_name_options(config = ActiveRecord::Base) + { + table_name_prefix: config.table_name_prefix, + table_name_suffix: config.table_name_suffix + } + end + + private + def execute_block + if connection.respond_to? :execute_block + super # use normal delegation to record the block + else + yield + end + end + end + + # MigrationProxy is used to defer loading of the actual migration classes + # until they are needed + class MigrationProxy < Struct.new(:name, :version, :filename, :scope) + + def initialize(name, version, filename, scope) + super + @migration = nil + end + + def basename + File.basename(filename) + end + + def mtime + File.mtime filename + end + + delegate :migrate, :announce, :write, :disable_ddl_transaction, to: :migration + + private + + def migration + @migration ||= load_migration + end + + def load_migration + require(File.expand_path(filename)) + name.constantize.new(name, version) + end + + end + + class NullMigration < MigrationProxy #:nodoc: + def initialize + super(nil, 0, nil, nil) + end + + def mtime + 0 + end + end + + class Migrator#:nodoc: + class << self + attr_writer :migrations_paths + alias :migrations_path= :migrations_paths= + + def migrate(migrations_paths, target_version = nil, &block) + case + when target_version.nil? + up(migrations_paths, target_version, &block) + when current_version == 0 && target_version == 0 + [] + when current_version > target_version + down(migrations_paths, target_version, &block) + else + up(migrations_paths, target_version, &block) + end + end + + def rollback(migrations_paths, steps=1) + move(:down, migrations_paths, steps) + end + + def forward(migrations_paths, steps=1) + move(:up, migrations_paths, steps) + end + + def up(migrations_paths, target_version = nil) + migrations = migrations(migrations_paths) + migrations.select! { |m| yield m } if block_given? + + new(:up, migrations, target_version).migrate + end + + def down(migrations_paths, target_version = nil, &block) + migrations = migrations(migrations_paths) + migrations.select! { |m| yield m } if block_given? + + new(:down, migrations, target_version).migrate + end + + def run(direction, migrations_paths, target_version) + new(direction, migrations(migrations_paths), target_version).run + end + + def open(migrations_paths) + new(:up, migrations(migrations_paths), nil) + end + + def schema_migrations_table_name + SchemaMigration.table_name + end + + def get_all_versions(connection = Base.connection) + if connection.table_exists?(schema_migrations_table_name) + SchemaMigration.all.map { |x| x.version.to_i }.sort + else + [] + end + end + + def current_version(connection = Base.connection) + get_all_versions(connection).max || 0 + end + + def needs_migration?(connection = Base.connection) + (migrations(migrations_paths).collect(&:version) - get_all_versions(connection)).size > 0 + end + + def any_migrations? + migrations(migrations_paths).any? + end + + def last_version + last_migration.version + end + + def last_migration #:nodoc: + migrations(migrations_paths).last || NullMigration.new + end + + def migrations_paths + @migrations_paths ||= ['db/migrate'] + # just to not break things if someone uses: migration_path = some_string + Array(@migrations_paths) + end + + def migrations_path + migrations_paths.first + end + + def migrations(paths) + paths = Array(paths) + + files = Dir[*paths.map { |p| "#{p}/**/[0-9]*_*.rb" }] + + migrations = files.map do |file| + version, name, scope = file.scan(/([0-9]+)_([_a-z0-9]*)\.?([_a-z0-9]*)?\.rb\z/).first + + raise IllegalMigrationNameError.new(file) unless version + version = version.to_i + name = name.camelize + + MigrationProxy.new(name, version, file, scope) + end + + migrations.sort_by(&:version) + end + + private + + def move(direction, migrations_paths, steps) + migrator = new(direction, migrations(migrations_paths)) + start_index = migrator.migrations.index(migrator.current_migration) + + if start_index + finish = migrator.migrations[start_index + steps] + version = finish ? finish.version : 0 + send(direction, migrations_paths, version) + end + end + end + + def initialize(direction, migrations, target_version = nil) + raise StandardError.new("This database does not yet support migrations") unless Base.connection.supports_migrations? + + @direction = direction + @target_version = target_version + @migrated_versions = nil + @migrations = migrations + + validate(@migrations) + + Base.connection.initialize_schema_migrations_table + end + + def current_version + migrated.max || 0 + end + + def current_migration + migrations.detect { |m| m.version == current_version } + end + alias :current :current_migration + + def run + migration = migrations.detect { |m| m.version == @target_version } + raise UnknownMigrationVersionError.new(@target_version) if migration.nil? + unless (up? && migrated.include?(migration.version.to_i)) || (down? && !migrated.include?(migration.version.to_i)) + begin + execute_migration_in_transaction(migration, @direction) + rescue => e + canceled_msg = use_transaction?(migration) ? ", this migration was canceled" : "" + raise StandardError, "An error has occurred#{canceled_msg}:\n\n#{e}", e.backtrace + end + end + end + + def migrate + if !target && @target_version && @target_version > 0 + raise UnknownMigrationVersionError.new(@target_version) + end + + runnable.each do |migration| + Base.logger.info "Migrating to #{migration.name} (#{migration.version})" if Base.logger + + begin + execute_migration_in_transaction(migration, @direction) + rescue => e + canceled_msg = use_transaction?(migration) ? "this and " : "" + raise StandardError, "An error has occurred, #{canceled_msg}all later migrations canceled:\n\n#{e}", e.backtrace + end + end + end + + def runnable + runnable = migrations[start..finish] + if up? + runnable.reject { |m| ran?(m) } + else + # skip the last migration if we're headed down, but not ALL the way down + runnable.pop if target + runnable.find_all { |m| ran?(m) } + end + end + + def migrations + down? ? @migrations.reverse : @migrations.sort_by(&:version) + end + + def pending_migrations + already_migrated = migrated + migrations.reject { |m| already_migrated.include?(m.version) } + end + + def migrated + @migrated_versions ||= Set.new(self.class.get_all_versions) + end + + private + def ran?(migration) + migrated.include?(migration.version.to_i) + end + + def execute_migration_in_transaction(migration, direction) + ddl_transaction(migration) do + migration.migrate(direction) + record_version_state_after_migrating(migration.version) + end + end + + def target + migrations.detect { |m| m.version == @target_version } + end + + def finish + migrations.index(target) || migrations.size - 1 + end + + def start + up? ? 0 : (migrations.index(current) || 0) + end + + def validate(migrations) + name ,= migrations.group_by(&:name).find { |_,v| v.length > 1 } + raise DuplicateMigrationNameError.new(name) if name + + version ,= migrations.group_by(&:version).find { |_,v| v.length > 1 } + raise DuplicateMigrationVersionError.new(version) if version + end + + def record_version_state_after_migrating(version) + if down? + migrated.delete(version) + ActiveRecord::SchemaMigration.where(:version => version.to_s).delete_all + else + migrated << version + ActiveRecord::SchemaMigration.create!(:version => version.to_s) + end + end + + def up? + @direction == :up + end + + def down? + @direction == :down + end + + # Wrap the migration in a transaction only if supported by the adapter. + def ddl_transaction(migration) + if use_transaction?(migration) + Base.transaction { yield } + else + yield + end + end + + def use_transaction?(migration) + !migration.disable_ddl_transaction && Base.connection.supports_ddl_transactions? + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/migration/command_recorder.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/migration/command_recorder.rb new file mode 100644 index 0000000..3625641 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/migration/command_recorder.rb @@ -0,0 +1,197 @@ +module ActiveRecord + class Migration + # ActiveRecord::Migration::CommandRecorder records commands done during + # a migration and knows how to reverse those commands. The CommandRecorder + # knows how to invert the following commands: + # + # * add_column + # * add_index + # * add_timestamps + # * create_table + # * create_join_table + # * remove_timestamps + # * rename_column + # * rename_index + # * rename_table + class CommandRecorder + include JoinTable + + attr_accessor :commands, :delegate, :reverting + + def initialize(delegate = nil) + @commands = [] + @delegate = delegate + @reverting = false + end + + # While executing the given block, the recorded will be in reverting mode. + # All commands recorded will end up being recorded reverted + # and in reverse order. + # For example: + # + # recorder.revert{ recorder.record(:rename_table, [:old, :new]) } + # # same effect as recorder.record(:rename_table, [:new, :old]) + def revert + @reverting = !@reverting + previous = @commands + @commands = [] + yield + ensure + @commands = previous.concat(@commands.reverse) + @reverting = !@reverting + end + + # record +command+. +command+ should be a method name and arguments. + # For example: + # + # recorder.record(:method_name, [:arg1, :arg2]) + def record(*command, &block) + if @reverting + @commands << inverse_of(*command, &block) + else + @commands << (command << block) + end + end + + # Returns the inverse of the given command. For example: + # + # recorder.inverse_of(:rename_table, [:old, :new]) + # # => [:rename_table, [:new, :old]] + # + # This method will raise an +IrreversibleMigration+ exception if it cannot + # invert the +command+. + def inverse_of(command, args, &block) + method = :"invert_#{command}" + raise IrreversibleMigration unless respond_to?(method, true) + send(method, args, &block) + end + + def respond_to?(*args) # :nodoc: + super || delegate.respond_to?(*args) + end + + [:create_table, :create_join_table, :rename_table, :add_column, :remove_column, + :rename_index, :rename_column, :add_index, :remove_index, :add_timestamps, :remove_timestamps, + :change_column_default, :add_reference, :remove_reference, :transaction, + :drop_join_table, :drop_table, :execute_block, :enable_extension, + :change_column, :execute, :remove_columns, :change_column_null, + :add_foreign_key, :remove_foreign_key + # irreversible methods need to be here too + ].each do |method| + class_eval <<-EOV, __FILE__, __LINE__ + 1 + def #{method}(*args, &block) # def create_table(*args, &block) + record(:"#{method}", args, &block) # record(:create_table, args, &block) + end # end + EOV + end + alias :add_belongs_to :add_reference + alias :remove_belongs_to :remove_reference + + def change_table(table_name, options = {}) # :nodoc: + yield delegate.update_table_definition(table_name, self) + end + + private + + module StraightReversions + private + { transaction: :transaction, + execute_block: :execute_block, + create_table: :drop_table, + create_join_table: :drop_join_table, + add_column: :remove_column, + add_timestamps: :remove_timestamps, + add_reference: :remove_reference, + enable_extension: :disable_extension + }.each do |cmd, inv| + [[inv, cmd], [cmd, inv]].uniq.each do |method, inverse| + class_eval <<-EOV, __FILE__, __LINE__ + 1 + def invert_#{method}(args, &block) # def invert_create_table(args, &block) + [:#{inverse}, args, block] # [:drop_table, args, block] + end # end + EOV + end + end + end + + include StraightReversions + + def invert_drop_table(args, &block) + if args.size == 1 && block == nil + raise ActiveRecord::IrreversibleMigration, "To avoid mistakes, drop_table is only reversible if given options or a block (can be empty)." + end + super + end + + def invert_rename_table(args) + [:rename_table, args.reverse] + end + + def invert_remove_column(args) + raise ActiveRecord::IrreversibleMigration, "remove_column is only reversible if given a type." if args.size <= 2 + super + end + + def invert_rename_index(args) + [:rename_index, [args.first] + args.last(2).reverse] + end + + def invert_rename_column(args) + [:rename_column, [args.first] + args.last(2).reverse] + end + + def invert_add_index(args) + table, columns, options = *args + options ||= {} + + index_name = options[:name] + options_hash = index_name ? { name: index_name } : { column: columns } + + [:remove_index, [table, options_hash]] + end + + def invert_remove_index(args) + table, options = *args + + unless options && options.is_a?(Hash) && options[:column] + raise ActiveRecord::IrreversibleMigration, "remove_index is only reversible if given a :column option." + end + + options = options.dup + [:add_index, [table, options.delete(:column), options]] + end + + alias :invert_add_belongs_to :invert_add_reference + alias :invert_remove_belongs_to :invert_remove_reference + + def invert_change_column_null(args) + args[2] = !args[2] + [:change_column_null, args] + end + + def invert_add_foreign_key(args) + from_table, to_table, add_options = args + add_options ||= {} + + if add_options[:name] + options = { name: add_options[:name] } + elsif add_options[:column] + options = { column: add_options[:column] } + else + options = to_table + end + + [:remove_foreign_key, [from_table, options]] + end + + # Forwards any missing method call to the \target. + def method_missing(method, *args, &block) + if @delegate.respond_to?(method) + @delegate.send(method, *args, &block) + else + super + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/migration/join_table.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/migration/join_table.rb new file mode 100644 index 0000000..05569fa --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/migration/join_table.rb @@ -0,0 +1,15 @@ +module ActiveRecord + class Migration + module JoinTable #:nodoc: + private + + def find_join_table_name(table_1, table_2, options = {}) + options.delete(:table_name) || join_table_name(table_1, table_2) + end + + def join_table_name(table_1, table_2) + ModelSchema.derive_join_table_name(table_1, table_2).to_sym + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/model_schema.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/model_schema.rb new file mode 100644 index 0000000..59e647c --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/model_schema.rb @@ -0,0 +1,340 @@ +module ActiveRecord + module ModelSchema + extend ActiveSupport::Concern + + included do + ## + # :singleton-method: + # Accessor for the prefix type that will be prepended to every primary key column name. + # The options are :table_name and :table_name_with_underscore. If the first is specified, + # the Product class will look for "productid" instead of "id" as the primary column. If the + # latter is specified, the Product class will look for "product_id" instead of "id". Remember + # that this is a global setting for all Active Records. + mattr_accessor :primary_key_prefix_type, instance_writer: false + + ## + # :singleton-method: + # Accessor for the name of the prefix string to prepend to every table name. So if set + # to "basecamp_", all table names will be named like "basecamp_projects", "basecamp_people", + # etc. This is a convenient way of creating a namespace for tables in a shared database. + # By default, the prefix is the empty string. + # + # If you are organising your models within modules you can add a prefix to the models within + # a namespace by defining a singleton method in the parent module called table_name_prefix which + # returns your chosen prefix. + class_attribute :table_name_prefix, instance_writer: false + self.table_name_prefix = "" + + ## + # :singleton-method: + # Works like +table_name_prefix+, but appends instead of prepends (set to "_basecamp" gives "projects_basecamp", + # "people_basecamp"). By default, the suffix is the empty string. + # + # If you are organising your models within modules, you can add a suffix to the models within + # a namespace by defining a singleton method in the parent module called table_name_suffix which + # returns your chosen suffix. + class_attribute :table_name_suffix, instance_writer: false + self.table_name_suffix = "" + + ## + # :singleton-method: + # Accessor for the name of the schema migrations table. By default, the value is "schema_migrations" + class_attribute :schema_migrations_table_name, instance_accessor: false + self.schema_migrations_table_name = "schema_migrations" + + ## + # :singleton-method: + # Indicates whether table names should be the pluralized versions of the corresponding class names. + # If true, the default table name for a Product class will be +products+. If false, it would just be +product+. + # See table_name for the full rules on table/class naming. This is true, by default. + class_attribute :pluralize_table_names, instance_writer: false + self.pluralize_table_names = true + + self.inheritance_column = 'type' + + delegate :type_for_attribute, to: :class + end + + # Derives the join table name for +first_table+ and +second_table+. The + # table names appear in alphabetical order. A common prefix is removed + # (useful for namespaced models like Music::Artist and Music::Record): + # + # artists, records => artists_records + # records, artists => artists_records + # music_artists, music_records => music_artists_records + def self.derive_join_table_name(first_table, second_table) # :nodoc: + [first_table.to_s, second_table.to_s].sort.join("\0").gsub(/^(.*_)(.+)\0\1(.+)/, '\1\2_\3').tr("\0", "_") + end + + module ClassMethods + # Guesses the table name (in forced lower-case) based on the name of the class in the + # inheritance hierarchy descending directly from ActiveRecord::Base. So if the hierarchy + # looks like: Reply < Message < ActiveRecord::Base, then Message is used + # to guess the table name even when called on Reply. The rules used to do the guess + # are handled by the Inflector class in Active Support, which knows almost all common + # English inflections. You can add new inflections in config/initializers/inflections.rb. + # + # Nested classes are given table names prefixed by the singular form of + # the parent's table name. Enclosing modules are not considered. + # + # ==== Examples + # + # class Invoice < ActiveRecord::Base + # end + # + # file class table_name + # invoice.rb Invoice invoices + # + # class Invoice < ActiveRecord::Base + # class Lineitem < ActiveRecord::Base + # end + # end + # + # file class table_name + # invoice.rb Invoice::Lineitem invoice_lineitems + # + # module Invoice + # class Lineitem < ActiveRecord::Base + # end + # end + # + # file class table_name + # invoice/lineitem.rb Invoice::Lineitem lineitems + # + # Additionally, the class-level +table_name_prefix+ is prepended and the + # +table_name_suffix+ is appended. So if you have "myapp_" as a prefix, + # the table name guess for an Invoice class becomes "myapp_invoices". + # Invoice::Lineitem becomes "myapp_invoice_lineitems". + # + # You can also set your own table name explicitly: + # + # class Mouse < ActiveRecord::Base + # self.table_name = "mice" + # end + # + # Alternatively, you can override the table_name method to define your + # own computation. (Possibly using super to manipulate the default + # table name.) Example: + # + # class Post < ActiveRecord::Base + # def self.table_name + # "special_" + super + # end + # end + # Post.table_name # => "special_posts" + def table_name + reset_table_name unless defined?(@table_name) + @table_name + end + + # Sets the table name explicitly. Example: + # + # class Project < ActiveRecord::Base + # self.table_name = "project" + # end + # + # You can also just define your own self.table_name method; see + # the documentation for ActiveRecord::Base#table_name. + def table_name=(value) + value = value && value.to_s + + if defined?(@table_name) + return if value == @table_name + reset_column_information if connected? + end + + @table_name = value + @quoted_table_name = nil + @arel_table = nil + @sequence_name = nil unless defined?(@explicit_sequence_name) && @explicit_sequence_name + @relation = Relation.create(self, arel_table) + end + + # Returns a quoted version of the table name, used to construct SQL statements. + def quoted_table_name + @quoted_table_name ||= connection.quote_table_name(table_name) + end + + # Computes the table name, (re)sets it internally, and returns it. + def reset_table_name #:nodoc: + self.table_name = if abstract_class? + superclass == Base ? nil : superclass.table_name + elsif superclass.abstract_class? + superclass.table_name || compute_table_name + else + compute_table_name + end + end + + def full_table_name_prefix #:nodoc: + (parents.detect{ |p| p.respond_to?(:table_name_prefix) } || self).table_name_prefix + end + + def full_table_name_suffix #:nodoc: + (parents.detect {|p| p.respond_to?(:table_name_suffix) } || self).table_name_suffix + end + + # Defines the name of the table column which will store the class name on single-table + # inheritance situations. + # + # The default inheritance column name is +type+, which means it's a + # reserved word inside Active Record. To be able to use single-table + # inheritance with another column name, or to use the column +type+ in + # your own model for something else, you can set +inheritance_column+: + # + # self.inheritance_column = 'zoink' + def inheritance_column + (@inheritance_column ||= nil) || superclass.inheritance_column + end + + # Sets the value of inheritance_column + def inheritance_column=(value) + @inheritance_column = value.to_s + @explicit_inheritance_column = true + end + + def sequence_name + if base_class == self + @sequence_name ||= reset_sequence_name + else + (@sequence_name ||= nil) || base_class.sequence_name + end + end + + def reset_sequence_name #:nodoc: + @explicit_sequence_name = false + @sequence_name = connection.default_sequence_name(table_name, primary_key) + end + + # Sets the name of the sequence to use when generating ids to the given + # value, or (if the value is nil or false) to the value returned by the + # given block. This is required for Oracle and is useful for any + # database which relies on sequences for primary key generation. + # + # If a sequence name is not explicitly set when using Oracle, + # it will default to the commonly used pattern of: #{table_name}_seq + # + # If a sequence name is not explicitly set when using PostgreSQL, it + # will discover the sequence corresponding to your primary key for you. + # + # class Project < ActiveRecord::Base + # self.sequence_name = "projectseq" # default would have been "project_seq" + # end + def sequence_name=(value) + @sequence_name = value.to_s + @explicit_sequence_name = true + end + + # Indicates whether the table associated with this class exists + def table_exists? + connection.schema_cache.table_exists?(table_name) + end + + def attributes_builder # :nodoc: + @attributes_builder ||= AttributeSet::Builder.new(column_types, primary_key) + end + + def column_types # :nodoc: + @column_types ||= columns_hash.transform_values(&:cast_type).tap do |h| + h.default = Type::Value.new + end + end + + def type_for_attribute(attr_name) # :nodoc: + column_types[attr_name] + end + + # Returns a hash where the keys are column names and the values are + # default values when instantiating the AR object for this table. + def column_defaults + _default_attributes.to_hash + end + + def _default_attributes # :nodoc: + @default_attributes ||= attributes_builder.build_from_database( + raw_default_values) + end + + # Returns an array of column names as strings. + def column_names + @column_names ||= columns.map { |column| column.name } + end + + # Returns an array of column objects where the primary id, all columns ending in "_id" or "_count", + # and columns used for single table inheritance have been removed. + def content_columns + @content_columns ||= columns.reject { |c| c.name == primary_key || c.name =~ /(_id|_count)$/ || c.name == inheritance_column } + end + + # Resets all the cached information about columns, which will cause them + # to be reloaded on the next request. + # + # The most common usage pattern for this method is probably in a migration, + # when just after creating a table you want to populate it with some default + # values, eg: + # + # class CreateJobLevels < ActiveRecord::Migration + # def up + # create_table :job_levels do |t| + # t.integer :id + # t.string :name + # + # t.timestamps + # end + # + # JobLevel.reset_column_information + # %w{assistant executive manager director}.each do |type| + # JobLevel.create(name: type) + # end + # end + # + # def down + # drop_table :job_levels + # end + # end + def reset_column_information + connection.clear_cache! + undefine_attribute_methods + connection.schema_cache.clear_table_cache!(table_name) + + @arel_engine = nil + @column_names = nil + @column_types = nil + @content_columns = nil + @default_attributes = nil + @inheritance_column = nil unless defined?(@explicit_inheritance_column) && @explicit_inheritance_column + @relation = nil + end + + private + + # Guesses the table name, but does not decorate it with prefix and suffix information. + def undecorated_table_name(class_name = base_class.name) + table_name = class_name.to_s.demodulize.underscore + pluralize_table_names ? table_name.pluralize : table_name + end + + # Computes and returns a table name according to default conventions. + def compute_table_name + base = base_class + if self == base + # Nested classes are prefixed with singular parent table name. + if parent < Base && !parent.abstract_class? + contained = parent.table_name + contained = contained.singularize if parent.pluralize_table_names + contained += '_' + end + + "#{full_table_name_prefix}#{contained}#{undecorated_table_name(name)}#{full_table_name_suffix}" + else + # STI subclasses always use their superclass' table. + base.table_name + end + end + + def raw_default_values + columns_hash.transform_values(&:default) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/nested_attributes.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/nested_attributes.rb new file mode 100644 index 0000000..a8ee082 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/nested_attributes.rb @@ -0,0 +1,558 @@ +require 'active_support/core_ext/hash/except' +require 'active_support/core_ext/object/try' +require 'active_support/core_ext/hash/indifferent_access' + +module ActiveRecord + module NestedAttributes #:nodoc: + class TooManyRecords < ActiveRecordError + end + + extend ActiveSupport::Concern + + included do + class_attribute :nested_attributes_options, instance_writer: false + self.nested_attributes_options = {} + end + + # = Active Record Nested Attributes + # + # Nested attributes allow you to save attributes on associated records + # through the parent. By default nested attribute updating is turned off + # and you can enable it using the accepts_nested_attributes_for class + # method. When you enable nested attributes an attribute writer is + # defined on the model. + # + # The attribute writer is named after the association, which means that + # in the following example, two new methods are added to your model: + # + # author_attributes=(attributes) and + # pages_attributes=(attributes). + # + # class Book < ActiveRecord::Base + # has_one :author + # has_many :pages + # + # accepts_nested_attributes_for :author, :pages + # end + # + # Note that the :autosave option is automatically enabled on every + # association that accepts_nested_attributes_for is used for. + # + # === One-to-one + # + # Consider a Member model that has one Avatar: + # + # class Member < ActiveRecord::Base + # has_one :avatar + # accepts_nested_attributes_for :avatar + # end + # + # Enabling nested attributes on a one-to-one association allows you to + # create the member and avatar in one go: + # + # params = { member: { name: 'Jack', avatar_attributes: { icon: 'smiling' } } } + # member = Member.create(params[:member]) + # member.avatar.id # => 2 + # member.avatar.icon # => 'smiling' + # + # It also allows you to update the avatar through the member: + # + # params = { member: { avatar_attributes: { id: '2', icon: 'sad' } } } + # member.update params[:member] + # member.avatar.icon # => 'sad' + # + # By default you will only be able to set and update attributes on the + # associated model. If you want to destroy the associated model through the + # attributes hash, you have to enable it first using the + # :allow_destroy option. + # + # class Member < ActiveRecord::Base + # has_one :avatar + # accepts_nested_attributes_for :avatar, allow_destroy: true + # end + # + # Now, when you add the _destroy key to the attributes hash, with a + # value that evaluates to +true+, you will destroy the associated model: + # + # member.avatar_attributes = { id: '2', _destroy: '1' } + # member.avatar.marked_for_destruction? # => true + # member.save + # member.reload.avatar # => nil + # + # Note that the model will _not_ be destroyed until the parent is saved. + # + # === One-to-many + # + # Consider a member that has a number of posts: + # + # class Member < ActiveRecord::Base + # has_many :posts + # accepts_nested_attributes_for :posts + # end + # + # You can now set or update attributes on the associated posts through + # an attribute hash for a member: include the key +:posts_attributes+ + # with an array of hashes of post attributes as a value. + # + # For each hash that does _not_ have an id key a new record will + # be instantiated, unless the hash also contains a _destroy key + # that evaluates to +true+. + # + # params = { member: { + # name: 'joe', posts_attributes: [ + # { title: 'Kari, the awesome Ruby documentation browser!' }, + # { title: 'The egalitarian assumption of the modern citizen' }, + # { title: '', _destroy: '1' } # this will be ignored + # ] + # }} + # + # member = Member.create(params[:member]) + # member.posts.length # => 2 + # member.posts.first.title # => 'Kari, the awesome Ruby documentation browser!' + # member.posts.second.title # => 'The egalitarian assumption of the modern citizen' + # + # You may also set a :reject_if proc to silently ignore any new record + # hashes if they fail to pass your criteria. For example, the previous + # example could be rewritten as: + # + # class Member < ActiveRecord::Base + # has_many :posts + # accepts_nested_attributes_for :posts, reject_if: proc { |attributes| attributes['title'].blank? } + # end + # + # params = { member: { + # name: 'joe', posts_attributes: [ + # { title: 'Kari, the awesome Ruby documentation browser!' }, + # { title: 'The egalitarian assumption of the modern citizen' }, + # { title: '' } # this will be ignored because of the :reject_if proc + # ] + # }} + # + # member = Member.create(params[:member]) + # member.posts.length # => 2 + # member.posts.first.title # => 'Kari, the awesome Ruby documentation browser!' + # member.posts.second.title # => 'The egalitarian assumption of the modern citizen' + # + # Alternatively, :reject_if also accepts a symbol for using methods: + # + # class Member < ActiveRecord::Base + # has_many :posts + # accepts_nested_attributes_for :posts, reject_if: :new_record? + # end + # + # class Member < ActiveRecord::Base + # has_many :posts + # accepts_nested_attributes_for :posts, reject_if: :reject_posts + # + # def reject_posts(attributed) + # attributed['title'].blank? + # end + # end + # + # If the hash contains an id key that matches an already + # associated record, the matching record will be modified: + # + # member.attributes = { + # name: 'Joe', + # posts_attributes: [ + # { id: 1, title: '[UPDATED] An, as of yet, undisclosed awesome Ruby documentation browser!' }, + # { id: 2, title: '[UPDATED] other post' } + # ] + # } + # + # member.posts.first.title # => '[UPDATED] An, as of yet, undisclosed awesome Ruby documentation browser!' + # member.posts.second.title # => '[UPDATED] other post' + # + # By default the associated records are protected from being destroyed. If + # you want to destroy any of the associated records through the attributes + # hash, you have to enable it first using the :allow_destroy + # option. This will allow you to also use the _destroy key to + # destroy existing records: + # + # class Member < ActiveRecord::Base + # has_many :posts + # accepts_nested_attributes_for :posts, allow_destroy: true + # end + # + # params = { member: { + # posts_attributes: [{ id: '2', _destroy: '1' }] + # }} + # + # member.attributes = params[:member] + # member.posts.detect { |p| p.id == 2 }.marked_for_destruction? # => true + # member.posts.length # => 2 + # member.save + # member.reload.posts.length # => 1 + # + # Nested attributes for an associated collection can also be passed in + # the form of a hash of hashes instead of an array of hashes: + # + # Member.create(name: 'joe', + # posts_attributes: { first: { title: 'Foo' }, + # second: { title: 'Bar' } }) + # + # has the same effect as + # + # Member.create(name: 'joe', + # posts_attributes: [ { title: 'Foo' }, + # { title: 'Bar' } ]) + # + # The keys of the hash which is the value for +:posts_attributes+ are + # ignored in this case. + # However, it is not allowed to use +'id'+ or +:id+ for one of + # such keys, otherwise the hash will be wrapped in an array and + # interpreted as an attribute hash for a single post. + # + # Passing attributes for an associated collection in the form of a hash + # of hashes can be used with hashes generated from HTTP/HTML parameters, + # where there maybe no natural way to submit an array of hashes. + # + # === Saving + # + # All changes to models, including the destruction of those marked for + # destruction, are saved and destroyed automatically and atomically when + # the parent model is saved. This happens inside the transaction initiated + # by the parents save method. See ActiveRecord::AutosaveAssociation. + # + # === Validating the presence of a parent model + # + # If you want to validate that a child record is associated with a parent + # record, you can use validates_presence_of and + # inverse_of as this example illustrates: + # + # class Member < ActiveRecord::Base + # has_many :posts, inverse_of: :member + # accepts_nested_attributes_for :posts + # end + # + # class Post < ActiveRecord::Base + # belongs_to :member, inverse_of: :posts + # validates_presence_of :member + # end + # + # Note that if you do not specify the inverse_of option, then + # Active Record will try to automatically guess the inverse association + # based on heuristics. + # + # For one-to-one nested associations, if you build the new (in-memory) + # child object yourself before assignment, then this module will not + # overwrite it, e.g.: + # + # class Member < ActiveRecord::Base + # has_one :avatar + # accepts_nested_attributes_for :avatar + # + # def avatar + # super || build_avatar(width: 200) + # end + # end + # + # member = Member.new + # member.avatar_attributes = {icon: 'sad'} + # member.avatar.width # => 200 + module ClassMethods + REJECT_ALL_BLANK_PROC = proc { |attributes| attributes.all? { |key, value| key == '_destroy' || value.blank? } } + + # Defines an attributes writer for the specified association(s). + # + # Supported options: + # [:allow_destroy] + # If true, destroys any members from the attributes hash with a + # _destroy key and a value that evaluates to +true+ + # (eg. 1, '1', true, or 'true'). This option is off by default. + # [:reject_if] + # Allows you to specify a Proc or a Symbol pointing to a method + # that checks whether a record should be built for a certain attribute + # hash. The hash is passed to the supplied Proc or the method + # and it should return either +true+ or +false+. When no :reject_if + # is specified, a record will be built for all attribute hashes that + # do not have a _destroy value that evaluates to true. + # Passing :all_blank instead of a Proc will create a proc + # that will reject a record where all the attributes are blank excluding + # any value for _destroy. + # [:limit] + # Allows you to specify the maximum number of the associated records that + # can be processed with the nested attributes. Limit also can be specified as a + # Proc or a Symbol pointing to a method that should return number. If the size of the + # nested attributes array exceeds the specified limit, NestedAttributes::TooManyRecords + # exception is raised. If omitted, any number associations can be processed. + # Note that the :limit option is only applicable to one-to-many associations. + # [:update_only] + # For a one-to-one association, this option allows you to specify how + # nested attributes are to be used when an associated record already + # exists. In general, an existing record may either be updated with the + # new set of attribute values or be replaced by a wholly new record + # containing those values. By default the :update_only option is +false+ + # and the nested attributes are used to update the existing record only + # if they include the record's :id value. Otherwise a new + # record will be instantiated and used to replace the existing one. + # However if the :update_only option is +true+, the nested attributes + # are used to update the record's attributes always, regardless of + # whether the :id is present. The option is ignored for collection + # associations. + # + # Examples: + # # creates avatar_attributes= + # accepts_nested_attributes_for :avatar, reject_if: proc { |attributes| attributes['name'].blank? } + # # creates avatar_attributes= + # accepts_nested_attributes_for :avatar, reject_if: :all_blank + # # creates avatar_attributes= and posts_attributes= + # accepts_nested_attributes_for :avatar, :posts, allow_destroy: true + def accepts_nested_attributes_for(*attr_names) + options = { :allow_destroy => false, :update_only => false } + options.update(attr_names.extract_options!) + options.assert_valid_keys(:allow_destroy, :reject_if, :limit, :update_only) + options[:reject_if] = REJECT_ALL_BLANK_PROC if options[:reject_if] == :all_blank + + attr_names.each do |association_name| + if reflection = _reflect_on_association(association_name) + reflection.autosave = true + define_autosave_validation_callbacks(reflection) + + nested_attributes_options = self.nested_attributes_options.dup + nested_attributes_options[association_name.to_sym] = options + self.nested_attributes_options = nested_attributes_options + + type = (reflection.collection? ? :collection : :one_to_one) + generate_association_writer(association_name, type) + else + raise ArgumentError, "No association found for name `#{association_name}'. Has it been defined yet?" + end + end + end + + private + + # Generates a writer method for this association. Serves as a point for + # accessing the objects in the association. For example, this method + # could generate the following: + # + # def pirate_attributes=(attributes) + # assign_nested_attributes_for_one_to_one_association(:pirate, attributes) + # end + # + # This redirects the attempts to write objects in an association through + # the helper methods defined below. Makes it seem like the nested + # associations are just regular associations. + def generate_association_writer(association_name, type) + generated_association_methods.module_eval <<-eoruby, __FILE__, __LINE__ + 1 + if method_defined?(:#{association_name}_attributes=) + remove_method(:#{association_name}_attributes=) + end + def #{association_name}_attributes=(attributes) + assign_nested_attributes_for_#{type}_association(:#{association_name}, attributes) + end + eoruby + end + end + + # Returns ActiveRecord::AutosaveAssociation::marked_for_destruction? It's + # used in conjunction with fields_for to build a form element for the + # destruction of this association. + # + # See ActionView::Helpers::FormHelper::fields_for for more info. + def _destroy + marked_for_destruction? + end + + private + + # Attribute hash keys that should not be assigned as normal attributes. + # These hash keys are nested attributes implementation details. + UNASSIGNABLE_KEYS = %w( id _destroy ) + + # Assigns the given attributes to the association. + # + # If an associated record does not yet exist, one will be instantiated. If + # an associated record already exists, the method's behavior depends on + # the value of the update_only option. If update_only is +false+ and the + # given attributes include an :id that matches the existing record's + # id, then the existing record will be modified. If no :id is provided + # it will be replaced with a new record. If update_only is +true+ the existing + # record will be modified regardless of whether an :id is provided. + # + # If the given attributes include a matching :id attribute, or + # update_only is true, and a :_destroy key set to a truthy value, + # then the existing record will be marked for destruction. + def assign_nested_attributes_for_one_to_one_association(association_name, attributes) + options = self.nested_attributes_options[association_name] + attributes = attributes.with_indifferent_access + existing_record = send(association_name) + + if (options[:update_only] || !attributes['id'].blank?) && existing_record && + (options[:update_only] || existing_record.id.to_s == attributes['id'].to_s) + assign_to_or_mark_for_destruction(existing_record, attributes, options[:allow_destroy]) unless call_reject_if(association_name, attributes) + + elsif attributes['id'].present? + raise_nested_attributes_record_not_found!(association_name, attributes['id']) + + elsif !reject_new_record?(association_name, attributes) + assignable_attributes = attributes.except(*UNASSIGNABLE_KEYS) + + if existing_record && existing_record.new_record? + existing_record.assign_attributes(assignable_attributes) + association(association_name).initialize_attributes(existing_record) + else + method = "build_#{association_name}" + if respond_to?(method) + send(method, assignable_attributes) + else + raise ArgumentError, "Cannot build association `#{association_name}'. Are you trying to build a polymorphic one-to-one association?" + end + end + end + end + + # Assigns the given attributes to the collection association. + # + # Hashes with an :id value matching an existing associated record + # will update that record. Hashes without an :id value will build + # a new record for the association. Hashes with a matching :id + # value and a :_destroy key set to a truthy value will mark the + # matched record for destruction. + # + # For example: + # + # assign_nested_attributes_for_collection_association(:people, { + # '1' => { id: '1', name: 'Peter' }, + # '2' => { name: 'John' }, + # '3' => { id: '2', _destroy: true } + # }) + # + # Will update the name of the Person with ID 1, build a new associated + # person with the name 'John', and mark the associated Person with ID 2 + # for destruction. + # + # Also accepts an Array of attribute hashes: + # + # assign_nested_attributes_for_collection_association(:people, [ + # { id: '1', name: 'Peter' }, + # { name: 'John' }, + # { id: '2', _destroy: true } + # ]) + def assign_nested_attributes_for_collection_association(association_name, attributes_collection) + options = self.nested_attributes_options[association_name] + + unless attributes_collection.is_a?(Hash) || attributes_collection.is_a?(Array) + raise ArgumentError, "Hash or Array expected, got #{attributes_collection.class.name} (#{attributes_collection.inspect})" + end + + check_record_limit!(options[:limit], attributes_collection) + + if attributes_collection.is_a? Hash + keys = attributes_collection.keys + attributes_collection = if keys.include?('id') || keys.include?(:id) + [attributes_collection] + else + attributes_collection.values + end + end + + association = association(association_name) + + existing_records = if association.loaded? + association.target + else + attribute_ids = attributes_collection.map {|a| a['id'] || a[:id] }.compact + attribute_ids.empty? ? [] : association.scope.where(association.klass.primary_key => attribute_ids) + end + + attributes_collection.each do |attributes| + attributes = attributes.with_indifferent_access + + if attributes['id'].blank? + unless reject_new_record?(association_name, attributes) + association.build(attributes.except(*UNASSIGNABLE_KEYS)) + end + elsif existing_record = existing_records.detect { |record| record.id.to_s == attributes['id'].to_s } + unless call_reject_if(association_name, attributes) + # Make sure we are operating on the actual object which is in the association's + # proxy_target array (either by finding it, or adding it if not found) + # Take into account that the proxy_target may have changed due to callbacks + target_record = association.target.detect { |record| record.id.to_s == attributes['id'].to_s } + if target_record + existing_record = target_record + else + association.add_to_target(existing_record, :skip_callbacks) + end + + assign_to_or_mark_for_destruction(existing_record, attributes, options[:allow_destroy]) + end + else + raise_nested_attributes_record_not_found!(association_name, attributes['id']) + end + end + end + + # Takes in a limit and checks if the attributes_collection has too many + # records. It accepts limit in the form of symbol, proc, or + # number-like object (anything that can be compared with an integer). + # + # Raises TooManyRecords error if the attributes_collection is + # larger than the limit. + def check_record_limit!(limit, attributes_collection) + if limit + limit = case limit + when Symbol + send(limit) + when Proc + limit.call + else + limit + end + + if limit && attributes_collection.size > limit + raise TooManyRecords, "Maximum #{limit} records are allowed. Got #{attributes_collection.size} records instead." + end + end + end + + # Updates a record with the +attributes+ or marks it for destruction if + # +allow_destroy+ is +true+ and has_destroy_flag? returns +true+. + def assign_to_or_mark_for_destruction(record, attributes, allow_destroy) + record.assign_attributes(attributes.except(*UNASSIGNABLE_KEYS)) + record.mark_for_destruction if has_destroy_flag?(attributes) && allow_destroy + end + + # Determines if a hash contains a truthy _destroy key. + def has_destroy_flag?(hash) + Type::Boolean.new.type_cast_from_user(hash['_destroy']) + end + + # Determines if a new record should be rejected by checking + # has_destroy_flag? or if a :reject_if proc exists for this + # association and evaluates to +true+. + def reject_new_record?(association_name, attributes) + will_be_destroyed?(association_name, attributes) || call_reject_if(association_name, attributes) + end + + # Determines if a record with the particular +attributes+ should be + # rejected by calling the reject_if Symbol or Proc (if defined). + # The reject_if option is defined by +accepts_nested_attributes_for+. + # + # Returns false if there is a +destroy_flag+ on the attributes. + def call_reject_if(association_name, attributes) + return false if will_be_destroyed?(association_name, attributes) + + case callback = self.nested_attributes_options[association_name][:reject_if] + when Symbol + method(callback).arity == 0 ? send(callback) : send(callback, attributes) + when Proc + callback.call(attributes) + end + end + + # Only take into account the destroy flag if :allow_destroy is true + def will_be_destroyed?(association_name, attributes) + allow_destroy?(association_name) && has_destroy_flag?(attributes) + end + + def allow_destroy?(association_name) + self.nested_attributes_options[association_name][:allow_destroy] + end + + def raise_nested_attributes_record_not_found!(association_name, record_id) + raise RecordNotFound, "Couldn't find #{self.class._reflect_on_association(association_name).klass.name} with ID=#{record_id} for #{self.class.name} with ID=#{id}" + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/no_touching.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/no_touching.rb new file mode 100644 index 0000000..edb5066 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/no_touching.rb @@ -0,0 +1,52 @@ +module ActiveRecord + # = Active Record No Touching + module NoTouching + extend ActiveSupport::Concern + + module ClassMethods + # Lets you selectively disable calls to `touch` for the + # duration of a block. + # + # ==== Examples + # ActiveRecord::Base.no_touching do + # Project.first.touch # does nothing + # Message.first.touch # does nothing + # end + # + # Project.no_touching do + # Project.first.touch # does nothing + # Message.first.touch # works, but does not touch the associated project + # end + # + def no_touching(&block) + NoTouching.apply_to(self, &block) + end + end + + class << self + def apply_to(klass) #:nodoc: + klasses.push(klass) + yield + ensure + klasses.pop + end + + def applied_to?(klass) #:nodoc: + klasses.any? { |k| k >= klass } + end + + private + def klasses + Thread.current[:no_touching_classes] ||= [] + end + end + + def no_touching? + NoTouching.applied_to?(self.class) + end + + def touch(*) # :nodoc: + super unless no_touching? + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/null_relation.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/null_relation.rb new file mode 100644 index 0000000..807c301 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/null_relation.rb @@ -0,0 +1,81 @@ +# -*- coding: utf-8 -*- + +module ActiveRecord + module NullRelation # :nodoc: + def exec_queries + @records = [] + end + + def pluck(*column_names) + [] + end + + def delete_all(_conditions = nil) + 0 + end + + def update_all(_updates, _conditions = nil, _options = {}) + 0 + end + + def delete(_id_or_array) + 0 + end + + def size + calculate :size, nil + end + + def empty? + true + end + + def any? + false + end + + def many? + false + end + + def to_sql + "" + end + + def count(*) + calculate :count, nil + end + + def sum(*) + calculate :sum, nil + end + + def average(*) + calculate :average, nil + end + + def minimum(*) + calculate :minimum, nil + end + + def maximum(*) + calculate :maximum, nil + end + + def calculate(operation, _column_name, _options = {}) + # TODO: Remove _options argument as soon we remove support to + # activerecord-deprecated_finders. + if [:count, :sum, :size].include? operation + group_values.any? ? Hash.new : 0 + elsif [:average, :minimum, :maximum].include?(operation) && group_values.any? + Hash.new + else + nil + end + end + + def exists?(_id = false) + false + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/persistence.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/persistence.rb new file mode 100644 index 0000000..be117ce --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/persistence.rb @@ -0,0 +1,535 @@ +module ActiveRecord + # = Active Record Persistence + module Persistence + extend ActiveSupport::Concern + + module ClassMethods + # Creates an object (or multiple objects) and saves it to the database, if validations pass. + # The resulting object is returned whether the object was saved successfully to the database or not. + # + # The +attributes+ parameter can be either a Hash or an Array of Hashes. These Hashes describe the + # attributes on the objects that are to be created. + # + # ==== Examples + # # Create a single new object + # User.create(first_name: 'Jamie') + # + # # Create an Array of new objects + # User.create([{ first_name: 'Jamie' }, { first_name: 'Jeremy' }]) + # + # # Create a single object and pass it into a block to set other attributes. + # User.create(first_name: 'Jamie') do |u| + # u.is_admin = false + # end + # + # # Creating an Array of new objects using a block, where the block is executed for each object: + # User.create([{ first_name: 'Jamie' }, { first_name: 'Jeremy' }]) do |u| + # u.is_admin = false + # end + def create(attributes = nil, &block) + if attributes.is_a?(Array) + attributes.collect { |attr| create(attr, &block) } + else + object = new(attributes, &block) + object.save + object + end + end + + # Creates an object (or multiple objects) and saves it to the database, + # if validations pass. Raises a RecordInvalid error if validations fail, + # unlike Base#create. + # + # The +attributes+ parameter can be either a Hash or an Array of Hashes. + # These describe which attributes to be created on the object, or + # multiple objects when given an Array of Hashes. + def create!(attributes = nil, &block) + if attributes.is_a?(Array) + attributes.collect { |attr| create!(attr, &block) } + else + object = new(attributes, &block) + object.save! + object + end + end + + # Given an attributes hash, +instantiate+ returns a new instance of + # the appropriate class. Accepts only keys as strings. + # + # For example, +Post.all+ may return Comments, Messages, and Emails + # by storing the record's subclass in a +type+ attribute. By calling + # +instantiate+ instead of +new+, finder methods ensure they get new + # instances of the appropriate class for each record. + # + # See +ActiveRecord::Inheritance#discriminate_class_for_record+ to see + # how this "single-table" inheritance mapping is implemented. + def instantiate(attributes, column_types = {}) + klass = discriminate_class_for_record(attributes) + attributes = klass.attributes_builder.build_from_database(attributes, column_types) + klass.allocate.init_with('attributes' => attributes, 'new_record' => false) + end + + private + # Called by +instantiate+ to decide which class to use for a new + # record instance. + # + # See +ActiveRecord::Inheritance#discriminate_class_for_record+ for + # the single-table inheritance discriminator. + def discriminate_class_for_record(record) + self + end + end + + # Returns true if this object hasn't been saved yet -- that is, a record + # for the object doesn't exist in the database yet; otherwise, returns false. + def new_record? + sync_with_transaction_state + @new_record + end + + # Returns true if this object has been destroyed, otherwise returns false. + def destroyed? + sync_with_transaction_state + @destroyed + end + + # Returns true if the record is persisted, i.e. it's not a new record and it was + # not destroyed, otherwise returns false. + def persisted? + !(new_record? || destroyed?) + end + + # Saves the model. + # + # If the model is new a record gets created in the database, otherwise + # the existing record gets updated. + # + # By default, save always run validations. If any of them fail the action + # is cancelled and +save+ returns +false+. However, if you supply + # validate: false, validations are bypassed altogether. See + # ActiveRecord::Validations for more information. + # + # There's a series of callbacks associated with +save+. If any of the + # before_* callbacks return +false+ the action is cancelled and + # +save+ returns +false+. See ActiveRecord::Callbacks for further + # details. + # + # Attributes marked as readonly are silently ignored if the record is + # being updated. + def save(*) + create_or_update + rescue ActiveRecord::RecordInvalid + false + end + + # Saves the model. + # + # If the model is new a record gets created in the database, otherwise + # the existing record gets updated. + # + # With save! validations always run. If any of them fail + # ActiveRecord::RecordInvalid gets raised. See ActiveRecord::Validations + # for more information. + # + # There's a series of callbacks associated with save!. If any of + # the before_* callbacks return +false+ the action is cancelled + # and save! raises ActiveRecord::RecordNotSaved. See + # ActiveRecord::Callbacks for further details. + # + # Attributes marked as readonly are silently ignored if the record is + # being updated. + def save!(*) + create_or_update || raise(RecordNotSaved.new("Failed to save the record", self)) + end + + # Deletes the record in the database and freezes this instance to + # reflect that no changes should be made (since they can't be + # persisted). Returns the frozen instance. + # + # The row is simply removed with an SQL +DELETE+ statement on the + # record's primary key, and no callbacks are executed. + # + # To enforce the object's +before_destroy+ and +after_destroy+ + # callbacks or any :dependent association + # options, use #destroy. + def delete + self.class.delete(id) if persisted? + @destroyed = true + freeze + end + + # Deletes the record in the database and freezes this instance to reflect + # that no changes should be made (since they can't be persisted). + # + # There's a series of callbacks associated with destroy. If + # the before_destroy callback return +false+ the action is cancelled + # and destroy returns +false+. See + # ActiveRecord::Callbacks for further details. + def destroy + raise ReadOnlyRecord, "#{self.class} is marked as readonly" if readonly? + destroy_associations + self.class.connection.add_transaction_record(self) + destroy_row if persisted? + @destroyed = true + freeze + end + + # Deletes the record in the database and freezes this instance to reflect + # that no changes should be made (since they can't be persisted). + # + # There's a series of callbacks associated with destroy!. If + # the before_destroy callback return +false+ the action is cancelled + # and destroy! raises ActiveRecord::RecordNotDestroyed. See + # ActiveRecord::Callbacks for further details. + def destroy! + destroy || raise(RecordNotDestroyed.new("Failed to destroy the record", self)) + end + + # Returns an instance of the specified +klass+ with the attributes of the + # current record. This is mostly useful in relation to single-table + # inheritance structures where you want a subclass to appear as the + # superclass. This can be used along with record identification in + # Action Pack to allow, say, Client < Company to do something + # like render partial: @client.becomes(Company) to render that + # instance using the companies/company partial instead of clients/client. + # + # Note: The new instance will share a link to the same attributes as the original class. + # So any change to the attributes in either instance will affect the other. + def becomes(klass) + became = klass.new + became.instance_variable_set("@attributes", @attributes) + changed_attributes = @changed_attributes if defined?(@changed_attributes) + became.instance_variable_set("@changed_attributes", changed_attributes || {}) + became.instance_variable_set("@new_record", new_record?) + became.instance_variable_set("@destroyed", destroyed?) + became.instance_variable_set("@errors", errors) + became + end + + # Wrapper around +becomes+ that also changes the instance's sti column value. + # This is especially useful if you want to persist the changed class in your + # database. + # + # Note: The old instance's sti column value will be changed too, as both objects + # share the same set of attributes. + def becomes!(klass) + became = becomes(klass) + sti_type = nil + if !klass.descends_from_active_record? + sti_type = klass.sti_name + end + became.public_send("#{klass.inheritance_column}=", sti_type) + became + end + + # Updates a single attribute and saves the record. + # This is especially useful for boolean flags on existing records. Also note that + # + # * Validation is skipped. + # * Callbacks are invoked. + # * updated_at/updated_on column is updated if that column is available. + # * Updates all the attributes that are dirty in this object. + # + # This method raises an +ActiveRecord::ActiveRecordError+ if the + # attribute is marked as readonly. + # + # See also +update_column+. + def update_attribute(name, value) + name = name.to_s + verify_readonly_attribute(name) + send("#{name}=", value) + save(validate: false) + end + + # Updates the attributes of the model from the passed-in hash and saves the + # record, all wrapped in a transaction. If the object is invalid, the saving + # will fail and false will be returned. + def update(attributes) + # The following transaction covers any possible database side-effects of the + # attributes assignment. For example, setting the IDs of a child collection. + with_transaction_returning_status do + assign_attributes(attributes) + save + end + end + + alias update_attributes update + + # Updates its receiver just like +update+ but calls save! instead + # of +save+, so an exception is raised if the record is invalid. + def update!(attributes) + # The following transaction covers any possible database side-effects of the + # attributes assignment. For example, setting the IDs of a child collection. + with_transaction_returning_status do + assign_attributes(attributes) + save! + end + end + + alias update_attributes! update! + + # Equivalent to update_columns(name => value). + def update_column(name, value) + update_columns(name => value) + end + + # Updates the attributes directly in the database issuing an UPDATE SQL + # statement and sets them in the receiver: + # + # user.update_columns(last_request_at: Time.current) + # + # This is the fastest way to update attributes because it goes straight to + # the database, but take into account that in consequence the regular update + # procedures are totally bypassed. In particular: + # + # * Validations are skipped. + # * Callbacks are skipped. + # * +updated_at+/+updated_on+ are not updated. + # + # This method raises an +ActiveRecord::ActiveRecordError+ when called on new + # objects, or when at least one of the attributes is marked as readonly. + def update_columns(attributes) + raise ActiveRecordError, "cannot update a new record" if new_record? + raise ActiveRecordError, "cannot update a destroyed record" if destroyed? + + attributes.each_key do |key| + verify_readonly_attribute(key.to_s) + end + + updated_count = self.class.unscoped.where(self.class.primary_key => id).update_all(attributes) + + attributes.each do |k, v| + raw_write_attribute(k, v) + end + + updated_count == 1 + end + + # Initializes +attribute+ to zero if +nil+ and adds the value passed as +by+ (default is 1). + # The increment is performed directly on the underlying attribute, no setter is invoked. + # Only makes sense for number-based attributes. Returns +self+. + def increment(attribute, by = 1) + self[attribute] ||= 0 + self[attribute] += by + self + end + + # Wrapper around +increment+ that saves the record. This method differs from + # its non-bang version in that it passes through the attribute setter. + # Saving is not subjected to validation checks. Returns +true+ if the + # record could be saved. + def increment!(attribute, by = 1) + increment(attribute, by).update_attribute(attribute, self[attribute]) + end + + # Initializes +attribute+ to zero if +nil+ and subtracts the value passed as +by+ (default is 1). + # The decrement is performed directly on the underlying attribute, no setter is invoked. + # Only makes sense for number-based attributes. Returns +self+. + def decrement(attribute, by = 1) + self[attribute] ||= 0 + self[attribute] -= by + self + end + + # Wrapper around +decrement+ that saves the record. This method differs from + # its non-bang version in that it passes through the attribute setter. + # Saving is not subjected to validation checks. Returns +true+ if the + # record could be saved. + def decrement!(attribute, by = 1) + decrement(attribute, by).update_attribute(attribute, self[attribute]) + end + + # Assigns to +attribute+ the boolean opposite of attribute?. So + # if the predicate returns +true+ the attribute will become +false+. This + # method toggles directly the underlying value without calling any setter. + # Returns +self+. + def toggle(attribute) + self[attribute] = !send("#{attribute}?") + self + end + + # Wrapper around +toggle+ that saves the record. This method differs from + # its non-bang version in that it passes through the attribute setter. + # Saving is not subjected to validation checks. Returns +true+ if the + # record could be saved. + def toggle!(attribute) + toggle(attribute).update_attribute(attribute, self[attribute]) + end + + # Reloads the record from the database. + # + # This method finds record by its primary key (which could be assigned manually) and + # modifies the receiver in-place: + # + # account = Account.new + # # => # + # account.id = 1 + # account.reload + # # Account Load (1.2ms) SELECT "accounts".* FROM "accounts" WHERE "accounts"."id" = $1 LIMIT 1 [["id", 1]] + # # => # + # + # Attributes are reloaded from the database, and caches busted, in + # particular the associations cache and the QueryCache. + # + # If the record no longer exists in the database ActiveRecord::RecordNotFound + # is raised. Otherwise, in addition to the in-place modification the method + # returns +self+ for convenience. + # + # The optional :lock flag option allows you to lock the reloaded record: + # + # reload(lock: true) # reload with pessimistic locking + # + # Reloading is commonly used in test suites to test something is actually + # written to the database, or when some action modifies the corresponding + # row in the database but not the object in memory: + # + # assert account.deposit!(25) + # assert_equal 25, account.credit # check it is updated in memory + # assert_equal 25, account.reload.credit # check it is also persisted + # + # Another common use case is optimistic locking handling: + # + # def with_optimistic_retry + # begin + # yield + # rescue ActiveRecord::StaleObjectError + # begin + # # Reload lock_version in particular. + # reload + # rescue ActiveRecord::RecordNotFound + # # If the record is gone there is nothing to do. + # else + # retry + # end + # end + # end + # + def reload(options = nil) + clear_aggregation_cache + clear_association_cache + self.class.connection.clear_query_cache + + fresh_object = + if options && options[:lock] + self.class.unscoped { self.class.lock(options[:lock]).find(id) } + else + self.class.unscoped { self.class.find(id) } + end + + @attributes = fresh_object.instance_variable_get('@attributes') + @new_record = false + self + end + + # Saves the record with the updated_at/on attributes set to the current time. + # Please note that no validation is performed and only the +after_touch+, + # +after_commit+ and +after_rollback+ callbacks are executed. + # + # If attribute names are passed, they are updated along with updated_at/on + # attributes. + # + # product.touch # updates updated_at/on + # product.touch(:designed_at) # updates the designed_at attribute and updated_at/on + # product.touch(:started_at, :ended_at) # updates started_at, ended_at and updated_at/on attributes + # + # If used along with +belongs_to+ then +touch+ will invoke +touch+ method on + # associated object. + # + # class Brake < ActiveRecord::Base + # belongs_to :car, touch: true + # end + # + # class Car < ActiveRecord::Base + # belongs_to :corporation, touch: true + # end + # + # # triggers @brake.car.touch and @brake.car.corporation.touch + # @brake.touch + # + # Note that +touch+ must be used on a persisted object, or else an + # ActiveRecordError will be thrown. For example: + # + # ball = Ball.new + # ball.touch(:updated_at) # => raises ActiveRecordError + # + def touch(*names) + raise ActiveRecordError, "cannot touch on a new record object" unless persisted? + + attributes = timestamp_attributes_for_update_in_model + attributes.concat(names) + + unless attributes.empty? + current_time = current_time_from_proper_timezone + changes = {} + + attributes.each do |column| + column = column.to_s + changes[column] = write_attribute(column, current_time) + end + + changes[self.class.locking_column] = increment_lock if locking_enabled? + + clear_attribute_changes(changes.keys) + primary_key = self.class.primary_key + self.class.unscoped.where(primary_key => self[primary_key]).update_all(changes) == 1 + else + true + end + end + + private + + # A hook to be overridden by association modules. + def destroy_associations + end + + def destroy_row + relation_for_destroy.delete_all + end + + def relation_for_destroy + pk = self.class.primary_key + column = self.class.columns_hash[pk] + substitute = self.class.connection.substitute_at(column) + + relation = self.class.unscoped.where( + self.class.arel_table[pk].eq(substitute)) + + relation.bind_values = [[column, id]] + relation + end + + def create_or_update + raise ReadOnlyRecord, "#{self.class} is marked as readonly" if readonly? + result = new_record? ? _create_record : _update_record + result != false + end + + # Updates the associated record with values matching those of the instance attributes. + # Returns the number of affected rows. + def _update_record(attribute_names = self.attribute_names) + attributes_values = arel_attributes_with_values_for_update(attribute_names) + if attributes_values.empty? + 0 + else + self.class.unscoped._update_record attributes_values, id, id_was + end + end + + # Creates a record with values matching those of the instance attributes + # and returns its id. + def _create_record(attribute_names = self.attribute_names) + attributes_values = arel_attributes_with_values_for_create(attribute_names) + + new_id = self.class.unscoped.insert attributes_values + self.id ||= new_id if self.class.primary_key + + @new_record = false + id + end + + def verify_readonly_attribute(name) + raise ActiveRecordError, "#{name} is marked as readonly" if self.class.readonly_attributes.include?(name) + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/query_cache.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/query_cache.rb new file mode 100644 index 0000000..dcb2bd3 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/query_cache.rb @@ -0,0 +1,56 @@ +module ActiveRecord + # = Active Record Query Cache + class QueryCache + module ClassMethods + # Enable the query cache within the block if Active Record is configured. + # If it's not, it will execute the given block. + def cache(&block) + if ActiveRecord::Base.connected? + connection.cache(&block) + else + yield + end + end + + # Disable the query cache within the block if Active Record is configured. + # If it's not, it will execute the given block. + def uncached(&block) + if ActiveRecord::Base.connected? + connection.uncached(&block) + else + yield + end + end + end + + def initialize(app) + @app = app + end + + def call(env) + connection = ActiveRecord::Base.connection + enabled = connection.query_cache_enabled + connection_id = ActiveRecord::Base.connection_id + connection.enable_query_cache! + + response = @app.call(env) + response[2] = Rack::BodyProxy.new(response[2]) do + restore_query_cache_settings(connection_id, enabled) + end + + response + rescue Exception => e + restore_query_cache_settings(connection_id, enabled) + raise e + end + + private + + def restore_query_cache_settings(connection_id, enabled) + ActiveRecord::Base.connection_id = connection_id + ActiveRecord::Base.connection.clear_query_cache + ActiveRecord::Base.connection.disable_query_cache! unless enabled + end + + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/querying.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/querying.rb new file mode 100644 index 0000000..e8de4db --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/querying.rb @@ -0,0 +1,68 @@ +module ActiveRecord + module Querying + delegate :find, :take, :take!, :first, :first!, :last, :last!, :exists?, :any?, :many?, to: :all + delegate :second, :second!, :third, :third!, :fourth, :fourth!, :fifth, :fifth!, :forty_two, :forty_two!, to: :all + delegate :first_or_create, :first_or_create!, :first_or_initialize, to: :all + delegate :find_or_create_by, :find_or_create_by!, :find_or_initialize_by, to: :all + delegate :find_by, :find_by!, to: :all + delegate :destroy, :destroy_all, :delete, :delete_all, :update, :update_all, to: :all + delegate :find_each, :find_in_batches, to: :all + delegate :select, :group, :order, :except, :reorder, :limit, :offset, :joins, + :where, :rewhere, :preload, :eager_load, :includes, :from, :lock, :readonly, + :having, :create_with, :uniq, :distinct, :references, :none, :unscope, to: :all + delegate :count, :average, :minimum, :maximum, :sum, :calculate, to: :all + delegate :pluck, :ids, to: :all + + # Executes a custom SQL query against your database and returns all the results. The results will + # be returned as an array with columns requested encapsulated as attributes of the model you call + # this method from. If you call Product.find_by_sql then the results will be returned in + # a +Product+ object with the attributes you specified in the SQL query. + # + # If you call a complicated SQL query which spans multiple tables the columns specified by the + # SELECT will be attributes of the model, whether or not they are columns of the corresponding + # table. + # + # The +sql+ parameter is a full SQL query as a string. It will be called as is, there will be + # no database agnostic conversions performed. This should be a last resort because using, for example, + # MySQL specific terms will lock you to using that particular database engine or require you to + # change your call if you switch engines. + # + # # A simple SQL query spanning multiple tables + # Post.find_by_sql "SELECT p.title, c.author FROM posts p, comments c WHERE p.id = c.post_id" + # # => [#"Ruby Meetup", "first_name"=>"Quentin"}>, ...] + # + # You can use the same string replacement techniques as you can with ActiveRecord::QueryMethods#where: + # + # Post.find_by_sql ["SELECT title FROM posts WHERE author = ? AND created > ?", author_id, start_date] + # Post.find_by_sql ["SELECT body FROM comments WHERE author = :user_id OR approved_by = :user_id", { :user_id => user_id }] + def find_by_sql(sql, binds = []) + result_set = connection.select_all(sanitize_sql(sql), "#{name} Load", binds) + column_types = result_set.column_types.dup + columns_hash.each_key { |k| column_types.delete k } + message_bus = ActiveSupport::Notifications.instrumenter + + payload = { + record_count: result_set.length, + class_name: name + } + + message_bus.instrument('instantiation.active_record', payload) do + result_set.map { |record| instantiate(record, column_types) } + end + end + + # Returns the result of an SQL statement that should only include a COUNT(*) in the SELECT part. + # The use of this method should be restricted to complicated SQL queries that can't be executed + # using the ActiveRecord::Calculations class methods. Look into those before using this. + # + # ==== Parameters + # + # * +sql+ - An SQL statement which should return a count query from the database, see the example below. + # + # Product.count_by_sql "SELECT COUNT(*) FROM sales s, customers c WHERE s.customer_id = c.id" + def count_by_sql(sql) + sql = sanitize_conditions(sql) + connection.select_value(sql, "#{name} Count").to_i + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/railtie.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/railtie.rb new file mode 100644 index 0000000..3f748e9 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/railtie.rb @@ -0,0 +1,162 @@ +require "active_record" +require "rails" +require "active_model/railtie" + +# For now, action_controller must always be present with +# rails, so let's make sure that it gets required before +# here. This is needed for correctly setting up the middleware. +# In the future, this might become an optional require. +require "action_controller/railtie" + +module ActiveRecord + # = Active Record Railtie + class Railtie < Rails::Railtie # :nodoc: + config.active_record = ActiveSupport::OrderedOptions.new + + config.app_generators.orm :active_record, :migration => true, + :timestamps => true + + config.app_middleware.insert_after "::ActionDispatch::Callbacks", + "ActiveRecord::QueryCache" + + config.app_middleware.insert_after "::ActionDispatch::Callbacks", + "ActiveRecord::ConnectionAdapters::ConnectionManagement" + + config.action_dispatch.rescue_responses.merge!( + 'ActiveRecord::RecordNotFound' => :not_found, + 'ActiveRecord::StaleObjectError' => :conflict, + 'ActiveRecord::RecordInvalid' => :unprocessable_entity, + 'ActiveRecord::RecordNotSaved' => :unprocessable_entity + ) + + + config.active_record.use_schema_cache_dump = true + config.active_record.maintain_test_schema = true + + config.eager_load_namespaces << ActiveRecord + + rake_tasks do + namespace :db do + task :load_config do + ActiveRecord::Tasks::DatabaseTasks.database_configuration = Rails.application.config.database_configuration + + if defined?(ENGINE_PATH) && engine = Rails::Engine.find(ENGINE_PATH) + if engine.paths['db/migrate'].existent + ActiveRecord::Tasks::DatabaseTasks.migrations_paths += engine.paths['db/migrate'].to_a + end + end + end + end + + load "active_record/railties/databases.rake" + end + + # When loading console, force ActiveRecord::Base to be loaded + # to avoid cross references when loading a constant for the + # first time. Also, make it output to STDERR. + console do |app| + require "active_record/railties/console_sandbox" if app.sandbox? + require "active_record/base" + console = ActiveSupport::Logger.new(STDERR) + Rails.logger.extend ActiveSupport::Logger.broadcast console + end + + runner do + require "active_record/base" + end + + initializer "active_record.initialize_timezone" do + ActiveSupport.on_load(:active_record) do + self.time_zone_aware_attributes = true + self.default_timezone = :utc + end + end + + initializer "active_record.logger" do + ActiveSupport.on_load(:active_record) { self.logger ||= ::Rails.logger } + end + + initializer "active_record.migration_error" do + if config.active_record.delete(:migration_error) == :page_load + config.app_middleware.insert_after "::ActionDispatch::Callbacks", + "ActiveRecord::Migration::CheckPending" + end + end + + initializer "active_record.check_schema_cache_dump" do + if config.active_record.delete(:use_schema_cache_dump) + config.after_initialize do |app| + ActiveSupport.on_load(:active_record) do + filename = File.join(app.config.paths["db"].first, "schema_cache.dump") + + if File.file?(filename) + cache = Marshal.load File.binread filename + if cache.version == ActiveRecord::Migrator.current_version + self.connection.schema_cache = cache + else + warn "Ignoring db/schema_cache.dump because it has expired. The current schema version is #{ActiveRecord::Migrator.current_version}, but the one in the cache is #{cache.version}." + end + end + end + end + end + end + + initializer "active_record.set_configs" do |app| + ActiveSupport.on_load(:active_record) do + app.config.active_record.each do |k,v| + send "#{k}=", v + end + end + end + + # This sets the database configuration from Configuration#database_configuration + # and then establishes the connection. + initializer "active_record.initialize_database" do |app| + ActiveSupport.on_load(:active_record) do + self.configurations = Rails.application.config.database_configuration + + begin + establish_connection + rescue ActiveRecord::NoDatabaseError + warn <<-end_warning +Oops - You have a database configured, but it doesn't exist yet! + +Here's how to get started: + + 1. Configure your database in config/database.yml. + 2. Run `bin/rake db:create` to create the database. + 3. Run `bin/rake db:setup` to load your database schema. +end_warning + raise + end + end + end + + # Expose database runtime to controller for logging. + initializer "active_record.log_runtime" do + require "active_record/railties/controller_runtime" + ActiveSupport.on_load(:action_controller) do + include ActiveRecord::Railties::ControllerRuntime + end + end + + initializer "active_record.set_reloader_hooks" do |app| + hook = app.config.reload_classes_only_on_change ? :to_prepare : :to_cleanup + + ActiveSupport.on_load(:active_record) do + ActionDispatch::Reloader.send(hook) do + if ActiveRecord::Base.connected? + ActiveRecord::Base.clear_cache! + ActiveRecord::Base.clear_reloadable_connections! + end + end + end + end + + initializer "active_record.add_watchable_files" do |app| + path = app.paths["db"].first + config.watchable_files.concat ["#{path}/schema.rb", "#{path}/structure.sql"] + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/railties/console_sandbox.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/railties/console_sandbox.rb new file mode 100644 index 0000000..604a220 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/railties/console_sandbox.rb @@ -0,0 +1,5 @@ +ActiveRecord::Base.connection.begin_transaction(joinable: false) + +at_exit do + ActiveRecord::Base.connection.rollback_transaction +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/railties/controller_runtime.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/railties/controller_runtime.rb new file mode 100644 index 0000000..af48404 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/railties/controller_runtime.rb @@ -0,0 +1,50 @@ +require 'active_support/core_ext/module/attr_internal' +require 'active_record/log_subscriber' + +module ActiveRecord + module Railties # :nodoc: + module ControllerRuntime #:nodoc: + extend ActiveSupport::Concern + + protected + + attr_internal :db_runtime + + def process_action(action, *args) + # We also need to reset the runtime before each action + # because of queries in middleware or in cases we are streaming + # and it won't be cleaned up by the method below. + ActiveRecord::LogSubscriber.reset_runtime + super + end + + def cleanup_view_runtime + if ActiveRecord::Base.connected? + db_rt_before_render = ActiveRecord::LogSubscriber.reset_runtime + self.db_runtime = (db_runtime || 0) + db_rt_before_render + runtime = super + db_rt_after_render = ActiveRecord::LogSubscriber.reset_runtime + self.db_runtime += db_rt_after_render + runtime - db_rt_after_render + else + super + end + end + + def append_info_to_payload(payload) + super + if ActiveRecord::Base.connected? + payload[:db_runtime] = (db_runtime || 0) + ActiveRecord::LogSubscriber.reset_runtime + end + end + + module ClassMethods # :nodoc: + def log_process_action(payload) + messages, db_runtime = super, payload[:db_runtime] + messages << ("ActiveRecord: %.1fms" % db_runtime.to_f) if db_runtime + messages + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/railties/databases.rake b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/railties/databases.rake new file mode 100644 index 0000000..6b4ee7c --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/railties/databases.rake @@ -0,0 +1,394 @@ +require 'active_record' + +db_namespace = namespace :db do + task :load_config do + ActiveRecord::Base.configurations = ActiveRecord::Tasks::DatabaseTasks.database_configuration || {} + ActiveRecord::Migrator.migrations_paths = ActiveRecord::Tasks::DatabaseTasks.migrations_paths + end + + namespace :create do + task :all => :load_config do + ActiveRecord::Tasks::DatabaseTasks.create_all + end + end + + desc 'Creates the database from DATABASE_URL or config/database.yml for the current RAILS_ENV (use db:create:all to create all databases in the config). Without RAILS_ENV it defaults to creating the development and test databases.' + task :create => [:load_config] do + ActiveRecord::Tasks::DatabaseTasks.create_current + end + + namespace :drop do + task :all => :load_config do + ActiveRecord::Tasks::DatabaseTasks.drop_all + end + end + + desc 'Drops the database from DATABASE_URL or config/database.yml for the current RAILS_ENV (use db:drop:all to drop all databases in the config). Without RAILS_ENV it defaults to dropping the development and test databases.' + task :drop => [:load_config] do + ActiveRecord::Tasks::DatabaseTasks.drop_current + end + + namespace :purge do + task :all => :load_config do + ActiveRecord::Tasks::DatabaseTasks.purge_all + end + end + + # desc "Empty the database from DATABASE_URL or config/database.yml for the current RAILS_ENV (use db:drop:all to drop all databases in the config). Without RAILS_ENV it defaults to purging the development and test databases." + task :purge => [:load_config] do + ActiveRecord::Tasks::DatabaseTasks.purge_current + end + + desc "Migrate the database (options: VERSION=x, VERBOSE=false, SCOPE=blog)." + task :migrate => [:environment, :load_config] do + ActiveRecord::Tasks::DatabaseTasks.migrate + db_namespace['_dump'].invoke + end + + # IMPORTANT: This task won't dump the schema if ActiveRecord::Base.dump_schema_after_migration is set to false + task :_dump do + if ActiveRecord::Base.dump_schema_after_migration + case ActiveRecord::Base.schema_format + when :ruby then db_namespace["schema:dump"].invoke + when :sql then db_namespace["structure:dump"].invoke + else + raise "unknown schema format #{ActiveRecord::Base.schema_format}" + end + end + # Allow this task to be called as many times as required. An example is the + # migrate:redo task, which calls other two internally that depend on this one. + db_namespace['_dump'].reenable + end + + namespace :migrate do + # desc 'Rollbacks the database one migration and re migrate up (options: STEP=x, VERSION=x).' + task :redo => [:environment, :load_config] do + if ENV['VERSION'] + db_namespace['migrate:down'].invoke + db_namespace['migrate:up'].invoke + else + db_namespace['rollback'].invoke + db_namespace['migrate'].invoke + end + end + + # desc 'Resets your database using your migrations for the current environment' + task :reset => ['db:drop', 'db:create', 'db:migrate'] + + # desc 'Runs the "up" for a given migration VERSION.' + task :up => [:environment, :load_config] do + version = ENV['VERSION'] ? ENV['VERSION'].to_i : nil + raise 'VERSION is required' unless version + ActiveRecord::Migrator.run(:up, ActiveRecord::Migrator.migrations_paths, version) + db_namespace['_dump'].invoke + end + + # desc 'Runs the "down" for a given migration VERSION.' + task :down => [:environment, :load_config] do + version = ENV['VERSION'] ? ENV['VERSION'].to_i : nil + raise 'VERSION is required - To go down one migration, run db:rollback' unless version + ActiveRecord::Migrator.run(:down, ActiveRecord::Migrator.migrations_paths, version) + db_namespace['_dump'].invoke + end + + desc 'Display status of migrations' + task :status => [:environment, :load_config] do + unless ActiveRecord::SchemaMigration.table_exists? + abort 'Schema migrations table does not exist yet.' + end + db_list = ActiveRecord::SchemaMigration.normalized_versions + + file_list = + ActiveRecord::Migrator.migrations_paths.flat_map do |path| + # match "20091231235959_some_name.rb" and "001_some_name.rb" pattern + Dir.foreach(path).grep(/^(\d{3,})_(.+)\.rb$/) do + version = ActiveRecord::SchemaMigration.normalize_migration_number($1) + status = db_list.delete(version) ? 'up' : 'down' + [status, version, $2.humanize] + end + end + + db_list.map! do |version| + ['up', version, '********** NO FILE **********'] + end + # output + puts "\ndatabase: #{ActiveRecord::Base.connection_config[:database]}\n\n" + puts "#{'Status'.center(8)} #{'Migration ID'.ljust(14)} Migration Name" + puts "-" * 50 + (db_list + file_list).sort_by { |_, version, _| version }.each do |status, version, name| + puts "#{status.center(8)} #{version.ljust(14)} #{name}" + end + puts + end + end + + desc 'Rolls the schema back to the previous version (specify steps w/ STEP=n).' + task :rollback => [:environment, :load_config] do + step = ENV['STEP'] ? ENV['STEP'].to_i : 1 + ActiveRecord::Migrator.rollback(ActiveRecord::Migrator.migrations_paths, step) + db_namespace['_dump'].invoke + end + + # desc 'Pushes the schema to the next version (specify steps w/ STEP=n).' + task :forward => [:environment, :load_config] do + step = ENV['STEP'] ? ENV['STEP'].to_i : 1 + ActiveRecord::Migrator.forward(ActiveRecord::Migrator.migrations_paths, step) + db_namespace['_dump'].invoke + end + + # desc 'Drops and recreates the database from db/schema.rb for the current environment and loads the seeds.' + task :reset => [:environment, :load_config] do + db_namespace["drop"].invoke + db_namespace["setup"].invoke + end + + # desc "Retrieves the charset for the current environment's database" + task :charset => [:environment, :load_config] do + puts ActiveRecord::Tasks::DatabaseTasks.charset_current + end + + # desc "Retrieves the collation for the current environment's database" + task :collation => [:environment, :load_config] do + begin + puts ActiveRecord::Tasks::DatabaseTasks.collation_current + rescue NoMethodError + $stderr.puts 'Sorry, your database adapter is not supported yet. Feel free to submit a patch.' + end + end + + desc 'Retrieves the current schema version number' + task :version => [:environment, :load_config] do + puts "Current version: #{ActiveRecord::Migrator.current_version}" + end + + # desc "Raises an error if there are pending migrations" + task :abort_if_pending_migrations => :environment do + pending_migrations = ActiveRecord::Migrator.open(ActiveRecord::Migrator.migrations_paths).pending_migrations + + if pending_migrations.any? + puts "You have #{pending_migrations.size} pending #{pending_migrations.size > 1 ? 'migrations:' : 'migration:'}" + pending_migrations.each do |pending_migration| + puts ' %4d %s' % [pending_migration.version, pending_migration.name] + end + abort %{Run `rake db:migrate` to update your database then try again.} + end + end + + desc 'Create the database, load the schema, and initialize with the seed data (use db:reset to also drop the database first)' + task :setup => ['db:schema:load_if_ruby', 'db:structure:load_if_sql', :seed] + + desc 'Load the seed data from db/seeds.rb' + task :seed do + db_namespace['abort_if_pending_migrations'].invoke + ActiveRecord::Tasks::DatabaseTasks.load_seed + end + + namespace :fixtures do + desc "Load fixtures into the current environment's database. Load specific fixtures using FIXTURES=x,y. Load from subdirectory in test/fixtures using FIXTURES_DIR=z. Specify an alternative path (eg. spec/fixtures) using FIXTURES_PATH=spec/fixtures." + task :load => [:environment, :load_config] do + require 'active_record/fixtures' + + base_dir = ActiveRecord::Tasks::DatabaseTasks.fixtures_path + + fixtures_dir = if ENV['FIXTURES_DIR'] + File.join base_dir, ENV['FIXTURES_DIR'] + else + base_dir + end + + fixture_files = if ENV['FIXTURES'] + ENV['FIXTURES'].split(',') + else + # The use of String#[] here is to support namespaced fixtures + Dir["#{fixtures_dir}/**/*.yml"].map {|f| f[(fixtures_dir.size + 1)..-5] } + end + + ActiveRecord::FixtureSet.create_fixtures(fixtures_dir, fixture_files) + end + + # desc "Search for a fixture given a LABEL or ID. Specify an alternative path (eg. spec/fixtures) using FIXTURES_PATH=spec/fixtures." + task :identify => [:environment, :load_config] do + require 'active_record/fixtures' + + label, id = ENV['LABEL'], ENV['ID'] + raise 'LABEL or ID required' if label.blank? && id.blank? + + puts %Q(The fixture ID for "#{label}" is #{ActiveRecord::FixtureSet.identify(label)}.) if label + + base_dir = ActiveRecord::Tasks::DatabaseTasks.fixtures_path + + Dir["#{base_dir}/**/*.yml"].each do |file| + if data = YAML::load(ERB.new(IO.read(file)).result) + data.each_key do |key| + key_id = ActiveRecord::FixtureSet.identify(key) + + if key == label || key_id == id.to_i + puts "#{file}: #{key} (#{key_id})" + end + end + end + end + end + end + + namespace :schema do + desc 'Create a db/schema.rb file that is portable against any DB supported by AR' + task :dump => [:environment, :load_config] do + require 'active_record/schema_dumper' + filename = ENV['SCHEMA'] || File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, 'schema.rb') + File.open(filename, "w:utf-8") do |file| + ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file) + end + db_namespace['schema:dump'].reenable + end + + desc 'Load a schema.rb file into the database' + task :load => [:environment, :load_config] do + ActiveRecord::Tasks::DatabaseTasks.load_schema_current(:ruby, ENV['SCHEMA']) + end + + task :load_if_ruby => ['db:create', :environment] do + db_namespace["schema:load"].invoke if ActiveRecord::Base.schema_format == :ruby + end + + namespace :cache do + desc 'Create a db/schema_cache.dump file.' + task :dump => [:environment, :load_config] do + con = ActiveRecord::Base.connection + filename = File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, "schema_cache.dump") + + con.schema_cache.clear! + con.tables.each { |table| con.schema_cache.add(table) } + open(filename, 'wb') { |f| f.write(Marshal.dump(con.schema_cache)) } + end + + desc 'Clear a db/schema_cache.dump file.' + task :clear => [:environment, :load_config] do + filename = File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, "schema_cache.dump") + FileUtils.rm(filename) if File.exist?(filename) + end + end + + end + + namespace :structure do + desc 'Dump the database structure to db/structure.sql. Specify another file with DB_STRUCTURE=db/my_structure.sql' + task :dump => [:environment, :load_config] do + filename = ENV['DB_STRUCTURE'] || File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, "structure.sql") + current_config = ActiveRecord::Tasks::DatabaseTasks.current_config + ActiveRecord::Tasks::DatabaseTasks.structure_dump(current_config, filename) + + if ActiveRecord::Base.connection.supports_migrations? && + ActiveRecord::SchemaMigration.table_exists? + File.open(filename, "a") do |f| + f.puts ActiveRecord::Base.connection.dump_schema_information + f.print "\n" + end + end + db_namespace['structure:dump'].reenable + end + + desc "Recreate the databases from the structure.sql file" + task :load => [:load_config] do + ActiveRecord::Tasks::DatabaseTasks.load_schema_current(:sql, ENV['DB_STRUCTURE']) + end + + task :load_if_sql => ['db:create', :environment] do + db_namespace["structure:load"].invoke if ActiveRecord::Base.schema_format == :sql + end + end + + namespace :test do + + task :deprecated do + Rake.application.top_level_tasks.grep(/^db:test:/).each do |task| + $stderr.puts "WARNING: #{task} is deprecated. The Rails test helper now maintains " \ + "your test schema automatically, see the release notes for details." + end + end + + # desc "Recreate the test database from the current schema" + task :load => %w(db:test:purge) do + case ActiveRecord::Base.schema_format + when :ruby + db_namespace["test:load_schema"].invoke + when :sql + db_namespace["test:load_structure"].invoke + end + end + + # desc "Recreate the test database from an existent schema.rb file" + task :load_schema => %w(db:test:purge) do + begin + should_reconnect = ActiveRecord::Base.connection_pool.active_connection? + ActiveRecord::Schema.verbose = false + ActiveRecord::Tasks::DatabaseTasks.load_schema_for ActiveRecord::Base.configurations['test'], :ruby, ENV['SCHEMA'] + ensure + if should_reconnect + ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations[ActiveRecord::Tasks::DatabaseTasks.env]) + end + end + end + + # desc "Recreate the test database from an existent structure.sql file" + task :load_structure => %w(db:test:purge) do + ActiveRecord::Tasks::DatabaseTasks.load_schema_for ActiveRecord::Base.configurations['test'], :sql, ENV['SCHEMA'] + end + + # desc "Recreate the test database from a fresh schema" + task :clone => %w(db:test:deprecated environment) do + case ActiveRecord::Base.schema_format + when :ruby + db_namespace["test:clone_schema"].invoke + when :sql + db_namespace["test:clone_structure"].invoke + end + end + + # desc "Recreate the test database from a fresh schema.rb file" + task :clone_schema => %w(db:test:deprecated db:schema:dump db:test:load_schema) + + # desc "Recreate the test database from a fresh structure.sql file" + task :clone_structure => %w(db:test:deprecated db:structure:dump db:test:load_structure) + + # desc "Empty the test database" + task :purge => %w(environment load_config) do + ActiveRecord::Tasks::DatabaseTasks.purge ActiveRecord::Base.configurations['test'] + end + + # desc 'Check for pending migrations and load the test schema' + task :prepare => %w(environment load_config) do + unless ActiveRecord::Base.configurations.blank? + db_namespace['test:load'].invoke + end + end + end +end + +namespace :railties do + namespace :install do + # desc "Copies missing migrations from Railties (e.g. engines). You can specify Railties to use with FROM=railtie1,railtie2" + task :migrations => :'db:load_config' do + to_load = ENV['FROM'].blank? ? :all : ENV['FROM'].split(",").map {|n| n.strip } + railties = {} + Rails.application.migration_railties.each do |railtie| + next unless to_load == :all || to_load.include?(railtie.railtie_name) + + if railtie.respond_to?(:paths) && (path = railtie.paths['db/migrate'].first) + railties[railtie.railtie_name] = path + end + end + + on_skip = Proc.new do |name, migration| + puts "NOTE: Migration #{migration.basename} from #{name} has been skipped. Migration with the same name already exists." + end + + on_copy = Proc.new do |name, migration| + puts "Copied migration #{migration.basename} from #{name}" + end + + ActiveRecord::Migration.copy(ActiveRecord::Migrator.migrations_paths.first, railties, + :on_skip => on_skip, :on_copy => on_copy) + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/railties/jdbcmysql_error.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/railties/jdbcmysql_error.rb new file mode 100644 index 0000000..6a38211 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/railties/jdbcmysql_error.rb @@ -0,0 +1,16 @@ +#FIXME Remove if ArJdbcMysql will give. +module ArJdbcMySQL #:nodoc: + class Error < StandardError #:nodoc: + attr_accessor :error_number, :sql_state + + def initialize msg + super + @error_number = nil + @sql_state = nil + end + + # Mysql gem compatibility + alias_method :errno, :error_number + alias_method :error, :message + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/readonly_attributes.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/readonly_attributes.rb new file mode 100644 index 0000000..85bbac4 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/readonly_attributes.rb @@ -0,0 +1,23 @@ +module ActiveRecord + module ReadonlyAttributes + extend ActiveSupport::Concern + + included do + class_attribute :_attr_readonly, instance_accessor: false + self._attr_readonly = [] + end + + module ClassMethods + # Attributes listed as readonly will be used to create a new record but update operations will + # ignore these fields. + def attr_readonly(*attributes) + self._attr_readonly = Set.new(attributes.map { |a| a.to_s }) + (self._attr_readonly || []) + end + + # Returns an array of all the attributes that have been specified as readonly. + def readonly_attributes + self._attr_readonly + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/reflection.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/reflection.rb new file mode 100644 index 0000000..b46df26 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/reflection.rb @@ -0,0 +1,893 @@ +require 'thread' +require 'active_support/core_ext/string/filters' + +module ActiveRecord + # = Active Record Reflection + module Reflection # :nodoc: + extend ActiveSupport::Concern + + included do + class_attribute :_reflections, instance_writer: false + class_attribute :aggregate_reflections, instance_writer: false + self._reflections = {} + self.aggregate_reflections = {} + end + + def self.create(macro, name, scope, options, ar) + klass = case macro + when :composed_of + AggregateReflection + when :has_many + HasManyReflection + when :has_one + HasOneReflection + when :belongs_to + BelongsToReflection + else + raise "Unsupported Macro: #{macro}" + end + + reflection = klass.new(name, scope, options, ar) + options[:through] ? ThroughReflection.new(reflection) : reflection + end + + def self.add_reflection(ar, name, reflection) + ar.clear_reflections_cache + ar._reflections = ar._reflections.merge(name.to_s => reflection) + end + + def self.add_aggregate_reflection(ar, name, reflection) + ar.aggregate_reflections = ar.aggregate_reflections.merge(name.to_s => reflection) + end + + # \Reflection enables interrogating of Active Record classes and objects + # about their associations and aggregations. This information can, + # for example, be used in a form builder that takes an Active Record object + # and creates input fields for all of the attributes depending on their type + # and displays the associations to other objects. + # + # MacroReflection class has info for AggregateReflection and AssociationReflection + # classes. + module ClassMethods + # Returns an array of AggregateReflection objects for all the aggregations in the class. + def reflect_on_all_aggregations + aggregate_reflections.values + end + + # Returns the AggregateReflection object for the named +aggregation+ (use the symbol). + # + # Account.reflect_on_aggregation(:balance) # => the balance AggregateReflection + # + def reflect_on_aggregation(aggregation) + aggregate_reflections[aggregation.to_s] + end + + # Returns a Hash of name of the reflection as the key and a AssociationReflection as the value. + # + # Account.reflections # => {"balance" => AggregateReflection} + # + # @api public + def reflections + @__reflections ||= begin + ref = {} + + _reflections.each do |name, reflection| + parent_name, parent_reflection = reflection.parent_reflection + + if parent_name + ref[parent_name] = parent_reflection + else + ref[name] = reflection + end + end + + ref + end + end + + # Returns an array of AssociationReflection objects for all the + # associations in the class. If you only want to reflect on a certain + # association type, pass in the symbol (:has_many, :has_one, + # :belongs_to) as the first parameter. + # + # Example: + # + # Account.reflect_on_all_associations # returns an array of all associations + # Account.reflect_on_all_associations(:has_many) # returns an array of all has_many associations + # + # @api public + def reflect_on_all_associations(macro = nil) + association_reflections = reflections.values + macro ? association_reflections.select { |reflection| reflection.macro == macro } : association_reflections + end + + # Returns the AssociationReflection object for the +association+ (use the symbol). + # + # Account.reflect_on_association(:owner) # returns the owner AssociationReflection + # Invoice.reflect_on_association(:line_items).macro # returns :has_many + # + # @api public + def reflect_on_association(association) + reflections[association.to_s] + end + + # @api private + def _reflect_on_association(association) #:nodoc: + _reflections[association.to_s] + end + + # Returns an array of AssociationReflection objects for all associations which have :autosave enabled. + # + # @api public + def reflect_on_all_autosave_associations + reflections.values.select { |reflection| reflection.options[:autosave] } + end + + def clear_reflections_cache #:nodoc: + @__reflections = nil + end + end + + # Holds all the methods that are shared between MacroReflection, AssociationReflection + # and ThroughReflection + class AbstractReflection # :nodoc: + def table_name + klass.table_name + end + + # Returns a new, unsaved instance of the associated class. +attributes+ will + # be passed to the class's constructor. + def build_association(attributes, &block) + klass.new(attributes, &block) + end + + def quoted_table_name + klass.quoted_table_name + end + + def primary_key_type + klass.type_for_attribute(klass.primary_key) + end + + # Returns the class name for the macro. + # + # composed_of :balance, class_name: 'Money' returns 'Money' + # has_many :clients returns 'Client' + def class_name + @class_name ||= (options[:class_name] || derive_class_name).to_s + end + + JoinKeys = Struct.new(:key, :foreign_key) # :nodoc: + + def join_keys(assoc_klass) + JoinKeys.new(foreign_key, active_record_primary_key) + end + + def source_macro + ActiveSupport::Deprecation.warn(<<-MSG.squish) + ActiveRecord::Base.source_macro is deprecated and will be removed + without replacement. + MSG + + macro + end + + def inverse_of + return unless inverse_name + + @inverse_of ||= klass._reflect_on_association inverse_name + end + + def check_validity_of_inverse! + unless polymorphic? + if has_inverse? && inverse_of.nil? + raise InverseOfAssociationNotFoundError.new(self) + end + end + end + end + # Base class for AggregateReflection and AssociationReflection. Objects of + # AggregateReflection and AssociationReflection are returned by the Reflection::ClassMethods. + # + # MacroReflection + # AssociationReflection + # AggregateReflection + # HasManyReflection + # HasOneReflection + # BelongsToReflection + # ThroughReflection + class MacroReflection < AbstractReflection + # Returns the name of the macro. + # + # composed_of :balance, class_name: 'Money' returns :balance + # has_many :clients returns :clients + attr_reader :name + + attr_reader :scope + + # Returns the hash of options used for the macro. + # + # composed_of :balance, class_name: 'Money' returns { class_name: "Money" } + # has_many :clients returns {} + attr_reader :options + + attr_reader :active_record + + attr_reader :plural_name # :nodoc: + + def initialize(name, scope, options, active_record) + @name = name + @scope = scope + @options = options + @active_record = active_record + @klass = options[:anonymous_class] + @plural_name = active_record.pluralize_table_names ? + name.to_s.pluralize : name.to_s + end + + def autosave=(autosave) + @automatic_inverse_of = false + @options[:autosave] = autosave + _, parent_reflection = self.parent_reflection + if parent_reflection + parent_reflection.autosave = autosave + end + end + + # Returns the class for the macro. + # + # composed_of :balance, class_name: 'Money' returns the Money class + # has_many :clients returns the Client class + def klass + @klass ||= compute_class(class_name) + end + + def compute_class(name) + name.constantize + end + + # Returns +true+ if +self+ and +other_aggregation+ have the same +name+ attribute, +active_record+ attribute, + # and +other_aggregation+ has an options hash assigned to it. + def ==(other_aggregation) + super || + other_aggregation.kind_of?(self.class) && + name == other_aggregation.name && + !other_aggregation.options.nil? && + active_record == other_aggregation.active_record + end + + private + def derive_class_name + name.to_s.camelize + end + end + + + # Holds all the meta-data about an aggregation as it was specified in the + # Active Record class. + class AggregateReflection < MacroReflection #:nodoc: + def mapping + mapping = options[:mapping] || [name, name] + mapping.first.is_a?(Array) ? mapping : [mapping] + end + end + + # Holds all the meta-data about an association as it was specified in the + # Active Record class. + class AssociationReflection < MacroReflection #:nodoc: + # Returns the target association's class. + # + # class Author < ActiveRecord::Base + # has_many :books + # end + # + # Author.reflect_on_association(:books).klass + # # => Book + # + # Note: Do not call +klass.new+ or +klass.create+ to instantiate + # a new association object. Use +build_association+ or +create_association+ + # instead. This allows plugins to hook into association object creation. + def klass + @klass ||= compute_class(class_name) + end + + def compute_class(name) + active_record.send(:compute_type, name) + end + + attr_reader :type, :foreign_type + attr_accessor :parent_reflection # [:name, Reflection] + + def initialize(name, scope, options, active_record) + super + @automatic_inverse_of = nil + @type = options[:as] && (options[:foreign_type] || "#{options[:as]}_type") + @foreign_type = options[:foreign_type] || "#{name}_type" + @constructable = calculate_constructable(macro, options) + @association_scope_cache = {} + @scope_lock = Mutex.new + end + + def association_scope_cache(conn, owner) + key = conn.prepared_statements + if polymorphic? + key = [key, owner._read_attribute(@foreign_type)] + end + @association_scope_cache[key] ||= @scope_lock.synchronize { + @association_scope_cache[key] ||= yield + } + end + + def constructable? # :nodoc: + @constructable + end + + def join_table + @join_table ||= options[:join_table] || derive_join_table + end + + def foreign_key + @foreign_key ||= options[:foreign_key] || derive_foreign_key.freeze + end + + def association_foreign_key + @association_foreign_key ||= options[:association_foreign_key] || class_name.foreign_key + end + + # klass option is necessary to support loading polymorphic associations + def association_primary_key(klass = nil) + options[:primary_key] || primary_key(klass || self.klass) + end + + def active_record_primary_key + @active_record_primary_key ||= options[:primary_key] || primary_key(active_record) + end + + def counter_cache_column + if options[:counter_cache] == true + "#{active_record.name.demodulize.underscore.pluralize}_count" + elsif options[:counter_cache] + options[:counter_cache].to_s + end + end + + def check_validity! + check_validity_of_inverse! + end + + def check_preloadable! + return unless scope + + if scope.arity > 0 + ActiveSupport::Deprecation.warn(<<-MSG.squish) + The association scope '#{name}' is instance dependent (the scope + block takes an argument). Preloading happens before the individual + instances are created. This means that there is no instance being + passed to the association scope. This will most likely result in + broken or incorrect behavior. Joining, Preloading and eager loading + of these associations is deprecated and will be removed in the future. + MSG + end + end + alias :check_eager_loadable! :check_preloadable! + + def join_id_for(owner) # :nodoc: + owner[active_record_primary_key] + end + + def through_reflection + nil + end + + def source_reflection + self + end + + # A chain of reflections from this one back to the owner. For more see the explanation in + # ThroughReflection. + def chain + [self] + end + + def nested? + false + end + + # An array of arrays of scopes. Each item in the outside array corresponds to a reflection + # in the #chain. + def scope_chain + scope ? [[scope]] : [[]] + end + + def has_inverse? + inverse_name + end + + def polymorphic_inverse_of(associated_class) + if has_inverse? + if inverse_relationship = associated_class._reflect_on_association(options[:inverse_of]) + inverse_relationship + else + raise InverseOfAssociationNotFoundError.new(self, associated_class) + end + end + end + + # Returns the macro type. + # + # has_many :clients returns :has_many + def macro; raise NotImplementedError; end + + # Returns whether or not this association reflection is for a collection + # association. Returns +true+ if the +macro+ is either +has_many+ or + # +has_and_belongs_to_many+, +false+ otherwise. + def collection? + false + end + + # Returns whether or not the association should be validated as part of + # the parent's validation. + # + # Unless you explicitly disable validation with + # validate: false, validation will take place when: + # + # * you explicitly enable validation; validate: true + # * you use autosave; autosave: true + # * the association is a +has_many+ association + def validate? + !options[:validate].nil? ? options[:validate] : (options[:autosave] == true || collection?) + end + + # Returns +true+ if +self+ is a +belongs_to+ reflection. + def belongs_to?; false; end + + # Returns +true+ if +self+ is a +has_one+ reflection. + def has_one?; false; end + + def association_class + case macro + when :belongs_to + if polymorphic? + Associations::BelongsToPolymorphicAssociation + else + Associations::BelongsToAssociation + end + when :has_many + if options[:through] + Associations::HasManyThroughAssociation + else + Associations::HasManyAssociation + end + when :has_one + if options[:through] + Associations::HasOneThroughAssociation + else + Associations::HasOneAssociation + end + end + end + + def polymorphic? + options[:polymorphic] + end + + VALID_AUTOMATIC_INVERSE_MACROS = [:has_many, :has_one, :belongs_to] + INVALID_AUTOMATIC_INVERSE_OPTIONS = [:conditions, :through, :polymorphic, :foreign_key] + + protected + + def actual_source_reflection # FIXME: this is a horrible name + self + end + + private + + def calculate_constructable(macro, options) + case macro + when :belongs_to + !polymorphic? + when :has_one + !options[:through] + else + true + end + end + + # Attempts to find the inverse association name automatically. + # If it cannot find a suitable inverse association name, it returns + # nil. + def inverse_name + options.fetch(:inverse_of) do + if @automatic_inverse_of == false + nil + else + @automatic_inverse_of ||= automatic_inverse_of + end + end + end + + # returns either nil or the inverse association name that it finds. + def automatic_inverse_of + if can_find_inverse_of_automatically?(self) + inverse_name = ActiveSupport::Inflector.underscore(options[:as] || active_record.name.demodulize).to_sym + + begin + reflection = klass._reflect_on_association(inverse_name) + rescue NameError + # Give up: we couldn't compute the klass type so we won't be able + # to find any associations either. + reflection = false + end + + if valid_inverse_reflection?(reflection) + return inverse_name + end + end + + false + end + + # Checks if the inverse reflection that is returned from the + # +automatic_inverse_of+ method is a valid reflection. We must + # make sure that the reflection's active_record name matches up + # with the current reflection's klass name. + # + # Note: klass will always be valid because when there's a NameError + # from calling +klass+, +reflection+ will already be set to false. + def valid_inverse_reflection?(reflection) + reflection && + klass.name == reflection.active_record.name && + can_find_inverse_of_automatically?(reflection) + end + + # Checks to see if the reflection doesn't have any options that prevent + # us from being able to guess the inverse automatically. First, the + # inverse_of option cannot be set to false. Second, we must + # have has_many, has_one, belongs_to associations. + # Third, we must not have options such as :polymorphic or + # :foreign_key which prevent us from correctly guessing the + # inverse association. + # + # Anything with a scope can additionally ruin our attempt at finding an + # inverse, so we exclude reflections with scopes. + def can_find_inverse_of_automatically?(reflection) + reflection.options[:inverse_of] != false && + VALID_AUTOMATIC_INVERSE_MACROS.include?(reflection.macro) && + !INVALID_AUTOMATIC_INVERSE_OPTIONS.any? { |opt| reflection.options[opt] } && + !reflection.scope + end + + def derive_class_name + class_name = name.to_s + class_name = class_name.singularize if collection? + class_name.camelize + end + + def derive_foreign_key + if belongs_to? + "#{name}_id" + elsif options[:as] + "#{options[:as]}_id" + else + active_record.name.foreign_key + end + end + + def derive_join_table + ModelSchema.derive_join_table_name active_record.table_name, klass.table_name + end + + def primary_key(klass) + klass.primary_key || raise(UnknownPrimaryKey.new(klass)) + end + end + + class HasManyReflection < AssociationReflection # :nodoc: + def initialize(name, scope, options, active_record) + super(name, scope, options, active_record) + end + + def macro; :has_many; end + + def collection?; true; end + end + + class HasOneReflection < AssociationReflection # :nodoc: + def initialize(name, scope, options, active_record) + super(name, scope, options, active_record) + end + + def macro; :has_one; end + + def has_one?; true; end + end + + class BelongsToReflection < AssociationReflection # :nodoc: + def initialize(name, scope, options, active_record) + super(name, scope, options, active_record) + end + + def macro; :belongs_to; end + + def belongs_to?; true; end + + def join_keys(assoc_klass) + key = polymorphic? ? association_primary_key(assoc_klass) : association_primary_key + JoinKeys.new(key, foreign_key) + end + + def join_id_for(owner) # :nodoc: + owner[foreign_key] + end + end + + class HasAndBelongsToManyReflection < AssociationReflection # :nodoc: + def initialize(name, scope, options, active_record) + super + end + + def macro; :has_and_belongs_to_many; end + + def collection? + true + end + end + + # Holds all the meta-data about a :through association as it was specified + # in the Active Record class. + class ThroughReflection < AbstractReflection #:nodoc: + attr_reader :delegate_reflection + delegate :foreign_key, :foreign_type, :association_foreign_key, + :active_record_primary_key, :type, :to => :source_reflection + + def initialize(delegate_reflection) + @delegate_reflection = delegate_reflection + @klass = delegate_reflection.options[:anonymous_class] + @source_reflection_name = delegate_reflection.options[:source] + end + + def klass + @klass ||= delegate_reflection.compute_class(class_name) + end + + # Returns the source of the through reflection. It checks both a singularized + # and pluralized form for :belongs_to or :has_many. + # + # class Post < ActiveRecord::Base + # has_many :taggings + # has_many :tags, through: :taggings + # end + # + # class Tagging < ActiveRecord::Base + # belongs_to :post + # belongs_to :tag + # end + # + # tags_reflection = Post.reflect_on_association(:tags) + # tags_reflection.source_reflection + # # => + # + def source_reflection + through_reflection.klass._reflect_on_association(source_reflection_name) + end + + # Returns the AssociationReflection object specified in the :through option + # of a HasManyThrough or HasOneThrough association. + # + # class Post < ActiveRecord::Base + # has_many :taggings + # has_many :tags, through: :taggings + # end + # + # tags_reflection = Post.reflect_on_association(:tags) + # tags_reflection.through_reflection + # # => + # + def through_reflection + active_record._reflect_on_association(options[:through]) + end + + # Returns an array of reflections which are involved in this association. Each item in the + # array corresponds to a table which will be part of the query for this association. + # + # The chain is built by recursively calling #chain on the source reflection and the through + # reflection. The base case for the recursion is a normal association, which just returns + # [self] as its #chain. + # + # class Post < ActiveRecord::Base + # has_many :taggings + # has_many :tags, through: :taggings + # end + # + # tags_reflection = Post.reflect_on_association(:tags) + # tags_reflection.chain + # # => [, + # ] + # + def chain + @chain ||= begin + a = source_reflection.chain + b = through_reflection.chain + chain = a + b + chain[0] = self # Use self so we don't lose the information from :source_type + chain + end + end + + # Consider the following example: + # + # class Person + # has_many :articles + # has_many :comment_tags, through: :articles + # end + # + # class Article + # has_many :comments + # has_many :comment_tags, through: :comments, source: :tags + # end + # + # class Comment + # has_many :tags + # end + # + # There may be scopes on Person.comment_tags, Article.comment_tags and/or Comment.tags, + # but only Comment.tags will be represented in the #chain. So this method creates an array + # of scopes corresponding to the chain. + def scope_chain + @scope_chain ||= begin + scope_chain = source_reflection.scope_chain.map(&:dup) + + # Add to it the scope from this reflection (if any) + scope_chain.first << scope if scope + + through_scope_chain = through_reflection.scope_chain.map(&:dup) + + if options[:source_type] + type = foreign_type + source_type = options[:source_type] + through_scope_chain.first << lambda { |object| + where(type => source_type) + } + end + + # Recursively fill out the rest of the array from the through reflection + scope_chain + through_scope_chain + end + end + + def join_keys(assoc_klass) + source_reflection.join_keys(assoc_klass) + end + + # The macro used by the source association + def source_macro + ActiveSupport::Deprecation.warn(<<-MSG.squish) + ActiveRecord::Base.source_macro is deprecated and will be removed + without replacement. + MSG + + source_reflection.source_macro + end + + # A through association is nested if there would be more than one join table + def nested? + chain.length > 2 + end + + # We want to use the klass from this reflection, rather than just delegate straight to + # the source_reflection, because the source_reflection may be polymorphic. We still + # need to respect the source_reflection's :primary_key option, though. + def association_primary_key(klass = nil) + # Get the "actual" source reflection if the immediate source reflection has a + # source reflection itself + actual_source_reflection.options[:primary_key] || primary_key(klass || self.klass) + end + + # Gets an array of possible :through source reflection names in both singular and plural form. + # + # class Post < ActiveRecord::Base + # has_many :taggings + # has_many :tags, through: :taggings + # end + # + # tags_reflection = Post.reflect_on_association(:tags) + # tags_reflection.source_reflection_names + # # => [:tag, :tags] + # + def source_reflection_names + options[:source] ? [options[:source]] : [name.to_s.singularize, name].uniq + end + + def source_reflection_name # :nodoc: + return @source_reflection_name if @source_reflection_name + + names = [name.to_s.singularize, name].collect { |n| n.to_sym }.uniq + names = names.find_all { |n| + through_reflection.klass._reflect_on_association(n) + } + + if names.length > 1 + example_options = options.dup + example_options[:source] = source_reflection_names.first + ActiveSupport::Deprecation.warn \ + "Ambiguous source reflection for through association. Please " \ + "specify a :source directive on your declaration like:\n" \ + "\n" \ + " class #{active_record.name} < ActiveRecord::Base\n" \ + " #{macro} :#{name}, #{example_options}\n" \ + " end" + end + + @source_reflection_name = names.first + end + + def source_options + source_reflection.options + end + + def through_options + through_reflection.options + end + + def join_id_for(owner) # :nodoc: + source_reflection.join_id_for(owner) + end + + def check_validity! + if through_reflection.nil? + raise HasManyThroughAssociationNotFoundError.new(active_record.name, self) + end + + if through_reflection.polymorphic? + if has_one? + raise HasOneAssociationPolymorphicThroughError.new(active_record.name, self) + else + raise HasManyThroughAssociationPolymorphicThroughError.new(active_record.name, self) + end + end + + if source_reflection.nil? + raise HasManyThroughSourceAssociationNotFoundError.new(self) + end + + if options[:source_type] && !source_reflection.polymorphic? + raise HasManyThroughAssociationPointlessSourceTypeError.new(active_record.name, self, source_reflection) + end + + if source_reflection.polymorphic? && options[:source_type].nil? + raise HasManyThroughAssociationPolymorphicSourceError.new(active_record.name, self, source_reflection) + end + + if has_one? && through_reflection.collection? + raise HasOneThroughCantAssociateThroughCollection.new(active_record.name, self, through_reflection) + end + + check_validity_of_inverse! + end + + protected + + def actual_source_reflection # FIXME: this is a horrible name + source_reflection.send(:actual_source_reflection) + end + + def primary_key(klass) + klass.primary_key || raise(UnknownPrimaryKey.new(klass)) + end + + def inverse_name; delegate_reflection.send(:inverse_name); end + + private + def derive_class_name + # get the class_name of the belongs_to association of the through reflection + options[:source_type] || source_reflection.class_name + end + + delegate_methods = AssociationReflection.public_instance_methods - + public_instance_methods + + delegate(*delegate_methods, to: :delegate_reflection) + + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/relation.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/relation.rb new file mode 100644 index 0000000..42e3316 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/relation.rb @@ -0,0 +1,682 @@ +# -*- coding: utf-8 -*- +require 'arel/collectors/bind' + +module ActiveRecord + # = Active Record Relation + class Relation + MULTI_VALUE_METHODS = [:includes, :eager_load, :preload, :select, :group, + :order, :joins, :where, :having, :bind, :references, + :extending, :unscope] + + SINGLE_VALUE_METHODS = [:limit, :offset, :lock, :readonly, :from, :reordering, + :reverse_order, :distinct, :create_with, :uniq] + INVALID_METHODS_FOR_DELETE_ALL = [:limit, :distinct, :offset, :group, :having] + + VALUE_METHODS = MULTI_VALUE_METHODS + SINGLE_VALUE_METHODS + + include FinderMethods, Calculations, SpawnMethods, QueryMethods, Batches, Explain, Delegation + + attr_reader :table, :klass, :loaded + alias :model :klass + alias :loaded? :loaded + + def initialize(klass, table, values = {}) + @klass = klass + @table = table + @values = values + @offsets = {} + @loaded = false + end + + def initialize_copy(other) + # This method is a hot spot, so for now, use Hash[] to dup the hash. + # https://bugs.ruby-lang.org/issues/7166 + @values = Hash[@values] + @values[:bind] = @values[:bind].dup if @values.key? :bind + reset + end + + def insert(values) # :nodoc: + primary_key_value = nil + + if primary_key && Hash === values + primary_key_value = values[values.keys.find { |k| + k.name == primary_key + }] + + if !primary_key_value && connection.prefetch_primary_key?(klass.table_name) + primary_key_value = connection.next_sequence_value(klass.sequence_name) + values[klass.arel_table[klass.primary_key]] = primary_key_value + end + end + + im = arel.create_insert + im.into @table + + substitutes, binds = substitute_values values + + if values.empty? # empty insert + im.values = Arel.sql(connection.empty_insert_statement_value) + else + im.insert substitutes + end + + @klass.connection.insert( + im, + 'SQL', + primary_key, + primary_key_value, + nil, + binds) + end + + def _update_record(values, id, id_was) # :nodoc: + substitutes, binds = substitute_values values + + scope = @klass.unscoped + + if @klass.finder_needs_type_condition? + scope.unscope!(where: @klass.inheritance_column) + end + + relation = scope.where(@klass.primary_key => (id_was || id)) + bvs = binds + relation.bind_values + um = relation + .arel + .compile_update(substitutes, @klass.primary_key) + + @klass.connection.update( + um, + 'SQL', + bvs, + ) + end + + def substitute_values(values) # :nodoc: + binds = values.map do |arel_attr, value| + [@klass.columns_hash[arel_attr.name], value] + end + + substitutes = values.each_with_index.map do |(arel_attr, _), i| + [arel_attr, @klass.connection.substitute_at(binds[i][0])] + end + + [substitutes, binds] + end + + # Initializes new record from relation while maintaining the current + # scope. + # + # Expects arguments in the same format as +Base.new+. + # + # users = User.where(name: 'DHH') + # user = users.new # => # + # + # You can also pass a block to new with the new record as argument: + # + # user = users.new { |user| user.name = 'Oscar' } + # user.name # => Oscar + def new(*args, &block) + scoping { @klass.new(*args, &block) } + end + + alias build new + + # Tries to create a new record with the same scoped attributes + # defined in the relation. Returns the initialized object if validation fails. + # + # Expects arguments in the same format as +Base.create+. + # + # ==== Examples + # users = User.where(name: 'Oscar') + # users.create # # + # + # users.create(name: 'fxn') + # users.create # # + # + # users.create { |user| user.name = 'tenderlove' } + # # # + # + # users.create(name: nil) # validation on name + # # # + def create(*args, &block) + scoping { @klass.create(*args, &block) } + end + + # Similar to #create, but calls +create!+ on the base class. Raises + # an exception if a validation error occurs. + # + # Expects arguments in the same format as Base.create!. + def create!(*args, &block) + scoping { @klass.create!(*args, &block) } + end + + def first_or_create(attributes = nil, &block) # :nodoc: + first || create(attributes, &block) + end + + def first_or_create!(attributes = nil, &block) # :nodoc: + first || create!(attributes, &block) + end + + def first_or_initialize(attributes = nil, &block) # :nodoc: + first || new(attributes, &block) + end + + # Finds the first record with the given attributes, or creates a record + # with the attributes if one is not found: + # + # # Find the first user named "Penélope" or create a new one. + # User.find_or_create_by(first_name: 'Penélope') + # # => # + # + # # Find the first user named "Penélope" or create a new one. + # # We already have one so the existing record will be returned. + # User.find_or_create_by(first_name: 'Penélope') + # # => # + # + # # Find the first user named "Scarlett" or create a new one with + # # a particular last name. + # User.create_with(last_name: 'Johansson').find_or_create_by(first_name: 'Scarlett') + # # => # + # + # This method accepts a block, which is passed down to +create+. The last example + # above can be alternatively written this way: + # + # # Find the first user named "Scarlett" or create a new one with a + # # different last name. + # User.find_or_create_by(first_name: 'Scarlett') do |user| + # user.last_name = 'Johansson' + # end + # # => # + # + # This method always returns a record, but if creation was attempted and + # failed due to validation errors it won't be persisted, you get what + # +create+ returns in such situation. + # + # Please note *this method is not atomic*, it runs first a SELECT, and if + # there are no results an INSERT is attempted. If there are other threads + # or processes there is a race condition between both calls and it could + # be the case that you end up with two similar records. + # + # Whether that is a problem or not depends on the logic of the + # application, but in the particular case in which rows have a UNIQUE + # constraint an exception may be raised, just retry: + # + # begin + # CreditAccount.find_or_create_by(user_id: user.id) + # rescue ActiveRecord::RecordNotUnique + # retry + # end + # + def find_or_create_by(attributes, &block) + find_by(attributes) || create(attributes, &block) + end + + # Like find_or_create_by, but calls create! so an exception + # is raised if the created record is invalid. + def find_or_create_by!(attributes, &block) + find_by(attributes) || create!(attributes, &block) + end + + # Like find_or_create_by, but calls new instead of create. + def find_or_initialize_by(attributes, &block) + find_by(attributes) || new(attributes, &block) + end + + # Runs EXPLAIN on the query or queries triggered by this relation and + # returns the result as a string. The string is formatted imitating the + # ones printed by the database shell. + # + # Note that this method actually runs the queries, since the results of some + # are needed by the next ones when eager loading is going on. + # + # Please see further details in the + # {Active Record Query Interface guide}[http://guides.rubyonrails.org/active_record_querying.html#running-explain]. + def explain + #TODO: Fix for binds. + exec_explain(collecting_queries_for_explain { exec_queries }) + end + + # Converts relation objects to Array. + def to_a + load + @records + end + + # Serializes the relation objects Array. + def encode_with(coder) + coder.represent_seq(nil, to_a) + end + + def as_json(options = nil) #:nodoc: + to_a.as_json(options) + end + + # Returns size of the records. + def size + loaded? ? @records.length : count(:all) + end + + # Returns true if there are no records. + def empty? + return @records.empty? if loaded? + + if limit_value == 0 + true + else + c = count(:all) + c.respond_to?(:zero?) ? c.zero? : c.empty? + end + end + + # Returns true if there are any records. + def any? + if block_given? + to_a.any? { |*block_args| yield(*block_args) } + else + !empty? + end + end + + # Returns true if there is more than one record. + def many? + if block_given? + to_a.many? { |*block_args| yield(*block_args) } + else + limit_value ? to_a.many? : size > 1 + end + end + + # Scope all queries to the current scope. + # + # Comment.where(post_id: 1).scoping do + # Comment.first + # end + # # => SELECT "comments".* FROM "comments" WHERE "comments"."post_id" = 1 ORDER BY "comments"."id" ASC LIMIT 1 + # + # Please check unscoped if you want to remove all previous scopes (including + # the default_scope) during the execution of a block. + def scoping + previous, klass.current_scope = klass.current_scope, self + yield + ensure + klass.current_scope = previous + end + + # Updates all records in the current relation with details given. This method constructs a single SQL UPDATE + # statement and sends it straight to the database. It does not instantiate the involved models and it does not + # trigger Active Record callbacks or validations. Values passed to `update_all` will not go through + # ActiveRecord's type-casting behavior. It should receive only values that can be passed as-is to the SQL + # database. + # + # ==== Parameters + # + # * +updates+ - A string, array, or hash representing the SET part of an SQL statement. + # + # ==== Examples + # + # # Update all customers with the given attributes + # Customer.update_all wants_email: true + # + # # Update all books with 'Rails' in their title + # Book.where('title LIKE ?', '%Rails%').update_all(author: 'David') + # + # # Update all books that match conditions, but limit it to 5 ordered by date + # Book.where('title LIKE ?', '%Rails%').order(:created_at).limit(5).update_all(author: 'David') + def update_all(updates) + raise ArgumentError, "Empty list of attributes to change" if updates.blank? + + stmt = Arel::UpdateManager.new(arel.engine) + + stmt.set Arel.sql(@klass.send(:sanitize_sql_for_assignment, updates)) + stmt.table(table) + stmt.key = table[primary_key] + + if joins_values.any? + @klass.connection.join_to_update(stmt, arel) + else + stmt.take(arel.limit) + stmt.order(*arel.orders) + stmt.wheres = arel.constraints + end + + bvs = arel.bind_values + bind_values + @klass.connection.update stmt, 'SQL', bvs + end + + # Updates an object (or multiple objects) and saves it to the database, if validations pass. + # The resulting object is returned whether the object was saved successfully to the database or not. + # + # ==== Parameters + # + # * +id+ - This should be the id or an array of ids to be updated. + # * +attributes+ - This should be a hash of attributes or an array of hashes. + # + # ==== Examples + # + # # Updates one record + # Person.update(15, user_name: 'Samuel', group: 'expert') + # + # # Updates multiple records + # people = { 1 => { "first_name" => "David" }, 2 => { "first_name" => "Jeremy" } } + # Person.update(people.keys, people.values) + def update(id, attributes) + if id.is_a?(Array) + id.map.with_index { |one_id, idx| update(one_id, attributes[idx]) } + else + object = find(id) + object.update(attributes) + object + end + end + + # Destroys the records matching +conditions+ by instantiating each + # record and calling its +destroy+ method. Each object's callbacks are + # executed (including :dependent association options). Returns the + # collection of objects that were destroyed; each will be frozen, to + # reflect that no changes should be made (since they can't be persisted). + # + # Note: Instantiation, callback execution, and deletion of each + # record can be time consuming when you're removing many records at + # once. It generates at least one SQL +DELETE+ query per record (or + # possibly more, to enforce your callbacks). If you want to delete many + # rows quickly, without concern for their associations or callbacks, use + # +delete_all+ instead. + # + # ==== Parameters + # + # * +conditions+ - A string, array, or hash that specifies which records + # to destroy. If omitted, all records are destroyed. See the + # Conditions section in the introduction to ActiveRecord::Base for + # more information. + # + # ==== Examples + # + # Person.destroy_all("last_login < '2004-04-04'") + # Person.destroy_all(status: "inactive") + # Person.where(age: 0..18).destroy_all + def destroy_all(conditions = nil) + if conditions + where(conditions).destroy_all + else + to_a.each {|object| object.destroy }.tap { reset } + end + end + + # Destroy an object (or multiple objects) that has the given id. The object is instantiated first, + # therefore all callbacks and filters are fired off before the object is deleted. This method is + # less efficient than ActiveRecord#delete but allows cleanup methods and other actions to be run. + # + # This essentially finds the object (or multiple objects) with the given id, creates a new object + # from the attributes, and then calls destroy on it. + # + # ==== Parameters + # + # * +id+ - Can be either an Integer or an Array of Integers. + # + # ==== Examples + # + # # Destroy a single object + # Todo.destroy(1) + # + # # Destroy multiple objects + # todos = [1,2,3] + # Todo.destroy(todos) + def destroy(id) + if id.is_a?(Array) + id.map { |one_id| destroy(one_id) } + else + find(id).destroy + end + end + + # Deletes the records matching +conditions+ without instantiating the records + # first, and hence not calling the +destroy+ method nor invoking callbacks. This + # is a single SQL DELETE statement that goes straight to the database, much more + # efficient than +destroy_all+. Be careful with relations though, in particular + # :dependent rules defined on associations are not honored. Returns the + # number of rows affected. + # + # Post.delete_all("person_id = 5 AND (category = 'Something' OR category = 'Else')") + # Post.delete_all(["person_id = ? AND (category = ? OR category = ?)", 5, 'Something', 'Else']) + # Post.where(person_id: 5).where(category: ['Something', 'Else']).delete_all + # + # Both calls delete the affected posts all at once with a single DELETE statement. + # If you need to destroy dependent associations or call your before_* or + # +after_destroy+ callbacks, use the +destroy_all+ method instead. + # + # If an invalid method is supplied, +delete_all+ raises an ActiveRecord error: + # + # Post.limit(100).delete_all + # # => ActiveRecord::ActiveRecordError: delete_all doesn't support limit + def delete_all(conditions = nil) + invalid_methods = INVALID_METHODS_FOR_DELETE_ALL.select { |method| + if MULTI_VALUE_METHODS.include?(method) + send("#{method}_values").any? + else + send("#{method}_value") + end + } + if invalid_methods.any? + raise ActiveRecordError.new("delete_all doesn't support #{invalid_methods.join(', ')}") + end + + if conditions + where(conditions).delete_all + else + stmt = Arel::DeleteManager.new(arel.engine) + stmt.from(table) + + if joins_values.any? + @klass.connection.join_to_delete(stmt, arel, table[primary_key]) + else + stmt.wheres = arel.constraints + end + + bvs = arel.bind_values + bind_values + affected = @klass.connection.delete(stmt, 'SQL', bvs) + + reset + affected + end + end + + # Deletes the row with a primary key matching the +id+ argument, using a + # SQL +DELETE+ statement, and returns the number of rows deleted. Active + # Record objects are not instantiated, so the object's callbacks are not + # executed, including any :dependent association options. + # + # You can delete multiple rows at once by passing an Array of ids. + # + # Note: Although it is often much faster than the alternative, + # #destroy, skipping callbacks might bypass business logic in + # your application that ensures referential integrity or performs other + # essential jobs. + # + # ==== Examples + # + # # Delete a single row + # Todo.delete(1) + # + # # Delete multiple rows + # Todo.delete([2,3,4]) + def delete(id_or_array) + where(primary_key => id_or_array).delete_all + end + + # Causes the records to be loaded from the database if they have not + # been loaded already. You can use this if for some reason you need + # to explicitly load some records before actually using them. The + # return value is the relation itself, not the records. + # + # Post.where(published: true).load # => # + def load + exec_queries unless loaded? + + self + end + + # Forces reloading of relation. + def reload + reset + load + end + + def reset + @last = @to_sql = @order_clause = @scope_for_create = @arel = @loaded = nil + @should_eager_load = @join_dependency = nil + @records = [] + @offsets = {} + self + end + + # Returns sql statement for the relation. + # + # User.where(name: 'Oscar').to_sql + # # => SELECT "users".* FROM "users" WHERE "users"."name" = 'Oscar' + def to_sql + @to_sql ||= begin + relation = self + connection = klass.connection + visitor = connection.visitor + + if eager_loading? + find_with_associations { |rel| relation = rel } + end + + arel = relation.arel + binds = (arel.bind_values + relation.bind_values).dup + binds.map! { |bv| connection.quote(*bv.reverse) } + collect = visitor.accept(arel.ast, Arel::Collectors::Bind.new) + collect.substitute_binds(binds).join + end + end + + # Returns a hash of where conditions. + # + # User.where(name: 'Oscar').where_values_hash + # # => {name: "Oscar"} + def where_values_hash(relation_table_name = table_name) + equalities = where_values.grep(Arel::Nodes::Equality).find_all { |node| + node.left.relation.name == relation_table_name + } + + binds = Hash[bind_values.find_all(&:first).map { |column, v| [column.name, v] }] + + Hash[equalities.map { |where| + name = where.left.name + [name, binds.fetch(name.to_s) { + case where.right + when Array then where.right.map(&:val) + when Arel::Nodes::Casted + where.right.val + end + }] + }] + end + + def scope_for_create + @scope_for_create ||= where_values_hash.merge(create_with_value) + end + + # Returns true if relation needs eager loading. + def eager_loading? + @should_eager_load ||= + eager_load_values.any? || + includes_values.any? && (joined_includes_values.any? || references_eager_loaded_tables?) + end + + # Joins that are also marked for preloading. In which case we should just eager load them. + # Note that this is a naive implementation because we could have strings and symbols which + # represent the same association, but that aren't matched by this. Also, we could have + # nested hashes which partially match, e.g. { a: :b } & { a: [:b, :c] } + def joined_includes_values + includes_values & joins_values + end + + # +uniq+ and +uniq!+ are silently deprecated. +uniq_value+ delegates to +distinct_value+ + # to maintain backwards compatibility. Use +distinct_value+ instead. + def uniq_value + distinct_value + end + + # Compares two relations for equality. + def ==(other) + case other + when Associations::CollectionProxy, AssociationRelation + self == other.to_a + when Relation + other.to_sql == to_sql + when Array + to_a == other + end + end + + def pretty_print(q) + q.pp(self.to_a) + end + + # Returns true if relation is blank. + def blank? + to_a.blank? + end + + def values + Hash[@values] + end + + def inspect + entries = to_a.take([limit_value, 11].compact.min).map!(&:inspect) + entries[10] = '...' if entries.size == 11 + + "#<#{self.class.name} [#{entries.join(', ')}]>" + end + + private + + def exec_queries + @records = eager_loading? ? find_with_associations : @klass.find_by_sql(arel, arel.bind_values + bind_values) + + preload = preload_values + preload += includes_values unless eager_loading? + preloader = build_preloader + preload.each do |associations| + preloader.preload @records, associations + end + + @records.each { |record| record.readonly! } if readonly_value + + @loaded = true + @records + end + + def build_preloader + ActiveRecord::Associations::Preloader.new + end + + def references_eager_loaded_tables? + joined_tables = arel.join_sources.map do |join| + if join.is_a?(Arel::Nodes::StringJoin) + tables_in_string(join.left) + else + [join.left.table_name, join.left.table_alias] + end + end + + joined_tables += [table.name, table.table_alias] + + # always convert table names to downcase as in Oracle quoted table names are in uppercase + joined_tables = joined_tables.flatten.compact.map { |t| t.downcase }.uniq + + (references_values - joined_tables).any? + end + + def tables_in_string(string) + return [] if string.blank? + # always convert table names to downcase as in Oracle quoted table names are in uppercase + # ignore raw_sql_ that is used by Oracle adapter as alias for limit/offset subqueries + string.scan(/([a-zA-Z_][.\w]+).?\./).flatten.map{ |s| s.downcase }.uniq - ['raw_sql_'] + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/relation/batches.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/relation/batches.rb new file mode 100644 index 0000000..b069cdc --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/relation/batches.rb @@ -0,0 +1,138 @@ +module ActiveRecord + module Batches + # Looping through a collection of records from the database + # (using the +all+ method, for example) is very inefficient + # since it will try to instantiate all the objects at once. + # + # In that case, batch processing methods allow you to work + # with the records in batches, thereby greatly reducing memory consumption. + # + # The #find_each method uses #find_in_batches with a batch size of 1000 (or as + # specified by the +:batch_size+ option). + # + # Person.find_each do |person| + # person.do_awesome_stuff + # end + # + # Person.where("age > 21").find_each do |person| + # person.party_all_night! + # end + # + # If you do not provide a block to #find_each, it will return an Enumerator + # for chaining with other methods: + # + # Person.find_each.with_index do |person, index| + # person.award_trophy(index + 1) + # end + # + # ==== Options + # * :batch_size - Specifies the size of the batch. Default to 1000. + # * :start - Specifies the starting point for the batch processing. + # This is especially useful if you want multiple workers dealing with + # the same processing queue. You can make worker 1 handle all the records + # between id 0 and 10,000 and worker 2 handle from 10,000 and beyond + # (by setting the +:start+ option on that worker). + # + # # Let's process for a batch of 2000 records, skipping the first 2000 rows + # Person.find_each(start: 2000, batch_size: 2000) do |person| + # person.party_all_night! + # end + # + # NOTE: It's not possible to set the order. That is automatically set to + # ascending on the primary key ("id ASC") to make the batch ordering + # work. This also means that this method only works with integer-based + # primary keys. + # + # NOTE: You can't set the limit either, that's used to control + # the batch sizes. + def find_each(options = {}) + if block_given? + find_in_batches(options) do |records| + records.each { |record| yield record } + end + else + enum_for :find_each, options do + options[:start] ? where(table[primary_key].gteq(options[:start])).size : size + end + end + end + + # Yields each batch of records that was found by the find +options+ as + # an array. + # + # Person.where("age > 21").find_in_batches do |group| + # sleep(50) # Make sure it doesn't get too crowded in there! + # group.each { |person| person.party_all_night! } + # end + # + # If you do not provide a block to #find_in_batches, it will return an Enumerator + # for chaining with other methods: + # + # Person.find_in_batches.with_index do |group, batch| + # puts "Processing group ##{batch}" + # group.each(&:recover_from_last_night!) + # end + # + # To be yielded each record one by one, use #find_each instead. + # + # ==== Options + # * :batch_size - Specifies the size of the batch. Default to 1000. + # * :start - Specifies the starting point for the batch processing. + # This is especially useful if you want multiple workers dealing with + # the same processing queue. You can make worker 1 handle all the records + # between id 0 and 10,000 and worker 2 handle from 10,000 and beyond + # (by setting the +:start+ option on that worker). + # + # # Let's process the next 2000 records + # Person.find_in_batches(start: 2000, batch_size: 2000) do |group| + # group.each { |person| person.party_all_night! } + # end + # + # NOTE: It's not possible to set the order. That is automatically set to + # ascending on the primary key ("id ASC") to make the batch ordering + # work. This also means that this method only works with integer-based + # primary keys. + # + # NOTE: You can't set the limit either, that's used to control + # the batch sizes. + def find_in_batches(options = {}) + options.assert_valid_keys(:start, :batch_size) + + relation = self + start = options[:start] + batch_size = options[:batch_size] || 1000 + + unless block_given? + return to_enum(:find_in_batches, options) do + total = start ? where(table[primary_key].gteq(start)).size : size + (total - 1).div(batch_size) + 1 + end + end + + if logger && (arel.orders.present? || arel.taken.present?) + logger.warn("Scoped order and limit are ignored, it's forced to be batch order and batch size") + end + + relation = relation.reorder(batch_order).limit(batch_size) + records = start ? relation.where(table[primary_key].gteq(start)).to_a : relation.to_a + + while records.any? + records_size = records.size + primary_key_offset = records.last.id + raise "Primary key not included in the custom select clause" unless primary_key_offset + + yield records + + break if records_size < batch_size + + records = relation.where(table[primary_key].gt(primary_key_offset)).to_a + end + end + + private + + def batch_order + "#{quoted_table_name}.#{quoted_primary_key} ASC" + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/relation/calculations.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/relation/calculations.rb new file mode 100644 index 0000000..7167332 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/relation/calculations.rb @@ -0,0 +1,403 @@ +module ActiveRecord + module Calculations + # Count the records. + # + # Person.count + # # => the total count of all people + # + # Person.count(:age) + # # => returns the total count of all people whose age is present in database + # + # Person.count(:all) + # # => performs a COUNT(*) (:all is an alias for '*') + # + # Person.distinct.count(:age) + # # => counts the number of different age values + # + # If +count+ is used with +group+, it returns a Hash whose keys represent the aggregated column, + # and the values are the respective amounts: + # + # Person.group(:city).count + # # => { 'Rome' => 5, 'Paris' => 3 } + # + # If +count+ is used with +group+ for multiple columns, it returns a Hash whose + # keys are an array containing the individual values of each column and the value + # of each key would be the +count+. + # + # Article.group(:status, :category).count + # # => {["draft", "business"]=>10, ["draft", "technology"]=>4, + # ["published", "business"]=>0, ["published", "technology"]=>2} + # + # If +count+ is used with +select+, it will count the selected columns: + # + # Person.select(:age).count + # # => counts the number of different age values + # + # Note: not all valid +select+ expressions are valid +count+ expressions. The specifics differ + # between databases. In invalid cases, an error from the database is thrown. + def count(column_name = nil, options = {}) + # TODO: Remove options argument as soon we remove support to + # activerecord-deprecated_finders. + column_name, options = nil, column_name if column_name.is_a?(Hash) + calculate(:count, column_name, options) + end + + # Calculates the average value on a given column. Returns +nil+ if there's + # no row. See +calculate+ for examples with options. + # + # Person.average(:age) # => 35.8 + def average(column_name, options = {}) + # TODO: Remove options argument as soon we remove support to + # activerecord-deprecated_finders. + calculate(:average, column_name, options) + end + + # Calculates the minimum value on a given column. The value is returned + # with the same data type of the column, or +nil+ if there's no row. See + # +calculate+ for examples with options. + # + # Person.minimum(:age) # => 7 + def minimum(column_name, options = {}) + # TODO: Remove options argument as soon we remove support to + # activerecord-deprecated_finders. + calculate(:minimum, column_name, options) + end + + # Calculates the maximum value on a given column. The value is returned + # with the same data type of the column, or +nil+ if there's no row. See + # +calculate+ for examples with options. + # + # Person.maximum(:age) # => 93 + def maximum(column_name, options = {}) + # TODO: Remove options argument as soon we remove support to + # activerecord-deprecated_finders. + calculate(:maximum, column_name, options) + end + + # Calculates the sum of values on a given column. The value is returned + # with the same data type of the column, 0 if there's no row. See + # +calculate+ for examples with options. + # + # Person.sum(:age) # => 4562 + def sum(*args) + calculate(:sum, *args) + end + + # This calculates aggregate values in the given column. Methods for count, sum, average, + # minimum, and maximum have been added as shortcuts. + # + # There are two basic forms of output: + # + # * Single aggregate value: The single value is type cast to Fixnum for COUNT, Float + # for AVG, and the given column's type for everything else. + # + # * Grouped values: This returns an ordered hash of the values and groups them. It + # takes either a column name, or the name of a belongs_to association. + # + # values = Person.group('last_name').maximum(:age) + # puts values["Drake"] + # # => 43 + # + # drake = Family.find_by(last_name: 'Drake') + # values = Person.group(:family).maximum(:age) # Person belongs_to :family + # puts values[drake] + # # => 43 + # + # values.each do |family, max_age| + # ... + # end + # + # Person.calculate(:count, :all) # The same as Person.count + # Person.average(:age) # SELECT AVG(age) FROM people... + # + # # Selects the minimum age for any family without any minors + # Person.group(:last_name).having("min(age) > 17").minimum(:age) + # + # Person.sum("2 * age") + def calculate(operation, column_name, options = {}) + # TODO: Remove options argument as soon we remove support to + # activerecord-deprecated_finders. + if column_name.is_a?(Symbol) && attribute_alias?(column_name) + column_name = attribute_alias(column_name) + end + + if has_include?(column_name) + construct_relation_for_association_calculations.calculate(operation, column_name, options) + else + perform_calculation(operation, column_name, options) + end + end + + # Use pluck as a shortcut to select one or more attributes without + # loading a bunch of records just to grab the attributes you want. + # + # Person.pluck(:name) + # + # instead of + # + # Person.all.map(&:name) + # + # Pluck returns an Array of attribute values type-casted to match + # the plucked column names, if they can be deduced. Plucking an SQL fragment + # returns String values by default. + # + # Person.pluck(:id) + # # SELECT people.id FROM people + # # => [1, 2, 3] + # + # Person.pluck(:id, :name) + # # SELECT people.id, people.name FROM people + # # => [[1, 'David'], [2, 'Jeremy'], [3, 'Jose']] + # + # Person.pluck('DISTINCT role') + # # SELECT DISTINCT role FROM people + # # => ['admin', 'member', 'guest'] + # + # Person.where(age: 21).limit(5).pluck(:id) + # # SELECT people.id FROM people WHERE people.age = 21 LIMIT 5 + # # => [2, 3] + # + # Person.pluck('DATEDIFF(updated_at, created_at)') + # # SELECT DATEDIFF(updated_at, created_at) FROM people + # # => ['0', '27761', '173'] + # + def pluck(*column_names) + column_names.map! do |column_name| + if column_name.is_a?(Symbol) && attribute_alias?(column_name) + attribute_alias(column_name) + else + column_name.to_s + end + end + + if has_include?(column_names.first) + construct_relation_for_association_calculations.pluck(*column_names) + else + relation = spawn + relation.select_values = column_names.map { |cn| + columns_hash.key?(cn) ? arel_table[cn] : cn + } + result = klass.connection.select_all(relation.arel, nil, relation.arel.bind_values + bind_values) + result.cast_values(klass.column_types) + end + end + + # Pluck all the ID's for the relation using the table's primary key + # + # Person.ids # SELECT people.id FROM people + # Person.joins(:companies).ids # SELECT people.id FROM people INNER JOIN companies ON companies.person_id = people.id + def ids + pluck primary_key + end + + private + + def has_include?(column_name) + eager_loading? || (includes_values.present? && ((column_name && column_name != :all) || references_eager_loaded_tables?)) + end + + def perform_calculation(operation, column_name, options = {}) + # TODO: Remove options argument as soon we remove support to + # activerecord-deprecated_finders. + operation = operation.to_s.downcase + + # If #count is used with #distinct / #uniq it is considered distinct. (eg. relation.distinct.count) + distinct = self.distinct_value + + if operation == "count" + column_name ||= select_for_count + + unless arel.ast.grep(Arel::Nodes::OuterJoin).empty? + distinct = true + end + + column_name = primary_key if column_name == :all && distinct + distinct = nil if column_name =~ /\s*DISTINCT[\s(]+/i + end + + if group_values.any? + execute_grouped_calculation(operation, column_name, distinct) + else + execute_simple_calculation(operation, column_name, distinct) + end + end + + def aggregate_column(column_name) + if @klass.column_names.include?(column_name.to_s) + Arel::Attribute.new(@klass.unscoped.table, column_name) + else + Arel.sql(column_name == :all ? "*" : column_name.to_s) + end + end + + def operation_over_aggregate_column(column, operation, distinct) + operation == 'count' ? column.count(distinct) : column.send(operation) + end + + def execute_simple_calculation(operation, column_name, distinct) #:nodoc: + # Postgresql doesn't like ORDER BY when there are no GROUP BY + relation = unscope(:order) + + column_alias = column_name + + bind_values = nil + + if operation == "count" && (relation.limit_value || relation.offset_value) + # Shortcut when limit is zero. + return 0 if relation.limit_value == 0 + + query_builder = build_count_subquery(relation, column_name, distinct) + bind_values = query_builder.bind_values + relation.bind_values + else + column = aggregate_column(column_name) + + select_value = operation_over_aggregate_column(column, operation, distinct) + + column_alias = select_value.alias + column_alias ||= @klass.connection.column_name_for_operation(operation, select_value) + relation.select_values = [select_value] + + query_builder = relation.arel + bind_values = query_builder.bind_values + relation.bind_values + end + + result = @klass.connection.select_all(query_builder, nil, bind_values) + row = result.first + value = row && row.values.first + column = result.column_types.fetch(column_alias) do + type_for(column_name) + end + + type_cast_calculated_value(value, column, operation) + end + + def execute_grouped_calculation(operation, column_name, distinct) #:nodoc: + group_attrs = group_values + + if group_attrs.first.respond_to?(:to_sym) + association = @klass._reflect_on_association(group_attrs.first) + associated = group_attrs.size == 1 && association && association.belongs_to? # only count belongs_to associations + group_fields = Array(associated ? association.foreign_key : group_attrs) + else + group_fields = group_attrs + end + + group_aliases = group_fields.map { |field| + column_alias_for(field) + } + group_columns = group_aliases.zip(group_fields).map { |aliaz,field| + [aliaz, field] + } + + group = group_fields + + if operation == 'count' && column_name == :all + aggregate_alias = 'count_all' + else + aggregate_alias = column_alias_for([operation, column_name].join(' ')) + end + + select_values = [ + operation_over_aggregate_column( + aggregate_column(column_name), + operation, + distinct).as(aggregate_alias) + ] + select_values += select_values unless having_values.empty? + + select_values.concat group_fields.zip(group_aliases).map { |field,aliaz| + if field.respond_to?(:as) + field.as(aliaz) + else + "#{field} AS #{aliaz}" + end + } + + relation = except(:group) + relation.group_values = group + relation.select_values = select_values + + calculated_data = @klass.connection.select_all(relation, nil, relation.arel.bind_values + bind_values) + + if association + key_ids = calculated_data.collect { |row| row[group_aliases.first] } + key_records = association.klass.base_class.find(key_ids) + key_records = Hash[key_records.map { |r| [r.id, r] }] + end + + Hash[calculated_data.map do |row| + key = group_columns.map { |aliaz, col_name| + column = calculated_data.column_types.fetch(aliaz) do + type_for(col_name) + end + type_cast_calculated_value(row[aliaz], column) + } + key = key.first if key.size == 1 + key = key_records[key] if associated + + column_type = calculated_data.column_types.fetch(aggregate_alias) { type_for(column_name) } + [key, type_cast_calculated_value(row[aggregate_alias], column_type, operation)] + end] + end + + # Converts the given keys to the value that the database adapter returns as + # a usable column name: + # + # column_alias_for("users.id") # => "users_id" + # column_alias_for("sum(id)") # => "sum_id" + # column_alias_for("count(distinct users.id)") # => "count_distinct_users_id" + # column_alias_for("count(*)") # => "count_all" + # column_alias_for("count", "id") # => "count_id" + def column_alias_for(keys) + if keys.respond_to? :name + keys = "#{keys.relation.name}.#{keys.name}" + end + + table_name = keys.to_s.downcase + table_name.gsub!(/\*/, 'all') + table_name.gsub!(/\W+/, ' ') + table_name.strip! + table_name.gsub!(/ +/, '_') + + @klass.connection.table_alias_for(table_name) + end + + def type_for(field) + field_name = field.respond_to?(:name) ? field.name.to_s : field.to_s.split('.').last + @klass.type_for_attribute(field_name) + end + + def type_cast_calculated_value(value, type, operation = nil) + case operation + when 'count' then value.to_i + when 'sum' then type.type_cast_from_database(value || 0) + when 'average' then value.respond_to?(:to_d) ? value.to_d : value + else type.type_cast_from_database(value) + end + end + + # TODO: refactor to allow non-string `select_values` (eg. Arel nodes). + def select_for_count + if select_values.present? + select_values.join(", ") + else + :all + end + end + + def build_count_subquery(relation, column_name, distinct) + column_alias = Arel.sql('count_column') + subquery_alias = Arel.sql('subquery_for_count') + + aliased_column = aggregate_column(column_name == :all ? 1 : column_name).as(column_alias) + relation.select_values = [aliased_column] + arel = relation.arel + subquery = arel.as(subquery_alias) + + sm = Arel::SelectManager.new relation.engine + sm.bind_values = arel.bind_values + select_value = operation_over_aggregate_column(column_alias, 'count', distinct) + sm.project(select_value).from(subquery) + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/relation/delegation.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/relation/delegation.rb new file mode 100644 index 0000000..76b2d08 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/relation/delegation.rb @@ -0,0 +1,140 @@ +require 'set' +require 'active_support/concern' +require 'active_support/deprecation' + +module ActiveRecord + module Delegation # :nodoc: + module DelegateCache + def relation_delegate_class(klass) # :nodoc: + @relation_delegate_cache[klass] + end + + def initialize_relation_delegate_cache # :nodoc: + @relation_delegate_cache = cache = {} + [ + ActiveRecord::Relation, + ActiveRecord::Associations::CollectionProxy, + ActiveRecord::AssociationRelation + ].each do |klass| + delegate = Class.new(klass) { + include ClassSpecificRelation + } + const_set klass.name.gsub('::', '_'), delegate + cache[klass] = delegate + end + end + + def inherited(child_class) + child_class.initialize_relation_delegate_cache + super + end + end + + extend ActiveSupport::Concern + + # This module creates compiled delegation methods dynamically at runtime, which makes + # subsequent calls to that method faster by avoiding method_missing. The delegations + # may vary depending on the klass of a relation, so we create a subclass of Relation + # for each different klass, and the delegations are compiled into that subclass only. + + BLACKLISTED_ARRAY_METHODS = [ + :compact!, :flatten!, :reject!, :reverse!, :rotate!, :map!, + :shuffle!, :slice!, :sort!, :sort_by!, :delete_if, + :keep_if, :pop, :shift, :delete_at, :select! + ].to_set # :nodoc: + + delegate :to_xml, :to_yaml, :length, :collect, :map, :each, :all?, :include?, :to_ary, :join, to: :to_a + + delegate :table_name, :quoted_table_name, :primary_key, :quoted_primary_key, + :connection, :columns_hash, :to => :klass + + module ClassSpecificRelation # :nodoc: + extend ActiveSupport::Concern + + included do + @delegation_mutex = Mutex.new + end + + module ClassMethods # :nodoc: + def name + superclass.name + end + + def delegate_to_scoped_klass(method) + @delegation_mutex.synchronize do + return if method_defined?(method) + + if method.to_s =~ /\A[a-zA-Z_]\w*[!?]?\z/ + module_eval <<-RUBY, __FILE__, __LINE__ + 1 + def #{method}(*args, &block) + scoping { @klass.#{method}(*args, &block) } + end + RUBY + else + define_method method do |*args, &block| + scoping { @klass.public_send(method, *args, &block) } + end + end + end + end + + def delegate(method, opts = {}) + @delegation_mutex.synchronize do + return if method_defined?(method) + super + end + end + end + + protected + + def method_missing(method, *args, &block) + if @klass.respond_to?(method) + self.class.delegate_to_scoped_klass(method) + scoping { @klass.public_send(method, *args, &block) } + elsif arel.respond_to?(method) + self.class.delegate method, :to => :arel + arel.public_send(method, *args, &block) + else + super + end + end + end + + module ClassMethods # :nodoc: + def create(klass, *args) + relation_class_for(klass).new(klass, *args) + end + + private + + def relation_class_for(klass) + klass.relation_delegate_class(self) + end + end + + def respond_to?(method, include_private = false) + super || @klass.respond_to?(method, include_private) || + array_delegable?(method) || + arel.respond_to?(method, include_private) + end + + protected + + def array_delegable?(method) + Array.method_defined?(method) && BLACKLISTED_ARRAY_METHODS.exclude?(method) + end + + def method_missing(method, *args, &block) + if @klass.respond_to?(method) + scoping { @klass.public_send(method, *args, &block) } + elsif array_delegable?(method) + to_a.public_send(method, *args, &block) + elsif arel.respond_to?(method) + arel.public_send(method, *args, &block) + else + super + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/relation/finder_methods.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/relation/finder_methods.rb new file mode 100644 index 0000000..ce165e1 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/relation/finder_methods.rb @@ -0,0 +1,516 @@ +require 'active_support/deprecation' +require 'active_support/core_ext/string/filters' + +module ActiveRecord + module FinderMethods + ONE_AS_ONE = '1 AS one' + + # Find by id - This can either be a specific id (1), a list of ids (1, 5, 6), or an array of ids ([5, 6, 10]). + # If no record can be found for all of the listed ids, then RecordNotFound will be raised. If the primary key + # is an integer, find by id coerces its arguments using +to_i+. + # + # Person.find(1) # returns the object for ID = 1 + # Person.find("1") # returns the object for ID = 1 + # Person.find("31-sarah") # returns the object for ID = 31 + # Person.find(1, 2, 6) # returns an array for objects with IDs in (1, 2, 6) + # Person.find([7, 17]) # returns an array for objects with IDs in (7, 17) + # Person.find([1]) # returns an array for the object with ID = 1 + # Person.where("administrator = 1").order("created_on DESC").find(1) + # + # ActiveRecord::RecordNotFound will be raised if one or more ids are not found. + # + # NOTE: The returned records may not be in the same order as the ids you + # provide since database rows are unordered. You'd need to provide an explicit order + # option if you want the results are sorted. + # + # ==== Find with lock + # + # Example for find with a lock: Imagine two concurrent transactions: + # each will read person.visits == 2, add 1 to it, and save, resulting + # in two saves of person.visits = 3. By locking the row, the second + # transaction has to wait until the first is finished; we get the + # expected person.visits == 4. + # + # Person.transaction do + # person = Person.lock(true).find(1) + # person.visits += 1 + # person.save! + # end + # + # ==== Variations of +find+ + # + # Person.where(name: 'Spartacus', rating: 4) + # # returns a chainable list (which can be empty). + # + # Person.find_by(name: 'Spartacus', rating: 4) + # # returns the first item or nil. + # + # Person.where(name: 'Spartacus', rating: 4).first_or_initialize + # # returns the first item or returns a new instance (requires you call .save to persist against the database). + # + # Person.where(name: 'Spartacus', rating: 4).first_or_create + # # returns the first item or creates it and returns it, available since Rails 3.2.1. + # + # ==== Alternatives for +find+ + # + # Person.where(name: 'Spartacus', rating: 4).exists?(conditions = :none) + # # returns a boolean indicating if any record with the given conditions exist. + # + # Person.where(name: 'Spartacus', rating: 4).select("field1, field2, field3") + # # returns a chainable list of instances with only the mentioned fields. + # + # Person.where(name: 'Spartacus', rating: 4).ids + # # returns an Array of ids, available since Rails 3.2.1. + # + # Person.where(name: 'Spartacus', rating: 4).pluck(:field1, :field2) + # # returns an Array of the required fields, available since Rails 3.1. + def find(*args) + if block_given? + to_a.find(*args) { |*block_args| yield(*block_args) } + else + find_with_ids(*args) + end + end + + # Finds the first record matching the specified conditions. There + # is no implied ordering so if order matters, you should specify it + # yourself. + # + # If no record is found, returns nil. + # + # Post.find_by name: 'Spartacus', rating: 4 + # Post.find_by "published_at < ?", 2.weeks.ago + def find_by(*args) + where(*args).take + rescue RangeError + nil + end + + # Like find_by, except that if no record is found, raises + # an ActiveRecord::RecordNotFound error. + def find_by!(*args) + where(*args).take! + rescue RangeError + raise RecordNotFound, "Couldn't find #{@klass.name} with an out of range value" + end + + # Gives a record (or N records if a parameter is supplied) without any implied + # order. The order will depend on the database implementation. + # If an order is supplied it will be respected. + # + # Person.take # returns an object fetched by SELECT * FROM people LIMIT 1 + # Person.take(5) # returns 5 objects fetched by SELECT * FROM people LIMIT 5 + # Person.where(["name LIKE '%?'", name]).take + def take(limit = nil) + limit ? limit(limit).to_a : find_take + end + + # Same as +take+ but raises ActiveRecord::RecordNotFound if no record + # is found. Note that take! accepts no arguments. + def take! + take or raise RecordNotFound.new("Couldn't find #{@klass.name} with [#{arel.where_sql}]") + end + + # Find the first record (or first N records if a parameter is supplied). + # If no order is defined it will order by primary key. + # + # Person.first # returns the first object fetched by SELECT * FROM people ORDER BY people.id LIMIT 1 + # Person.where(["user_name = ?", user_name]).first + # Person.where(["user_name = :u", { u: user_name }]).first + # Person.order("created_on DESC").offset(5).first + # Person.first(3) # returns the first three objects fetched by SELECT * FROM people ORDER BY people.id LIMIT 3 + # + def first(limit = nil) + if limit + find_nth_with_limit(offset_index, limit) + else + find_nth(0, offset_index) + end + end + + # Same as +first+ but raises ActiveRecord::RecordNotFound if no record + # is found. Note that first! accepts no arguments. + def first! + find_nth! 0 + end + + # Find the last record (or last N records if a parameter is supplied). + # If no order is defined it will order by primary key. + # + # Person.last # returns the last object fetched by SELECT * FROM people + # Person.where(["user_name = ?", user_name]).last + # Person.order("created_on DESC").offset(5).last + # Person.last(3) # returns the last three objects fetched by SELECT * FROM people. + # + # Take note that in that last case, the results are sorted in ascending order: + # + # [#, #, #] + # + # and not: + # + # [#, #, #] + def last(limit = nil) + if limit + if order_values.empty? && primary_key + order(arel_table[primary_key].desc).limit(limit).reverse + else + to_a.last(limit) + end + else + find_last + end + end + + # Same as +last+ but raises ActiveRecord::RecordNotFound if no record + # is found. Note that last! accepts no arguments. + def last! + last or raise RecordNotFound.new("Couldn't find #{@klass.name} with [#{arel.where_sql}]") + end + + # Find the second record. + # If no order is defined it will order by primary key. + # + # Person.second # returns the second object fetched by SELECT * FROM people + # Person.offset(3).second # returns the second object from OFFSET 3 (which is OFFSET 4) + # Person.where(["user_name = :u", { u: user_name }]).second + def second + find_nth(1, offset_index) + end + + # Same as +second+ but raises ActiveRecord::RecordNotFound if no record + # is found. + def second! + find_nth! 1 + end + + # Find the third record. + # If no order is defined it will order by primary key. + # + # Person.third # returns the third object fetched by SELECT * FROM people + # Person.offset(3).third # returns the third object from OFFSET 3 (which is OFFSET 5) + # Person.where(["user_name = :u", { u: user_name }]).third + def third + find_nth(2, offset_index) + end + + # Same as +third+ but raises ActiveRecord::RecordNotFound if no record + # is found. + def third! + find_nth! 2 + end + + # Find the fourth record. + # If no order is defined it will order by primary key. + # + # Person.fourth # returns the fourth object fetched by SELECT * FROM people + # Person.offset(3).fourth # returns the fourth object from OFFSET 3 (which is OFFSET 6) + # Person.where(["user_name = :u", { u: user_name }]).fourth + def fourth + find_nth(3, offset_index) + end + + # Same as +fourth+ but raises ActiveRecord::RecordNotFound if no record + # is found. + def fourth! + find_nth! 3 + end + + # Find the fifth record. + # If no order is defined it will order by primary key. + # + # Person.fifth # returns the fifth object fetched by SELECT * FROM people + # Person.offset(3).fifth # returns the fifth object from OFFSET 3 (which is OFFSET 7) + # Person.where(["user_name = :u", { u: user_name }]).fifth + def fifth + find_nth(4, offset_index) + end + + # Same as +fifth+ but raises ActiveRecord::RecordNotFound if no record + # is found. + def fifth! + find_nth! 4 + end + + # Find the forty-second record. Also known as accessing "the reddit". + # If no order is defined it will order by primary key. + # + # Person.forty_two # returns the forty-second object fetched by SELECT * FROM people + # Person.offset(3).forty_two # returns the forty-second object from OFFSET 3 (which is OFFSET 44) + # Person.where(["user_name = :u", { u: user_name }]).forty_two + def forty_two + find_nth(41, offset_index) + end + + # Same as +forty_two+ but raises ActiveRecord::RecordNotFound if no record + # is found. + def forty_two! + find_nth! 41 + end + + # Returns +true+ if a record exists in the table that matches the +id+ or + # conditions given, or +false+ otherwise. The argument can take six forms: + # + # * Integer - Finds the record with this primary key. + # * String - Finds the record with a primary key corresponding to this + # string (such as '5'). + # * Array - Finds the record that matches these +find+-style conditions + # (such as ['name LIKE ?', "%#{query}%"]). + # * Hash - Finds the record that matches these +find+-style conditions + # (such as {name: 'David'}). + # * +false+ - Returns always +false+. + # * No args - Returns +false+ if the table is empty, +true+ otherwise. + # + # For more information about specifying conditions as a hash or array, + # see the Conditions section in the introduction to ActiveRecord::Base. + # + # Note: You can't pass in a condition as a string (like name = + # 'Jamie'), since it would be sanitized and then queried against + # the primary key column, like id = 'name = \'Jamie\''. + # + # Person.exists?(5) + # Person.exists?('5') + # Person.exists?(['name LIKE ?', "%#{query}%"]) + # Person.exists?(id: [1, 4, 8]) + # Person.exists?(name: 'David') + # Person.exists?(false) + # Person.exists? + def exists?(conditions = :none) + if Base === conditions + conditions = conditions.id + ActiveSupport::Deprecation.warn(<<-MSG.squish) + You are passing an instance of ActiveRecord::Base to `exists?`. + Please pass the id of the object by calling `.id` + MSG + end + + return false if !conditions + + relation = apply_join_dependency(self, construct_join_dependency) + return false if ActiveRecord::NullRelation === relation + + relation = relation.except(:select, :order).select(ONE_AS_ONE).limit(1) + + case conditions + when Array, Hash + relation = relation.where(conditions) + else + unless conditions == :none + relation = relation.where(primary_key => conditions) + end + end + + connection.select_value(relation, "#{name} Exists", relation.arel.bind_values + relation.bind_values) ? true : false + end + + # This method is called whenever no records are found with either a single + # id or multiple ids and raises a +ActiveRecord::RecordNotFound+ exception. + # + # The error message is different depending on whether a single id or + # multiple ids are provided. If multiple ids are provided, then the number + # of results obtained should be provided in the +result_size+ argument and + # the expected number of results should be provided in the +expected_size+ + # argument. + def raise_record_not_found_exception!(ids, result_size, expected_size) #:nodoc: + conditions = arel.where_sql + conditions = " [#{conditions}]" if conditions + + if Array(ids).size == 1 + error = "Couldn't find #{@klass.name} with '#{primary_key}'=#{ids}#{conditions}" + else + error = "Couldn't find all #{@klass.name.pluralize} with '#{primary_key}': " + error << "(#{ids.join(", ")})#{conditions} (found #{result_size} results, but was looking for #{expected_size})" + end + + raise RecordNotFound, error + end + + private + + def offset_index + offset_value || 0 + end + + def find_with_associations + # NOTE: the JoinDependency constructed here needs to know about + # any joins already present in `self`, so pass them in + # + # failing to do so means that in cases like activerecord/test/cases/associations/inner_join_association_test.rb:136 + # incorrect SQL is generated. In that case, the join dependency for + # SpecialCategorizations is constructed without knowledge of the + # preexisting join in joins_values to categorizations (by way of + # the `has_many :through` for categories). + # + join_dependency = construct_join_dependency(joins_values) + + aliases = join_dependency.aliases + relation = select aliases.columns + relation = apply_join_dependency(relation, join_dependency) + + if block_given? + yield relation + else + if ActiveRecord::NullRelation === relation + [] + else + arel = relation.arel + rows = connection.select_all(arel, 'SQL', arel.bind_values + relation.bind_values) + join_dependency.instantiate(rows, aliases) + end + end + end + + def construct_join_dependency(joins = []) + including = eager_load_values + includes_values + ActiveRecord::Associations::JoinDependency.new(@klass, including, joins) + end + + def construct_relation_for_association_calculations + from = arel.froms.first + if Arel::Table === from + apply_join_dependency(self, construct_join_dependency(joins_values)) + else + # FIXME: as far as I can tell, `from` will always be an Arel::Table. + # There are no tests that test this branch, but presumably it's + # possible for `from` to be a list? + apply_join_dependency(self, construct_join_dependency(from)) + end + end + + def apply_join_dependency(relation, join_dependency) + relation = relation.except(:includes, :eager_load, :preload) + relation = relation.joins join_dependency + + if using_limitable_reflections?(join_dependency.reflections) + relation + else + if relation.limit_value + limited_ids = limited_ids_for(relation) + limited_ids.empty? ? relation.none! : relation.where!(table[primary_key].in(limited_ids)) + end + relation.except(:limit, :offset) + end + end + + def limited_ids_for(relation) + values = @klass.connection.columns_for_distinct( + "#{quoted_table_name}.#{quoted_primary_key}", relation.order_values) + + relation = relation.except(:select).select(values).distinct! + arel = relation.arel + + id_rows = @klass.connection.select_all(arel, 'SQL', arel.bind_values + relation.bind_values) + id_rows.map {|row| row[primary_key]} + end + + def using_limitable_reflections?(reflections) + reflections.none? { |r| r.collection? } + end + + protected + + def find_with_ids(*ids) + raise UnknownPrimaryKey.new(@klass) if primary_key.nil? + + expects_array = ids.first.kind_of?(Array) + return ids.first if expects_array && ids.first.empty? + + ids = ids.flatten.compact.uniq + + case ids.size + when 0 + raise RecordNotFound, "Couldn't find #{@klass.name} without an ID" + when 1 + result = find_one(ids.first) + expects_array ? [ result ] : result + else + find_some(ids) + end + rescue RangeError + raise RecordNotFound, "Couldn't find #{@klass.name} with an out of range ID" + end + + def find_one(id) + if ActiveRecord::Base === id + id = id.id + ActiveSupport::Deprecation.warn(<<-MSG.squish) + You are passing an instance of ActiveRecord::Base to `find`. + Please pass the id of the object by calling `.id` + MSG + end + + relation = where(primary_key => id) + record = relation.take + + raise_record_not_found_exception!(id, 0, 1) unless record + + record + end + + def find_some(ids) + result = where(primary_key => ids).to_a + + expected_size = + if limit_value && ids.size > limit_value + limit_value + else + ids.size + end + + # 11 ids with limit 3, offset 9 should give 2 results. + if offset_value && (ids.size - offset_value < expected_size) + expected_size = ids.size - offset_value + end + + if result.size == expected_size + result + else + raise_record_not_found_exception!(ids, result.size, expected_size) + end + end + + def find_take + if loaded? + @records.first + else + @take ||= limit(1).to_a.first + end + end + + def find_nth(index, offset) + if loaded? + @records[index] + else + offset += index + @offsets[offset] ||= find_nth_with_limit(offset, 1).first + end + end + + def find_nth!(index) + find_nth(index, offset_index) or raise RecordNotFound.new("Couldn't find #{@klass.name} with [#{arel.where_sql}]") + end + + def find_nth_with_limit(offset, limit) + relation = if order_values.empty? && primary_key + order(arel_table[primary_key].asc) + else + self + end + + relation = relation.offset(offset) unless offset.zero? + relation.limit(limit).to_a + end + + def find_last + if loaded? + @records.last + else + @last ||= + if limit_value + to_a.last + else + reverse_order.limit(1).to_a.first + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/relation/merger.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/relation/merger.rb new file mode 100644 index 0000000..828a184 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/relation/merger.rb @@ -0,0 +1,193 @@ +require 'active_support/core_ext/hash/keys' +require "set" + +module ActiveRecord + class Relation + class HashMerger # :nodoc: + attr_reader :relation, :hash + + def initialize(relation, hash) + hash.assert_valid_keys(*Relation::VALUE_METHODS) + + @relation = relation + @hash = hash + end + + def merge #:nodoc: + Merger.new(relation, other).merge + end + + # Applying values to a relation has some side effects. E.g. + # interpolation might take place for where values. So we should + # build a relation to merge in rather than directly merging + # the values. + def other + other = Relation.create(relation.klass, relation.table) + hash.each { |k, v| + if k == :joins + if Hash === v + other.joins!(v) + else + other.joins!(*v) + end + elsif k == :select + other._select!(v) + else + other.send("#{k}!", v) + end + } + other + end + end + + class Merger # :nodoc: + attr_reader :relation, :values, :other + + def initialize(relation, other) + @relation = relation + @values = other.values + @other = other + end + + NORMAL_VALUES = Relation::SINGLE_VALUE_METHODS + + Relation::MULTI_VALUE_METHODS - + [:includes, :preload, :joins, :where, :order, :bind, :reverse_order, :lock, :create_with, :reordering, :from] # :nodoc: + + + def normal_values + NORMAL_VALUES + end + + def merge + normal_values.each do |name| + value = values[name] + # The unless clause is here mostly for performance reasons (since the `send` call might be moderately + # expensive), most of the time the value is going to be `nil` or `.blank?`, the only catch is that + # `false.blank?` returns `true`, so there needs to be an extra check so that explicit `false` values + # don't fall through the cracks. + unless value.nil? || (value.blank? && false != value) + if name == :select + relation._select!(*value) + else + relation.send("#{name}!", *value) + end + end + end + + merge_multi_values + merge_single_values + merge_preloads + merge_joins + + relation + end + + private + + def merge_preloads + return if other.preload_values.empty? && other.includes_values.empty? + + if other.klass == relation.klass + relation.preload!(*other.preload_values) unless other.preload_values.empty? + relation.includes!(other.includes_values) unless other.includes_values.empty? + else + reflection = relation.klass.reflect_on_all_associations.find do |r| + r.class_name == other.klass.name + end || return + + unless other.preload_values.empty? + relation.preload! reflection.name => other.preload_values + end + + unless other.includes_values.empty? + relation.includes! reflection.name => other.includes_values + end + end + end + + def merge_joins + return if other.joins_values.blank? + + if other.klass == relation.klass + relation.joins!(*other.joins_values) + else + joins_dependency, rest = other.joins_values.partition do |join| + case join + when Hash, Symbol, Array + true + else + false + end + end + + join_dependency = ActiveRecord::Associations::JoinDependency.new(other.klass, + joins_dependency, + []) + relation.joins! rest + + @relation = relation.joins join_dependency + end + end + + def merge_multi_values + lhs_wheres = relation.where_values + rhs_wheres = other.where_values + + lhs_binds = relation.bind_values + rhs_binds = other.bind_values + + removed, kept = partition_overwrites(lhs_wheres, rhs_wheres) + + where_values = kept + rhs_wheres + bind_values = filter_binds(lhs_binds, removed) + rhs_binds + + relation.where_values = where_values + relation.bind_values = bind_values + + if other.reordering_value + # override any order specified in the original relation + relation.reorder! other.order_values + elsif other.order_values + # merge in order_values from relation + relation.order! other.order_values + end + + relation.extend(*other.extending_values) unless other.extending_values.blank? + end + + def merge_single_values + relation.from_value = other.from_value unless relation.from_value + relation.lock_value = other.lock_value unless relation.lock_value + + unless other.create_with_value.blank? + relation.create_with_value = (relation.create_with_value || {}).merge(other.create_with_value) + end + end + + def filter_binds(lhs_binds, removed_wheres) + return lhs_binds if removed_wheres.empty? + + set = Set.new removed_wheres.map { |x| x.left.name.to_s } + lhs_binds.dup.delete_if { |col,_| set.include? col.name } + end + + # Remove equalities from the existing relation with a LHS which is + # present in the relation being merged in. + # returns [things_to_remove, things_to_keep] + def partition_overwrites(lhs_wheres, rhs_wheres) + if lhs_wheres.empty? || rhs_wheres.empty? + return [[], lhs_wheres] + end + + nodes = rhs_wheres.find_all do |w| + w.respond_to?(:operator) && w.operator == :== + end + seen = Set.new(nodes) { |node| node.left } + + lhs_wheres.partition do |w| + w.respond_to?(:operator) && w.operator == :== && seen.include?(w.left) + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/relation/predicate_builder.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/relation/predicate_builder.rb new file mode 100644 index 0000000..d7b9539 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/relation/predicate_builder.rb @@ -0,0 +1,155 @@ +module ActiveRecord + class PredicateBuilder # :nodoc: + @handlers = [] + + autoload :RelationHandler, 'active_record/relation/predicate_builder/relation_handler' + autoload :ArrayHandler, 'active_record/relation/predicate_builder/array_handler' + + def self.resolve_column_aliases(klass, hash) + # This method is a hot spot, so for now, use Hash[] to dup the hash. + # https://bugs.ruby-lang.org/issues/7166 + hash = Hash[hash] + hash.keys.grep(Symbol) do |key| + if klass.attribute_alias? key + hash[klass.attribute_alias(key)] = hash.delete key + end + end + hash + end + + def self.build_from_hash(klass, attributes, default_table) + queries = [] + + attributes.each do |column, value| + table = default_table + + if value.is_a?(Hash) + if value.empty? + queries << '1=0' + else + table = Arel::Table.new(column, default_table.engine) + association = klass._reflect_on_association(column) + + value.each do |k, v| + queries.concat expand(association && association.klass, table, k, v) + end + end + else + column = column.to_s + + if column.include?('.') + table_name, column = column.split('.', 2) + table = Arel::Table.new(table_name, default_table.engine) + end + + queries.concat expand(klass, table, column, value) + end + end + + queries + end + + def self.expand(klass, table, column, value) + queries = [] + + # Find the foreign key when using queries such as: + # Post.where(author: author) + # + # For polymorphic relationships, find the foreign key and type: + # PriceEstimate.where(estimate_of: treasure) + if klass && reflection = klass._reflect_on_association(column) + base_class = polymorphic_base_class_from_value(value) + + if reflection.polymorphic? && base_class + queries << build(table[reflection.foreign_type], base_class) + end + + column = reflection.foreign_key + + if base_class + primary_key = reflection.association_primary_key(base_class) + value = convert_value_to_association_ids(value, primary_key) + end + end + + queries << build(table[column], value) + queries + end + + def self.polymorphic_base_class_from_value(value) + case value + when Relation + value.klass.base_class + when Array + val = value.compact.first + val.class.base_class if val.is_a?(Base) + when Base + value.class.base_class + end + end + + def self.references(attributes) + attributes.map do |key, value| + if value.is_a?(Hash) + key + else + key = key.to_s + key.split('.').first if key.include?('.') + end + end.compact + end + + # Define how a class is converted to Arel nodes when passed to +where+. + # The handler can be any object that responds to +call+, and will be used + # for any value that +===+ the class given. For example: + # + # MyCustomDateRange = Struct.new(:start, :end) + # handler = proc do |column, range| + # Arel::Nodes::Between.new(column, + # Arel::Nodes::And.new([range.start, range.end]) + # ) + # end + # ActiveRecord::PredicateBuilder.register_handler(MyCustomDateRange, handler) + def self.register_handler(klass, handler) + @handlers.unshift([klass, handler]) + end + + BASIC_OBJECT_HANDLER = ->(attribute, value) { attribute.eq(value) } # :nodoc: + register_handler(BasicObject, BASIC_OBJECT_HANDLER) + # FIXME: I think we need to deprecate this behavior + register_handler(Class, ->(attribute, value) { attribute.eq(value.name) }) + register_handler(Base, ->(attribute, value) { attribute.eq(value.id) }) + register_handler(Range, ->(attribute, value) { attribute.between(value) }) + register_handler(Relation, RelationHandler.new) + register_handler(Array, ArrayHandler.new) + + def self.build(attribute, value) + handler_for(value).call(attribute, value) + end + private_class_method :build + + def self.handler_for(object) + @handlers.detect { |klass, _| klass === object }.last + end + private_class_method :handler_for + + def self.convert_value_to_association_ids(value, primary_key) + case value + when Relation + value.select(primary_key) + when Array + value.map { |v| convert_value_to_association_ids(v, primary_key) } + when Base + value._read_attribute(primary_key) + else + value + end + end + + def self.can_be_bound?(value) # :nodoc: + !value.nil? && + !value.is_a?(Hash) && + handler_for(value) == BASIC_OBJECT_HANDLER + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/relation/predicate_builder/array_handler.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/relation/predicate_builder/array_handler.rb new file mode 100644 index 0000000..fb08326 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/relation/predicate_builder/array_handler.rb @@ -0,0 +1,47 @@ +require 'active_support/core_ext/string/filters' + +module ActiveRecord + class PredicateBuilder + class ArrayHandler # :nodoc: + def call(attribute, value) + values = value.map { |x| x.is_a?(Base) ? x.id : x } + nils, values = values.partition(&:nil?) + + if values.any? { |val| val.is_a?(Array) } + ActiveSupport::Deprecation.warn(<<-MSG.squish) + Passing a nested array to Active Record finder methods is + deprecated and will be removed. Flatten your array before using + it for 'IN' conditions. + MSG + + values = values.flatten + end + + return attribute.in([]) if values.empty? && nils.empty? + + ranges, values = values.partition { |v| v.is_a?(Range) } + + values_predicate = + case values.length + when 0 then NullPredicate + when 1 then attribute.eq(values.first) + else attribute.in(values) + end + + unless nils.empty? + values_predicate = values_predicate.or(attribute.eq(nil)) + end + + array_predicates = ranges.map { |range| attribute.between(range) } + array_predicates.unshift(values_predicate) + array_predicates.inject { |composite, predicate| composite.or(predicate) } + end + + module NullPredicate # :nodoc: + def self.or(other) + other + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/relation/predicate_builder/relation_handler.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/relation/predicate_builder/relation_handler.rb new file mode 100644 index 0000000..0631509 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/relation/predicate_builder/relation_handler.rb @@ -0,0 +1,13 @@ +module ActiveRecord + class PredicateBuilder + class RelationHandler # :nodoc: + def call(attribute, value) + if value.select_values.empty? + value = value.select(value.klass.arel_table[value.klass.primary_key]) + end + + attribute.in(value.arel) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/relation/query_methods.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/relation/query_methods.rb new file mode 100644 index 0000000..19b1f3a --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/relation/query_methods.rb @@ -0,0 +1,1178 @@ +require 'active_support/core_ext/array/wrap' +require 'active_support/core_ext/string/filters' +require 'active_model/forbidden_attributes_protection' + +module ActiveRecord + module QueryMethods + extend ActiveSupport::Concern + + include ActiveModel::ForbiddenAttributesProtection + + # WhereChain objects act as placeholder for queries in which #where does not have any parameter. + # In this case, #where must be chained with #not to return a new relation. + class WhereChain + def initialize(scope) + @scope = scope + end + + # Returns a new relation expressing WHERE + NOT condition according to + # the conditions in the arguments. + # + # +not+ accepts conditions as a string, array, or hash. See #where for + # more details on each format. + # + # User.where.not("name = 'Jon'") + # # SELECT * FROM users WHERE NOT (name = 'Jon') + # + # User.where.not(["name = ?", "Jon"]) + # # SELECT * FROM users WHERE NOT (name = 'Jon') + # + # User.where.not(name: "Jon") + # # SELECT * FROM users WHERE name != 'Jon' + # + # User.where.not(name: nil) + # # SELECT * FROM users WHERE name IS NOT NULL + # + # User.where.not(name: %w(Ko1 Nobu)) + # # SELECT * FROM users WHERE name NOT IN ('Ko1', 'Nobu') + # + # User.where.not(name: "Jon", role: "admin") + # # SELECT * FROM users WHERE name != 'Jon' AND role != 'admin' + def not(opts, *rest) + where_value = @scope.send(:build_where, opts, rest).map do |rel| + case rel + when NilClass + raise ArgumentError, 'Invalid argument for .where.not(), got nil.' + when Arel::Nodes::In + Arel::Nodes::NotIn.new(rel.left, rel.right) + when Arel::Nodes::Equality + Arel::Nodes::NotEqual.new(rel.left, rel.right) + when String + Arel::Nodes::Not.new(Arel::Nodes::SqlLiteral.new(rel)) + else + Arel::Nodes::Not.new(rel) + end + end + + @scope.references!(PredicateBuilder.references(opts)) if Hash === opts + @scope.where_values += where_value + @scope + end + end + + Relation::MULTI_VALUE_METHODS.each do |name| + class_eval <<-CODE, __FILE__, __LINE__ + 1 + def #{name}_values # def select_values + @values[:#{name}] || [] # @values[:select] || [] + end # end + # + def #{name}_values=(values) # def select_values=(values) + raise ImmutableRelation if @loaded # raise ImmutableRelation if @loaded + check_cached_relation + @values[:#{name}] = values # @values[:select] = values + end # end + CODE + end + + (Relation::SINGLE_VALUE_METHODS - [:create_with]).each do |name| + class_eval <<-CODE, __FILE__, __LINE__ + 1 + def #{name}_value # def readonly_value + @values[:#{name}] # @values[:readonly] + end # end + CODE + end + + Relation::SINGLE_VALUE_METHODS.each do |name| + class_eval <<-CODE, __FILE__, __LINE__ + 1 + def #{name}_value=(value) # def readonly_value=(value) + raise ImmutableRelation if @loaded # raise ImmutableRelation if @loaded + check_cached_relation + @values[:#{name}] = value # @values[:readonly] = value + end # end + CODE + end + + def check_cached_relation # :nodoc: + if defined?(@arel) && @arel + @arel = nil + ActiveSupport::Deprecation.warn(<<-MSG.squish) + Modifying already cached Relation. The cache will be reset. Use a + cloned Relation to prevent this warning. + MSG + end + end + + def create_with_value # :nodoc: + @values[:create_with] || {} + end + + alias extensions extending_values + + # Specify relationships to be included in the result set. For + # example: + # + # users = User.includes(:address) + # users.each do |user| + # user.address.city + # end + # + # allows you to access the +address+ attribute of the +User+ model without + # firing an additional query. This will often result in a + # performance improvement over a simple +join+. + # + # You can also specify multiple relationships, like this: + # + # users = User.includes(:address, :friends) + # + # Loading nested relationships is possible using a Hash: + # + # users = User.includes(:address, friends: [:address, :followers]) + # + # === conditions + # + # If you want to add conditions to your included models you'll have + # to explicitly reference them. For example: + # + # User.includes(:posts).where('posts.name = ?', 'example') + # + # Will throw an error, but this will work: + # + # User.includes(:posts).where('posts.name = ?', 'example').references(:posts) + # + # Note that +includes+ works with association names while +references+ needs + # the actual table name. + def includes(*args) + check_if_method_has_arguments!(:includes, args) + spawn.includes!(*args) + end + + def includes!(*args) # :nodoc: + args.reject!(&:blank?) + args.flatten! + + self.includes_values |= args + self + end + + # Forces eager loading by performing a LEFT OUTER JOIN on +args+: + # + # User.eager_load(:posts) + # => SELECT "users"."id" AS t0_r0, "users"."name" AS t0_r1, ... + # FROM "users" LEFT OUTER JOIN "posts" ON "posts"."user_id" = + # "users"."id" + def eager_load(*args) + check_if_method_has_arguments!(:eager_load, args) + spawn.eager_load!(*args) + end + + def eager_load!(*args) # :nodoc: + self.eager_load_values += args + self + end + + # Allows preloading of +args+, in the same way that +includes+ does: + # + # User.preload(:posts) + # => SELECT "posts".* FROM "posts" WHERE "posts"."user_id" IN (1, 2, 3) + def preload(*args) + check_if_method_has_arguments!(:preload, args) + spawn.preload!(*args) + end + + def preload!(*args) # :nodoc: + self.preload_values += args + self + end + + # Use to indicate that the given +table_names+ are referenced by an SQL string, + # and should therefore be JOINed in any query rather than loaded separately. + # This method only works in conjunction with +includes+. + # See #includes for more details. + # + # User.includes(:posts).where("posts.name = 'foo'") + # # => Doesn't JOIN the posts table, resulting in an error. + # + # User.includes(:posts).where("posts.name = 'foo'").references(:posts) + # # => Query now knows the string references posts, so adds a JOIN + def references(*table_names) + check_if_method_has_arguments!(:references, table_names) + spawn.references!(*table_names) + end + + def references!(*table_names) # :nodoc: + table_names.flatten! + table_names.map!(&:to_s) + + self.references_values |= table_names + self + end + + # Works in two unique ways. + # + # First: takes a block so it can be used just like Array#select. + # + # Model.all.select { |m| m.field == value } + # + # This will build an array of objects from the database for the scope, + # converting them into an array and iterating through them using Array#select. + # + # Second: Modifies the SELECT statement for the query so that only certain + # fields are retrieved: + # + # Model.select(:field) + # # => [#] + # + # Although in the above example it looks as though this method returns an + # array, it actually returns a relation object and can have other query + # methods appended to it, such as the other methods in ActiveRecord::QueryMethods. + # + # The argument to the method can also be an array of fields. + # + # Model.select(:field, :other_field, :and_one_more) + # # => [#] + # + # You can also use one or more strings, which will be used unchanged as SELECT fields. + # + # Model.select('field AS field_one', 'other_field AS field_two') + # # => [#] + # + # If an alias was specified, it will be accessible from the resulting objects: + # + # Model.select('field AS field_one').first.field_one + # # => "value" + # + # Accessing attributes of an object that do not have fields retrieved by a select + # except +id+ will throw ActiveModel::MissingAttributeError: + # + # Model.select(:field).first.other_field + # # => ActiveModel::MissingAttributeError: missing attribute: other_field + def select(*fields) + if block_given? + to_a.select { |*block_args| yield(*block_args) } + else + raise ArgumentError, 'Call this with at least one field' if fields.empty? + spawn._select!(*fields) + end + end + + def _select!(*fields) # :nodoc: + fields.flatten! + fields.map! do |field| + klass.attribute_alias?(field) ? klass.attribute_alias(field).to_sym : field + end + self.select_values += fields + self + end + + # Allows to specify a group attribute: + # + # User.group(:name) + # => SELECT "users".* FROM "users" GROUP BY name + # + # Returns an array with distinct records based on the +group+ attribute: + # + # User.select([:id, :name]) + # => [#, #, # + # + # User.group(:name) + # => [#, #] + # + # User.group('name AS grouped_name, age') + # => [#, #, #] + # + # Passing in an array of attributes to group by is also supported. + # User.select([:id, :first_name]).group(:id, :first_name).first(3) + # => [#, #, #] + def group(*args) + check_if_method_has_arguments!(:group, args) + spawn.group!(*args) + end + + def group!(*args) # :nodoc: + args.flatten! + + self.group_values += args + self + end + + # Allows to specify an order attribute: + # + # User.order(:name) + # => SELECT "users".* FROM "users" ORDER BY "users"."name" ASC + # + # User.order(email: :desc) + # => SELECT "users".* FROM "users" ORDER BY "users"."email" DESC + # + # User.order(:name, email: :desc) + # => SELECT "users".* FROM "users" ORDER BY "users"."name" ASC, "users"."email" DESC + # + # User.order('name') + # => SELECT "users".* FROM "users" ORDER BY name + # + # User.order('name DESC') + # => SELECT "users".* FROM "users" ORDER BY name DESC + # + # User.order('name DESC, email') + # => SELECT "users".* FROM "users" ORDER BY name DESC, email + def order(*args) + check_if_method_has_arguments!(:order, args) + spawn.order!(*args) + end + + def order!(*args) # :nodoc: + preprocess_order_args(args) + + self.order_values += args + self + end + + # Replaces any existing order defined on the relation with the specified order. + # + # User.order('email DESC').reorder('id ASC') # generated SQL has 'ORDER BY id ASC' + # + # Subsequent calls to order on the same relation will be appended. For example: + # + # User.order('email DESC').reorder('id ASC').order('name ASC') + # + # generates a query with 'ORDER BY id ASC, name ASC'. + def reorder(*args) + check_if_method_has_arguments!(:reorder, args) + spawn.reorder!(*args) + end + + def reorder!(*args) # :nodoc: + preprocess_order_args(args) + + self.reordering_value = true + self.order_values = args + self + end + + VALID_UNSCOPING_VALUES = Set.new([:where, :select, :group, :order, :lock, + :limit, :offset, :joins, :includes, :from, + :readonly, :having]) + + # Removes an unwanted relation that is already defined on a chain of relations. + # This is useful when passing around chains of relations and would like to + # modify the relations without reconstructing the entire chain. + # + # User.order('email DESC').unscope(:order) == User.all + # + # The method arguments are symbols which correspond to the names of the methods + # which should be unscoped. The valid arguments are given in VALID_UNSCOPING_VALUES. + # The method can also be called with multiple arguments. For example: + # + # User.order('email DESC').select('id').where(name: "John") + # .unscope(:order, :select, :where) == User.all + # + # One can additionally pass a hash as an argument to unscope specific :where values. + # This is done by passing a hash with a single key-value pair. The key should be + # :where and the value should be the where value to unscope. For example: + # + # User.where(name: "John", active: true).unscope(where: :name) + # == User.where(active: true) + # + # This method is similar to except, but unlike + # except, it persists across merges: + # + # User.order('email').merge(User.except(:order)) + # == User.order('email') + # + # User.order('email').merge(User.unscope(:order)) + # == User.all + # + # This means it can be used in association definitions: + # + # has_many :comments, -> { unscope where: :trashed } + # + def unscope(*args) + check_if_method_has_arguments!(:unscope, args) + spawn.unscope!(*args) + end + + def unscope!(*args) # :nodoc: + args.flatten! + self.unscope_values += args + + args.each do |scope| + case scope + when Symbol + symbol_unscoping(scope) + when Hash + scope.each do |key, target_value| + if key != :where + raise ArgumentError, "Hash arguments in .unscope(*args) must have :where as the key." + end + + Array(target_value).each do |val| + where_unscoping(val) + end + end + else + raise ArgumentError, "Unrecognized scoping: #{args.inspect}. Use .unscope(where: :attribute_name) or .unscope(:order), for example." + end + end + + self + end + + # Performs a joins on +args+: + # + # User.joins(:posts) + # => SELECT "users".* FROM "users" INNER JOIN "posts" ON "posts"."user_id" = "users"."id" + # + # You can use strings in order to customize your joins: + # + # User.joins("LEFT JOIN bookmarks ON bookmarks.bookmarkable_type = 'Post' AND bookmarks.user_id = users.id") + # => SELECT "users".* FROM "users" LEFT JOIN bookmarks ON bookmarks.bookmarkable_type = 'Post' AND bookmarks.user_id = users.id + def joins(*args) + check_if_method_has_arguments!(:joins, args) + spawn.joins!(*args) + end + + def joins!(*args) # :nodoc: + args.compact! + args.flatten! + self.joins_values += args + self + end + + def bind(value) # :nodoc: + spawn.bind!(value) + end + + def bind!(value) # :nodoc: + self.bind_values += [value] + self + end + + # Returns a new relation, which is the result of filtering the current relation + # according to the conditions in the arguments. + # + # #where accepts conditions in one of several formats. In the examples below, the resulting + # SQL is given as an illustration; the actual query generated may be different depending + # on the database adapter. + # + # === string + # + # A single string, without additional arguments, is passed to the query + # constructor as an SQL fragment, and used in the where clause of the query. + # + # Client.where("orders_count = '2'") + # # SELECT * from clients where orders_count = '2'; + # + # Note that building your own string from user input may expose your application + # to injection attacks if not done properly. As an alternative, it is recommended + # to use one of the following methods. + # + # === array + # + # If an array is passed, then the first element of the array is treated as a template, and + # the remaining elements are inserted into the template to generate the condition. + # Active Record takes care of building the query to avoid injection attacks, and will + # convert from the ruby type to the database type where needed. Elements are inserted + # into the string in the order in which they appear. + # + # User.where(["name = ? and email = ?", "Joe", "joe@example.com"]) + # # SELECT * FROM users WHERE name = 'Joe' AND email = 'joe@example.com'; + # + # Alternatively, you can use named placeholders in the template, and pass a hash as the + # second element of the array. The names in the template are replaced with the corresponding + # values from the hash. + # + # User.where(["name = :name and email = :email", { name: "Joe", email: "joe@example.com" }]) + # # SELECT * FROM users WHERE name = 'Joe' AND email = 'joe@example.com'; + # + # This can make for more readable code in complex queries. + # + # Lastly, you can use sprintf-style % escapes in the template. This works slightly differently + # than the previous methods; you are responsible for ensuring that the values in the template + # are properly quoted. The values are passed to the connector for quoting, but the caller + # is responsible for ensuring they are enclosed in quotes in the resulting SQL. After quoting, + # the values are inserted using the same escapes as the Ruby core method Kernel::sprintf. + # + # User.where(["name = '%s' and email = '%s'", "Joe", "joe@example.com"]) + # # SELECT * FROM users WHERE name = 'Joe' AND email = 'joe@example.com'; + # + # If #where is called with multiple arguments, these are treated as if they were passed as + # the elements of a single array. + # + # User.where("name = :name and email = :email", { name: "Joe", email: "joe@example.com" }) + # # SELECT * FROM users WHERE name = 'Joe' AND email = 'joe@example.com'; + # + # When using strings to specify conditions, you can use any operator available from + # the database. While this provides the most flexibility, you can also unintentionally introduce + # dependencies on the underlying database. If your code is intended for general consumption, + # test with multiple database backends. + # + # === hash + # + # #where will also accept a hash condition, in which the keys are fields and the values + # are values to be searched for. + # + # Fields can be symbols or strings. Values can be single values, arrays, or ranges. + # + # User.where({ name: "Joe", email: "joe@example.com" }) + # # SELECT * FROM users WHERE name = 'Joe' AND email = 'joe@example.com' + # + # User.where({ name: ["Alice", "Bob"]}) + # # SELECT * FROM users WHERE name IN ('Alice', 'Bob') + # + # User.where({ created_at: (Time.now.midnight - 1.day)..Time.now.midnight }) + # # SELECT * FROM users WHERE (created_at BETWEEN '2012-06-09 07:00:00.000000' AND '2012-06-10 07:00:00.000000') + # + # In the case of a belongs_to relationship, an association key can be used + # to specify the model if an ActiveRecord object is used as the value. + # + # author = Author.find(1) + # + # # The following queries will be equivalent: + # Post.where(author: author) + # Post.where(author_id: author) + # + # This also works with polymorphic belongs_to relationships: + # + # treasure = Treasure.create(name: 'gold coins') + # treasure.price_estimates << PriceEstimate.create(price: 125) + # + # # The following queries will be equivalent: + # PriceEstimate.where(estimate_of: treasure) + # PriceEstimate.where(estimate_of_type: 'Treasure', estimate_of_id: treasure) + # + # === Joins + # + # If the relation is the result of a join, you may create a condition which uses any of the + # tables in the join. For string and array conditions, use the table name in the condition. + # + # User.joins(:posts).where("posts.created_at < ?", Time.now) + # + # For hash conditions, you can either use the table name in the key, or use a sub-hash. + # + # User.joins(:posts).where({ "posts.published" => true }) + # User.joins(:posts).where({ posts: { published: true } }) + # + # === no argument + # + # If no argument is passed, #where returns a new instance of WhereChain, that + # can be chained with #not to return a new relation that negates the where clause. + # + # User.where.not(name: "Jon") + # # SELECT * FROM users WHERE name != 'Jon' + # + # See WhereChain for more details on #not. + # + # === blank condition + # + # If the condition is any blank-ish object, then #where is a no-op and returns + # the current relation. + def where(opts = :chain, *rest) + if opts == :chain + WhereChain.new(spawn) + elsif opts.blank? + self + else + spawn.where!(opts, *rest) + end + end + + def where!(opts, *rest) # :nodoc: + if Hash === opts + opts = sanitize_forbidden_attributes(opts) + references!(PredicateBuilder.references(opts)) + end + + self.where_values += build_where(opts, rest) + self + end + + # Allows you to change a previously set where condition for a given attribute, instead of appending to that condition. + # + # Post.where(trashed: true).where(trashed: false) # => WHERE `trashed` = 1 AND `trashed` = 0 + # Post.where(trashed: true).rewhere(trashed: false) # => WHERE `trashed` = 0 + # Post.where(active: true).where(trashed: true).rewhere(trashed: false) # => WHERE `active` = 1 AND `trashed` = 0 + # + # This is short-hand for unscope(where: conditions.keys).where(conditions). Note that unlike reorder, we're only unscoping + # the named conditions -- not the entire where statement. + def rewhere(conditions) + unscope(where: conditions.keys).where(conditions) + end + + # Allows to specify a HAVING clause. Note that you can't use HAVING + # without also specifying a GROUP clause. + # + # Order.having('SUM(price) > 30').group('user_id') + def having(opts, *rest) + opts.blank? ? self : spawn.having!(opts, *rest) + end + + def having!(opts, *rest) # :nodoc: + references!(PredicateBuilder.references(opts)) if Hash === opts + + self.having_values += build_where(opts, rest) + self + end + + # Specifies a limit for the number of records to retrieve. + # + # User.limit(10) # generated SQL has 'LIMIT 10' + # + # User.limit(10).limit(20) # generated SQL has 'LIMIT 20' + def limit(value) + spawn.limit!(value) + end + + def limit!(value) # :nodoc: + self.limit_value = value + self + end + + # Specifies the number of rows to skip before returning rows. + # + # User.offset(10) # generated SQL has "OFFSET 10" + # + # Should be used with order. + # + # User.offset(10).order("name ASC") + def offset(value) + spawn.offset!(value) + end + + def offset!(value) # :nodoc: + self.offset_value = value + self + end + + # Specifies locking settings (default to +true+). For more information + # on locking, please see +ActiveRecord::Locking+. + def lock(locks = true) + spawn.lock!(locks) + end + + def lock!(locks = true) # :nodoc: + case locks + when String, TrueClass, NilClass + self.lock_value = locks || true + else + self.lock_value = false + end + + self + end + + # Returns a chainable relation with zero records. + # + # The returned relation implements the Null Object pattern. It is an + # object with defined null behavior and always returns an empty array of + # records without querying the database. + # + # Any subsequent condition chained to the returned relation will continue + # generating an empty relation and will not fire any query to the database. + # + # Used in cases where a method or scope could return zero records but the + # result needs to be chainable. + # + # For example: + # + # @posts = current_user.visible_posts.where(name: params[:name]) + # # => the visible_posts method is expected to return a chainable Relation + # + # def visible_posts + # case role + # when 'Country Manager' + # Post.where(country: country) + # when 'Reviewer' + # Post.published + # when 'Bad User' + # Post.none # It can't be chained if [] is returned. + # end + # end + # + def none + where("1=0").extending!(NullRelation) + end + + def none! # :nodoc: + where!("1=0").extending!(NullRelation) + end + + # Sets readonly attributes for the returned relation. If value is + # true (default), attempting to update a record will result in an error. + # + # users = User.readonly + # users.first.save + # => ActiveRecord::ReadOnlyRecord: ActiveRecord::ReadOnlyRecord + def readonly(value = true) + spawn.readonly!(value) + end + + def readonly!(value = true) # :nodoc: + self.readonly_value = value + self + end + + # Sets attributes to be used when creating new records from a + # relation object. + # + # users = User.where(name: 'Oscar') + # users.new.name # => 'Oscar' + # + # users = users.create_with(name: 'DHH') + # users.new.name # => 'DHH' + # + # You can pass +nil+ to +create_with+ to reset attributes: + # + # users = users.create_with(nil) + # users.new.name # => 'Oscar' + def create_with(value) + spawn.create_with!(value) + end + + def create_with!(value) # :nodoc: + if value + value = sanitize_forbidden_attributes(value) + self.create_with_value = create_with_value.merge(value) + else + self.create_with_value = {} + end + + self + end + + # Specifies table from which the records will be fetched. For example: + # + # Topic.select('title').from('posts') + # # => SELECT title FROM posts + # + # Can accept other relation objects. For example: + # + # Topic.select('title').from(Topic.approved) + # # => SELECT title FROM (SELECT * FROM topics WHERE approved = 't') subquery + # + # Topic.select('a.title').from(Topic.approved, :a) + # # => SELECT a.title FROM (SELECT * FROM topics WHERE approved = 't') a + # + def from(value, subquery_name = nil) + spawn.from!(value, subquery_name) + end + + def from!(value, subquery_name = nil) # :nodoc: + self.from_value = [value, subquery_name] + if value.is_a? Relation + self.bind_values = value.arel.bind_values + value.bind_values + bind_values + end + self + end + + # Specifies whether the records should be unique or not. For example: + # + # User.select(:name) + # # => Might return two records with the same name + # + # User.select(:name).distinct + # # => Returns 1 record per distinct name + # + # User.select(:name).distinct.distinct(false) + # # => You can also remove the uniqueness + def distinct(value = true) + spawn.distinct!(value) + end + alias uniq distinct + + # Like #distinct, but modifies relation in place. + def distinct!(value = true) # :nodoc: + self.distinct_value = value + self + end + alias uniq! distinct! + + # Used to extend a scope with additional methods, either through + # a module or through a block provided. + # + # The object returned is a relation, which can be further extended. + # + # === Using a module + # + # module Pagination + # def page(number) + # # pagination code goes here + # end + # end + # + # scope = Model.all.extending(Pagination) + # scope.page(params[:page]) + # + # You can also pass a list of modules: + # + # scope = Model.all.extending(Pagination, SomethingElse) + # + # === Using a block + # + # scope = Model.all.extending do + # def page(number) + # # pagination code goes here + # end + # end + # scope.page(params[:page]) + # + # You can also use a block and a module list: + # + # scope = Model.all.extending(Pagination) do + # def per_page(number) + # # pagination code goes here + # end + # end + def extending(*modules, &block) + if modules.any? || block + spawn.extending!(*modules, &block) + else + self + end + end + + def extending!(*modules, &block) # :nodoc: + modules << Module.new(&block) if block + modules.flatten! + + self.extending_values += modules + extend(*extending_values) if extending_values.any? + + self + end + + # Reverse the existing order clause on the relation. + # + # User.order('name ASC').reverse_order # generated SQL has 'ORDER BY name DESC' + def reverse_order + spawn.reverse_order! + end + + def reverse_order! # :nodoc: + orders = order_values.uniq + orders.reject!(&:blank?) + self.order_values = reverse_sql_order(orders) + self + end + + # Returns the Arel object associated with the relation. + def arel # :nodoc: + @arel ||= build_arel + end + + private + + def build_arel + arel = Arel::SelectManager.new(table.engine, table) + + build_joins(arel, joins_values.flatten) unless joins_values.empty? + + collapse_wheres(arel, (where_values - [''])) #TODO: Add uniq with real value comparison / ignore uniqs that have binds + + arel.having(*having_values.uniq.reject(&:blank?)) unless having_values.empty? + + arel.take(connection.sanitize_limit(limit_value)) if limit_value + arel.skip(offset_value.to_i) if offset_value + arel.group(*arel_columns(group_values.uniq.reject(&:blank?))) unless group_values.empty? + + build_order(arel) + + build_select(arel) + + arel.distinct(distinct_value) + arel.from(build_from) if from_value + arel.lock(lock_value) if lock_value + + arel + end + + def symbol_unscoping(scope) + if !VALID_UNSCOPING_VALUES.include?(scope) + raise ArgumentError, "Called unscope() with invalid unscoping argument ':#{scope}'. Valid arguments are :#{VALID_UNSCOPING_VALUES.to_a.join(", :")}." + end + + single_val_method = Relation::SINGLE_VALUE_METHODS.include?(scope) + unscope_code = "#{scope}_value#{'s' unless single_val_method}=" + + case scope + when :order + result = [] + when :where + self.bind_values = [] + else + result = [] unless single_val_method + end + + self.send(unscope_code, result) + end + + def where_unscoping(target_value) + target_value = target_value.to_s + + self.where_values = where_values.reject do |rel| + case rel + when Arel::Nodes::Between, Arel::Nodes::In, Arel::Nodes::NotIn, Arel::Nodes::Equality, Arel::Nodes::NotEqual, Arel::Nodes::LessThan, Arel::Nodes::LessThanOrEqual, Arel::Nodes::GreaterThan, Arel::Nodes::GreaterThanOrEqual + subrelation = (rel.left.kind_of?(Arel::Attributes::Attribute) ? rel.left : rel.right) + subrelation.name == target_value + end + end + + bind_values.reject! { |col,_| col.name == target_value } + end + + def custom_join_ast(table, joins) + joins = joins.reject(&:blank?) + + return [] if joins.empty? + + joins.map! do |join| + case join + when Array + join = Arel.sql(join.join(' ')) if array_of_strings?(join) + when String + join = Arel.sql(join) + end + table.create_string_join(join) + end + end + + def collapse_wheres(arel, wheres) + predicates = wheres.map do |where| + next where if ::Arel::Nodes::Equality === where + where = Arel.sql(where) if String === where + Arel::Nodes::Grouping.new(where) + end + + arel.where(Arel::Nodes::And.new(predicates)) if predicates.present? + end + + def build_where(opts, other = []) + case opts + when String, Array + [@klass.send(:sanitize_sql, other.empty? ? opts : ([opts] + other))] + when Hash + opts = PredicateBuilder.resolve_column_aliases(klass, opts) + + tmp_opts, bind_values = create_binds(opts) + self.bind_values += bind_values + + attributes = @klass.send(:expand_hash_conditions_for_aggregates, tmp_opts) + add_relations_to_bind_values(attributes) + + PredicateBuilder.build_from_hash(klass, attributes, table) + else + [opts] + end + end + + def create_binds(opts) + bindable, non_binds = opts.partition do |column, value| + PredicateBuilder.can_be_bound?(value) && + @klass.columns_hash.include?(column.to_s) && + !@klass.reflect_on_aggregation(column) + end + + association_binds, non_binds = non_binds.partition do |column, value| + value.is_a?(Hash) && association_for_table(column) + end + + new_opts = {} + binds = [] + + connection = self.connection + + bindable.each do |(column,value)| + binds.push [@klass.columns_hash[column.to_s], value] + new_opts[column] = connection.substitute_at(column) + end + + association_binds.each do |(column, value)| + association_relation = association_for_table(column).klass.send(:relation) + association_new_opts, association_bind = association_relation.send(:create_binds, value) + new_opts[column] = association_new_opts + binds += association_bind + end + + non_binds.each { |column,value| new_opts[column] = value } + + [new_opts, binds] + end + + def association_for_table(table_name) + table_name = table_name.to_s + @klass._reflect_on_association(table_name) || + @klass._reflect_on_association(table_name.singularize) + end + + def build_from + opts, name = from_value + case opts + when Relation + name ||= 'subquery' + opts.arel.as(name.to_s) + else + opts + end + end + + def build_joins(manager, joins) + buckets = joins.group_by do |join| + case join + when String + :string_join + when Hash, Symbol, Array + :association_join + when ActiveRecord::Associations::JoinDependency + :stashed_join + when Arel::Nodes::Join + :join_node + else + raise 'unknown class: %s' % join.class.name + end + end + + association_joins = buckets[:association_join] || [] + stashed_association_joins = buckets[:stashed_join] || [] + join_nodes = (buckets[:join_node] || []).uniq + string_joins = (buckets[:string_join] || []).map(&:strip).uniq + + join_list = join_nodes + custom_join_ast(manager, string_joins) + + join_dependency = ActiveRecord::Associations::JoinDependency.new( + @klass, + association_joins, + join_list + ) + + join_infos = join_dependency.join_constraints stashed_association_joins + + join_infos.each do |info| + info.joins.each { |join| manager.from(join) } + manager.bind_values.concat info.binds + end + + manager.join_sources.concat(join_list) + + manager + end + + def build_select(arel) + if select_values.any? + arel.project(*arel_columns(select_values.uniq)) + else + arel.project(@klass.arel_table[Arel.star]) + end + end + + def arel_columns(columns) + columns.map do |field| + if (Symbol === field || String === field) && columns_hash.key?(field.to_s) && !from_value + arel_table[field] + elsif Symbol === field + connection.quote_table_name(field.to_s) + else + field + end + end + end + + def reverse_sql_order(order_query) + order_query = ["#{quoted_table_name}.#{quoted_primary_key} ASC"] if order_query.empty? + + order_query.flat_map do |o| + case o + when Arel::Nodes::Ordering + o.reverse + when String + o.to_s.split(',').map! do |s| + s.strip! + s.gsub!(/\sasc\Z/i, ' DESC') || s.gsub!(/\sdesc\Z/i, ' ASC') || s.concat(' DESC') + end + else + o + end + end + end + + def array_of_strings?(o) + o.is_a?(Array) && o.all? { |obj| obj.is_a?(String) } + end + + def build_order(arel) + orders = order_values.uniq + orders.reject!(&:blank?) + + arel.order(*orders) unless orders.empty? + end + + VALID_DIRECTIONS = [:asc, :desc, :ASC, :DESC, + 'asc', 'desc', 'ASC', 'DESC'] # :nodoc: + + def validate_order_args(args) + args.each do |arg| + next unless arg.is_a?(Hash) + arg.each do |_key, value| + raise ArgumentError, "Direction \"#{value}\" is invalid. Valid " \ + "directions are: #{VALID_DIRECTIONS.inspect}" unless VALID_DIRECTIONS.include?(value) + end + end + end + + def preprocess_order_args(order_args) + order_args.flatten! + validate_order_args(order_args) + + references = order_args.grep(String) + references.map! { |arg| arg =~ /^([a-zA-Z]\w*)\.(\w+)/ && $1 }.compact! + references!(references) if references.any? + + # if a symbol is given we prepend the quoted table name + order_args.map! do |arg| + case arg + when Symbol + arg = klass.attribute_alias(arg) if klass.attribute_alias?(arg) + table[arg].asc + when Hash + arg.map { |field, dir| + field = klass.attribute_alias(field) if klass.attribute_alias?(field) + table[field].send(dir.downcase) + } + else + arg + end + end.flatten! + end + + # Checks to make sure that the arguments are not blank. Note that if some + # blank-like object were initially passed into the query method, then this + # method will not raise an error. + # + # Example: + # + # Post.references() # => raises an error + # Post.references([]) # => does not raise an error + # + # This particular method should be called with a method_name and the args + # passed into that method as an input. For example: + # + # def references(*args) + # check_if_method_has_arguments!("references", args) + # ... + # end + def check_if_method_has_arguments!(method_name, args) + if args.blank? + raise ArgumentError, "The method .#{method_name}() must contain arguments." + end + end + + def add_relations_to_bind_values(attributes) + if attributes.is_a?(Hash) + attributes.each_value do |value| + if value.is_a?(ActiveRecord::Relation) + self.bind_values += value.arel.bind_values + value.bind_values + else + add_relations_to_bind_values(value) + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/relation/spawn_methods.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/relation/spawn_methods.rb new file mode 100644 index 0000000..6551344 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/relation/spawn_methods.rb @@ -0,0 +1,79 @@ +require 'active_support/core_ext/hash/except' +require 'active_support/core_ext/hash/slice' +require 'active_record/relation/merger' + +module ActiveRecord + module SpawnMethods + + # This is overridden by Associations::CollectionProxy + def spawn #:nodoc: + clone + end + + # Merges in the conditions from other, if other is an ActiveRecord::Relation. + # Returns an array representing the intersection of the resulting records with other, if other is an array. + # + # Post.where(published: true).joins(:comments).merge( Comment.where(spam: false) ) + # # Performs a single join query with both where conditions. + # + # recent_posts = Post.order('created_at DESC').first(5) + # Post.where(published: true).merge(recent_posts) + # # Returns the intersection of all published posts with the 5 most recently created posts. + # # (This is just an example. You'd probably want to do this with a single query!) + # + # Procs will be evaluated by merge: + # + # Post.where(published: true).merge(-> { joins(:comments) }) + # # => Post.where(published: true).joins(:comments) + # + # This is mainly intended for sharing common conditions between multiple associations. + def merge(other) + if other.is_a?(Array) + to_a & other + elsif other + spawn.merge!(other) + else + self + end + end + + def merge!(other) # :nodoc: + if other.is_a?(Hash) + Relation::HashMerger.new(self, other).merge + elsif other.is_a?(Relation) + Relation::Merger.new(self, other).merge + elsif other.respond_to?(:to_proc) + instance_exec(&other) + else + raise ArgumentError, "#{other.inspect} is not an ActiveRecord::Relation" + end + end + + # Removes from the query the condition(s) specified in +skips+. + # + # Post.order('id asc').except(:order) # discards the order condition + # Post.where('id > 10').order('id asc').except(:where) # discards the where condition but keeps the order + def except(*skips) + relation_with values.except(*skips) + end + + # Removes any condition from the query other than the one(s) specified in +onlies+. + # + # Post.order('id asc').only(:where) # discards the order condition + # Post.order('id asc').only(:where, :order) # uses the specified order + def only(*onlies) + if onlies.any? { |o| o == :where } + onlies << :bind + end + relation_with values.slice(*onlies) + end + + private + + def relation_with(values) # :nodoc: + result = Relation.create(klass, table, values) + result.extend(*extending_values) if extending_values.any? + result + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/result.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/result.rb new file mode 100644 index 0000000..3a3e65e --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/result.rb @@ -0,0 +1,131 @@ +module ActiveRecord + ### + # This class encapsulates a Result returned from calling +exec_query+ on any + # database connection adapter. For example: + # + # result = ActiveRecord::Base.connection.exec_query('SELECT id, title, body FROM posts') + # result # => # + # + # # Get the column names of the result: + # result.columns + # # => ["id", "title", "body"] + # + # # Get the record values of the result: + # result.rows + # # => [[1, "title_1", "body_1"], + # [2, "title_2", "body_2"], + # ... + # ] + # + # # Get an array of hashes representing the result (column => value): + # result.to_hash + # # => [{"id" => 1, "title" => "title_1", "body" => "body_1"}, + # {"id" => 2, "title" => "title_2", "body" => "body_2"}, + # ... + # ] + # + # # ActiveRecord::Result also includes Enumerable. + # result.each do |row| + # puts row['title'] + " " + row['body'] + # end + class Result + include Enumerable + + IDENTITY_TYPE = Type::Value.new # :nodoc: + + attr_reader :columns, :rows, :column_types + + def initialize(columns, rows, column_types = {}) + @columns = columns + @rows = rows + @hash_rows = nil + @column_types = column_types + end + + def length + @rows.length + end + + def each + if block_given? + hash_rows.each { |row| yield row } + else + hash_rows.to_enum { @rows.size } + end + end + + def to_hash + hash_rows + end + + alias :map! :map + alias :collect! :map + + # Returns true if there are no records. + def empty? + rows.empty? + end + + def to_ary + hash_rows + end + + def [](idx) + hash_rows[idx] + end + + def last + hash_rows.last + end + + def cast_values(type_overrides = {}) # :nodoc: + types = columns.map { |name| column_type(name, type_overrides) } + result = rows.map do |values| + types.zip(values).map { |type, value| type.type_cast_from_database(value) } + end + + columns.one? ? result.map!(&:first) : result + end + + def initialize_copy(other) + @columns = columns.dup + @rows = rows.dup + @column_types = column_types.dup + @hash_rows = nil + end + + private + + def column_type(name, type_overrides = {}) + type_overrides.fetch(name) do + column_types.fetch(name, IDENTITY_TYPE) + end + end + + def hash_rows + @hash_rows ||= + begin + # We freeze the strings to prevent them getting duped when + # used as keys in ActiveRecord::Base's @attributes hash + columns = @columns.map { |c| c.dup.freeze } + @rows.map { |row| + # In the past we used Hash[columns.zip(row)] + # though elegant, the verbose way is much more efficient + # both time and memory wise cause it avoids a big array allocation + # this method is called a lot and needs to be micro optimised + hash = {} + + index = 0 + length = columns.length + + while index < length + hash[columns[index]] = row[index] + index += 1 + end + + hash + } + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/runtime_registry.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/runtime_registry.rb new file mode 100644 index 0000000..9d605b8 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/runtime_registry.rb @@ -0,0 +1,22 @@ +require 'active_support/per_thread_registry' + +module ActiveRecord + # This is a thread locals registry for Active Record. For example: + # + # ActiveRecord::RuntimeRegistry.connection_handler + # + # returns the connection handler local to the current thread. + # + # See the documentation of ActiveSupport::PerThreadRegistry + # for further details. + class RuntimeRegistry # :nodoc: + extend ActiveSupport::PerThreadRegistry + + attr_accessor :connection_handler, :sql_runtime, :connection_id + + [:connection_handler, :sql_runtime, :connection_id].each do |val| + class_eval %{ def self.#{val}; instance.#{val}; end }, __FILE__, __LINE__ + class_eval %{ def self.#{val}=(x); instance.#{val}=x; end }, __FILE__, __LINE__ + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/sanitization.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/sanitization.rb new file mode 100644 index 0000000..6a130c1 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/sanitization.rb @@ -0,0 +1,191 @@ +module ActiveRecord + module Sanitization + extend ActiveSupport::Concern + + module ClassMethods + def quote_value(value, column) #:nodoc: + connection.quote(value, column) + end + + # Used to sanitize objects before they're used in an SQL SELECT statement. Delegates to connection.quote. + def sanitize(object) #:nodoc: + connection.quote(object) + end + + protected + + # Accepts an array, hash, or string of SQL conditions and sanitizes + # them into a valid SQL fragment for a WHERE clause. + # ["name='%s' and group_id='%s'", "foo'bar", 4] returns "name='foo''bar' and group_id='4'" + # { name: "foo'bar", group_id: 4 } returns "name='foo''bar' and group_id='4'" + # "name='foo''bar' and group_id='4'" returns "name='foo''bar' and group_id='4'" + def sanitize_sql_for_conditions(condition, table_name = self.table_name) + return nil if condition.blank? + + case condition + when Array; sanitize_sql_array(condition) + when Hash; sanitize_sql_hash_for_conditions(condition, table_name) + else condition + end + end + alias_method :sanitize_sql, :sanitize_sql_for_conditions + alias_method :sanitize_conditions, :sanitize_sql + + # Accepts an array, hash, or string of SQL conditions and sanitizes + # them into a valid SQL fragment for a SET clause. + # { name: nil, group_id: 4 } returns "name = NULL , group_id='4'" + def sanitize_sql_for_assignment(assignments, default_table_name = self.table_name) + case assignments + when Array; sanitize_sql_array(assignments) + when Hash; sanitize_sql_hash_for_assignment(assignments, default_table_name) + else assignments + end + end + + # Accepts a hash of SQL conditions and replaces those attributes + # that correspond to a +composed_of+ relationship with their expanded + # aggregate attribute values. + # Given: + # class Person < ActiveRecord::Base + # composed_of :address, class_name: "Address", + # mapping: [%w(address_street street), %w(address_city city)] + # end + # Then: + # { address: Address.new("813 abc st.", "chicago") } + # # => { address_street: "813 abc st.", address_city: "chicago" } + def expand_hash_conditions_for_aggregates(attrs) + expanded_attrs = {} + attrs.each do |attr, value| + if aggregation = reflect_on_aggregation(attr.to_sym) + mapping = aggregation.mapping + mapping.each do |field_attr, aggregate_attr| + if mapping.size == 1 && !value.respond_to?(aggregate_attr) + expanded_attrs[field_attr] = value + else + expanded_attrs[field_attr] = value.send(aggregate_attr) + end + end + else + expanded_attrs[attr] = value + end + end + expanded_attrs + end + + # Sanitizes a hash of attribute/value pairs into SQL conditions for a WHERE clause. + # { name: "foo'bar", group_id: 4 } + # # => "name='foo''bar' and group_id= 4" + # { status: nil, group_id: [1,2,3] } + # # => "status IS NULL and group_id IN (1,2,3)" + # { age: 13..18 } + # # => "age BETWEEN 13 AND 18" + # { 'other_records.id' => 7 } + # # => "`other_records`.`id` = 7" + # { other_records: { id: 7 } } + # # => "`other_records`.`id` = 7" + # And for value objects on a composed_of relationship: + # { address: Address.new("123 abc st.", "chicago") } + # # => "address_street='123 abc st.' and address_city='chicago'" + def sanitize_sql_hash_for_conditions(attrs, default_table_name = self.table_name) + ActiveSupport::Deprecation.warn(<<-EOWARN) +sanitize_sql_hash_for_conditions is deprecated, and will be removed in Rails 5.0 + EOWARN + attrs = PredicateBuilder.resolve_column_aliases self, attrs + attrs = expand_hash_conditions_for_aggregates(attrs) + + table = Arel::Table.new(table_name, arel_engine).alias(default_table_name) + PredicateBuilder.build_from_hash(self, attrs, table).map { |b| + connection.visitor.compile b + }.join(' AND ') + end + alias_method :sanitize_sql_hash, :sanitize_sql_hash_for_conditions + + # Sanitizes a hash of attribute/value pairs into SQL conditions for a SET clause. + # { status: nil, group_id: 1 } + # # => "status = NULL , group_id = 1" + def sanitize_sql_hash_for_assignment(attrs, table) + c = connection + attrs.map do |attr, value| + "#{c.quote_table_name_for_assignment(table, attr)} = #{quote_bound_value(value, c, columns_hash[attr.to_s])}" + end.join(', ') + end + + # Sanitizes a +string+ so that it is safe to use within an SQL + # LIKE statement. This method uses +escape_character+ to escape all occurrences of "\", "_" and "%" + def sanitize_sql_like(string, escape_character = "\\") + pattern = Regexp.union(escape_character, "%", "_") + string.gsub(pattern) { |x| [escape_character, x].join } + end + + # Accepts an array of conditions. The array has each value + # sanitized and interpolated into the SQL statement. + # ["name='%s' and group_id='%s'", "foo'bar", 4] returns "name='foo''bar' and group_id='4'" + def sanitize_sql_array(ary) + statement, *values = ary + if values.first.is_a?(Hash) && statement =~ /:\w+/ + replace_named_bind_variables(statement, values.first) + elsif statement.include?('?') + replace_bind_variables(statement, values) + elsif statement.blank? + statement + else + statement % values.collect { |value| connection.quote_string(value.to_s) } + end + end + + def replace_bind_variables(statement, values) #:nodoc: + raise_if_bind_arity_mismatch(statement, statement.count('?'), values.size) + bound = values.dup + c = connection + statement.gsub(/\?/) do + replace_bind_variable(bound.shift, c) + end + end + + def replace_bind_variable(value, c = connection) #:nodoc: + if ActiveRecord::Relation === value + value.to_sql + else + quote_bound_value(value, c) + end + end + + def replace_named_bind_variables(statement, bind_vars) #:nodoc: + statement.gsub(/(:?):([a-zA-Z]\w*)/) do + if $1 == ':' # skip postgresql casts + $& # return the whole match + elsif bind_vars.include?(match = $2.to_sym) + replace_bind_variable(bind_vars[match]) + else + raise PreparedStatementInvalid, "missing value for :#{match} in #{statement}" + end + end + end + + def quote_bound_value(value, c = connection, column = nil) #:nodoc: + if column + c.quote(value, column) + elsif value.respond_to?(:map) && !value.acts_like?(:string) + if value.respond_to?(:empty?) && value.empty? + c.quote(nil) + else + value.map { |v| c.quote(v) }.join(',') + end + else + c.quote(value) + end + end + + def raise_if_bind_arity_mismatch(statement, expected, provided) #:nodoc: + unless expected == provided + raise PreparedStatementInvalid, "wrong number of bind variables (#{provided} for #{expected}) in: #{statement}" + end + end + end + + # TODO: Deprecate this + def quoted_id + self.class.quote_value(id, column_for_attribute(self.class.primary_key)) + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/schema.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/schema.rb new file mode 100644 index 0000000..0a5546a --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/schema.rb @@ -0,0 +1,64 @@ +module ActiveRecord + # = Active Record Schema + # + # Allows programmers to programmatically define a schema in a portable + # DSL. This means you can define tables, indexes, etc. without using SQL + # directly, so your applications can more easily support multiple + # databases. + # + # Usage: + # + # ActiveRecord::Schema.define do + # create_table :authors do |t| + # t.string :name, null: false + # end + # + # add_index :authors, :name, :unique + # + # create_table :posts do |t| + # t.integer :author_id, null: false + # t.string :subject + # t.text :body + # t.boolean :private, default: false + # end + # + # add_index :posts, :author_id + # end + # + # ActiveRecord::Schema is only supported by database adapters that also + # support migrations, the two features being very similar. + class Schema < Migration + + # Returns the migrations paths. + # + # ActiveRecord::Schema.new.migrations_paths + # # => ["db/migrate"] # Rails migration path by default. + def migrations_paths + ActiveRecord::Migrator.migrations_paths + end + + def define(info, &block) # :nodoc: + instance_eval(&block) + + unless info[:version].blank? + initialize_schema_migrations_table + connection.assume_migrated_upto_version(info[:version], migrations_paths) + end + end + + # Eval the given block. All methods available to the current connection + # adapter are available within the block, so you can easily use the + # database definition DSL to build up your schema (+create_table+, + # +add_index+, etc.). + # + # The +info+ hash is optional, and if given is used to define metadata + # about the current schema (currently, only the schema's version): + # + # ActiveRecord::Schema.define(version: 20380119000001) do + # ... + # end + def self.define(info={}, &block) + new.define(info, &block) + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/schema_dumper.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/schema_dumper.rb new file mode 100644 index 0000000..73a50bd --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/schema_dumper.rb @@ -0,0 +1,251 @@ +require 'stringio' +require 'active_support/core_ext/big_decimal' + +module ActiveRecord + # = Active Record Schema Dumper + # + # This class is used to dump the database schema for some connection to some + # output format (i.e., ActiveRecord::Schema). + class SchemaDumper #:nodoc: + private_class_method :new + + ## + # :singleton-method: + # A list of tables which should not be dumped to the schema. + # Acceptable values are strings as well as regexp. + # This setting is only used if ActiveRecord::Base.schema_format == :ruby + cattr_accessor :ignore_tables + @@ignore_tables = [] + + class << self + def dump(connection=ActiveRecord::Base.connection, stream=STDOUT, config = ActiveRecord::Base) + new(connection, generate_options(config)).dump(stream) + stream + end + + private + def generate_options(config) + { + table_name_prefix: config.table_name_prefix, + table_name_suffix: config.table_name_suffix + } + end + end + + def dump(stream) + header(stream) + extensions(stream) + tables(stream) + trailer(stream) + stream + end + + private + + def initialize(connection, options = {}) + @connection = connection + @types = @connection.native_database_types + @version = Migrator::current_version rescue nil + @options = options + end + + def header(stream) + define_params = @version ? "version: #{@version}" : "" + + if stream.respond_to?(:external_encoding) && stream.external_encoding + stream.puts "# encoding: #{stream.external_encoding.name}" + end + + stream.puts <
    e + stream.puts "# Could not dump table #{table.inspect} because of following #{e.class}" + stream.puts "# #{e.message}" + stream.puts + end + + stream + end + + def indexes(table, stream) + if (indexes = @connection.indexes(table)).any? + add_index_statements = indexes.map do |index| + statement_parts = [ + "add_index #{remove_prefix_and_suffix(index.table).inspect}", + index.columns.inspect, + "name: #{index.name.inspect}", + ] + statement_parts << 'unique: true' if index.unique + + index_lengths = (index.lengths || []).compact + statement_parts << "length: #{Hash[index.columns.zip(index.lengths)].inspect}" if index_lengths.any? + + index_orders = index.orders || {} + statement_parts << "order: #{index.orders.inspect}" if index_orders.any? + statement_parts << "where: #{index.where.inspect}" if index.where + statement_parts << "using: #{index.using.inspect}" if index.using + statement_parts << "type: #{index.type.inspect}" if index.type + + " #{statement_parts.join(', ')}" + end + + stream.puts add_index_statements.sort.join("\n") + stream.puts + end + end + + def foreign_keys(table, stream) + if (foreign_keys = @connection.foreign_keys(table)).any? + add_foreign_key_statements = foreign_keys.map do |foreign_key| + parts = [ + "add_foreign_key #{remove_prefix_and_suffix(foreign_key.from_table).inspect}", + remove_prefix_and_suffix(foreign_key.to_table).inspect, + ] + + if foreign_key.column != @connection.foreign_key_column_for(foreign_key.to_table) + parts << "column: #{foreign_key.column.inspect}" + end + + if foreign_key.custom_primary_key? + parts << "primary_key: #{foreign_key.primary_key.inspect}" + end + + if foreign_key.name !~ /^fk_rails_[0-9a-f]{10}$/ + parts << "name: #{foreign_key.name.inspect}" + end + + parts << "on_update: #{foreign_key.on_update.inspect}" if foreign_key.on_update + parts << "on_delete: #{foreign_key.on_delete.inspect}" if foreign_key.on_delete + + " #{parts.join(', ')}" + end + + stream.puts add_foreign_key_statements.sort.join("\n") + end + end + + def remove_prefix_and_suffix(table) + table.gsub(/^(#{@options[:table_name_prefix]})(.+)(#{@options[:table_name_suffix]})$/, "\\2") + end + + def ignored?(table_name) + ['schema_migrations', ignore_tables].flatten.any? do |ignored| + ignored === remove_prefix_and_suffix(table_name) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/schema_migration.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/schema_migration.rb new file mode 100644 index 0000000..b503810 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/schema_migration.rb @@ -0,0 +1,56 @@ +require 'active_record/scoping/default' +require 'active_record/scoping/named' +require 'active_record/base' + +module ActiveRecord + class SchemaMigration < ActiveRecord::Base + class << self + def primary_key + nil + end + + def table_name + "#{table_name_prefix}#{ActiveRecord::Base.schema_migrations_table_name}#{table_name_suffix}" + end + + def index_name + "#{table_name_prefix}unique_#{ActiveRecord::Base.schema_migrations_table_name}#{table_name_suffix}" + end + + def table_exists? + connection.table_exists?(table_name) + end + + def create_table(limit=nil) + unless table_exists? + version_options = {null: false} + version_options[:limit] = limit if limit + + connection.create_table(table_name, id: false) do |t| + t.column :version, :string, version_options + end + connection.add_index table_name, :version, unique: true, name: index_name + end + end + + def drop_table + if table_exists? + connection.remove_index table_name, name: index_name + connection.drop_table(table_name) + end + end + + def normalize_migration_number(number) + "%.3d" % number.to_i + end + + def normalized_versions + pluck(:version).map { |v| normalize_migration_number v } + end + end + + def version + super.to_i + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/scoping.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/scoping.rb new file mode 100644 index 0000000..3e43591 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/scoping.rb @@ -0,0 +1,87 @@ +require 'active_support/per_thread_registry' + +module ActiveRecord + module Scoping + extend ActiveSupport::Concern + + included do + include Default + include Named + end + + module ClassMethods + def current_scope #:nodoc: + ScopeRegistry.value_for(:current_scope, base_class.to_s) + end + + def current_scope=(scope) #:nodoc: + ScopeRegistry.set_value_for(:current_scope, base_class.to_s, scope) + end + end + + def populate_with_current_scope_attributes + return unless self.class.scope_attributes? + + self.class.scope_attributes.each do |att,value| + send("#{att}=", value) if respond_to?("#{att}=") + end + end + + def initialize_internals_callback + super + populate_with_current_scope_attributes + end + + # This class stores the +:current_scope+ and +:ignore_default_scope+ values + # for different classes. The registry is stored as a thread local, which is + # accessed through +ScopeRegistry.current+. + # + # This class allows you to store and get the scope values on different + # classes and different types of scopes. For example, if you are attempting + # to get the current_scope for the +Board+ model, then you would use the + # following code: + # + # registry = ActiveRecord::Scoping::ScopeRegistry + # registry.set_value_for(:current_scope, "Board", some_new_scope) + # + # Now when you run: + # + # registry.value_for(:current_scope, "Board") + # + # You will obtain whatever was defined in +some_new_scope+. The +value_for+ + # and +set_value_for+ methods are delegated to the current +ScopeRegistry+ + # object, so the above example code can also be called as: + # + # ActiveRecord::Scoping::ScopeRegistry.set_value_for(:current_scope, + # "Board", some_new_scope) + class ScopeRegistry # :nodoc: + extend ActiveSupport::PerThreadRegistry + + VALID_SCOPE_TYPES = [:current_scope, :ignore_default_scope] + + def initialize + @registry = Hash.new { |hash, key| hash[key] = {} } + end + + # Obtains the value for a given +scope_name+ and +variable_name+. + def value_for(scope_type, variable_name) + raise_invalid_scope_type!(scope_type) + @registry[scope_type][variable_name] + end + + # Sets the +value+ for a given +scope_type+ and +variable_name+. + def set_value_for(scope_type, variable_name, value) + raise_invalid_scope_type!(scope_type) + @registry[scope_type][variable_name] = value + end + + private + + def raise_invalid_scope_type!(scope_type) + if !VALID_SCOPE_TYPES.include?(scope_type) + raise ArgumentError, "Invalid scope type '#{scope_type}' sent to the registry. Scope types must be included in VALID_SCOPE_TYPES" + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/scoping/default.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/scoping/default.rb new file mode 100644 index 0000000..52e5200 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/scoping/default.rb @@ -0,0 +1,135 @@ +module ActiveRecord + module Scoping + module Default + extend ActiveSupport::Concern + + included do + # Stores the default scope for the class. + class_attribute :default_scopes, instance_writer: false, instance_predicate: false + + self.default_scopes = [] + end + + module ClassMethods + # Returns a scope for the model without the previously set scopes. + # + # class Post < ActiveRecord::Base + # def self.default_scope + # where published: true + # end + # end + # + # Post.all # Fires "SELECT * FROM posts WHERE published = true" + # Post.unscoped.all # Fires "SELECT * FROM posts" + # Post.where(published: false).unscoped.all # Fires "SELECT * FROM posts" + # + # This method also accepts a block. All queries inside the block will + # not use the previously set scopes. + # + # Post.unscoped { + # Post.limit(10) # Fires "SELECT * FROM posts LIMIT 10" + # } + def unscoped + block_given? ? relation.scoping { yield } : relation + end + + def before_remove_const #:nodoc: + self.current_scope = nil + end + + protected + + # Use this macro in your model to set a default scope for all operations on + # the model. + # + # class Article < ActiveRecord::Base + # default_scope { where(published: true) } + # end + # + # Article.all # => SELECT * FROM articles WHERE published = true + # + # The +default_scope+ is also applied while creating/building a record. + # It is not applied while updating a record. + # + # Article.new.published # => true + # Article.create.published # => true + # + # (You can also pass any object which responds to +call+ to the + # +default_scope+ macro, and it will be called when building the + # default scope.) + # + # If you use multiple +default_scope+ declarations in your model then + # they will be merged together: + # + # class Article < ActiveRecord::Base + # default_scope { where(published: true) } + # default_scope { where(rating: 'G') } + # end + # + # Article.all # => SELECT * FROM articles WHERE published = true AND rating = 'G' + # + # This is also the case with inheritance and module includes where the + # parent or module defines a +default_scope+ and the child or including + # class defines a second one. + # + # If you need to do more complex things with a default scope, you can + # alternatively define it as a class method: + # + # class Article < ActiveRecord::Base + # def self.default_scope + # # Should return a scope, you can call 'super' here etc. + # end + # end + def default_scope(scope = nil) + scope = Proc.new if block_given? + + if scope.is_a?(Relation) || !scope.respond_to?(:call) + raise ArgumentError, + "Support for calling #default_scope without a block is removed. For example instead " \ + "of `default_scope where(color: 'red')`, please use " \ + "`default_scope { where(color: 'red') }`. (Alternatively you can just redefine " \ + "self.default_scope.)" + end + + self.default_scopes += [scope] + end + + def build_default_scope(base_rel = relation) # :nodoc: + return if abstract_class? + if !Base.is_a?(method(:default_scope).owner) + # The user has defined their own default scope method, so call that + evaluate_default_scope { default_scope } + elsif default_scopes.any? + evaluate_default_scope do + default_scopes.inject(base_rel) do |default_scope, scope| + default_scope.merge(base_rel.scoping { scope.call }) + end + end + end + end + + def ignore_default_scope? # :nodoc: + ScopeRegistry.value_for(:ignore_default_scope, self) + end + + def ignore_default_scope=(ignore) # :nodoc: + ScopeRegistry.set_value_for(:ignore_default_scope, self, ignore) + end + + # The ignore_default_scope flag is used to prevent an infinite recursion + # situation where a default scope references a scope which has a default + # scope which references a scope... + def evaluate_default_scope # :nodoc: + return if ignore_default_scope? + + begin + self.ignore_default_scope = true + yield + ensure + self.ignore_default_scope = false + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/scoping/named.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/scoping/named.rb new file mode 100644 index 0000000..35420e6 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/scoping/named.rb @@ -0,0 +1,164 @@ +require 'active_support/core_ext/array' +require 'active_support/core_ext/hash/except' +require 'active_support/core_ext/kernel/singleton_class' + +module ActiveRecord + # = Active Record \Named \Scopes + module Scoping + module Named + extend ActiveSupport::Concern + + module ClassMethods + # Returns an ActiveRecord::Relation scope object. + # + # posts = Post.all + # posts.size # Fires "select count(*) from posts" and returns the count + # posts.each {|p| puts p.name } # Fires "select * from posts" and loads post objects + # + # fruits = Fruit.all + # fruits = fruits.where(color: 'red') if options[:red_only] + # fruits = fruits.limit(10) if limited? + # + # You can define a scope that applies to all finders using + # ActiveRecord::Base.default_scope. + def all + if current_scope + current_scope.clone + else + default_scoped + end + end + + def default_scoped # :nodoc: + relation.merge(build_default_scope) + end + + # Collects attributes from scopes that should be applied when creating + # an AR instance for the particular class this is called on. + def scope_attributes # :nodoc: + all.scope_for_create + end + + # Are there default attributes associated with this scope? + def scope_attributes? # :nodoc: + current_scope || default_scopes.any? + end + + # Adds a class method for retrieving and querying objects. A \scope + # represents a narrowing of a database query, such as + # where(color: :red).select('shirts.*').includes(:washing_instructions). + # + # class Shirt < ActiveRecord::Base + # scope :red, -> { where(color: 'red') } + # scope :dry_clean_only, -> { joins(:washing_instructions).where('washing_instructions.dry_clean_only = ?', true) } + # end + # + # The above calls to +scope+ define class methods Shirt.red and + # Shirt.dry_clean_only. Shirt.red, in effect, + # represents the query Shirt.where(color: 'red'). + # + # You should always pass a callable object to the scopes defined + # with +scope+. This ensures that the scope is re-evaluated each + # time it is called. + # + # Note that this is simply 'syntactic sugar' for defining an actual + # class method: + # + # class Shirt < ActiveRecord::Base + # def self.red + # where(color: 'red') + # end + # end + # + # Unlike Shirt.find(...), however, the object returned by + # Shirt.red is not an Array; it resembles the association object + # constructed by a +has_many+ declaration. For instance, you can invoke + # Shirt.red.first, Shirt.red.count, + # Shirt.red.where(size: 'small'). Also, just as with the + # association objects, named \scopes act like an Array, implementing + # Enumerable; Shirt.red.each(&block), Shirt.red.first, + # and Shirt.red.inject(memo, &block) all behave as if + # Shirt.red really was an Array. + # + # These named \scopes are composable. For instance, + # Shirt.red.dry_clean_only will produce all shirts that are + # both red and dry clean only. Nested finds and calculations also work + # with these compositions: Shirt.red.dry_clean_only.count + # returns the number of garments for which these criteria obtain. + # Similarly with Shirt.red.dry_clean_only.average(:thread_count). + # + # All scopes are available as class methods on the ActiveRecord::Base + # descendant upon which the \scopes were defined. But they are also + # available to +has_many+ associations. If, + # + # class Person < ActiveRecord::Base + # has_many :shirts + # end + # + # then elton.shirts.red.dry_clean_only will return all of + # Elton's red, dry clean only shirts. + # + # \Named scopes can also have extensions, just as with +has_many+ + # declarations: + # + # class Shirt < ActiveRecord::Base + # scope :red, -> { where(color: 'red') } do + # def dom_id + # 'red_shirts' + # end + # end + # end + # + # Scopes can also be used while creating/building a record. + # + # class Article < ActiveRecord::Base + # scope :published, -> { where(published: true) } + # end + # + # Article.published.new.published # => true + # Article.published.create.published # => true + # + # \Class methods on your model are automatically available + # on scopes. Assuming the following setup: + # + # class Article < ActiveRecord::Base + # scope :published, -> { where(published: true) } + # scope :featured, -> { where(featured: true) } + # + # def self.latest_article + # order('published_at desc').first + # end + # + # def self.titles + # pluck(:title) + # end + # end + # + # We are able to call the methods like this: + # + # Article.published.featured.latest_article + # Article.featured.titles + def scope(name, body, &block) + unless body.respond_to?(:call) + raise ArgumentError, 'The scope body needs to be callable.' + end + + if dangerous_class_method?(name) + raise ArgumentError, "You tried to define a scope named \"#{name}\" " \ + "on the model \"#{self.name}\", but Active Record already defined " \ + "a class method with the same name." + end + + extension = Module.new(&block) if block + + singleton_class.send(:define_method, name) do |*args| + scope = all.scoping { body.call(*args) } + scope = scope.extending(extension) if extension + + scope || all + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/serialization.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/serialization.rb new file mode 100644 index 0000000..bd9079b --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/serialization.rb @@ -0,0 +1,22 @@ +module ActiveRecord #:nodoc: + # = Active Record Serialization + module Serialization + extend ActiveSupport::Concern + include ActiveModel::Serializers::JSON + + included do + self.include_root_in_json = false + end + + def serializable_hash(options = nil) + options = options.try(:clone) || {} + + options[:except] = Array(options[:except]).map { |n| n.to_s } + options[:except] |= Array(self.class.inheritance_column) + + super(options) + end + end +end + +require 'active_record/serializers/xml_serializer' diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/serializers/xml_serializer.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/serializers/xml_serializer.rb new file mode 100644 index 0000000..c2484d0 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/serializers/xml_serializer.rb @@ -0,0 +1,193 @@ +require 'active_support/core_ext/hash/conversions' + +module ActiveRecord #:nodoc: + module Serialization + include ActiveModel::Serializers::Xml + + # Builds an XML document to represent the model. Some configuration is + # available through +options+. However more complicated cases should + # override ActiveRecord::Base#to_xml. + # + # By default the generated XML document will include the processing + # instruction and all the object's attributes. For example: + # + # + # + # The First Topic + # David + # 1 + # false + # 0 + # 2000-01-01T08:28:00+12:00 + # 2003-07-16T09:28:00+1200 + # Have a nice day + # david@loudthinking.com + # + # 2004-04-15 + # + # + # This behavior can be controlled with :only, :except, + # :skip_instruct, :skip_types, :dasherize and :camelize . + # The :only and :except options are the same as for the + # +attributes+ method. The default is to dasherize all column names, but you + # can disable this setting :dasherize to +false+. Setting :camelize + # to +true+ will camelize all column names - this also overrides :dasherize. + # To not have the column type included in the XML output set :skip_types to +true+. + # + # For instance: + # + # topic.to_xml(skip_instruct: true, except: [ :id, :bonus_time, :written_on, :replies_count ]) + # + # + # The First Topic + # David + # false + # Have a nice day + # david@loudthinking.com + # + # 2004-04-15 + # + # + # To include first level associations use :include: + # + # firm.to_xml include: [ :account, :clients ] + # + # + # + # 1 + # 1 + # 37signals + # + # + # 1 + # Summit + # + # + # 1 + # Microsoft + # + # + # + # 1 + # 50 + # + # + # + # Additionally, the record being serialized will be passed to a Proc's second + # parameter. This allows for ad hoc additions to the resultant document that + # incorporate the context of the record being serialized. And by leveraging the + # closure created by a Proc, to_xml can be used to add elements that normally fall + # outside of the scope of the model -- for example, generating and appending URLs + # associated with models. + # + # proc = Proc.new { |options, record| options[:builder].tag!('name-reverse', record.name.reverse) } + # firm.to_xml procs: [ proc ] + # + # + # # ... normal attributes as shown above ... + # slangis73 + # + # + # To include deeper levels of associations pass a hash like this: + # + # firm.to_xml include: {account: {}, clients: {include: :address}} + # + # + # 1 + # 1 + # 37signals + # + # + # 1 + # Summit + #
    + # ... + #
    + #
    + # + # 1 + # Microsoft + #
    + # ... + #
    + #
    + #
    + # + # 1 + # 50 + # + #
    + # + # To include any methods on the model being called use :methods: + # + # firm.to_xml methods: [ :calculated_earnings, :real_earnings ] + # + # + # # ... normal attributes as shown above ... + # 100000000000000000 + # 5 + # + # + # To call any additional Procs use :procs. The Procs are passed a + # modified version of the options hash that was given to +to_xml+: + # + # proc = Proc.new { |options| options[:builder].tag!('abc', 'def') } + # firm.to_xml procs: [ proc ] + # + # + # # ... normal attributes as shown above ... + # def + # + # + # Alternatively, you can yield the builder object as part of the +to_xml+ call: + # + # firm.to_xml do |xml| + # xml.creator do + # xml.first_name "David" + # xml.last_name "Heinemeier Hansson" + # end + # end + # + # + # # ... normal attributes as shown above ... + # + # David + # Heinemeier Hansson + # + # + # + # As noted above, you may override +to_xml+ in your ActiveRecord::Base + # subclasses to have complete control about what's generated. The general + # form of doing this is: + # + # class IHaveMyOwnXML < ActiveRecord::Base + # def to_xml(options = {}) + # require 'builder' + # options[:indent] ||= 2 + # xml = options[:builder] ||= ::Builder::XmlMarkup.new(indent: options[:indent]) + # xml.instruct! unless options[:skip_instruct] + # xml.level_one do + # xml.tag!(:second_level, 'content') + # end + # end + # end + def to_xml(options = {}, &block) + XmlSerializer.new(self, options).serialize(&block) + end + end + + class XmlSerializer < ActiveModel::Serializers::Xml::Serializer #:nodoc: + class Attribute < ActiveModel::Serializers::Xml::Serializer::Attribute #:nodoc: + def compute_type + klass = @serializable.class + column = klass.columns_hash[name] || Type::Value.new + + type = ActiveSupport::XmlMini::TYPE_NAMES[value.class.name] || column.type + + { :text => :string, + :time => :datetime }[type] || type + end + protected :compute_type + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/statement_cache.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/statement_cache.rb new file mode 100644 index 0000000..c68990b --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/statement_cache.rb @@ -0,0 +1,111 @@ +module ActiveRecord + + # Statement cache is used to cache a single statement in order to avoid creating the AST again. + # Initializing the cache is done by passing the statement in the create block: + # + # cache = StatementCache.create(Book.connection) do |params| + # Book.where(name: "my book").where("author_id > 3") + # end + # + # The cached statement is executed by using the +execute+ method: + # + # cache.execute([], Book, Book.connection) + # + # The relation returned by the block is cached, and for each +execute+ call the cached relation gets duped. + # Database is queried when +to_a+ is called on the relation. + # + # If you want to cache the statement without the values you can use the +bind+ method of the + # block parameter. + # + # cache = StatementCache.create(Book.connection) do |params| + # Book.where(name: params.bind) + # end + # + # And pass the bind values as the first argument of +execute+ call. + # + # cache.execute(["my book"], Book, Book.connection) + class StatementCache # :nodoc: + class Substitute; end # :nodoc: + + class Query # :nodoc: + def initialize(sql) + @sql = sql + end + + def sql_for(binds, connection) + @sql + end + end + + class PartialQuery < Query # :nodoc: + def initialize values + @values = values + @indexes = values.each_with_index.find_all { |thing,i| + Arel::Nodes::BindParam === thing + }.map(&:last) + end + + def sql_for(binds, connection) + val = @values.dup + binds = binds.dup + @indexes.each { |i| val[i] = connection.quote(*binds.shift.reverse) } + val.join + end + end + + def self.query(visitor, ast) + Query.new visitor.accept(ast, Arel::Collectors::SQLString.new).value + end + + def self.partial_query(visitor, ast, collector) + collected = visitor.accept(ast, collector).value + PartialQuery.new collected + end + + class Params # :nodoc: + def bind; Substitute.new; end + end + + class BindMap # :nodoc: + def initialize(bind_values) + @indexes = [] + @bind_values = bind_values + + bind_values.each_with_index do |(_, value), i| + if Substitute === value + @indexes << i + end + end + end + + def bind(values) + bvs = @bind_values.map { |pair| pair.dup } + @indexes.each_with_index { |offset,i| bvs[offset][1] = values[i] } + bvs + end + end + + attr_reader :bind_map, :query_builder + + def self.create(connection, block = Proc.new) + relation = block.call Params.new + bind_map = BindMap.new relation.bind_values + query_builder = connection.cacheable_query relation.arel + new query_builder, bind_map + end + + def initialize(query_builder, bind_map) + @query_builder = query_builder + @bind_map = bind_map + end + + def execute(params, klass, connection) + bind_values = bind_map.bind params + + sql = query_builder.sql_for bind_values, connection + + klass.find_by_sql sql, bind_values + end + alias :call :execute + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/store.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/store.rb new file mode 100644 index 0000000..3c291f2 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/store.rb @@ -0,0 +1,205 @@ +require 'active_support/core_ext/hash/indifferent_access' + +module ActiveRecord + # Store gives you a thin wrapper around serialize for the purpose of storing hashes in a single column. + # It's like a simple key/value store baked into your record when you don't care about being able to + # query that store outside the context of a single record. + # + # You can then declare accessors to this store that are then accessible just like any other attribute + # of the model. This is very helpful for easily exposing store keys to a form or elsewhere that's + # already built around just accessing attributes on the model. + # + # Make sure that you declare the database column used for the serialized store as a text, so there's + # plenty of room. + # + # You can set custom coder to encode/decode your serialized attributes to/from different formats. + # JSON, YAML, Marshal are supported out of the box. Generally it can be any wrapper that provides +load+ and +dump+. + # + # NOTE - If you are using PostgreSQL specific columns like +hstore+ or +json+ there is no need for + # the serialization provided by +store+. Simply use +store_accessor+ instead to generate + # the accessor methods. Be aware that these columns use a string keyed hash and do not allow access + # using a symbol. + # + # Examples: + # + # class User < ActiveRecord::Base + # store :settings, accessors: [ :color, :homepage ], coder: JSON + # end + # + # u = User.new(color: 'black', homepage: '37signals.com') + # u.color # Accessor stored attribute + # u.settings[:country] = 'Denmark' # Any attribute, even if not specified with an accessor + # + # # There is no difference between strings and symbols for accessing custom attributes + # u.settings[:country] # => 'Denmark' + # u.settings['country'] # => 'Denmark' + # + # # Add additional accessors to an existing store through store_accessor + # class SuperUser < User + # store_accessor :settings, :privileges, :servants + # end + # + # The stored attribute names can be retrieved using +stored_attributes+. + # + # User.stored_attributes[:settings] # [:color, :homepage] + # + # == Overwriting default accessors + # + # All stored values are automatically available through accessors on the Active Record + # object, but sometimes you want to specialize this behavior. This can be done by overwriting + # the default accessors (using the same name as the attribute) and calling super + # to actually change things. + # + # class Song < ActiveRecord::Base + # # Uses a stored integer to hold the volume adjustment of the song + # store :settings, accessors: [:volume_adjustment] + # + # def volume_adjustment=(decibels) + # super(decibels.to_i) + # end + # + # def volume_adjustment + # super.to_i + # end + # end + module Store + extend ActiveSupport::Concern + + included do + class << self + attr_accessor :local_stored_attributes + end + end + + module ClassMethods + def store(store_attribute, options = {}) + serialize store_attribute, IndifferentCoder.new(options[:coder]) + store_accessor(store_attribute, options[:accessors]) if options.has_key? :accessors + end + + def store_accessor(store_attribute, *keys) + keys = keys.flatten + + _store_accessors_module.module_eval do + keys.each do |key| + define_method("#{key}=") do |value| + write_store_attribute(store_attribute, key, value) + end + + define_method(key) do + read_store_attribute(store_attribute, key) + end + end + end + + # assign new store attribute and create new hash to ensure that each class in the hierarchy + # has its own hash of stored attributes. + self.local_stored_attributes ||= {} + self.local_stored_attributes[store_attribute] ||= [] + self.local_stored_attributes[store_attribute] |= keys + end + + def _store_accessors_module # :nodoc: + @_store_accessors_module ||= begin + mod = Module.new + include mod + mod + end + end + + def stored_attributes + parent = superclass.respond_to?(:stored_attributes) ? superclass.stored_attributes : {} + if self.local_stored_attributes + parent.merge!(self.local_stored_attributes) { |k, a, b| a | b } + end + parent + end + end + + protected + def read_store_attribute(store_attribute, key) + accessor = store_accessor_for(store_attribute) + accessor.read(self, store_attribute, key) + end + + def write_store_attribute(store_attribute, key, value) + accessor = store_accessor_for(store_attribute) + accessor.write(self, store_attribute, key, value) + end + + private + def store_accessor_for(store_attribute) + type_for_attribute(store_attribute.to_s).accessor + end + + class HashAccessor # :nodoc: + def self.read(object, attribute, key) + prepare(object, attribute) + object.public_send(attribute)[key] + end + + def self.write(object, attribute, key, value) + prepare(object, attribute) + if value != read(object, attribute, key) + object.public_send :"#{attribute}_will_change!" + object.public_send(attribute)[key] = value + end + end + + def self.prepare(object, attribute) + object.public_send :"#{attribute}=", {} unless object.send(attribute) + end + end + + class StringKeyedHashAccessor < HashAccessor # :nodoc: + def self.read(object, attribute, key) + super object, attribute, key.to_s + end + + def self.write(object, attribute, key, value) + super object, attribute, key.to_s, value + end + end + + class IndifferentHashAccessor < ActiveRecord::Store::HashAccessor # :nodoc: + def self.prepare(object, store_attribute) + attribute = object.send(store_attribute) + unless attribute.is_a?(ActiveSupport::HashWithIndifferentAccess) + attribute = IndifferentCoder.as_indifferent_hash(attribute) + object.send :"#{store_attribute}=", attribute + end + attribute + end + end + + class IndifferentCoder # :nodoc: + def initialize(coder_or_class_name) + @coder = + if coder_or_class_name.respond_to?(:load) && coder_or_class_name.respond_to?(:dump) + coder_or_class_name + else + ActiveRecord::Coders::YAMLColumn.new(coder_or_class_name || Object) + end + end + + def dump(obj) + @coder.dump self.class.as_indifferent_hash(obj) + end + + def load(yaml) + self.class.as_indifferent_hash(@coder.load(yaml || '')) + end + + def self.as_indifferent_hash(obj) + case obj + when ActiveSupport::HashWithIndifferentAccess + obj + when Hash + obj.with_indifferent_access + else + ActiveSupport::HashWithIndifferentAccess.new + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/tasks/database_tasks.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/tasks/database_tasks.rb new file mode 100644 index 0000000..f776130 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/tasks/database_tasks.rb @@ -0,0 +1,296 @@ +require 'active_support/core_ext/string/filters' + +module ActiveRecord + module Tasks # :nodoc: + class DatabaseAlreadyExists < StandardError; end # :nodoc: + class DatabaseNotSupported < StandardError; end # :nodoc: + + # ActiveRecord::Tasks::DatabaseTasks is a utility class, which encapsulates + # logic behind common tasks used to manage database and migrations. + # + # The tasks defined here are used with Rake tasks provided by Active Record. + # + # In order to use DatabaseTasks, a few config values need to be set. All the needed + # config values are set by Rails already, so it's necessary to do it only if you + # want to change the defaults or when you want to use Active Record outside of Rails + # (in such case after configuring the database tasks, you can also use the rake tasks + # defined in Active Record). + # + # The possible config values are: + # + # * +env+: current environment (like Rails.env). + # * +database_configuration+: configuration of your databases (as in +config/database.yml+). + # * +db_dir+: your +db+ directory. + # * +fixtures_path+: a path to fixtures directory. + # * +migrations_paths+: a list of paths to directories with migrations. + # * +seed_loader+: an object which will load seeds, it needs to respond to the +load_seed+ method. + # * +root+: a path to the root of the application. + # + # Example usage of +DatabaseTasks+ outside Rails could look as such: + # + # include ActiveRecord::Tasks + # DatabaseTasks.database_configuration = YAML.load_file('my_database_config.yml') + # DatabaseTasks.db_dir = 'db' + # # other settings... + # + # DatabaseTasks.create_current('production') + module DatabaseTasks + extend self + + attr_writer :current_config, :db_dir, :migrations_paths, :fixtures_path, :root, :env, :seed_loader + attr_accessor :database_configuration + + LOCAL_HOSTS = ['127.0.0.1', 'localhost'] + + def register_task(pattern, task) + @tasks ||= {} + @tasks[pattern] = task + end + + register_task(/mysql/, ActiveRecord::Tasks::MySQLDatabaseTasks) + register_task(/postgresql/, ActiveRecord::Tasks::PostgreSQLDatabaseTasks) + register_task(/sqlite/, ActiveRecord::Tasks::SQLiteDatabaseTasks) + + def db_dir + @db_dir ||= Rails.application.config.paths["db"].first + end + + def migrations_paths + @migrations_paths ||= Rails.application.paths['db/migrate'].to_a + end + + def fixtures_path + @fixtures_path ||= if ENV['FIXTURES_PATH'] + File.join(root, ENV['FIXTURES_PATH']) + else + File.join(root, 'test', 'fixtures') + end + end + + def root + @root ||= Rails.root + end + + def env + @env ||= Rails.env + end + + def seed_loader + @seed_loader ||= Rails.application + end + + def current_config(options = {}) + options.reverse_merge! :env => env + if options.has_key?(:config) + @current_config = options[:config] + else + @current_config ||= ActiveRecord::Base.configurations[options[:env]] + end + end + + def create(*arguments) + configuration = arguments.first + class_for_adapter(configuration['adapter']).new(*arguments).create + rescue DatabaseAlreadyExists + $stderr.puts "#{configuration['database']} already exists" + rescue Exception => error + $stderr.puts error, *(error.backtrace) + $stderr.puts "Couldn't create database for #{configuration.inspect}" + end + + def create_all + each_local_configuration { |configuration| create configuration } + end + + def create_current(environment = env) + each_current_configuration(environment) { |configuration| + create configuration + } + ActiveRecord::Base.establish_connection(environment.to_sym) + end + + def drop(*arguments) + configuration = arguments.first + class_for_adapter(configuration['adapter']).new(*arguments).drop + rescue ActiveRecord::NoDatabaseError + $stderr.puts "Database '#{configuration['database']}' does not exist" + rescue Exception => error + $stderr.puts error, *(error.backtrace) + $stderr.puts "Couldn't drop #{configuration['database']}" + end + + def drop_all + each_local_configuration { |configuration| drop configuration } + end + + def drop_current(environment = env) + each_current_configuration(environment) { |configuration| + drop configuration + } + end + + def migrate + verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true + version = ENV["VERSION"] ? ENV["VERSION"].to_i : nil + scope = ENV['SCOPE'] + verbose_was, Migration.verbose = Migration.verbose, verbose + Migrator.migrate(migrations_paths, version) do |migration| + scope.blank? || scope == migration.scope + end + ensure + Migration.verbose = verbose_was + end + + def charset_current(environment = env) + charset ActiveRecord::Base.configurations[environment] + end + + def charset(*arguments) + configuration = arguments.first + class_for_adapter(configuration['adapter']).new(*arguments).charset + end + + def collation_current(environment = env) + collation ActiveRecord::Base.configurations[environment] + end + + def collation(*arguments) + configuration = arguments.first + class_for_adapter(configuration['adapter']).new(*arguments).collation + end + + def purge(configuration) + class_for_adapter(configuration['adapter']).new(configuration).purge + end + + def purge_all + each_local_configuration { |configuration| + purge configuration + } + end + + def purge_current(environment = env) + each_current_configuration(environment) { |configuration| + purge configuration + } + ActiveRecord::Base.establish_connection(environment.to_sym) + end + + def structure_dump(*arguments) + configuration = arguments.first + filename = arguments.delete_at 1 + class_for_adapter(configuration['adapter']).new(*arguments).structure_dump(filename) + end + + def structure_load(*arguments) + configuration = arguments.first + filename = arguments.delete_at 1 + class_for_adapter(configuration['adapter']).new(*arguments).structure_load(filename) + end + + def load_schema(format = ActiveRecord::Base.schema_format, file = nil) + ActiveSupport::Deprecation.warn(<<-MSG.squish) + This method will act on a specific connection in the future. + To act on the current connection, use `load_schema_current` instead. + MSG + + load_schema_current(format, file) + end + + def schema_file(format = ActiveRecord::Base.schema_format) + case format + when :ruby + File.join(db_dir, "schema.rb") + when :sql + File.join(db_dir, "structure.sql") + end + end + + # This method is the successor of +load_schema+. We should rename it + # after +load_schema+ went through a deprecation cycle. (Rails > 4.2) + def load_schema_for(configuration, format = ActiveRecord::Base.schema_format, file = nil) # :nodoc: + file ||= schema_file(format) + + case format + when :ruby + check_schema_file(file) + ActiveRecord::Base.establish_connection(configuration) + load(file) + when :sql + check_schema_file(file) + structure_load(configuration, file) + else + raise ArgumentError, "unknown format #{format.inspect}" + end + end + + def load_schema_current_if_exists(format = ActiveRecord::Base.schema_format, file = nil, environment = env) + if File.exist?(file || schema_file(format)) + load_schema_current(format, file, environment) + end + end + + def load_schema_current(format = ActiveRecord::Base.schema_format, file = nil, environment = env) + each_current_configuration(environment) { |configuration| + load_schema_for configuration, format, file + } + ActiveRecord::Base.establish_connection(environment.to_sym) + end + + def check_schema_file(filename) + unless File.exist?(filename) + message = %{#{filename} doesn't exist yet. Run `rake db:migrate` to create it, then try again.} + message << %{ If you do not intend to use a database, you should instead alter #{Rails.root}/config/application.rb to limit the frameworks that will be loaded.} if defined?(::Rails) + Kernel.abort message + end + end + + def load_seed + if seed_loader + seed_loader.load_seed + else + raise "You tried to load seed data, but no seed loader is specified. Please specify seed " + + "loader with ActiveRecord::Tasks::DatabaseTasks.seed_loader = your_seed_loader\n" + + "Seed loader should respond to load_seed method" + end + end + + private + + def class_for_adapter(adapter) + key = @tasks.keys.detect { |pattern| adapter[pattern] } + unless key + raise DatabaseNotSupported, "Rake tasks not supported by '#{adapter}' adapter" + end + @tasks[key] + end + + def each_current_configuration(environment) + environments = [environment] + # add test environment only if no RAILS_ENV was specified. + environments << 'test' if environment == 'development' && ENV['RAILS_ENV'].nil? + + configurations = ActiveRecord::Base.configurations.values_at(*environments) + configurations.compact.each do |configuration| + yield configuration unless configuration['database'].blank? + end + end + + def each_local_configuration + ActiveRecord::Base.configurations.each_value do |configuration| + next unless configuration['database'] + + if local_database?(configuration) + yield configuration + else + $stderr.puts "This task only modifies local databases. #{configuration['database']} is on a remote host." + end + end + end + + def local_database?(configuration) + configuration['host'].blank? || LOCAL_HOSTS.include?(configuration['host']) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/tasks/mysql_database_tasks.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/tasks/mysql_database_tasks.rb new file mode 100644 index 0000000..3bf9f6d --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/tasks/mysql_database_tasks.rb @@ -0,0 +1,155 @@ +module ActiveRecord + module Tasks # :nodoc: + class MySQLDatabaseTasks # :nodoc: + DEFAULT_CHARSET = ENV['CHARSET'] || 'utf8' + DEFAULT_COLLATION = ENV['COLLATION'] || 'utf8_unicode_ci' + ACCESS_DENIED_ERROR = 1045 + + delegate :connection, :establish_connection, to: ActiveRecord::Base + + def initialize(configuration) + @configuration = configuration + end + + def create + establish_connection configuration_without_database + connection.create_database configuration['database'], creation_options + establish_connection configuration + rescue ActiveRecord::StatementInvalid => error + if /database exists/ === error.message + raise DatabaseAlreadyExists + else + raise + end + rescue error_class => error + if error.respond_to?(:errno) && error.errno == ACCESS_DENIED_ERROR + $stdout.print error.error + establish_connection root_configuration_without_database + connection.create_database configuration['database'], creation_options + if configuration['username'] != 'root' + connection.execute grant_statement.gsub(/\s+/, ' ').strip + end + establish_connection configuration + else + $stderr.puts error.inspect + $stderr.puts "Couldn't create database for #{configuration.inspect}, #{creation_options.inspect}" + $stderr.puts "(If you set the charset manually, make sure you have a matching collation)" if configuration['encoding'] + end + end + + def drop + establish_connection configuration + connection.drop_database configuration['database'] + end + + def purge + establish_connection configuration + connection.recreate_database configuration['database'], creation_options + end + + def charset + connection.charset + end + + def collation + connection.collation + end + + def structure_dump(filename) + args = prepare_command_options + args.concat(["--result-file", "#{filename}"]) + args.concat(["--no-data"]) + args.concat(["#{configuration['database']}"]) + + run_cmd('mysqldump', args, 'dumping') + end + + def structure_load(filename) + args = prepare_command_options + args.concat(['--execute', %{SET FOREIGN_KEY_CHECKS = 0; SOURCE #{filename}; SET FOREIGN_KEY_CHECKS = 1}]) + args.concat(["--database", "#{configuration['database']}"]) + + run_cmd('mysql', args, 'loading') + end + + private + + def configuration + @configuration + end + + def configuration_without_database + configuration.merge('database' => nil) + end + + def creation_options + Hash.new.tap do |options| + options[:charset] = configuration['encoding'] if configuration.include? 'encoding' + options[:collation] = configuration['collation'] if configuration.include? 'collation' + + # Set default charset only when collation isn't set. + options[:charset] ||= DEFAULT_CHARSET unless options[:collation] + + # Set default collation only when charset is also default. + options[:collation] ||= DEFAULT_COLLATION if options[:charset] == DEFAULT_CHARSET + end + end + + def error_class + if configuration['adapter'] =~ /jdbc/ + require 'active_record/railties/jdbcmysql_error' + ArJdbcMySQL::Error + elsif defined?(Mysql2) + Mysql2::Error + elsif defined?(Mysql) + Mysql::Error + else + StandardError + end + end + + def grant_statement + <<-SQL +GRANT ALL PRIVILEGES ON #{configuration['database']}.* + TO '#{configuration['username']}'@'localhost' +IDENTIFIED BY '#{configuration['password']}' WITH GRANT OPTION; + SQL + end + + def root_configuration_without_database + configuration_without_database.merge( + 'username' => 'root', + 'password' => root_password + ) + end + + def root_password + $stdout.print "Please provide the root password for your MySQL installation\n>" + $stdin.gets.strip + end + + def prepare_command_options + args = [] + args.concat(['--user', configuration['username']]) if configuration['username'] + args << "--password=#{configuration['password']}" if configuration['password'] + args.concat(['--default-character-set', configuration['encoding']]) if configuration['encoding'] + configuration.slice('host', 'port', 'socket').each do |k, v| + args.concat([ "--#{k}", v.to_s ]) if v + end + + args + end + + def run_cmd(cmd, args, action) + fail run_cmd_error(cmd, args, action) unless Kernel.system(cmd, *args) + end + + def run_cmd_error(cmd, args, action) + msg = "failed to execute:\n" + msg << "#{cmd}" + msg << "Please check the output above for any errors and make sure that `#{cmd}` is installed in your PATH and has proper permissions.\n\n" + msg + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/tasks/postgresql_database_tasks.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/tasks/postgresql_database_tasks.rb new file mode 100644 index 0000000..9edd2ba --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/tasks/postgresql_database_tasks.rb @@ -0,0 +1,101 @@ +module ActiveRecord + module Tasks # :nodoc: + class PostgreSQLDatabaseTasks # :nodoc: + DEFAULT_ENCODING = ENV['CHARSET'] || 'utf8' + + delegate :connection, :establish_connection, :clear_active_connections!, + to: ActiveRecord::Base + + def initialize(configuration) + @configuration = configuration + end + + def create(master_established = false) + establish_master_connection unless master_established + connection.create_database configuration['database'], + configuration.merge('encoding' => encoding) + establish_connection configuration + rescue ActiveRecord::StatementInvalid => error + if /database .* already exists/ === error.message + raise DatabaseAlreadyExists + else + raise + end + end + + def drop + establish_master_connection + connection.drop_database configuration['database'] + end + + def charset + connection.encoding + end + + def collation + connection.collation + end + + def purge + clear_active_connections! + drop + create true + end + + def structure_dump(filename) + set_psql_env + args = ['-s', '-x', '-O', '-f', filename] + search_path = configuration['schema_search_path'] + unless search_path.blank? + args += search_path.split(',').map do |part| + "--schema=#{part.strip}" + end + end + args << configuration['database'] + run_cmd('pg_dump', args, 'dumping') + File.open(filename, "a") { |f| f << "SET search_path TO #{connection.schema_search_path};\n\n" } + end + + def structure_load(filename) + set_psql_env + args = [ '-q', '-f', filename, configuration['database'] ] + run_cmd('psql', args, 'loading') + end + + private + + def configuration + @configuration + end + + def encoding + configuration['encoding'] || DEFAULT_ENCODING + end + + def establish_master_connection + establish_connection configuration.merge( + 'database' => 'postgres', + 'schema_search_path' => 'public' + ) + end + + def set_psql_env + ENV['PGHOST'] = configuration['host'] if configuration['host'] + ENV['PGPORT'] = configuration['port'].to_s if configuration['port'] + ENV['PGPASSWORD'] = configuration['password'].to_s if configuration['password'] + ENV['PGUSER'] = configuration['username'].to_s if configuration['username'] + end + + def run_cmd(cmd, args, action) + fail run_cmd_error(cmd, args, action) unless Kernel.system(cmd, *args) + end + + def run_cmd_error(cmd, args, action) + msg = "failed to execute:\n" + msg << "#{cmd} #{args.join(' ')}\n\n" + msg << "Please check the output above for any errors and make sure that `#{cmd}` is installed in your PATH and has proper permissions.\n\n" + msg + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/tasks/sqlite_database_tasks.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/tasks/sqlite_database_tasks.rb new file mode 100644 index 0000000..9ab64d0 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/tasks/sqlite_database_tasks.rb @@ -0,0 +1,55 @@ +module ActiveRecord + module Tasks # :nodoc: + class SQLiteDatabaseTasks # :nodoc: + delegate :connection, :establish_connection, to: ActiveRecord::Base + + def initialize(configuration, root = ActiveRecord::Tasks::DatabaseTasks.root) + @configuration, @root = configuration, root + end + + def create + raise DatabaseAlreadyExists if File.exist?(configuration['database']) + + establish_connection configuration + connection + end + + def drop + require 'pathname' + path = Pathname.new configuration['database'] + file = path.absolute? ? path.to_s : File.join(root, path) + + FileUtils.rm(file) if File.exist?(file) + end + + def purge + drop + create + end + + def charset + connection.encoding + end + + def structure_dump(filename) + dbfile = configuration['database'] + `sqlite3 #{dbfile} .schema > #{filename}` + end + + def structure_load(filename) + dbfile = configuration['database'] + `sqlite3 #{dbfile} < "#{filename}"` + end + + private + + def configuration + @configuration + end + + def root + @root + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/timestamp.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/timestamp.rb new file mode 100644 index 0000000..936a18d --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/timestamp.rb @@ -0,0 +1,121 @@ +module ActiveRecord + # = Active Record Timestamp + # + # Active Record automatically timestamps create and update operations if the + # table has fields named created_at/created_on or + # updated_at/updated_on. + # + # Timestamping can be turned off by setting: + # + # config.active_record.record_timestamps = false + # + # Timestamps are in UTC by default but you can use the local timezone by setting: + # + # config.active_record.default_timezone = :local + # + # == Time Zone aware attributes + # + # By default, ActiveRecord::Base keeps all the datetime columns time zone aware by executing following code. + # + # config.active_record.time_zone_aware_attributes = true + # + # This feature can easily be turned off by assigning value false . + # + # If your attributes are time zone aware and you desire to skip time zone conversion to the current Time.zone + # when reading certain attributes then you can do following: + # + # class Topic < ActiveRecord::Base + # self.skip_time_zone_conversion_for_attributes = [:written_on] + # end + module Timestamp + extend ActiveSupport::Concern + + included do + class_attribute :record_timestamps + self.record_timestamps = true + end + + def initialize_dup(other) # :nodoc: + super + clear_timestamp_attributes + end + + private + + def _create_record + if self.record_timestamps + current_time = current_time_from_proper_timezone + + all_timestamp_attributes.each do |column| + column = column.to_s + if has_attribute?(column) && !attribute_present?(column) + write_attribute(column, current_time) + end + end + end + + super + end + + def _update_record(*args) + if should_record_timestamps? + current_time = current_time_from_proper_timezone + + timestamp_attributes_for_update_in_model.each do |column| + column = column.to_s + next if attribute_changed?(column) + write_attribute(column, current_time) + end + end + super + end + + def should_record_timestamps? + self.record_timestamps && (!partial_writes? || changed?) + end + + def timestamp_attributes_for_create_in_model + timestamp_attributes_for_create.select { |c| self.class.column_names.include?(c.to_s) } + end + + def timestamp_attributes_for_update_in_model + timestamp_attributes_for_update.select { |c| self.class.column_names.include?(c.to_s) } + end + + def all_timestamp_attributes_in_model + timestamp_attributes_for_create_in_model + timestamp_attributes_for_update_in_model + end + + def timestamp_attributes_for_update + [:updated_at, :updated_on] + end + + def timestamp_attributes_for_create + [:created_at, :created_on] + end + + def all_timestamp_attributes + timestamp_attributes_for_create + timestamp_attributes_for_update + end + + def max_updated_column_timestamp(timestamp_names = timestamp_attributes_for_update) + timestamp_names + .map { |attr| self[attr] } + .compact + .map(&:to_time) + .max + end + + def current_time_from_proper_timezone + self.class.default_timezone == :utc ? Time.now.utc : Time.now + end + + # Clear attributes and changed_attributes + def clear_timestamp_attributes + all_timestamp_attributes_in_model.each do |attribute_name| + self[attribute_name] = nil + clear_attribute_changes([attribute_name]) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/transactions.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/transactions.rb new file mode 100644 index 0000000..574a2e6 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/transactions.rb @@ -0,0 +1,427 @@ +module ActiveRecord + # See ActiveRecord::Transactions::ClassMethods for documentation. + module Transactions + extend ActiveSupport::Concern + #:nodoc: + ACTIONS = [:create, :destroy, :update] + #:nodoc: + CALLBACK_WARN_MESSAGE = "Currently, Active Record suppresses errors raised " \ + "within `after_rollback`/`after_commit` callbacks and only print them to " \ + "the logs. In the next version, these errors will no longer be suppressed. " \ + "Instead, the errors will propagate normally just like in other Active " \ + "Record callbacks.\n" \ + "\n" \ + "You can opt into the new behavior and remove this warning by setting:\n" \ + "\n" \ + " config.active_record.raise_in_transactional_callbacks = true\n\n" + + included do + define_callbacks :commit, :rollback, + terminator: ->(_, result) { result == false }, + scope: [:kind, :name] + + mattr_accessor :raise_in_transactional_callbacks, instance_writer: false + self.raise_in_transactional_callbacks = false + end + + # = Active Record Transactions + # + # Transactions are protective blocks where SQL statements are only permanent + # if they can all succeed as one atomic action. The classic example is a + # transfer between two accounts where you can only have a deposit if the + # withdrawal succeeded and vice versa. Transactions enforce the integrity of + # the database and guard the data against program errors or database + # break-downs. So basically you should use transaction blocks whenever you + # have a number of statements that must be executed together or not at all. + # + # For example: + # + # ActiveRecord::Base.transaction do + # david.withdrawal(100) + # mary.deposit(100) + # end + # + # This example will only take money from David and give it to Mary if neither + # +withdrawal+ nor +deposit+ raise an exception. Exceptions will force a + # ROLLBACK that returns the database to the state before the transaction + # began. Be aware, though, that the objects will _not_ have their instance + # data returned to their pre-transactional state. + # + # == Different Active Record classes in a single transaction + # + # Though the transaction class method is called on some Active Record class, + # the objects within the transaction block need not all be instances of + # that class. This is because transactions are per-database connection, not + # per-model. + # + # In this example a +balance+ record is transactionally saved even + # though +transaction+ is called on the +Account+ class: + # + # Account.transaction do + # balance.save! + # account.save! + # end + # + # The +transaction+ method is also available as a model instance method. + # For example, you can also do this: + # + # balance.transaction do + # balance.save! + # account.save! + # end + # + # == Transactions are not distributed across database connections + # + # A transaction acts on a single database connection. If you have + # multiple class-specific databases, the transaction will not protect + # interaction among them. One workaround is to begin a transaction + # on each class whose models you alter: + # + # Student.transaction do + # Course.transaction do + # course.enroll(student) + # student.units += course.units + # end + # end + # + # This is a poor solution, but fully distributed transactions are beyond + # the scope of Active Record. + # + # == +save+ and +destroy+ are automatically wrapped in a transaction + # + # Both +save+ and +destroy+ come wrapped in a transaction that ensures + # that whatever you do in validations or callbacks will happen under its + # protected cover. So you can use validations to check for values that + # the transaction depends on or you can raise exceptions in the callbacks + # to rollback, including after_* callbacks. + # + # As a consequence changes to the database are not seen outside your connection + # until the operation is complete. For example, if you try to update the index + # of a search engine in +after_save+ the indexer won't see the updated record. + # The +after_commit+ callback is the only one that is triggered once the update + # is committed. See below. + # + # == Exception handling and rolling back + # + # Also have in mind that exceptions thrown within a transaction block will + # be propagated (after triggering the ROLLBACK), so you should be ready to + # catch those in your application code. + # + # One exception is the ActiveRecord::Rollback exception, which will trigger + # a ROLLBACK when raised, but not be re-raised by the transaction block. + # + # *Warning*: one should not catch ActiveRecord::StatementInvalid exceptions + # inside a transaction block. ActiveRecord::StatementInvalid exceptions indicate that an + # error occurred at the database level, for example when a unique constraint + # is violated. On some database systems, such as PostgreSQL, database errors + # inside a transaction cause the entire transaction to become unusable + # until it's restarted from the beginning. Here is an example which + # demonstrates the problem: + # + # # Suppose that we have a Number model with a unique column called 'i'. + # Number.transaction do + # Number.create(i: 0) + # begin + # # This will raise a unique constraint error... + # Number.create(i: 0) + # rescue ActiveRecord::StatementInvalid + # # ...which we ignore. + # end + # + # # On PostgreSQL, the transaction is now unusable. The following + # # statement will cause a PostgreSQL error, even though the unique + # # constraint is no longer violated: + # Number.create(i: 1) + # # => "PGError: ERROR: current transaction is aborted, commands + # # ignored until end of transaction block" + # end + # + # One should restart the entire transaction if an + # ActiveRecord::StatementInvalid occurred. + # + # == Nested transactions + # + # +transaction+ calls can be nested. By default, this makes all database + # statements in the nested transaction block become part of the parent + # transaction. For example, the following behavior may be surprising: + # + # User.transaction do + # User.create(username: 'Kotori') + # User.transaction do + # User.create(username: 'Nemu') + # raise ActiveRecord::Rollback + # end + # end + # + # creates both "Kotori" and "Nemu". Reason is the ActiveRecord::Rollback + # exception in the nested block does not issue a ROLLBACK. Since these exceptions + # are captured in transaction blocks, the parent block does not see it and the + # real transaction is committed. + # + # In order to get a ROLLBACK for the nested transaction you may ask for a real + # sub-transaction by passing requires_new: true. If anything goes wrong, + # the database rolls back to the beginning of the sub-transaction without rolling + # back the parent transaction. If we add it to the previous example: + # + # User.transaction do + # User.create(username: 'Kotori') + # User.transaction(requires_new: true) do + # User.create(username: 'Nemu') + # raise ActiveRecord::Rollback + # end + # end + # + # only "Kotori" is created. This works on MySQL and PostgreSQL. SQLite3 version >= '3.6.8' also supports it. + # + # Most databases don't support true nested transactions. At the time of + # writing, the only database that we're aware of that supports true nested + # transactions, is MS-SQL. Because of this, Active Record emulates nested + # transactions by using savepoints on MySQL and PostgreSQL. See + # http://dev.mysql.com/doc/refman/5.6/en/savepoint.html + # for more information about savepoints. + # + # === Callbacks + # + # There are two types of callbacks associated with committing and rolling back transactions: + # +after_commit+ and +after_rollback+. + # + # +after_commit+ callbacks are called on every record saved or destroyed within a + # transaction immediately after the transaction is committed. +after_rollback+ callbacks + # are called on every record saved or destroyed within a transaction immediately after the + # transaction or savepoint is rolled back. + # + # These callbacks are useful for interacting with other systems since you will be guaranteed + # that the callback is only executed when the database is in a permanent state. For example, + # +after_commit+ is a good spot to put in a hook to clearing a cache since clearing it from + # within a transaction could trigger the cache to be regenerated before the database is updated. + # + # === Caveats + # + # If you're on MySQL, then do not use DDL operations in nested transactions + # blocks that are emulated with savepoints. That is, do not execute statements + # like 'CREATE TABLE' inside such blocks. This is because MySQL automatically + # releases all savepoints upon executing a DDL operation. When +transaction+ + # is finished and tries to release the savepoint it created earlier, a + # database error will occur because the savepoint has already been + # automatically released. The following example demonstrates the problem: + # + # Model.connection.transaction do # BEGIN + # Model.connection.transaction(requires_new: true) do # CREATE SAVEPOINT active_record_1 + # Model.connection.create_table(...) # active_record_1 now automatically released + # end # RELEASE savepoint active_record_1 + # # ^^^^ BOOM! database error! + # end + # + # Note that "TRUNCATE" is also a MySQL DDL statement! + module ClassMethods + # See ActiveRecord::Transactions::ClassMethods for detailed documentation. + def transaction(options = {}, &block) + # See the ConnectionAdapters::DatabaseStatements#transaction API docs. + connection.transaction(options, &block) + end + + # This callback is called after a record has been created, updated, or destroyed. + # + # You can specify that the callback should only be fired by a certain action with + # the +:on+ option: + # + # after_commit :do_foo, on: :create + # after_commit :do_bar, on: :update + # after_commit :do_baz, on: :destroy + # + # after_commit :do_foo_bar, on: [:create, :update] + # after_commit :do_bar_baz, on: [:update, :destroy] + # + # Note that transactional fixtures do not play well with this feature. Please + # use the +test_after_commit+ gem to have these hooks fired in tests. + def after_commit(*args, &block) + set_options_for_callbacks!(args) + set_callback(:commit, :after, *args, &block) + unless ActiveRecord::Base.raise_in_transactional_callbacks + ActiveSupport::Deprecation.warn(CALLBACK_WARN_MESSAGE) + end + end + + # This callback is called after a create, update, or destroy are rolled back. + # + # Please check the documentation of +after_commit+ for options. + def after_rollback(*args, &block) + set_options_for_callbacks!(args) + set_callback(:rollback, :after, *args, &block) + unless ActiveRecord::Base.raise_in_transactional_callbacks + ActiveSupport::Deprecation.warn(CALLBACK_WARN_MESSAGE) + end + end + + private + + def set_options_for_callbacks!(args) + options = args.last + if options.is_a?(Hash) && options[:on] + fire_on = Array(options[:on]) + assert_valid_transaction_action(fire_on) + options[:if] = Array(options[:if]) + options[:if] << "transaction_include_any_action?(#{fire_on})" + end + end + + def assert_valid_transaction_action(actions) + if (actions - ACTIONS).any? + raise ArgumentError, ":on conditions for after_commit and after_rollback callbacks have to be one of #{ACTIONS}" + end + end + end + + # See ActiveRecord::Transactions::ClassMethods for detailed documentation. + def transaction(options = {}, &block) + self.class.transaction(options, &block) + end + + def destroy #:nodoc: + with_transaction_returning_status { super } + end + + def save(*) #:nodoc: + rollback_active_record_state! do + with_transaction_returning_status { super } + end + end + + def save!(*) #:nodoc: + with_transaction_returning_status { super } + end + + def touch(*) #:nodoc: + with_transaction_returning_status { super } + end + + # Reset id and @new_record if the transaction rolls back. + def rollback_active_record_state! + remember_transaction_record_state + yield + rescue Exception + restore_transaction_record_state + raise + ensure + clear_transaction_record_state + end + + # Call the +after_commit+ callbacks. + # + # Ensure that it is not called if the object was never persisted (failed create), + # but call it after the commit of a destroyed object. + def committed!(should_run_callbacks = true) #:nodoc: + _run_commit_callbacks if should_run_callbacks && destroyed? || persisted? + ensure + force_clear_transaction_record_state + end + + # Call the +after_rollback+ callbacks. The +force_restore_state+ argument indicates if the record + # state should be rolled back to the beginning or just to the last savepoint. + def rolledback!(force_restore_state = false, should_run_callbacks = true) #:nodoc: + _run_rollback_callbacks if should_run_callbacks + ensure + restore_transaction_record_state(force_restore_state) + clear_transaction_record_state + end + + # Add the record to the current transaction so that the +after_rollback+ and +after_commit+ callbacks + # can be called. + def add_to_transaction + if has_transactional_callbacks? + self.class.connection.add_transaction_record(self) + else + sync_with_transaction_state + set_transaction_state(self.class.connection.transaction_state) + end + remember_transaction_record_state + end + + # Executes +method+ within a transaction and captures its return value as a + # status flag. If the status is true the transaction is committed, otherwise + # a ROLLBACK is issued. In any case the status flag is returned. + # + # This method is available within the context of an ActiveRecord::Base + # instance. + def with_transaction_returning_status + status = nil + self.class.transaction do + add_to_transaction + begin + status = yield + rescue ActiveRecord::Rollback + clear_transaction_record_state + status = nil + end + + raise ActiveRecord::Rollback unless status + end + status + ensure + if @transaction_state && @transaction_state.committed? + clear_transaction_record_state + end + end + + protected + + # Save the new record state and id of a record so it can be restored later if a transaction fails. + def remember_transaction_record_state #:nodoc: + @_start_transaction_state[:id] = id + @_start_transaction_state.reverse_merge!( + new_record: @new_record, + destroyed: @destroyed, + frozen?: frozen?, + ) + @_start_transaction_state[:level] = (@_start_transaction_state[:level] || 0) + 1 + end + + # Clear the new record state and id of a record. + def clear_transaction_record_state #:nodoc: + @_start_transaction_state[:level] = (@_start_transaction_state[:level] || 0) - 1 + force_clear_transaction_record_state if @_start_transaction_state[:level] < 1 + end + + # Force to clear the transaction record state. + def force_clear_transaction_record_state #:nodoc: + @_start_transaction_state.clear + end + + # Restore the new record state and id of a record that was previously saved by a call to save_record_state. + def restore_transaction_record_state(force = false) #:nodoc: + unless @_start_transaction_state.empty? + transaction_level = (@_start_transaction_state[:level] || 0) - 1 + if transaction_level < 1 || force + restore_state = @_start_transaction_state + thaw + @new_record = restore_state[:new_record] + @destroyed = restore_state[:destroyed] + pk = self.class.primary_key + if pk && read_attribute(pk) != restore_state[:id] + write_attribute(pk, restore_state[:id]) + end + freeze if restore_state[:frozen?] + end + end + end + + # Determine if a record was created or destroyed in a transaction. State should be one of :new_record or :destroyed. + def transaction_record_state(state) #:nodoc: + @_start_transaction_state[state] + end + + # Determine if a transaction included an action for :create, :update, or :destroy. Used in filtering callbacks. + def transaction_include_any_action?(actions) #:nodoc: + actions.any? do |action| + case action + when :create + transaction_record_state(:new_record) + when :destroy + destroyed? + when :update + !(transaction_record_state(:new_record) || destroyed?) + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/translation.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/translation.rb new file mode 100644 index 0000000..ddcb5f2 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/translation.rb @@ -0,0 +1,22 @@ +module ActiveRecord + module Translation + include ActiveModel::Translation + + # Set the lookup ancestors for ActiveModel. + def lookup_ancestors #:nodoc: + klass = self + classes = [klass] + return classes if klass == ActiveRecord::Base + + while klass != klass.base_class + classes << klass = klass.superclass + end + classes + end + + # Set the i18n scope to overwrite ActiveModel. + def i18n_scope #:nodoc: + :activerecord + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type.rb new file mode 100644 index 0000000..250e8d5 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type.rb @@ -0,0 +1,23 @@ +require 'active_record/type/decorator' +require 'active_record/type/mutable' +require 'active_record/type/numeric' +require 'active_record/type/time_value' +require 'active_record/type/value' + +require 'active_record/type/big_integer' +require 'active_record/type/binary' +require 'active_record/type/boolean' +require 'active_record/type/date' +require 'active_record/type/date_time' +require 'active_record/type/decimal' +require 'active_record/type/decimal_without_scale' +require 'active_record/type/float' +require 'active_record/type/integer' +require 'active_record/type/serialized' +require 'active_record/type/string' +require 'active_record/type/text' +require 'active_record/type/time' +require 'active_record/type/unsigned_integer' + +require 'active_record/type/type_map' +require 'active_record/type/hash_lookup_type_map' diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/big_integer.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/big_integer.rb new file mode 100644 index 0000000..0c72d89 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/big_integer.rb @@ -0,0 +1,13 @@ +require 'active_record/type/integer' + +module ActiveRecord + module Type + class BigInteger < Integer # :nodoc: + private + + def max_value + ::Float::INFINITY + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/binary.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/binary.rb new file mode 100644 index 0000000..005a48e --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/binary.rb @@ -0,0 +1,50 @@ +module ActiveRecord + module Type + class Binary < Value # :nodoc: + def type + :binary + end + + def binary? + true + end + + def type_cast(value) + if value.is_a?(Data) + value.to_s + else + super + end + end + + def type_cast_for_database(value) + return if value.nil? + Data.new(super) + end + + def changed_in_place?(raw_old_value, value) + old_value = type_cast_from_database(raw_old_value) + old_value != value + end + + class Data # :nodoc: + def initialize(value) + @value = value.to_s + end + + def to_s + @value + end + alias_method :to_str, :to_s + + def hex + @value.unpack('H*')[0] + end + + def ==(other) + other == to_s || super + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/boolean.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/boolean.rb new file mode 100644 index 0000000..799b2e9 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/boolean.rb @@ -0,0 +1,31 @@ +module ActiveRecord + module Type + class Boolean < Value # :nodoc: + def type + :boolean + end + + private + + def cast_value(value) + if value == '' + nil + elsif ConnectionAdapters::Column::TRUE_VALUES.include?(value) + true + else + if !ConnectionAdapters::Column::FALSE_VALUES.include?(value) + ActiveSupport::Deprecation.warn(<<-MSG.squish) + You attempted to assign a value which is not explicitly `true` or `false` + (#{value.inspect}) + to a boolean column. Currently this value casts to `false`. This will + change to match Ruby's semantics, and will cast to `true` in Rails 5. + If you would like to maintain the current behavior, you should + explicitly handle the values you would like cast to `false`. + MSG + end + false + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/date.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/date.rb new file mode 100644 index 0000000..d90a606 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/date.rb @@ -0,0 +1,46 @@ +module ActiveRecord + module Type + class Date < Value # :nodoc: + def type + :date + end + + def klass + ::Date + end + + def type_cast_for_schema(value) + "'#{value.to_s(:db)}'" + end + + private + + def cast_value(value) + if value.is_a?(::String) + return if value.empty? + fast_string_to_date(value) || fallback_string_to_date(value) + elsif value.respond_to?(:to_date) + value.to_date + else + value + end + end + + def fast_string_to_date(string) + if string =~ ConnectionAdapters::Column::Format::ISO_DATE + new_date $1.to_i, $2.to_i, $3.to_i + end + end + + def fallback_string_to_date(string) + new_date(*::Date._parse(string, false).values_at(:year, :mon, :mday)) + end + + def new_date(year, mon, mday) + if year && year != 0 + ::Date.new(year, mon, mday) rescue nil + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/date_time.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/date_time.rb new file mode 100644 index 0000000..fadd707 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/date_time.rb @@ -0,0 +1,54 @@ +module ActiveRecord + module Type + class DateTime < Value # :nodoc: + include TimeValue + + def type + :datetime + end + + def type_cast_for_database(value) + return super unless value.acts_like?(:time) + + zone_conversion_method = ActiveRecord::Base.default_timezone == :utc ? :getutc : :getlocal + + if value.respond_to?(zone_conversion_method) + value = value.send(zone_conversion_method) + end + + return value unless has_precision? + + result = value.to_s(:db) + if value.respond_to?(:usec) && (1..6).cover?(precision) + "#{result}.#{sprintf("%0#{precision}d", value.usec / 10 ** (6 - precision))}" + else + result + end + end + + private + + alias has_precision? precision + + def cast_value(string) + return string unless string.is_a?(::String) + return if string.empty? + + fast_string_to_time(string) || fallback_string_to_time(string) + end + + # '0.123456' -> 123456 + # '1.123456' -> 123456 + def microseconds(time) + time[:sec_fraction] ? (time[:sec_fraction] * 1_000_000).to_i : 0 + end + + def fallback_string_to_time(string) + time_hash = ::Date._parse(string) + time_hash[:sec_fraction] = microseconds(time_hash) + + new_time(*time_hash.values_at(:year, :mon, :mday, :hour, :min, :sec, :sec_fraction, :offset)) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/decimal.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/decimal.rb new file mode 100644 index 0000000..30443c6 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/decimal.rb @@ -0,0 +1,50 @@ +module ActiveRecord + module Type + class Decimal < Value # :nodoc: + include Numeric + + def type + :decimal + end + + def type_cast_for_schema(value) + value.to_s + end + + private + + def cast_value(value) + casted_value = case value + when ::Float + convert_float_to_big_decimal(value) + when ::Numeric, ::String + BigDecimal(value, precision.to_i) + else + if value.respond_to?(:to_d) + value.to_d + else + cast_value(value.to_s) + end + end + + scale ? casted_value.round(scale) : casted_value + end + + def convert_float_to_big_decimal(value) + if precision + BigDecimal(value, float_precision) + else + value.to_d + end + end + + def float_precision + if precision.to_i > ::Float::DIG + 1 + ::Float::DIG + 1 + else + precision.to_i + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/decimal_without_scale.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/decimal_without_scale.rb new file mode 100644 index 0000000..ff5559e --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/decimal_without_scale.rb @@ -0,0 +1,11 @@ +require 'active_record/type/big_integer' + +module ActiveRecord + module Type + class DecimalWithoutScale < BigInteger # :nodoc: + def type + :decimal + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/decorator.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/decorator.rb new file mode 100644 index 0000000..9fce38e --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/decorator.rb @@ -0,0 +1,14 @@ +module ActiveRecord + module Type + module Decorator # :nodoc: + def init_with(coder) + @subtype = coder['subtype'] + __setobj__(@subtype) + end + + def encode_with(coder) + coder['subtype'] = __getobj__ + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/float.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/float.rb new file mode 100644 index 0000000..42eb44b --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/float.rb @@ -0,0 +1,19 @@ +module ActiveRecord + module Type + class Float < Value # :nodoc: + include Numeric + + def type + :float + end + + alias type_cast_for_database type_cast + + private + + def cast_value(value) + value.to_f + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/hash_lookup_type_map.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/hash_lookup_type_map.rb new file mode 100644 index 0000000..3b01e3f --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/hash_lookup_type_map.rb @@ -0,0 +1,23 @@ +module ActiveRecord + module Type + class HashLookupTypeMap < TypeMap # :nodoc: + def alias_type(type, alias_type) + register_type(type) { |_, *args| lookup(alias_type, *args) } + end + + def key?(key) + @mapping.key?(key) + end + + def keys + @mapping.keys + end + + private + + def perform_fetch(type, *args, &block) + @mapping.fetch(type, block).call(type, *args) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/integer.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/integer.rb new file mode 100644 index 0000000..493af4e --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/integer.rb @@ -0,0 +1,59 @@ +module ActiveRecord + module Type + class Integer < Value # :nodoc: + include Numeric + + def initialize(*) + super + @range = min_value...max_value + end + + def type + :integer + end + + def type_cast_from_database(value) + return if value.nil? + value.to_i + end + + def type_cast_for_database(value) + result = type_cast(value) + if result + ensure_in_range(result) + end + result + end + + protected + + attr_reader :range + + private + + def cast_value(value) + case value + when true then 1 + when false then 0 + else + value.to_i rescue nil + end + end + + def ensure_in_range(value) + unless range.cover?(value) + raise RangeError, "#{value} is out of range for #{self.class} with limit #{limit || 4}" + end + end + + def max_value + limit = self.limit || 4 + 1 << (limit * 8 - 1) # 8 bits per byte with one bit for sign + end + + def min_value + -max_value + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/mutable.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/mutable.rb new file mode 100644 index 0000000..066617e --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/mutable.rb @@ -0,0 +1,16 @@ +module ActiveRecord + module Type + module Mutable # :nodoc: + def type_cast_from_user(value) + type_cast_from_database(type_cast_for_database(value)) + end + + # +raw_old_value+ will be the `_before_type_cast` version of the + # value (likely a string). +new_value+ will be the current, type + # cast value. + def changed_in_place?(raw_old_value, new_value) + raw_old_value != type_cast_for_database(new_value) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/numeric.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/numeric.rb new file mode 100644 index 0000000..674f996 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/numeric.rb @@ -0,0 +1,36 @@ +module ActiveRecord + module Type + module Numeric # :nodoc: + def number? + true + end + + def type_cast(value) + value = case value + when true then 1 + when false then 0 + when ::String then value.presence + else value + end + super(value) + end + + def changed?(old_value, _new_value, new_value_before_type_cast) # :nodoc: + super || number_to_non_number?(old_value, new_value_before_type_cast) + end + + private + + def number_to_non_number?(old_value, new_value_before_type_cast) + old_value != nil && non_numeric_string?(new_value_before_type_cast) + end + + def non_numeric_string?(value) + # 'wibble'.to_i will give zero, we want to make sure + # that we aren't marking int zero to string zero as + # changed. + value.to_s !~ /\A-?\d+\.?\d*\z/ + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/serialized.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/serialized.rb new file mode 100644 index 0000000..e7dffd4 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/serialized.rb @@ -0,0 +1,62 @@ +module ActiveRecord + module Type + class Serialized < DelegateClass(Type::Value) # :nodoc: + include Mutable + include Decorator + + attr_reader :subtype, :coder + + def initialize(subtype, coder) + @subtype = subtype + @coder = coder + super(subtype) + end + + def type_cast_from_database(value) + if default_value?(value) + value + else + coder.load(super) + end + end + + def type_cast_for_database(value) + return if value.nil? + unless default_value?(value) + super coder.dump(value) + end + end + + def inspect + Kernel.instance_method(:inspect).bind(self).call + end + + def changed_in_place?(raw_old_value, value) + return false if value.nil? + raw_new_value = type_cast_for_database(value) + raw_old_value.nil? != raw_new_value.nil? || + subtype.changed_in_place?(raw_old_value, raw_new_value) + end + + def accessor + ActiveRecord::Store::IndifferentHashAccessor + end + + def init_with(coder) + @coder = coder['coder'] + super + end + + def encode_with(coder) + coder['coder'] = @coder + super + end + + private + + def default_value?(value) + value == coder.load(nil) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/string.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/string.rb new file mode 100644 index 0000000..cf95e25 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/string.rb @@ -0,0 +1,40 @@ +module ActiveRecord + module Type + class String < Value # :nodoc: + def type + :string + end + + def changed_in_place?(raw_old_value, new_value) + if new_value.is_a?(::String) + raw_old_value != new_value + end + end + + def type_cast_for_database(value) + case value + when ::Numeric, ActiveSupport::Duration then value.to_s + when ::String then ::String.new(value) + when true then "t" + when false then "f" + else super + end + end + + def text? + true + end + + private + + def cast_value(value) + case value + when true then "t" + when false then "f" + # String.new is slightly faster than dup + else ::String.new(value.to_s) + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/text.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/text.rb new file mode 100644 index 0000000..26f980f --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/text.rb @@ -0,0 +1,11 @@ +require 'active_record/type/string' + +module ActiveRecord + module Type + class Text < String # :nodoc: + def type + :text + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/time.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/time.rb new file mode 100644 index 0000000..41f7d97 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/time.rb @@ -0,0 +1,26 @@ +module ActiveRecord + module Type + class Time < Value # :nodoc: + include TimeValue + + def type + :time + end + + private + + def cast_value(value) + return value unless value.is_a?(::String) + return if value.empty? + + dummy_time_value = "2000-01-01 #{value}" + + fast_string_to_time(dummy_time_value) || begin + time_hash = ::Date._parse(dummy_time_value) + return if time_hash[:hour].nil? + new_time(*time_hash.values_at(:year, :mon, :mday, :hour, :min, :sec, :sec_fraction)) + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/time_value.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/time_value.rb new file mode 100644 index 0000000..d611d72 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/time_value.rb @@ -0,0 +1,38 @@ +module ActiveRecord + module Type + module TimeValue # :nodoc: + def klass + ::Time + end + + def type_cast_for_schema(value) + "'#{value.to_s(:db)}'" + end + + private + + def new_time(year, mon, mday, hour, min, sec, microsec, offset = nil) + # Treat 0000-00-00 00:00:00 as nil. + return if year.nil? || (year == 0 && mon == 0 && mday == 0) + + if offset + time = ::Time.utc(year, mon, mday, hour, min, sec, microsec) rescue nil + return unless time + + time -= offset + Base.default_timezone == :utc ? time : time.getlocal + else + ::Time.public_send(Base.default_timezone, year, mon, mday, hour, min, sec, microsec) rescue nil + end + end + + # Doesn't handle time zones. + def fast_string_to_time(string) + if string =~ ConnectionAdapters::Column::Format::ISO_DATETIME + microsec = ($7.to_r * 1_000_000).to_i + new_time $1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, $6.to_i, microsec + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/type_map.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/type_map.rb new file mode 100644 index 0000000..09f5ba6 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/type_map.rb @@ -0,0 +1,64 @@ +require 'thread_safe' + +module ActiveRecord + module Type + class TypeMap # :nodoc: + def initialize + @mapping = {} + @cache = ThreadSafe::Cache.new do |h, key| + h.fetch_or_store(key, ThreadSafe::Cache.new) + end + end + + def lookup(lookup_key, *args) + fetch(lookup_key, *args) { default_value } + end + + def fetch(lookup_key, *args, &block) + @cache[lookup_key].fetch_or_store(args) do + perform_fetch(lookup_key, *args, &block) + end + end + + def register_type(key, value = nil, &block) + raise ::ArgumentError unless value || block + @cache.clear + + if block + @mapping[key] = block + else + @mapping[key] = proc { value } + end + end + + def alias_type(key, target_key) + register_type(key) do |sql_type, *args| + metadata = sql_type[/\(.*\)/, 0] + lookup("#{target_key}#{metadata}", *args) + end + end + + def clear + @mapping.clear + end + + private + + def perform_fetch(lookup_key, *args) + matching_pair = @mapping.reverse_each.detect do |key, _| + key === lookup_key + end + + if matching_pair + matching_pair.last.call(lookup_key, *args) + else + yield lookup_key, *args + end + end + + def default_value + @default_value ||= Value.new + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/unsigned_integer.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/unsigned_integer.rb new file mode 100644 index 0000000..ed3e527 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/unsigned_integer.rb @@ -0,0 +1,15 @@ +module ActiveRecord + module Type + class UnsignedInteger < Integer # :nodoc: + private + + def max_value + super * 2 + end + + def min_value + 0 + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/value.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/value.rb new file mode 100644 index 0000000..ff99dbc --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/type/value.rb @@ -0,0 +1,105 @@ +module ActiveRecord + module Type + class Value # :nodoc: + attr_reader :precision, :scale, :limit + + # Valid options are +precision+, +scale+, and +limit+. They are only + # used when dumping schema. + def initialize(options = {}) + options.assert_valid_keys(:precision, :scale, :limit) + @precision = options[:precision] + @scale = options[:scale] + @limit = options[:limit] + end + + # The simplified type that this object represents. Returns a symbol such + # as +:string+ or +:integer+ + def type; end + + # Type casts a string from the database into the appropriate ruby type. + # Classes which do not need separate type casting behavior for database + # and user provided values should override +cast_value+ instead. + def type_cast_from_database(value) + type_cast(value) + end + + # Type casts a value from user input (e.g. from a setter). This value may + # be a string from the form builder, or an already type cast value + # provided manually to a setter. + # + # Classes which do not need separate type casting behavior for database + # and user provided values should override +type_cast+ or +cast_value+ + # instead. + def type_cast_from_user(value) + type_cast(value) + end + + # Cast a value from the ruby type to a type that the database knows how + # to understand. The returned value from this method should be a + # +String+, +Numeric+, +Date+, +Time+, +Symbol+, +true+, +false+, or + # +nil+ + def type_cast_for_database(value) + value + end + + # Type cast a value for schema dumping. This method is private, as we are + # hoping to remove it entirely. + def type_cast_for_schema(value) # :nodoc: + value.inspect + end + + # These predicates are not documented, as I need to look further into + # their use, and see if they can be removed entirely. + def text? # :nodoc: + false + end + + def number? # :nodoc: + false + end + + def binary? # :nodoc: + false + end + + def klass # :nodoc: + end + + # Determines whether a value has changed for dirty checking. +old_value+ + # and +new_value+ will always be type-cast. Types should not need to + # override this method. + def changed?(old_value, new_value, _new_value_before_type_cast) + old_value != new_value + end + + # Determines whether the mutable value has been modified since it was + # read. Returns +false+ by default. This method should not be overridden + # directly. Types which return a mutable value should include + # +Type::Mutable+, which will define this method. + def changed_in_place?(*) + false + end + + def ==(other) + self.class == other.class && + precision == other.precision && + scale == other.scale && + limit == other.limit + end + + private + + def type_cast(value) + cast_value(value) unless value.nil? + end + + # Convenience method for types which do not need separate type casting + # behavior for user and database inputs. Called by + # `type_cast_from_database` and `type_cast_from_user` for all values + # except `nil`. + def cast_value(value) # :doc: + value + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/validations.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/validations.rb new file mode 100644 index 0000000..a6c8ff7 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/validations.rb @@ -0,0 +1,90 @@ +module ActiveRecord + # = Active Record RecordInvalid + # + # Raised by save! and create! when the record is invalid. Use the + # +record+ method to retrieve the record which did not validate. + # + # begin + # complex_operation_that_internally_calls_save! + # rescue ActiveRecord::RecordInvalid => invalid + # puts invalid.record.errors + # end + class RecordInvalid < ActiveRecordError + attr_reader :record + + def initialize(record) + @record = record + errors = @record.errors.full_messages.join(", ") + super(I18n.t(:"#{@record.class.i18n_scope}.errors.messages.record_invalid", :errors => errors, :default => :"errors.messages.record_invalid")) + end + end + + # = Active Record Validations + # + # Active Record includes the majority of its validations from ActiveModel::Validations + # all of which accept the :on argument to define the context where the + # validations are active. Active Record will always supply either the context of + # :create or :update dependent on whether the model is a + # new_record?. + module Validations + extend ActiveSupport::Concern + include ActiveModel::Validations + + # The validation process on save can be skipped by passing validate: false. + # The regular Base#save method is replaced with this when the validations + # module is mixed in, which it is by default. + def save(options={}) + perform_validations(options) ? super : false + end + + # Attempts to save the record just like Base#save but will raise a +RecordInvalid+ + # exception instead of returning +false+ if the record is not valid. + def save!(options={}) + perform_validations(options) ? super : raise_record_invalid + end + + # Runs all the validations within the specified context. Returns +true+ if + # no errors are found, +false+ otherwise. + # + # Aliased as validate. + # + # If the argument is +false+ (default is +nil+), the context is set to :create if + # new_record? is +true+, and to :update if it is not. + # + # Validations with no :on option will run no matter the context. Validations with + # some :on option will only run in the specified context. + def valid?(context = nil) + context ||= (new_record? ? :create : :update) + output = super(context) + errors.empty? && output + end + + alias_method :validate, :valid? + + # Runs all the validations within the specified context. Returns +true+ if + # no errors are found, raises +RecordInvalid+ otherwise. + # + # If the argument is +false+ (default is +nil+), the context is set to :create if + # new_record? is +true+, and to :update if it is not. + # + # Validations with no :on option will run no matter the context. Validations with + # some :on option will only run in the specified context. + def validate!(context = nil) + valid?(context) || raise_record_invalid + end + + protected + + def raise_record_invalid + raise(RecordInvalid.new(self)) + end + + def perform_validations(options={}) # :nodoc: + options[:validate] == false || valid?(options[:context]) + end + end +end + +require "active_record/validations/associated" +require "active_record/validations/uniqueness" +require "active_record/validations/presence" diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/validations/associated.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/validations/associated.rb new file mode 100644 index 0000000..47ccef3 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/validations/associated.rb @@ -0,0 +1,51 @@ +module ActiveRecord + module Validations + class AssociatedValidator < ActiveModel::EachValidator #:nodoc: + def validate_each(record, attribute, value) + if Array.wrap(value).reject {|r| r.marked_for_destruction? || r.valid?}.any? + record.errors.add(attribute, :invalid, options.merge(:value => value)) + end + end + end + + module ClassMethods + # Validates whether the associated object or objects are all valid. + # Works with any kind of association. + # + # class Book < ActiveRecord::Base + # has_many :pages + # belongs_to :library + # + # validates_associated :pages, :library + # end + # + # WARNING: This validation must not be used on both ends of an association. + # Doing so will lead to a circular dependency and cause infinite recursion. + # + # NOTE: This validation will not fail if the association hasn't been + # assigned. If you want to ensure that the association is both present and + # guaranteed to be valid, you also need to use +validates_presence_of+. + # + # Configuration options: + # + # * :message - A custom error message (default is: "is invalid"). + # * :on - Specifies the contexts where this validation is active. + # Runs in all validation contexts by default (nil). You can pass a symbol + # or an array of symbols. (e.g. on: :create or + # on: :custom_validation_context or + # on: [:create, :custom_validation_context]) + # * :if - Specifies a method, proc or string to call to determine + # if the validation should occur (e.g. if: :allow_validation, + # or if: Proc.new { |user| user.signup_step > 2 }). The method, + # proc or string should return or evaluate to a +true+ or +false+ value. + # * :unless - Specifies a method, proc or string to call to + # determine if the validation should not occur (e.g. unless: :skip_validation, + # or unless: Proc.new { |user| user.signup_step <= 2 }). The + # method, proc or string should return or evaluate to a +true+ or +false+ + # value. + def validates_associated(*attr_names) + validates_with AssociatedValidator, _merge_attributes(attr_names) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/validations/presence.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/validations/presence.rb new file mode 100644 index 0000000..c7aa814 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/validations/presence.rb @@ -0,0 +1,67 @@ +module ActiveRecord + module Validations + class PresenceValidator < ActiveModel::Validations::PresenceValidator # :nodoc: + def validate(record) + super + attributes.each do |attribute| + next unless record.class._reflect_on_association(attribute) + associated_records = Array.wrap(record.send(attribute)) + + # Superclass validates presence. Ensure present records aren't about to be destroyed. + if associated_records.present? && associated_records.all? { |r| r.marked_for_destruction? } + record.errors.add(attribute, :blank, options) + end + end + end + end + + module ClassMethods + # Validates that the specified attributes are not blank (as defined by + # Object#blank?), and, if the attribute is an association, that the + # associated object is not marked for destruction. Happens by default + # on save. + # + # class Person < ActiveRecord::Base + # has_one :face + # validates_presence_of :face + # end + # + # The face attribute must be in the object and it cannot be blank or marked + # for destruction. + # + # If you want to validate the presence of a boolean field (where the real values + # are true and false), you will want to use + # validates_inclusion_of :field_name, in: [true, false]. + # + # This is due to the way Object#blank? handles boolean values: + # false.blank? # => true. + # + # This validator defers to the ActiveModel validation for presence, adding the + # check to see that an associated object is not marked for destruction. This + # prevents the parent object from validating successfully and saving, which then + # deletes the associated object, thus putting the parent object into an invalid + # state. + # + # Configuration options: + # * :message - A custom error message (default is: "can't be blank"). + # * :on - Specifies the contexts where this validation is active. + # Runs in all validation contexts by default (nil). You can pass a symbol + # or an array of symbols. (e.g. on: :create or + # on: :custom_validation_context or + # on: [:create, :custom_validation_context]) + # * :if - Specifies a method, proc or string to call to determine if + # the validation should occur (e.g. if: :allow_validation, or + # if: Proc.new { |user| user.signup_step > 2 }). The method, proc + # or string should return or evaluate to a +true+ or +false+ value. + # * :unless - Specifies a method, proc or string to call to determine + # if the validation should not occur (e.g. unless: :skip_validation, + # or unless: Proc.new { |user| user.signup_step <= 2 }). The method, + # proc or string should return or evaluate to a +true+ or +false+ value. + # * :strict - Specifies whether validation should be strict. + # See ActiveModel::Validation#validates! for more information. + def validates_presence_of(*attr_names) + validates_with PresenceValidator, _merge_attributes(attr_names) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/validations/uniqueness.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/validations/uniqueness.rb new file mode 100644 index 0000000..ce09967 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/validations/uniqueness.rb @@ -0,0 +1,239 @@ +module ActiveRecord + module Validations + class UniquenessValidator < ActiveModel::EachValidator # :nodoc: + def initialize(options) + if options[:conditions] && !options[:conditions].respond_to?(:call) + raise ArgumentError, "#{options[:conditions]} was passed as :conditions but is not callable. " \ + "Pass a callable instead: `conditions: -> { where(approved: true) }`" + end + super({ case_sensitive: true }.merge!(options)) + @klass = options[:class] + end + + def validate_each(record, attribute, value) + finder_class = find_finder_class_for(record) + table = finder_class.arel_table + value = map_enum_attribute(finder_class, attribute, value) + + begin + relation = build_relation(finder_class, table, attribute, value) + if record.persisted? + if finder_class.primary_key + relation = relation.and(table[finder_class.primary_key.to_sym].not_eq(record.id)) + else + raise UnknownPrimaryKey.new(finder_class, "Can not validate uniqueness for persisted record without primary key.") + end + end + relation = scope_relation(record, table, relation) + relation = finder_class.unscoped.where(relation) + relation = relation.merge(options[:conditions]) if options[:conditions] + rescue RangeError + relation = finder_class.none + end + + if relation.exists? + error_options = options.except(:case_sensitive, :scope, :conditions) + error_options[:value] = value + + record.errors.add(attribute, :taken, error_options) + end + end + + protected + # The check for an existing value should be run from a class that + # isn't abstract. This means working down from the current class + # (self), to the first non-abstract class. Since classes don't know + # their subclasses, we have to build the hierarchy between self and + # the record's class. + def find_finder_class_for(record) #:nodoc: + class_hierarchy = [record.class] + + while class_hierarchy.first != @klass + class_hierarchy.unshift(class_hierarchy.first.superclass) + end + + class_hierarchy.detect { |klass| !klass.abstract_class? } + end + + def build_relation(klass, table, attribute, value) #:nodoc: + if reflection = klass._reflect_on_association(attribute) + attribute = reflection.foreign_key + value = value.attributes[reflection.klass.primary_key] unless value.nil? + end + + attribute_name = attribute.to_s + + # the attribute may be an aliased attribute + if klass.attribute_aliases[attribute_name] + attribute = klass.attribute_aliases[attribute_name] + attribute_name = attribute.to_s + end + + column = klass.columns_hash[attribute_name] + value = klass.connection.type_cast(value, column) + if value.is_a?(String) && column.limit + value = value.to_s[0, column.limit] + end + + if !options[:case_sensitive] && value && column.text? + # will use SQL LOWER function before comparison, unless it detects a case insensitive collation + klass.connection.case_insensitive_comparison(table, attribute, column, value) + else + klass.connection.case_sensitive_comparison(table, attribute, column, value) + end + end + + def scope_relation(record, table, relation) + Array(options[:scope]).each do |scope_item| + if reflection = record.class._reflect_on_association(scope_item) + scope_value = record.send(reflection.foreign_key) + scope_item = reflection.foreign_key + else + scope_value = record._read_attribute(scope_item) + end + relation = relation.and(table[scope_item].eq(scope_value)) + end + + relation + end + + def map_enum_attribute(klass, attribute, value) + mapping = klass.defined_enums[attribute.to_s] + value = mapping[value] if value && mapping + value + end + end + + module ClassMethods + # Validates whether the value of the specified attributes are unique + # across the system. Useful for making sure that only one user + # can be named "davidhh". + # + # class Person < ActiveRecord::Base + # validates_uniqueness_of :user_name + # end + # + # It can also validate whether the value of the specified attributes are + # unique based on a :scope parameter: + # + # class Person < ActiveRecord::Base + # validates_uniqueness_of :user_name, scope: :account_id + # end + # + # Or even multiple scope parameters. For example, making sure that a + # teacher can only be on the schedule once per semester for a particular + # class. + # + # class TeacherSchedule < ActiveRecord::Base + # validates_uniqueness_of :teacher_id, scope: [:semester_id, :class_id] + # end + # + # It is also possible to limit the uniqueness constraint to a set of + # records matching certain conditions. In this example archived articles + # are not being taken into consideration when validating uniqueness + # of the title attribute: + # + # class Article < ActiveRecord::Base + # validates_uniqueness_of :title, conditions: -> { where.not(status: 'archived') } + # end + # + # When the record is created, a check is performed to make sure that no + # record exists in the database with the given value for the specified + # attribute (that maps to a column). When the record is updated, + # the same check is made but disregarding the record itself. + # + # Configuration options: + # + # * :message - Specifies a custom error message (default is: + # "has already been taken"). + # * :scope - One or more columns by which to limit the scope of + # the uniqueness constraint. + # * :conditions - Specify the conditions to be included as a + # WHERE SQL fragment to limit the uniqueness constraint lookup + # (e.g. conditions: -> { where(status: 'active') }). + # * :case_sensitive - Looks for an exact match. Ignored by + # non-text columns (+true+ by default). + # * :allow_nil - If set to +true+, skips this validation if the + # attribute is +nil+ (default is +false+). + # * :allow_blank - If set to +true+, skips this validation if the + # attribute is blank (default is +false+). + # * :if - Specifies a method, proc or string to call to determine + # if the validation should occur (e.g. if: :allow_validation, + # or if: Proc.new { |user| user.signup_step > 2 }). The method, + # proc or string should return or evaluate to a +true+ or +false+ value. + # * :unless - Specifies a method, proc or string to call to + # determine if the validation should not occur (e.g. unless: :skip_validation, + # or unless: Proc.new { |user| user.signup_step <= 2 }). The + # method, proc or string should return or evaluate to a +true+ or +false+ + # value. + # + # === Concurrency and integrity + # + # Using this validation method in conjunction with ActiveRecord::Base#save + # does not guarantee the absence of duplicate record insertions, because + # uniqueness checks on the application level are inherently prone to race + # conditions. For example, suppose that two users try to post a Comment at + # the same time, and a Comment's title must be unique. At the database-level, + # the actions performed by these users could be interleaved in the following manner: + # + # User 1 | User 2 + # ------------------------------------+-------------------------------------- + # # User 1 checks whether there's | + # # already a comment with the title | + # # 'My Post'. This is not the case. | + # SELECT * FROM comments | + # WHERE title = 'My Post' | + # | + # | # User 2 does the same thing and also + # | # infers that their title is unique. + # | SELECT * FROM comments + # | WHERE title = 'My Post' + # | + # # User 1 inserts their comment. | + # INSERT INTO comments | + # (title, content) VALUES | + # ('My Post', 'hi!') | + # | + # | # User 2 does the same thing. + # | INSERT INTO comments + # | (title, content) VALUES + # | ('My Post', 'hello!') + # | + # | # ^^^^^^ + # | # Boom! We now have a duplicate + # | # title! + # + # This could even happen if you use transactions with the 'serializable' + # isolation level. The best way to work around this problem is to add a unique + # index to the database table using + # ActiveRecord::ConnectionAdapters::SchemaStatements#add_index. In the + # rare case that a race condition occurs, the database will guarantee + # the field's uniqueness. + # + # When the database catches such a duplicate insertion, + # ActiveRecord::Base#save will raise an ActiveRecord::StatementInvalid + # exception. You can either choose to let this error propagate (which + # will result in the default Rails exception page being shown), or you + # can catch it and restart the transaction (e.g. by telling the user + # that the title already exists, and asking them to re-enter the title). + # This technique is also known as + # {optimistic concurrency control}[http://en.wikipedia.org/wiki/Optimistic_concurrency_control]. + # + # The bundled ActiveRecord::ConnectionAdapters distinguish unique index + # constraint errors from other types of database errors by throwing an + # ActiveRecord::RecordNotUnique exception. For other adapters you will + # have to parse the (database-specific) exception message to detect such + # a case. + # + # The following bundled adapters throw the ActiveRecord::RecordNotUnique exception: + # + # * ActiveRecord::ConnectionAdapters::MysqlAdapter. + # * ActiveRecord::ConnectionAdapters::Mysql2Adapter. + # * ActiveRecord::ConnectionAdapters::SQLite3Adapter. + # * ActiveRecord::ConnectionAdapters::PostgreSQLAdapter. + def validates_uniqueness_of(*attr_names) + validates_with UniquenessValidator, _merge_attributes(attr_names) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/version.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/version.rb new file mode 100644 index 0000000..cf76a13 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/version.rb @@ -0,0 +1,8 @@ +require_relative 'gem_version' + +module ActiveRecord + # Returns the version of the currently loaded ActiveRecord as a Gem::Version + def self.version + gem_version + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/rails/generators/active_record.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/rails/generators/active_record.rb new file mode 100644 index 0000000..dc29213 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/rails/generators/active_record.rb @@ -0,0 +1,17 @@ +require 'rails/generators/named_base' +require 'rails/generators/active_model' +require 'rails/generators/active_record/migration' +require 'active_record' + +module ActiveRecord + module Generators # :nodoc: + class Base < Rails::Generators::NamedBase # :nodoc: + include ActiveRecord::Generators::Migration + + # Set the current directory as base for the inherited generators. + def self.base_root + File.dirname(__FILE__) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/rails/generators/active_record/migration.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/rails/generators/active_record/migration.rb new file mode 100644 index 0000000..b7418cf --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/rails/generators/active_record/migration.rb @@ -0,0 +1,18 @@ +require 'rails/generators/migration' + +module ActiveRecord + module Generators # :nodoc: + module Migration + extend ActiveSupport::Concern + include Rails::Generators::Migration + + module ClassMethods + # Implement the required interface for Rails::Generators::Migration. + def next_migration_number(dirname) + next_migration_number = current_migration_number(dirname) + 1 + ActiveRecord::Migration.next_migration_number(next_migration_number) + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/rails/generators/active_record/migration/migration_generator.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/rails/generators/active_record/migration/migration_generator.rb new file mode 100644 index 0000000..7a3c6f5 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/rails/generators/active_record/migration/migration_generator.rb @@ -0,0 +1,70 @@ +require 'rails/generators/active_record' + +module ActiveRecord + module Generators # :nodoc: + class MigrationGenerator < Base # :nodoc: + argument :attributes, :type => :array, :default => [], :banner => "field[:type][:index] field[:type][:index]" + + def create_migration_file + set_local_assigns! + validate_file_name! + migration_template @migration_template, "db/migrate/#{file_name}.rb" + end + + protected + attr_reader :migration_action, :join_tables + + # sets the default migration template that is being used for the generation of the migration + # depending on the arguments which would be sent out in the command line, the migration template + # and the table name instance variables are setup. + + def set_local_assigns! + @migration_template = "migration.rb" + case file_name + when /^(add|remove)_.*_(?:to|from)_(.*)/ + @migration_action = $1 + @table_name = normalize_table_name($2) + when /join_table/ + if attributes.length == 2 + @migration_action = 'join' + @join_tables = pluralize_table_names? ? attributes.map(&:plural_name) : attributes.map(&:singular_name) + + set_index_names + end + when /^create_(.+)/ + @table_name = normalize_table_name($1) + @migration_template = "create_table_migration.rb" + end + end + + def set_index_names + attributes.each_with_index do |attr, i| + attr.index_name = [attr, attributes[i - 1]].map{ |a| index_name_for(a) } + end + end + + def index_name_for(attribute) + if attribute.foreign_key? + attribute.name + else + attribute.name.singularize.foreign_key + end.to_sym + end + + private + def attributes_with_index + attributes.select { |a| !a.reference? && a.has_index? } + end + + def validate_file_name! + unless file_name =~ /^[_a-z0-9]+$/ + raise IllegalMigrationNameError.new(file_name) + end + end + + def normalize_table_name(_table_name) + pluralize_table_names? ? _table_name.pluralize : _table_name.singularize + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/rails/generators/active_record/migration/templates/create_table_migration.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/rails/generators/active_record/migration/templates/create_table_migration.rb new file mode 100644 index 0000000..f7bf698 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/rails/generators/active_record/migration/templates/create_table_migration.rb @@ -0,0 +1,19 @@ +class <%= migration_class_name %> < ActiveRecord::Migration + def change + create_table :<%= table_name %> do |t| +<% attributes.each do |attribute| -%> +<% if attribute.password_digest? -%> + t.string :password_digest<%= attribute.inject_options %> +<% else -%> + t.<%= attribute.type %> :<%= attribute.name %><%= attribute.inject_options %> +<% end -%> +<% end -%> +<% if options[:timestamps] %> + t.timestamps null: false +<% end -%> + end +<% attributes_with_index.each do |attribute| -%> + add_index :<%= table_name %>, :<%= attribute.index_name %><%= attribute.inject_index_options %> +<% end -%> + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/rails/generators/active_record/migration/templates/migration.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/rails/generators/active_record/migration/templates/migration.rb new file mode 100644 index 0000000..ae9c74f --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/rails/generators/active_record/migration/templates/migration.rb @@ -0,0 +1,39 @@ +class <%= migration_class_name %> < ActiveRecord::Migration +<%- if migration_action == 'add' -%> + def change +<% attributes.each do |attribute| -%> + <%- if attribute.reference? -%> + add_reference :<%= table_name %>, :<%= attribute.name %><%= attribute.inject_options %> + <%- else -%> + add_column :<%= table_name %>, :<%= attribute.name %>, :<%= attribute.type %><%= attribute.inject_options %> + <%- if attribute.has_index? -%> + add_index :<%= table_name %>, :<%= attribute.index_name %><%= attribute.inject_index_options %> + <%- end -%> + <%- end -%> +<%- end -%> + end +<%- elsif migration_action == 'join' -%> + def change + create_join_table :<%= join_tables.first %>, :<%= join_tables.second %> do |t| + <%- attributes.each do |attribute| -%> + <%= '# ' unless attribute.has_index? -%>t.index <%= attribute.index_name %><%= attribute.inject_index_options %> + <%- end -%> + end + end +<%- else -%> + def change +<% attributes.each do |attribute| -%> +<%- if migration_action -%> + <%- if attribute.reference? -%> + remove_reference :<%= table_name %>, :<%= attribute.name %><%= attribute.inject_options %> + <%- else -%> + <%- if attribute.has_index? -%> + remove_index :<%= table_name %>, :<%= attribute.index_name %><%= attribute.inject_index_options %> + <%- end -%> + remove_column :<%= table_name %>, :<%= attribute.name %>, :<%= attribute.type %><%= attribute.inject_options %> + <%- end -%> +<%- end -%> +<%- end -%> + end +<%- end -%> +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/rails/generators/active_record/model/model_generator.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/rails/generators/active_record/model/model_generator.rb new file mode 100644 index 0000000..7e8d68c --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/rails/generators/active_record/model/model_generator.rb @@ -0,0 +1,52 @@ +require 'rails/generators/active_record' + +module ActiveRecord + module Generators # :nodoc: + class ModelGenerator < Base # :nodoc: + argument :attributes, :type => :array, :default => [], :banner => "field[:type][:index] field[:type][:index]" + + check_class_collision + + class_option :migration, :type => :boolean + class_option :timestamps, :type => :boolean + class_option :parent, :type => :string, :desc => "The parent class for the generated model" + class_option :indexes, :type => :boolean, :default => true, :desc => "Add indexes for references and belongs_to columns" + + + # creates the migration file for the model. + + def create_migration_file + return unless options[:migration] && options[:parent].nil? + attributes.each { |a| a.attr_options.delete(:index) if a.reference? && !a.has_index? } if options[:indexes] == false + migration_template "../../migration/templates/create_table_migration.rb", "db/migrate/create_#{table_name}.rb" + end + + def create_model_file + template 'model.rb', File.join('app/models', class_path, "#{file_name}.rb") + end + + def create_module_file + return if regular_class_path.empty? + template 'module.rb', File.join('app/models', "#{class_path.join('/')}.rb") if behavior == :invoke + end + + def attributes_with_index + attributes.select { |a| !a.reference? && a.has_index? } + end + + def accessible_attributes + attributes.reject(&:reference?) + end + + hook_for :test_framework + + protected + + # Used by the migration template to determine the parent name of the model + def parent_class_name + options[:parent] || "ActiveRecord::Base" + end + + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/rails/generators/active_record/model/templates/model.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/rails/generators/active_record/model/templates/model.rb new file mode 100644 index 0000000..539d969 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/rails/generators/active_record/model/templates/model.rb @@ -0,0 +1,10 @@ +<% module_namespacing do -%> +class <%= class_name %> < <%= parent_class_name.classify %> +<% attributes.select(&:reference?).each do |attribute| -%> + belongs_to :<%= attribute.name %><%= ', polymorphic: true' if attribute.polymorphic? %><%= ', required: true' if attribute.required? %> +<% end -%> +<% if attributes.any?(&:password_digest?) -%> + has_secure_password +<% end -%> +end +<% end -%> diff --git a/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/rails/generators/active_record/model/templates/module.rb b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/rails/generators/active_record/model/templates/module.rb new file mode 100644 index 0000000..a3bf1c3 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.6/lib/rails/generators/active_record/model/templates/module.rb @@ -0,0 +1,7 @@ +<% module_namespacing do -%> +module <%= class_path.map(&:camelize).join('::') %> + def self.table_name_prefix + '<%= namespaced? ? namespaced_class_path.join('_') : class_path.join('_') %>_' + end +end +<% end -%> diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/CHANGELOG.md b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/CHANGELOG.md new file mode 100644 index 0000000..0bcb987 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/CHANGELOG.md @@ -0,0 +1,503 @@ +## Rails 4.2.6 (March 07, 2016) ## + +* No changes. + + +## Rails 4.2.5.2 (February 26, 2016) ## + +* No changes. + + +## Rails 4.2.5.1 (January 25, 2015) ## + +* No changes. + + +## Rails 4.2.5 (November 12, 2015) ## + +* Fix `TimeWithZone#eql?` to properly handle `TimeWithZone` created from `DateTime`: + twz = DateTime.now.in_time_zone + twz.eql?(twz.dup) => true + + Fixes #14178. + + *Roque Pinel* + +* Handle invalid UTF-8 characters in `MessageVerifier.verify`. + + *Roque Pinel*, *Grey Baker* + + +## Rails 4.2.4 (August 24, 2015) ## + +* Fix a `SystemStackError` when encoding an `Enumerable` with `json` gem and + with the Active Support JSON encoder loaded. + + Fixes #20775. + + *Sammy Larbi*, *Prathamesh Sonpatki* + +* Fix not calling `#default` on `HashWithIndifferentAcess#to_hash` when only + `default_proc` is set, which could raise. + + *Simon Eskildsen* + +* Fix setting `default_proc` on `HashWithIndifferentAccess#dup` + + *Simon Eskildsen* + + +## Rails 4.2.3 (June 25, 2015) ## + +* Fix a range of values for parameters of the Time#change + + *Nikolay Kondratyev* + +* Add some missing `require 'active_support/deprecation'` + + *Akira Matsuda* + + +## Rails 4.2.2 (June 16, 2015) ## + +* Fix XSS vulnerability in `ActiveSupport::JSON.encode` method. + + CVE-2015-3226. + + *Rafael Mendonça França* + +* Fix denial of service vulnerability in the XML processing. + + CVE-2015-3227. + + *Aaron Patterson* + + +## Rails 4.2.1 (March 19, 2015) ## + +* Fixed a problem where String#truncate_words would get stuck with a complex + string. + + *Henrik Nygren* + +* Fixed a roundtrip problem with AS::SafeBuffer where primitive-like strings + will be dumped as primitives: + + Before: + + YAML.load ActiveSupport::SafeBuffer.new("Hello").to_yaml # => "Hello" + YAML.load ActiveSupport::SafeBuffer.new("true").to_yaml # => true + YAML.load ActiveSupport::SafeBuffer.new("false").to_yaml # => false + YAML.load ActiveSupport::SafeBuffer.new("1").to_yaml # => 1 + YAML.load ActiveSupport::SafeBuffer.new("1.1").to_yaml # => 1.1 + + After: + + YAML.load ActiveSupport::SafeBuffer.new("Hello").to_yaml # => "Hello" + YAML.load ActiveSupport::SafeBuffer.new("true").to_yaml # => "true" + YAML.load ActiveSupport::SafeBuffer.new("false").to_yaml # => "false" + YAML.load ActiveSupport::SafeBuffer.new("1").to_yaml # => "1" + YAML.load ActiveSupport::SafeBuffer.new("1.1").to_yaml # => "1.1" + + *Godfrey Chan* + +* Replace fixed `:en` with `I18n.default_locale` in `Duration#inspect`. + + *Dominik Masur* + +* Add missing time zone definitions for Russian Federation and sync them + with `zone.tab` file from tzdata version 2014j (latest). + + *Andrey Novikov* + + +## Rails 4.2.0 (December 20, 2014) ## + +* The decorated `load` and `require` methods are now kept private. + + Fixes #17553. + + *Xavier Noria* + +* `String#remove` and `String#remove!` accept multiple arguments. + + *Pavel Pravosud* + +* `TimeWithZone#strftime` now delegates every directive to `Time#strftime` except for '%Z', + it also now correctly handles escaped '%' characters placed just before time zone related directives. + + *Pablo Herrero* + +* Corrected `Inflector#underscore` handling of multiple successive acroynms. + + *James Le Cuirot* + +* Delegation now works with ruby reserved words passed to `:to` option. + + Fixes #16956. + + *Agis Anastasopoulos* + +* Added method `#eql?` to `ActiveSupport::Duration`, in addition to `#==`. + + Currently, the following returns `false`, contrary to expectation: + + 1.minute.eql?(1.minute) + + Adding method `#eql?` will make this behave like expected. Method `#eql?` is + just a bit stricter than `#==`, as it checks whether the argument is also a duration. Their + parts may be different though. + + 1.minute.eql?(60.seconds) # => true + 1.minute.eql?(60) # => false + + *Joost Lubach* + +* `Time#change` can now change nanoseconds (`:nsec`) as a higher-precision + alternative to microseconds (`:usec`). + + *Agis Anastasooulos* + +* `MessageVerifier.new` raises an appropriate exception if the secret is `nil`. + This prevents `MessageVerifier#generate` from raising a cryptic error later on. + + *Kostiantyn Kahanskyi* + +* Introduced new configuration option `active_support.test_order` for + specifying the order in which test cases are executed. This option currently defaults + to `:sorted` but will be changed to `:random` in Rails 5.0. + + *Akira Matsuda*, *Godfrey Chan* + +* Fixed a bug in `Inflector#underscore` where acroynms in nested constant names + are incorrectly parsed as camelCase. + + Fixes #8015. + + *Fred Wu*, *Matthew Draper* + +* Make `Time#change` throw an exception if the `:usec` option is out of range and + the time has an offset other than UTC or local. + + *Agis Anastasopoulos* + +* `Method` objects now report themselves as not `duplicable?`. This allows + hashes and arrays containing `Method` objects to be `deep_dup`ed. + + *Peter Jaros* + +* `determine_constant_from_test_name` does no longer shadow `NameError`s + which happens during constant autoloading. + + Fixes #9933. + + *Guo Xiang Tan* + +* Added instance_eval version to Object#try and Object#try!, so you can do this: + + person.try { name.first } + + instead of: + + person.try { |person| person.name.first } + + *DHH*, *Ari Pollak* + +* Fix the `ActiveSupport::Duration#instance_of?` method to return the right + value with the class itself since it was previously delegated to the + internal value. + + *Robin Dupret* + +* Fix rounding errors with `#travel_to` by resetting the usec on any passed time to zero, so we only travel + with per-second precision, not anything deeper than that. + + *DHH* + +* Fix DateTime comparison with `DateTime::Infinity` object. + + *Rafael Mendonça França* + +* Added Object#itself which returns the object itself. Useful when dealing with a chaining scenario, like Active Record scopes: + + Event.public_send(state.presence_in([ :trashed, :drafted ]) || :itself).order(:created_at) + + *DHH* + +* `Object#with_options` executes block in merging option context when + explicit receiver in not passed. + + *Pavel Pravosud* + +* Fixed a compatibility issue with the `Oj` gem when cherry-picking the file + `active_support/core_ext/object/json` without requiring `active_support/json`. + + Fixes #16131. + + *Godfrey Chan* + +* Make `Hash#with_indifferent_access` copy the default proc too. + + *arthurnn*, *Xanders* + +* Add `String#truncate_words` to truncate a string by a number of words. + + *Mohamed Osama* + +* Deprecate `capture` and `quietly`. + + These methods are not thread safe and may cause issues when used in threaded environments. + To avoid problems we are deprecating them. + + *Tom Meier* + +* `DateTime#to_f` now preserves the fractional seconds instead of always + rounding to `.0`. + + Fixes #15994. + + *John Paul Ashenfelter* + +* Add `Hash#transform_values` to simplify a common pattern where the values of a + hash must change, but the keys are left the same. + + *Sean Griffin* + +* Always instrument `ActiveSupport::Cache`. + + Since `ActiveSupport::Notifications` only instruments items when there + are attached subscribers, we don't need to disable instrumentation. + + *Peter Wagenet* + +* Make the `apply_inflections` method case-insensitive when checking + whether a word is uncountable or not. + + *Robin Dupret* + +* Make Dependencies pass a name to NameError error. + + *arthurnn* + +* Fixed `ActiveSupport::Cache::FileStore` exploding with long paths. + + *Adam Panzer*, *Michael Grosser* + +* Fixed `ActiveSupport::TimeWithZone#-` so precision is not unnecessarily lost + when working with objects with a nanosecond component. + + `ActiveSupport::TimeWithZone#-` should return the same result as if we were + using `Time#-`: + + Time.now.end_of_day - Time.now.beginning_of_day # => 86399.999999999 + + Before: + + Time.zone.now.end_of_day.nsec # => 999999999 + Time.zone.now.end_of_day - Time.zone.now.beginning_of_day # => 86400.0 + + After: + + Time.zone.now.end_of_day - Time.zone.now.beginning_of_day + # => 86399.999999999 + + *Gordon Chan* + +* Fixed precision error in NumberHelper when using Rationals. + + Before: + + ActiveSupport::NumberHelper.number_to_rounded Rational(1000, 3), precision: 2 + # => "330.00" + + After: + + ActiveSupport::NumberHelper.number_to_rounded Rational(1000, 3), precision: 2 + # => "333.33" + + See #15379. + + *Juanjo Bazán* + +* Removed deprecated `Numeric#ago` and friends + + Replacements: + + 5.ago => 5.seconds.ago + 5.until => 5.seconds.until + 5.since => 5.seconds.since + 5.from_now => 5.seconds.from_now + + See #12389 for the history and rationale behind this. + + *Godfrey Chan* + +* DateTime `advance` now supports partial days. + + Before: + + DateTime.now.advance(days: 1, hours: 12) + + After: + + DateTime.now.advance(days: 1.5) + + Fixes #12005. + + *Shay Davidson* + +* `Hash#deep_transform_keys` and `Hash#deep_transform_keys!` now transform hashes + in nested arrays. This change also applies to `Hash#deep_stringify_keys`, + `Hash#deep_stringify_keys!`, `Hash#deep_symbolize_keys` and + `Hash#deep_symbolize_keys!`. + + *OZAWA Sakuro* + +* Fixed confusing `DelegationError` in `Module#delegate`. + + See #15186. + + *Vladimir Yarotsky* + +* Fixed `ActiveSupport::Subscriber` so that no duplicate subscriber is created + when a subscriber method is redefined. + + *Dennis Schön* + +* Remove deprecated string based terminators for `ActiveSupport::Callbacks`. + + *Eileen M. Uchitelle* + +* Fixed an issue when using + `ActiveSupport::NumberHelper::NumberToDelimitedConverter` to + convert a value that is an `ActiveSupport::SafeBuffer` introduced + in 2da9d67. + + See #15064. + + *Mark J. Titorenko* + +* `TimeZone#parse` defaults the day of the month to '1' if any other date + components are specified. This is more consistent with the behavior of + `Time#parse`. + + *Ulysse Carion* + +* `humanize` strips leading underscores, if any. + + Before: + + '_id'.humanize # => "" + + After: + + '_id'.humanize # => "Id" + + *Xavier Noria* + +* Fixed backward compatibility issues introduced in 326e652. + + Empty Hash or Array should not be present in serialization result. + + {a: []}.to_query # => "" + {a: {}}.to_query # => "" + + For more info see #14948. + + *Bogdan Gusiev* + +* Add `Digest::UUID::uuid_v3` and `Digest::UUID::uuid_v5` to support stable + UUID fixtures on PostgreSQL. + + *Roderick van Domburg* + +* Fixed `ActiveSupport::Duration#eql?` so that `1.second.eql?(1.second)` is + true. + + This fixes the current situation of: + + 1.second.eql?(1.second) # => false + + `eql?` also requires that the other object is an `ActiveSupport::Duration`. + This requirement makes `ActiveSupport::Duration`'s behavior consistent with + the behavior of Ruby's numeric types: + + 1.eql?(1.0) # => false + 1.0.eql?(1) # => false + + 1.second.eql?(1) # => false (was true) + 1.eql?(1.second) # => false + + { 1 => "foo", 1.0 => "bar" } + # => { 1 => "foo", 1.0 => "bar" } + + { 1 => "foo", 1.second => "bar" } + # now => { 1 => "foo", 1.second => "bar" } + # was => { 1 => "bar" } + + And though the behavior of these hasn't changed, for reference: + + 1 == 1.0 # => true + 1.0 == 1 # => true + + 1 == 1.second # => true + 1.second == 1 # => true + + *Emily Dobervich* + +* `ActiveSupport::SafeBuffer#prepend` acts like `String#prepend` and modifies + instance in-place, returning self. `ActiveSupport::SafeBuffer#prepend!` is + deprecated. + + *Pavel Pravosud* + +* `HashWithIndifferentAccess` better respects `#to_hash` on objects it + receives. In particular, `.new`, `#update`, `#merge`, and `#replace` accept + objects which respond to `#to_hash`, even if those objects are not hashes + directly. + + *Peter Jaros* + +* Deprecate `Class#superclass_delegating_accessor`, use `Class#class_attribute` instead. + + *Akshay Vishnoi* + +* Ensure classes which `include Enumerable` get `#to_json` in addition to + `#as_json`. + + *Sammy Larbi* + +* Change the signature of `fetch_multi` to return a hash rather than an + array. This makes it consistent with the output of `read_multi`. + + *Parker Selbert* + +* Introduce `Concern#class_methods` as a sleek alternative to clunky + `module ClassMethods`. Add `Kernel#concern` to define at the toplevel + without chunky `module Foo; extend ActiveSupport::Concern` boilerplate. + + # app/models/concerns/authentication.rb + concern :Authentication do + included do + after_create :generate_private_key + end + + class_methods do + def authenticate(credentials) + # ... + end + end + + def generate_private_key + # ... + end + end + + # app/models/user.rb + class User < ActiveRecord::Base + include Authentication + end + + *Jeremy Kemper* + +Please check [4-1-stable](https://github.com/rails/rails/blob/4-1-stable/activesupport/CHANGELOG.md) for previous changes. diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/MIT-LICENSE b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/MIT-LICENSE new file mode 100644 index 0000000..d06d4f3 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/MIT-LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2005-2014 David Heinemeier Hansson + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/README.rdoc b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/README.rdoc new file mode 100644 index 0000000..015cd81 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/README.rdoc @@ -0,0 +1,40 @@ += Active Support -- Utility classes and Ruby extensions from Rails + +Active Support is a collection of utility classes and standard library +extensions that were found useful for the Rails framework. These additions +reside in this package so they can be loaded as needed in Ruby projects +outside of Rails. + + +== Download and installation + +The latest version of Active Support can be installed with RubyGems: + + % [sudo] gem install activesupport + +Source code can be downloaded as part of the Rails project on GitHub: + +* https://github.com/rails/rails/tree/4-2-stable/activesupport + + +== License + +Active Support is released under the MIT license: + +* http://www.opensource.org/licenses/MIT + + +== Support + +API documentation is at: + +* http://api.rubyonrails.org + +Bug reports can be filed for the Ruby on Rails project here: + +* https://github.com/rails/rails/issues + +Feature requests should be discussed on the rails-core mailing list here: + +* https://groups.google.com/forum/?fromgroups#!forum/rubyonrails-core + diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support.rb new file mode 100644 index 0000000..34040e9 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support.rb @@ -0,0 +1,85 @@ +#-- +# Copyright (c) 2005-2014 David Heinemeier Hansson +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +#++ + +require 'securerandom' +require "active_support/dependencies/autoload" +require "active_support/version" +require "active_support/logger" +require "active_support/lazy_load_hooks" + +module ActiveSupport + extend ActiveSupport::Autoload + + autoload :Concern + autoload :Dependencies + autoload :DescendantsTracker + autoload :FileUpdateChecker + autoload :LogSubscriber + autoload :Notifications + + eager_autoload do + autoload :BacktraceCleaner + autoload :ProxyObject + autoload :Benchmarkable + autoload :Cache + autoload :Callbacks + autoload :Configurable + autoload :Deprecation + autoload :Gzip + autoload :Inflector + autoload :JSON + autoload :KeyGenerator + autoload :MessageEncryptor + autoload :MessageVerifier + autoload :Multibyte + autoload :NumberHelper + autoload :OptionMerger + autoload :OrderedHash + autoload :OrderedOptions + autoload :StringInquirer + autoload :TaggedLogging + autoload :XmlMini + end + + autoload :Rescuable + autoload :SafeBuffer, "active_support/core_ext/string/output_safety" + autoload :TestCase + + def self.eager_load! + super + + NumberHelper.eager_load! + end + + @@test_order = nil + + def self.test_order=(new_order) # :nodoc: + @@test_order = new_order + end + + def self.test_order # :nodoc: + @@test_order + end +end + +autoload :I18n, "active_support/i18n" diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/all.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/all.rb new file mode 100644 index 0000000..f537818 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/all.rb @@ -0,0 +1,3 @@ +require 'active_support' +require 'active_support/time' +require 'active_support/core_ext' diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/backtrace_cleaner.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/backtrace_cleaner.rb new file mode 100644 index 0000000..d06f22a --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/backtrace_cleaner.rb @@ -0,0 +1,103 @@ +module ActiveSupport + # Backtraces often include many lines that are not relevant for the context + # under review. This makes it hard to find the signal amongst the backtrace + # noise, and adds debugging time. With a BacktraceCleaner, filters and + # silencers are used to remove the noisy lines, so that only the most relevant + # lines remain. + # + # Filters are used to modify lines of data, while silencers are used to remove + # lines entirely. The typical filter use case is to remove lengthy path + # information from the start of each line, and view file paths relevant to the + # app directory instead of the file system root. The typical silencer use case + # is to exclude the output of a noisy library from the backtrace, so that you + # can focus on the rest. + # + # bc = BacktraceCleaner.new + # bc.add_filter { |line| line.gsub(Rails.root.to_s, '') } # strip the Rails.root prefix + # bc.add_silencer { |line| line =~ /mongrel|rubygems/ } # skip any lines from mongrel or rubygems + # bc.clean(exception.backtrace) # perform the cleanup + # + # To reconfigure an existing BacktraceCleaner (like the default one in Rails) + # and show as much data as possible, you can always call + # BacktraceCleaner#remove_silencers!, which will restore the + # backtrace to a pristine state. If you need to reconfigure an existing + # BacktraceCleaner so that it does not filter or modify the paths of any lines + # of the backtrace, you can call BacktraceCleaner#remove_filters! + # These two methods will give you a completely untouched backtrace. + # + # Inspired by the Quiet Backtrace gem by Thoughtbot. + class BacktraceCleaner + def initialize + @filters, @silencers = [], [] + end + + # Returns the backtrace after all filters and silencers have been run + # against it. Filters run first, then silencers. + def clean(backtrace, kind = :silent) + filtered = filter_backtrace(backtrace) + + case kind + when :silent + silence(filtered) + when :noise + noise(filtered) + else + filtered + end + end + alias :filter :clean + + # Adds a filter from the block provided. Each line in the backtrace will be + # mapped against this filter. + # + # # Will turn "/my/rails/root/app/models/person.rb" into "/app/models/person.rb" + # backtrace_cleaner.add_filter { |line| line.gsub(Rails.root, '') } + def add_filter(&block) + @filters << block + end + + # Adds a silencer from the block provided. If the silencer returns +true+ + # for a given line, it will be excluded from the clean backtrace. + # + # # Will reject all lines that include the word "mongrel", like "/gems/mongrel/server.rb" or "/app/my_mongrel_server/rb" + # backtrace_cleaner.add_silencer { |line| line =~ /mongrel/ } + def add_silencer(&block) + @silencers << block + end + + # Removes all silencers, but leaves in the filters. Useful if your + # context of debugging suddenly expands as you suspect a bug in one of + # the libraries you use. + def remove_silencers! + @silencers = [] + end + + # Removes all filters, but leaves in the silencers. Useful if you suddenly + # need to see entire filepaths in the backtrace that you had already + # filtered out. + def remove_filters! + @filters = [] + end + + private + def filter_backtrace(backtrace) + @filters.each do |f| + backtrace = backtrace.map { |line| f.call(line) } + end + + backtrace + end + + def silence(backtrace) + @silencers.each do |s| + backtrace = backtrace.reject { |line| s.call(line) } + end + + backtrace + end + + def noise(backtrace) + backtrace - silence(backtrace) + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/benchmarkable.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/benchmarkable.rb new file mode 100644 index 0000000..805b7a7 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/benchmarkable.rb @@ -0,0 +1,49 @@ +require 'active_support/core_ext/benchmark' +require 'active_support/core_ext/hash/keys' + +module ActiveSupport + module Benchmarkable + # Allows you to measure the execution time of a block in a template and + # records the result to the log. Wrap this block around expensive operations + # or possible bottlenecks to get a time reading for the operation. For + # example, let's say you thought your file processing method was taking too + # long; you could wrap it in a benchmark block. + # + # <% benchmark 'Process data files' do %> + # <%= expensive_files_operation %> + # <% end %> + # + # That would add something like "Process data files (345.2ms)" to the log, + # which you can then use to compare timings when optimizing your code. + # + # You may give an optional logger level (:debug, :info, + # :warn, :error) as the :level option. The + # default logger level value is :info. + # + # <% benchmark 'Low-level files', level: :debug do %> + # <%= lowlevel_files_operation %> + # <% end %> + # + # Finally, you can pass true as the third argument to silence all log + # activity (other than the timing information) from inside the block. This + # is great for boiling down a noisy block to just a single statement that + # produces one log line: + # + # <% benchmark 'Process data files', level: :info, silence: true do %> + # <%= expensive_and_chatty_files_operation %> + # <% end %> + def benchmark(message = "Benchmarking", options = {}) + if logger + options.assert_valid_keys(:level, :silence) + options[:level] ||= :info + + result = nil + ms = Benchmark.ms { result = options[:silence] ? silence { yield } : yield } + logger.send(options[:level], '%s (%.1fms)' % [ message, ms ]) + result + else + yield + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/builder.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/builder.rb new file mode 100644 index 0000000..321e462 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/builder.rb @@ -0,0 +1,6 @@ +begin + require 'builder' +rescue LoadError => e + $stderr.puts "You don't have builder installed in your application. Please add it to your Gemfile and run bundle install" + raise e +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/cache.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/cache.rb new file mode 100644 index 0000000..c193d21 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/cache.rb @@ -0,0 +1,717 @@ +require 'benchmark' +require 'zlib' +require 'active_support/core_ext/array/extract_options' +require 'active_support/core_ext/array/wrap' +require 'active_support/core_ext/benchmark' +require 'active_support/core_ext/module/attribute_accessors' +require 'active_support/core_ext/numeric/bytes' +require 'active_support/core_ext/numeric/time' +require 'active_support/core_ext/object/to_param' +require 'active_support/core_ext/string/inflections' +require 'active_support/deprecation' + +module ActiveSupport + # See ActiveSupport::Cache::Store for documentation. + module Cache + autoload :FileStore, 'active_support/cache/file_store' + autoload :MemoryStore, 'active_support/cache/memory_store' + autoload :MemCacheStore, 'active_support/cache/mem_cache_store' + autoload :NullStore, 'active_support/cache/null_store' + + # These options mean something to all cache implementations. Individual cache + # implementations may support additional options. + UNIVERSAL_OPTIONS = [:namespace, :compress, :compress_threshold, :expires_in, :race_condition_ttl] + + module Strategy + autoload :LocalCache, 'active_support/cache/strategy/local_cache' + end + + class << self + # Creates a new Store object according to the given options. + # + # If no arguments are passed to this method, then a new + # ActiveSupport::Cache::MemoryStore object will be returned. + # + # If you pass a Symbol as the first argument, then a corresponding cache + # store class under the ActiveSupport::Cache namespace will be created. + # For example: + # + # ActiveSupport::Cache.lookup_store(:memory_store) + # # => returns a new ActiveSupport::Cache::MemoryStore object + # + # ActiveSupport::Cache.lookup_store(:mem_cache_store) + # # => returns a new ActiveSupport::Cache::MemCacheStore object + # + # Any additional arguments will be passed to the corresponding cache store + # class's constructor: + # + # ActiveSupport::Cache.lookup_store(:file_store, '/tmp/cache') + # # => same as: ActiveSupport::Cache::FileStore.new('/tmp/cache') + # + # If the first argument is not a Symbol, then it will simply be returned: + # + # ActiveSupport::Cache.lookup_store(MyOwnCacheStore.new) + # # => returns MyOwnCacheStore.new + def lookup_store(*store_option) + store, *parameters = *Array.wrap(store_option).flatten + + case store + when Symbol + retrieve_store_class(store).new(*parameters) + when nil + ActiveSupport::Cache::MemoryStore.new + else + store + end + end + + # Expands out the +key+ argument into a key that can be used for the + # cache store. Optionally accepts a namespace, and all keys will be + # scoped within that namespace. + # + # If the +key+ argument provided is an array, or responds to +to_a+, then + # each of elements in the array will be turned into parameters/keys and + # concatenated into a single key. For example: + # + # expand_cache_key([:foo, :bar]) # => "foo/bar" + # expand_cache_key([:foo, :bar], "namespace") # => "namespace/foo/bar" + # + # The +key+ argument can also respond to +cache_key+ or +to_param+. + def expand_cache_key(key, namespace = nil) + expanded_cache_key = namespace ? "#{namespace}/" : "" + + if prefix = ENV["RAILS_CACHE_ID"] || ENV["RAILS_APP_VERSION"] + expanded_cache_key << "#{prefix}/" + end + + expanded_cache_key << retrieve_cache_key(key) + expanded_cache_key + end + + private + def retrieve_cache_key(key) + case + when key.respond_to?(:cache_key) then key.cache_key + when key.is_a?(Array) then key.map { |element| retrieve_cache_key(element) }.to_param + when key.respond_to?(:to_a) then retrieve_cache_key(key.to_a) + else key.to_param + end.to_s + end + + # Obtains the specified cache store class, given the name of the +store+. + # Raises an error when the store class cannot be found. + def retrieve_store_class(store) + require "active_support/cache/#{store}" + rescue LoadError => e + raise "Could not find cache store adapter for #{store} (#{e})" + else + ActiveSupport::Cache.const_get(store.to_s.camelize) + end + end + + # An abstract cache store class. There are multiple cache store + # implementations, each having its own additional features. See the classes + # under the ActiveSupport::Cache module, e.g. + # ActiveSupport::Cache::MemCacheStore. MemCacheStore is currently the most + # popular cache store for large production websites. + # + # Some implementations may not support all methods beyond the basic cache + # methods of +fetch+, +write+, +read+, +exist?+, and +delete+. + # + # ActiveSupport::Cache::Store can store any serializable Ruby object. + # + # cache = ActiveSupport::Cache::MemoryStore.new + # + # cache.read('city') # => nil + # cache.write('city', "Duckburgh") + # cache.read('city') # => "Duckburgh" + # + # Keys are always translated into Strings and are case sensitive. When an + # object is specified as a key and has a +cache_key+ method defined, this + # method will be called to define the key. Otherwise, the +to_param+ + # method will be called. Hashes and Arrays can also be used as keys. The + # elements will be delimited by slashes, and the elements within a Hash + # will be sorted by key so they are consistent. + # + # cache.read('city') == cache.read(:city) # => true + # + # Nil values can be cached. + # + # If your cache is on a shared infrastructure, you can define a namespace + # for your cache entries. If a namespace is defined, it will be prefixed on + # to every key. The namespace can be either a static value or a Proc. If it + # is a Proc, it will be invoked when each key is evaluated so that you can + # use application logic to invalidate keys. + # + # cache.namespace = -> { @last_mod_time } # Set the namespace to a variable + # @last_mod_time = Time.now # Invalidate the entire cache by changing namespace + # + # Caches can also store values in a compressed format to save space and + # reduce time spent sending data. Since there is overhead, values must be + # large enough to warrant compression. To turn on compression either pass + # compress: true in the initializer or as an option to +fetch+ + # or +write+. To specify the threshold at which to compress values, set the + # :compress_threshold option. The default threshold is 16K. + class Store + cattr_accessor :logger, :instance_writer => true + + attr_reader :silence, :options + alias :silence? :silence + + # Create a new cache. The options will be passed to any write method calls + # except for :namespace which can be used to set the global + # namespace for the cache. + def initialize(options = nil) + @options = options ? options.dup : {} + end + + # Silence the logger. + def silence! + @silence = true + self + end + + # Silence the logger within a block. + def mute + previous_silence, @silence = defined?(@silence) && @silence, true + yield + ensure + @silence = previous_silence + end + + # :deprecated: + def self.instrument=(boolean) + ActiveSupport::Deprecation.warn "ActiveSupport::Cache.instrument= is deprecated and will be removed in Rails 5. Instrumentation is now always on so you can safely stop using it." + true + end + + # :deprecated: + def self.instrument + ActiveSupport::Deprecation.warn "ActiveSupport::Cache.instrument is deprecated and will be removed in Rails 5. Instrumentation is now always on so you can safely stop using it." + true + end + + # Fetches data from the cache, using the given key. If there is data in + # the cache with the given key, then that data is returned. + # + # If there is no such data in the cache (a cache miss), then +nil+ will be + # returned. However, if a block has been passed, that block will be passed + # the key and executed in the event of a cache miss. The return value of the + # block will be written to the cache under the given cache key, and that + # return value will be returned. + # + # cache.write('today', 'Monday') + # cache.fetch('today') # => "Monday" + # + # cache.fetch('city') # => nil + # cache.fetch('city') do + # 'Duckburgh' + # end + # cache.fetch('city') # => "Duckburgh" + # + # You may also specify additional options via the +options+ argument. + # Setting force: true will force a cache miss: + # + # cache.write('today', 'Monday') + # cache.fetch('today', force: true) # => nil + # + # Setting :compress will store a large cache entry set by the call + # in a compressed format. + # + # Setting :expires_in will set an expiration time on the cache. + # All caches support auto-expiring content after a specified number of + # seconds. This value can be specified as an option to the constructor + # (in which case all entries will be affected), or it can be supplied to + # the +fetch+ or +write+ method to effect just one entry. + # + # cache = ActiveSupport::Cache::MemoryStore.new(expires_in: 5.minutes) + # cache.write(key, value, expires_in: 1.minute) # Set a lower value for one entry + # + # Setting :race_condition_ttl is very useful in situations where + # a cache entry is used very frequently and is under heavy load. If a + # cache expires and due to heavy load several different processes will try + # to read data natively and then they all will try to write to cache. To + # avoid that case the first process to find an expired cache entry will + # bump the cache expiration time by the value set in :race_condition_ttl. + # Yes, this process is extending the time for a stale value by another few + # seconds. Because of extended life of the previous cache, other processes + # will continue to use slightly stale data for a just a bit longer. In the + # meantime that first process will go ahead and will write into cache the + # new value. After that all the processes will start getting the new value. + # The key is to keep :race_condition_ttl small. + # + # If the process regenerating the entry errors out, the entry will be + # regenerated after the specified number of seconds. Also note that the + # life of stale cache is extended only if it expired recently. Otherwise + # a new value is generated and :race_condition_ttl does not play + # any role. + # + # # Set all values to expire after one minute. + # cache = ActiveSupport::Cache::MemoryStore.new(expires_in: 1.minute) + # + # cache.write('foo', 'original value') + # val_1 = nil + # val_2 = nil + # sleep 60 + # + # Thread.new do + # val_1 = cache.fetch('foo', race_condition_ttl: 10) do + # sleep 1 + # 'new value 1' + # end + # end + # + # Thread.new do + # val_2 = cache.fetch('foo', race_condition_ttl: 10) do + # 'new value 2' + # end + # end + # + # # val_1 => "new value 1" + # # val_2 => "original value" + # # sleep 10 # First thread extend the life of cache by another 10 seconds + # # cache.fetch('foo') => "new value 1" + # + # Other options will be handled by the specific cache store implementation. + # Internally, #fetch calls #read_entry, and calls #write_entry on a cache + # miss. +options+ will be passed to the #read and #write calls. + # + # For example, MemCacheStore's #write method supports the +:raw+ + # option, which tells the memcached server to store all values as strings. + # We can use this option with #fetch too: + # + # cache = ActiveSupport::Cache::MemCacheStore.new + # cache.fetch("foo", force: true, raw: true) do + # :bar + # end + # cache.fetch('foo') # => "bar" + def fetch(name, options = nil) + if block_given? + options = merged_options(options) + key = namespaced_key(name, options) + + cached_entry = find_cached_entry(key, name, options) unless options[:force] + entry = handle_expired_entry(cached_entry, key, options) + + if entry + get_entry_value(entry, name, options) + else + save_block_result_to_cache(name, options) { |_name| yield _name } + end + else + read(name, options) + end + end + + # Fetches data from the cache, using the given key. If there is data in + # the cache with the given key, then that data is returned. Otherwise, + # +nil+ is returned. + # + # Options are passed to the underlying cache implementation. + def read(name, options = nil) + options = merged_options(options) + key = namespaced_key(name, options) + instrument(:read, name, options) do |payload| + entry = read_entry(key, options) + if entry + if entry.expired? + delete_entry(key, options) + payload[:hit] = false if payload + nil + else + payload[:hit] = true if payload + entry.value + end + else + payload[:hit] = false if payload + nil + end + end + end + + # Read multiple values at once from the cache. Options can be passed + # in the last argument. + # + # Some cache implementation may optimize this method. + # + # Returns a hash mapping the names provided to the values found. + def read_multi(*names) + options = names.extract_options! + options = merged_options(options) + results = {} + names.each do |name| + key = namespaced_key(name, options) + entry = read_entry(key, options) + if entry + if entry.expired? + delete_entry(key, options) + else + results[name] = entry.value + end + end + end + results + end + + # Fetches data from the cache, using the given keys. If there is data in + # the cache with the given keys, then that data is returned. Otherwise, + # the supplied block is called for each key for which there was no data, + # and the result will be written to the cache and returned. + # + # Options are passed to the underlying cache implementation. + # + # Returns a hash with the data for each of the names. For example: + # + # cache.write("bim", "bam") + # cache.fetch_multi("bim", "boom") { |key| key * 2 } + # # => { "bam" => "bam", "boom" => "boomboom" } + # + def fetch_multi(*names) + options = names.extract_options! + options = merged_options(options) + results = read_multi(*names, options) + + names.each_with_object({}) do |name, memo| + memo[name] = results.fetch(name) do + value = yield name + write(name, value, options) + value + end + end + end + + # Writes the value to the cache, with the key. + # + # Options are passed to the underlying cache implementation. + def write(name, value, options = nil) + options = merged_options(options) + + instrument(:write, name, options) do + entry = Entry.new(value, options) + write_entry(namespaced_key(name, options), entry, options) + end + end + + # Deletes an entry in the cache. Returns +true+ if an entry is deleted. + # + # Options are passed to the underlying cache implementation. + def delete(name, options = nil) + options = merged_options(options) + + instrument(:delete, name) do + delete_entry(namespaced_key(name, options), options) + end + end + + # Returns +true+ if the cache contains an entry for the given key. + # + # Options are passed to the underlying cache implementation. + def exist?(name, options = nil) + options = merged_options(options) + + instrument(:exist?, name) do + entry = read_entry(namespaced_key(name, options), options) + (entry && !entry.expired?) || false + end + end + + # Delete all entries with keys matching the pattern. + # + # Options are passed to the underlying cache implementation. + # + # All implementations may not support this method. + def delete_matched(matcher, options = nil) + raise NotImplementedError.new("#{self.class.name} does not support delete_matched") + end + + # Increment an integer value in the cache. + # + # Options are passed to the underlying cache implementation. + # + # All implementations may not support this method. + def increment(name, amount = 1, options = nil) + raise NotImplementedError.new("#{self.class.name} does not support increment") + end + + # Decrement an integer value in the cache. + # + # Options are passed to the underlying cache implementation. + # + # All implementations may not support this method. + def decrement(name, amount = 1, options = nil) + raise NotImplementedError.new("#{self.class.name} does not support decrement") + end + + # Cleanup the cache by removing expired entries. + # + # Options are passed to the underlying cache implementation. + # + # All implementations may not support this method. + def cleanup(options = nil) + raise NotImplementedError.new("#{self.class.name} does not support cleanup") + end + + # Clear the entire cache. Be careful with this method since it could + # affect other processes if shared cache is being used. + # + # The options hash is passed to the underlying cache implementation. + # + # All implementations may not support this method. + def clear(options = nil) + raise NotImplementedError.new("#{self.class.name} does not support clear") + end + + protected + # Add the namespace defined in the options to a pattern designed to + # match keys. Implementations that support delete_matched should call + # this method to translate a pattern that matches names into one that + # matches namespaced keys. + def key_matcher(pattern, options) + prefix = options[:namespace].is_a?(Proc) ? options[:namespace].call : options[:namespace] + if prefix + source = pattern.source + if source.start_with?('^') + source = source[1, source.length] + else + source = ".*#{source[0, source.length]}" + end + Regexp.new("^#{Regexp.escape(prefix)}:#{source}", pattern.options) + else + pattern + end + end + + # Read an entry from the cache implementation. Subclasses must implement + # this method. + def read_entry(key, options) # :nodoc: + raise NotImplementedError.new + end + + # Write an entry to the cache implementation. Subclasses must implement + # this method. + def write_entry(key, entry, options) # :nodoc: + raise NotImplementedError.new + end + + # Delete an entry from the cache implementation. Subclasses must + # implement this method. + def delete_entry(key, options) # :nodoc: + raise NotImplementedError.new + end + + private + # Merge the default options with ones specific to a method call. + def merged_options(call_options) # :nodoc: + if call_options + options.merge(call_options) + else + options.dup + end + end + + # Expand key to be a consistent string value. Invoke +cache_key+ if + # object responds to +cache_key+. Otherwise, +to_param+ method will be + # called. If the key is a Hash, then keys will be sorted alphabetically. + def expanded_key(key) # :nodoc: + return key.cache_key.to_s if key.respond_to?(:cache_key) + + case key + when Array + if key.size > 1 + key = key.collect{|element| expanded_key(element)} + else + key = key.first + end + when Hash + key = key.sort_by { |k,_| k.to_s }.collect{|k,v| "#{k}=#{v}"} + end + + key.to_param + end + + # Prefix a key with the namespace. Namespace and key will be delimited + # with a colon. + def namespaced_key(key, options) + key = expanded_key(key) + namespace = options[:namespace] if options + prefix = namespace.is_a?(Proc) ? namespace.call : namespace + key = "#{prefix}:#{key}" if prefix + key + end + + def instrument(operation, key, options = nil) + log(operation, key, options) + + payload = { :key => key } + payload.merge!(options) if options.is_a?(Hash) + ActiveSupport::Notifications.instrument("cache_#{operation}.active_support", payload){ yield(payload) } + end + + def log(operation, key, options = nil) + return unless logger && logger.debug? && !silence? + logger.debug("Cache #{operation}: #{key}#{options.blank? ? "" : " (#{options.inspect})"}") + end + + def find_cached_entry(key, name, options) + instrument(:read, name, options) do |payload| + payload[:super_operation] = :fetch if payload + read_entry(key, options) + end + end + + def handle_expired_entry(entry, key, options) + if entry && entry.expired? + race_ttl = options[:race_condition_ttl].to_i + if (race_ttl > 0) && (Time.now.to_f - entry.expires_at <= race_ttl) + # When an entry has :race_condition_ttl defined, put the stale entry back into the cache + # for a brief period while the entry is begin recalculated. + entry.expires_at = Time.now + race_ttl + write_entry(key, entry, :expires_in => race_ttl * 2) + else + delete_entry(key, options) + end + entry = nil + end + entry + end + + def get_entry_value(entry, name, options) + instrument(:fetch_hit, name, options) { |payload| } + entry.value + end + + def save_block_result_to_cache(name, options) + result = instrument(:generate, name, options) do |payload| + yield(name) + end + + write(name, result, options) + result + end + end + + # This class is used to represent cache entries. Cache entries have a value and an optional + # expiration time. The expiration time is used to support the :race_condition_ttl option + # on the cache. + # + # Since cache entries in most instances will be serialized, the internals of this class are highly optimized + # using short instance variable names that are lazily defined. + class Entry # :nodoc: + DEFAULT_COMPRESS_LIMIT = 16.kilobytes + + # Create a new cache entry for the specified value. Options supported are + # +:compress+, +:compress_threshold+, and +:expires_in+. + def initialize(value, options = {}) + if should_compress?(value, options) + @value = compress(value) + @compressed = true + else + @value = value + end + + @created_at = Time.now.to_f + @expires_in = options[:expires_in] + @expires_in = @expires_in.to_f if @expires_in + end + + def value + convert_version_4beta1_entry! if defined?(@v) + compressed? ? uncompress(@value) : @value + end + + # Check if the entry is expired. The +expires_in+ parameter can override + # the value set when the entry was created. + def expired? + convert_version_4beta1_entry! if defined?(@v) + @expires_in && @created_at + @expires_in <= Time.now.to_f + end + + def expires_at + @expires_in ? @created_at + @expires_in : nil + end + + def expires_at=(value) + if value + @expires_in = value.to_f - @created_at + else + @expires_in = nil + end + end + + # Returns the size of the cached value. This could be less than + # value.size if the data is compressed. + def size + if defined?(@s) + @s + else + case value + when NilClass + 0 + when String + @value.bytesize + else + @s = Marshal.dump(@value).bytesize + end + end + end + + # Duplicate the value in a class. This is used by cache implementations that don't natively + # serialize entries to protect against accidental cache modifications. + def dup_value! + convert_version_4beta1_entry! if defined?(@v) + + if @value && !compressed? && !(@value.is_a?(Numeric) || @value == true || @value == false) + if @value.is_a?(String) + @value = @value.dup + else + @value = Marshal.load(Marshal.dump(@value)) + end + end + end + + private + def should_compress?(value, options) + if value && options[:compress] + compress_threshold = options[:compress_threshold] || DEFAULT_COMPRESS_LIMIT + serialized_value_size = (value.is_a?(String) ? value : Marshal.dump(value)).bytesize + + return true if serialized_value_size >= compress_threshold + end + + false + end + + def compressed? + defined?(@compressed) ? @compressed : false + end + + def compress(value) + Zlib::Deflate.deflate(Marshal.dump(value)) + end + + def uncompress(value) + Marshal.load(Zlib::Inflate.inflate(value)) + end + + # The internals of this method changed between Rails 3.x and 4.0. This method provides the glue + # to ensure that cache entries created under the old version still work with the new class definition. + def convert_version_4beta1_entry! + if defined?(@v) + @value = @v + remove_instance_variable(:@v) + end + + if defined?(@c) + @compressed = @c + remove_instance_variable(:@c) + end + + if defined?(@x) && @x + @created_at ||= Time.now.to_f + @expires_in = @x - @created_at + remove_instance_variable(:@x) + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/cache/file_store.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/cache/file_store.rb new file mode 100644 index 0000000..d08ecd2 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/cache/file_store.rb @@ -0,0 +1,190 @@ +require 'active_support/core_ext/marshal' +require 'active_support/core_ext/file/atomic' +require 'active_support/core_ext/string/conversions' +require 'uri/common' + +module ActiveSupport + module Cache + # A cache store implementation which stores everything on the filesystem. + # + # FileStore implements the Strategy::LocalCache strategy which implements + # an in-memory cache inside of a block. + class FileStore < Store + attr_reader :cache_path + + DIR_FORMATTER = "%03X" + FILENAME_MAX_SIZE = 228 # max filename size on file system is 255, minus room for timestamp and random characters appended by Tempfile (used by atomic write) + FILEPATH_MAX_SIZE = 900 # max is 1024, plus some room + EXCLUDED_DIRS = ['.', '..'].freeze + + def initialize(cache_path, options = nil) + super(options) + @cache_path = cache_path.to_s + extend Strategy::LocalCache + end + + # Deletes all items from the cache. In this case it deletes all the entries in the specified + # file store directory except for .gitkeep. Be careful which directory is specified in your + # config file when using +FileStore+ because everything in that directory will be deleted. + def clear(options = nil) + root_dirs = Dir.entries(cache_path).reject {|f| (EXCLUDED_DIRS + [".gitkeep"]).include?(f)} + FileUtils.rm_r(root_dirs.collect{|f| File.join(cache_path, f)}) + end + + # Preemptively iterates through all stored keys and removes the ones which have expired. + def cleanup(options = nil) + options = merged_options(options) + search_dir(cache_path) do |fname| + key = file_path_key(fname) + entry = read_entry(key, options) + delete_entry(key, options) if entry && entry.expired? + end + end + + # Increments an already existing integer value that is stored in the cache. + # If the key is not found nothing is done. + def increment(name, amount = 1, options = nil) + modify_value(name, amount, options) + end + + # Decrements an already existing integer value that is stored in the cache. + # If the key is not found nothing is done. + def decrement(name, amount = 1, options = nil) + modify_value(name, -amount, options) + end + + def delete_matched(matcher, options = nil) + options = merged_options(options) + instrument(:delete_matched, matcher.inspect) do + matcher = key_matcher(matcher, options) + search_dir(cache_path) do |path| + key = file_path_key(path) + delete_entry(key, options) if key.match(matcher) + end + end + end + + protected + + def read_entry(key, options) + file_name = key_file_path(key) + if File.exist?(file_name) + File.open(file_name) { |f| Marshal.load(f) } + end + rescue => e + logger.error("FileStoreError (#{e}): #{e.message}") if logger + nil + end + + def write_entry(key, entry, options) + file_name = key_file_path(key) + return false if options[:unless_exist] && File.exist?(file_name) + ensure_cache_path(File.dirname(file_name)) + File.atomic_write(file_name, cache_path) {|f| Marshal.dump(entry, f)} + true + end + + def delete_entry(key, options) + file_name = key_file_path(key) + if File.exist?(file_name) + begin + File.delete(file_name) + delete_empty_directories(File.dirname(file_name)) + true + rescue => e + # Just in case the error was caused by another process deleting the file first. + raise e if File.exist?(file_name) + false + end + end + end + + private + # Lock a file for a block so only one process can modify it at a time. + def lock_file(file_name, &block) # :nodoc: + if File.exist?(file_name) + File.open(file_name, 'r+') do |f| + begin + f.flock File::LOCK_EX + yield + ensure + f.flock File::LOCK_UN + end + end + else + yield + end + end + + # Translate a key into a file path. + def key_file_path(key) + if key.size > FILEPATH_MAX_SIZE + key = Digest::MD5.hexdigest(key) + end + + fname = URI.encode_www_form_component(key) + hash = Zlib.adler32(fname) + hash, dir_1 = hash.divmod(0x1000) + dir_2 = hash.modulo(0x1000) + fname_paths = [] + + # Make sure file name doesn't exceed file system limits. + begin + fname_paths << fname[0, FILENAME_MAX_SIZE] + fname = fname[FILENAME_MAX_SIZE..-1] + end until fname.blank? + + File.join(cache_path, DIR_FORMATTER % dir_1, DIR_FORMATTER % dir_2, *fname_paths) + end + + # Translate a file path into a key. + def file_path_key(path) + fname = path[cache_path.to_s.size..-1].split(File::SEPARATOR, 4).last + URI.decode_www_form_component(fname, Encoding::UTF_8) + end + + # Delete empty directories in the cache. + def delete_empty_directories(dir) + return if File.realpath(dir) == File.realpath(cache_path) + if Dir.entries(dir).reject {|f| EXCLUDED_DIRS.include?(f)}.empty? + Dir.delete(dir) rescue nil + delete_empty_directories(File.dirname(dir)) + end + end + + # Make sure a file path's directories exist. + def ensure_cache_path(path) + FileUtils.makedirs(path) unless File.exist?(path) + end + + def search_dir(dir, &callback) + return if !File.exist?(dir) + Dir.foreach(dir) do |d| + next if EXCLUDED_DIRS.include?(d) + name = File.join(dir, d) + if File.directory?(name) + search_dir(name, &callback) + else + callback.call name + end + end + end + + # Modifies the amount of an already existing integer value that is stored in the cache. + # If the key is not found nothing is done. + def modify_value(name, amount, options) + file_name = key_file_path(namespaced_key(name, options)) + + lock_file(file_name) do + options = merged_options(options) + + if num = read(name, options) + num = num.to_i + amount + write(name, num, options) + num + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/cache/mem_cache_store.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/cache/mem_cache_store.rb new file mode 100644 index 0000000..61b4f0b --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/cache/mem_cache_store.rb @@ -0,0 +1,198 @@ +begin + require 'dalli' +rescue LoadError => e + $stderr.puts "You don't have dalli installed in your application. Please add it to your Gemfile and run bundle install" + raise e +end + +require 'digest/md5' +require 'active_support/core_ext/marshal' +require 'active_support/core_ext/array/extract_options' + +module ActiveSupport + module Cache + # A cache store implementation which stores data in Memcached: + # http://memcached.org/ + # + # This is currently the most popular cache store for production websites. + # + # Special features: + # - Clustering and load balancing. One can specify multiple memcached servers, + # and MemCacheStore will load balance between all available servers. If a + # server goes down, then MemCacheStore will ignore it until it comes back up. + # + # MemCacheStore implements the Strategy::LocalCache strategy which implements + # an in-memory cache inside of a block. + class MemCacheStore < Store + ESCAPE_KEY_CHARS = /[\x00-\x20%\x7F-\xFF]/n + + def self.build_mem_cache(*addresses) + addresses = addresses.flatten + options = addresses.extract_options! + addresses = ["localhost:11211"] if addresses.empty? + Dalli::Client.new(addresses, options) + end + + # Creates a new MemCacheStore object, with the given memcached server + # addresses. Each address is either a host name, or a host-with-port string + # in the form of "host_name:port". For example: + # + # ActiveSupport::Cache::MemCacheStore.new("localhost", "server-downstairs.localnetwork:8229") + # + # If no addresses are specified, then MemCacheStore will connect to + # localhost port 11211 (the default memcached port). + def initialize(*addresses) + addresses = addresses.flatten + options = addresses.extract_options! + super(options) + + unless [String, Dalli::Client, NilClass].include?(addresses.first.class) + raise ArgumentError, "First argument must be an empty array, an array of hosts or a Dalli::Client instance." + end + if addresses.first.is_a?(Dalli::Client) + @data = addresses.first + else + mem_cache_options = options.dup + UNIVERSAL_OPTIONS.each{|name| mem_cache_options.delete(name)} + @data = self.class.build_mem_cache(*(addresses + [mem_cache_options])) + end + + extend Strategy::LocalCache + extend LocalCacheWithRaw + end + + # Reads multiple values from the cache using a single call to the + # servers for all keys. Options can be passed in the last argument. + def read_multi(*names) + options = names.extract_options! + options = merged_options(options) + keys_to_names = Hash[names.map{|name| [escape_key(namespaced_key(name, options)), name]}] + raw_values = @data.get_multi(keys_to_names.keys, :raw => true) + values = {} + raw_values.each do |key, value| + entry = deserialize_entry(value) + values[keys_to_names[key]] = entry.value unless entry.expired? + end + values + end + + # Increment a cached value. This method uses the memcached incr atomic + # operator and can only be used on values written with the :raw option. + # Calling it on a value not stored with :raw will initialize that value + # to zero. + def increment(name, amount = 1, options = nil) # :nodoc: + options = merged_options(options) + instrument(:increment, name, :amount => amount) do + @data.incr(escape_key(namespaced_key(name, options)), amount) + end + rescue Dalli::DalliError => e + logger.error("DalliError (#{e}): #{e.message}") if logger + nil + end + + # Decrement a cached value. This method uses the memcached decr atomic + # operator and can only be used on values written with the :raw option. + # Calling it on a value not stored with :raw will initialize that value + # to zero. + def decrement(name, amount = 1, options = nil) # :nodoc: + options = merged_options(options) + instrument(:decrement, name, :amount => amount) do + @data.decr(escape_key(namespaced_key(name, options)), amount) + end + rescue Dalli::DalliError => e + logger.error("DalliError (#{e}): #{e.message}") if logger + nil + end + + # Clear the entire cache on all memcached servers. This method should + # be used with care when shared cache is being used. + def clear(options = nil) + @data.flush_all + rescue Dalli::DalliError => e + logger.error("DalliError (#{e}): #{e.message}") if logger + nil + end + + # Get the statistics from the memcached servers. + def stats + @data.stats + end + + protected + # Read an entry from the cache. + def read_entry(key, options) # :nodoc: + deserialize_entry(@data.get(escape_key(key), options)) + rescue Dalli::DalliError => e + logger.error("DalliError (#{e}): #{e.message}") if logger + nil + end + + # Write an entry to the cache. + def write_entry(key, entry, options) # :nodoc: + method = options && options[:unless_exist] ? :add : :set + value = options[:raw] ? entry.value.to_s : entry + expires_in = options[:expires_in].to_i + if expires_in > 0 && !options[:raw] + # Set the memcache expire a few minutes in the future to support race condition ttls on read + expires_in += 5.minutes + end + @data.send(method, escape_key(key), value, expires_in, options) + rescue Dalli::DalliError => e + logger.error("DalliError (#{e}): #{e.message}") if logger + false + end + + # Delete an entry from the cache. + def delete_entry(key, options) # :nodoc: + @data.delete(escape_key(key)) + rescue Dalli::DalliError => e + logger.error("DalliError (#{e}): #{e.message}") if logger + false + end + + private + + # Memcache keys are binaries. So we need to force their encoding to binary + # before applying the regular expression to ensure we are escaping all + # characters properly. + def escape_key(key) + key = key.to_s.dup + key = key.force_encoding(Encoding::ASCII_8BIT) + key = key.gsub(ESCAPE_KEY_CHARS){ |match| "%#{match.getbyte(0).to_s(16).upcase}" } + key = "#{key[0, 213]}:md5:#{Digest::MD5.hexdigest(key)}" if key.size > 250 + key + end + + def deserialize_entry(raw_value) + if raw_value + entry = Marshal.load(raw_value) rescue raw_value + entry.is_a?(Entry) ? entry : Entry.new(entry) + else + nil + end + end + + # Provide support for raw values in the local cache strategy. + module LocalCacheWithRaw # :nodoc: + protected + def read_entry(key, options) + entry = super + if options[:raw] && local_cache && entry + entry = deserialize_entry(entry.value) + end + entry + end + + def write_entry(key, entry, options) # :nodoc: + retval = super + if options[:raw] && local_cache && retval + raw_entry = Entry.new(entry.value.to_s) + raw_entry.expires_at = entry.expires_at + local_cache.write_entry(key, raw_entry, options) + end + retval + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/cache/memory_store.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/cache/memory_store.rb new file mode 100644 index 0000000..8a0523d --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/cache/memory_store.rb @@ -0,0 +1,172 @@ +require 'monitor' + +module ActiveSupport + module Cache + # A cache store implementation which stores everything into memory in the + # same process. If you're running multiple Ruby on Rails server processes + # (which is the case if you're using mongrel_cluster or Phusion Passenger), + # then this means that Rails server process instances won't be able + # to share cache data with each other and this may not be the most + # appropriate cache in that scenario. + # + # This cache has a bounded size specified by the :size options to the + # initializer (default is 32Mb). When the cache exceeds the allotted size, + # a cleanup will occur which tries to prune the cache down to three quarters + # of the maximum size by removing the least recently used entries. + # + # MemoryStore is thread-safe. + class MemoryStore < Store + def initialize(options = nil) + options ||= {} + super(options) + @data = {} + @key_access = {} + @max_size = options[:size] || 32.megabytes + @max_prune_time = options[:max_prune_time] || 2 + @cache_size = 0 + @monitor = Monitor.new + @pruning = false + end + + def clear(options = nil) + synchronize do + @data.clear + @key_access.clear + @cache_size = 0 + end + end + + # Preemptively iterates through all stored keys and removes the ones which have expired. + def cleanup(options = nil) + options = merged_options(options) + instrument(:cleanup, :size => @data.size) do + keys = synchronize{ @data.keys } + keys.each do |key| + entry = @data[key] + delete_entry(key, options) if entry && entry.expired? + end + end + end + + # To ensure entries fit within the specified memory prune the cache by removing the least + # recently accessed entries. + def prune(target_size, max_time = nil) + return if pruning? + @pruning = true + begin + start_time = Time.now + cleanup + instrument(:prune, target_size, :from => @cache_size) do + keys = synchronize{ @key_access.keys.sort{|a,b| @key_access[a].to_f <=> @key_access[b].to_f} } + keys.each do |key| + delete_entry(key, options) + return if @cache_size <= target_size || (max_time && Time.now - start_time > max_time) + end + end + ensure + @pruning = false + end + end + + # Returns true if the cache is currently being pruned. + def pruning? + @pruning + end + + # Increment an integer value in the cache. + def increment(name, amount = 1, options = nil) + synchronize do + options = merged_options(options) + if num = read(name, options) + num = num.to_i + amount + write(name, num, options) + num + else + nil + end + end + end + + # Decrement an integer value in the cache. + def decrement(name, amount = 1, options = nil) + synchronize do + options = merged_options(options) + if num = read(name, options) + num = num.to_i - amount + write(name, num, options) + num + else + nil + end + end + end + + def delete_matched(matcher, options = nil) + options = merged_options(options) + instrument(:delete_matched, matcher.inspect) do + matcher = key_matcher(matcher, options) + keys = synchronize { @data.keys } + keys.each do |key| + delete_entry(key, options) if key.match(matcher) + end + end + end + + def inspect # :nodoc: + "<##{self.class.name} entries=#{@data.size}, size=#{@cache_size}, options=#{@options.inspect}>" + end + + # Synchronize calls to the cache. This should be called wherever the underlying cache implementation + # is not thread safe. + def synchronize(&block) # :nodoc: + @monitor.synchronize(&block) + end + + protected + + PER_ENTRY_OVERHEAD = 240 + + def cached_size(key, entry) + key.to_s.bytesize + entry.size + PER_ENTRY_OVERHEAD + end + + def read_entry(key, options) # :nodoc: + entry = @data[key] + synchronize do + if entry + @key_access[key] = Time.now.to_f + else + @key_access.delete(key) + end + end + entry + end + + def write_entry(key, entry, options) # :nodoc: + entry.dup_value! + synchronize do + old_entry = @data[key] + return false if @data.key?(key) && options[:unless_exist] + if old_entry + @cache_size -= (old_entry.size - entry.size) + else + @cache_size += cached_size(key, entry) + end + @key_access[key] = Time.now.to_f + @data[key] = entry + prune(@max_size * 0.75, @max_prune_time) if @cache_size > @max_size + true + end + end + + def delete_entry(key, options) # :nodoc: + synchronize do + @key_access.delete(key) + entry = @data.delete(key) + @cache_size -= cached_size(key, entry) if entry + !!entry + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/cache/null_store.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/cache/null_store.rb new file mode 100644 index 0000000..4427eaa --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/cache/null_store.rb @@ -0,0 +1,44 @@ +module ActiveSupport + module Cache + # A cache store implementation which doesn't actually store anything. Useful in + # development and test environments where you don't want caching turned on but + # need to go through the caching interface. + # + # This cache does implement the local cache strategy, so values will actually + # be cached inside blocks that utilize this strategy. See + # ActiveSupport::Cache::Strategy::LocalCache for more details. + class NullStore < Store + def initialize(options = nil) + super(options) + extend Strategy::LocalCache + end + + def clear(options = nil) + end + + def cleanup(options = nil) + end + + def increment(name, amount = 1, options = nil) + end + + def decrement(name, amount = 1, options = nil) + end + + def delete_matched(matcher, options = nil) + end + + protected + def read_entry(key, options) # :nodoc: + end + + def write_entry(key, entry, options) # :nodoc: + true + end + + def delete_entry(key, options) # :nodoc: + false + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/cache/strategy/local_cache.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/cache/strategy/local_cache.rb new file mode 100644 index 0000000..73c6b3c --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/cache/strategy/local_cache.rb @@ -0,0 +1,161 @@ +require 'active_support/core_ext/object/duplicable' +require 'active_support/core_ext/string/inflections' +require 'active_support/per_thread_registry' + +module ActiveSupport + module Cache + module Strategy + # Caches that implement LocalCache will be backed by an in-memory cache for the + # duration of a block. Repeated calls to the cache for the same key will hit the + # in-memory cache for faster access. + module LocalCache + autoload :Middleware, 'active_support/cache/strategy/local_cache_middleware' + + # Class for storing and registering the local caches. + class LocalCacheRegistry # :nodoc: + extend ActiveSupport::PerThreadRegistry + + def initialize + @registry = {} + end + + def cache_for(local_cache_key) + @registry[local_cache_key] + end + + def set_cache_for(local_cache_key, value) + @registry[local_cache_key] = value + end + + def self.set_cache_for(l, v); instance.set_cache_for l, v; end + def self.cache_for(l); instance.cache_for l; end + end + + # Simple memory backed cache. This cache is not thread safe and is intended only + # for serving as a temporary memory cache for a single thread. + class LocalStore < Store + def initialize + super + @data = {} + end + + # Don't allow synchronizing since it isn't thread safe, + def synchronize # :nodoc: + yield + end + + def clear(options = nil) + @data.clear + end + + def read_entry(key, options) + @data[key] + end + + def write_entry(key, value, options) + @data[key] = value + true + end + + def delete_entry(key, options) + !!@data.delete(key) + end + end + + # Use a local cache for the duration of block. + def with_local_cache + use_temporary_local_cache(LocalStore.new) { yield } + end + # Middleware class can be inserted as a Rack handler to be local cache for the + # duration of request. + def middleware + @middleware ||= Middleware.new( + "ActiveSupport::Cache::Strategy::LocalCache", + local_cache_key) + end + + def clear(options = nil) # :nodoc: + local_cache.clear(options) if local_cache + super + end + + def cleanup(options = nil) # :nodoc: + local_cache.clear(options) if local_cache + super + end + + def increment(name, amount = 1, options = nil) # :nodoc: + value = bypass_local_cache{super} + set_cache_value(value, name, amount, options) + value + end + + def decrement(name, amount = 1, options = nil) # :nodoc: + value = bypass_local_cache{super} + set_cache_value(value, name, amount, options) + value + end + + protected + def read_entry(key, options) # :nodoc: + if local_cache + entry = local_cache.read_entry(key, options) + unless entry + entry = super + local_cache.write_entry(key, entry, options) + end + entry + else + super + end + end + + def write_entry(key, entry, options) # :nodoc: + local_cache.write_entry(key, entry, options) if local_cache + super + end + + def delete_entry(key, options) # :nodoc: + local_cache.delete_entry(key, options) if local_cache + super + end + + def set_cache_value(value, name, amount, options) + if local_cache + local_cache.mute do + if value + local_cache.write(name, value, options) + else + local_cache.delete(name, options) + end + end + end + end + + private + + def local_cache_key + @local_cache_key ||= "#{self.class.name.underscore}_local_cache_#{object_id}".gsub(/[\/-]/, '_').to_sym + end + + def local_cache + LocalCacheRegistry.cache_for(local_cache_key) + end + + def bypass_local_cache + use_temporary_local_cache(nil) { yield } + end + + def use_temporary_local_cache(temporary_cache) + save_cache = LocalCacheRegistry.cache_for(local_cache_key) + begin + LocalCacheRegistry.set_cache_for(local_cache_key, temporary_cache) + yield + ensure + LocalCacheRegistry.set_cache_for(local_cache_key, save_cache) + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/cache/strategy/local_cache_middleware.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/cache/strategy/local_cache_middleware.rb new file mode 100644 index 0000000..a6f24b1 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/cache/strategy/local_cache_middleware.rb @@ -0,0 +1,44 @@ +require 'rack/body_proxy' +require 'rack/utils' + +module ActiveSupport + module Cache + module Strategy + module LocalCache + + #-- + # This class wraps up local storage for middlewares. Only the middleware method should + # construct them. + class Middleware # :nodoc: + attr_reader :name, :local_cache_key + + def initialize(name, local_cache_key) + @name = name + @local_cache_key = local_cache_key + @app = nil + end + + def new(app) + @app = app + self + end + + def call(env) + LocalCacheRegistry.set_cache_for(local_cache_key, LocalStore.new) + response = @app.call(env) + response[2] = ::Rack::BodyProxy.new(response[2]) do + LocalCacheRegistry.set_cache_for(local_cache_key, nil) + end + response + rescue Rack::Utils::InvalidParameterError + LocalCacheRegistry.set_cache_for(local_cache_key, nil) + [400, {}, []] + rescue Exception + LocalCacheRegistry.set_cache_for(local_cache_key, nil) + raise + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/callbacks.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/callbacks.rb new file mode 100644 index 0000000..98fd6b5 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/callbacks.rb @@ -0,0 +1,795 @@ +require 'active_support/concern' +require 'active_support/descendants_tracker' +require 'active_support/core_ext/array/extract_options' +require 'active_support/core_ext/class/attribute' +require 'active_support/core_ext/kernel/reporting' +require 'active_support/core_ext/kernel/singleton_class' +require 'thread' + +module ActiveSupport + # Callbacks are code hooks that are run at key points in an object's life cycle. + # The typical use case is to have a base class define a set of callbacks + # relevant to the other functionality it supplies, so that subclasses can + # install callbacks that enhance or modify the base functionality without + # needing to override or redefine methods of the base class. + # + # Mixing in this module allows you to define the events in the object's + # life cycle that will support callbacks (via +ClassMethods.define_callbacks+), + # set the instance methods, procs, or callback objects to be called (via + # +ClassMethods.set_callback+), and run the installed callbacks at the + # appropriate times (via +run_callbacks+). + # + # Three kinds of callbacks are supported: before callbacks, run before a + # certain event; after callbacks, run after the event; and around callbacks, + # blocks that surround the event, triggering it when they yield. Callback code + # can be contained in instance methods, procs or lambdas, or callback objects + # that respond to certain predetermined methods. See +ClassMethods.set_callback+ + # for details. + # + # class Record + # include ActiveSupport::Callbacks + # define_callbacks :save + # + # def save + # run_callbacks :save do + # puts "- save" + # end + # end + # end + # + # class PersonRecord < Record + # set_callback :save, :before, :saving_message + # def saving_message + # puts "saving..." + # end + # + # set_callback :save, :after do |object| + # puts "saved" + # end + # end + # + # person = PersonRecord.new + # person.save + # + # Output: + # saving... + # - save + # saved + module Callbacks + extend Concern + + included do + extend ActiveSupport::DescendantsTracker + end + + CALLBACK_FILTER_TYPES = [:before, :after, :around] + + # Runs the callbacks for the given event. + # + # Calls the before and around callbacks in the order they were set, yields + # the block (if given one), and then runs the after callbacks in reverse + # order. + # + # If the callback chain was halted, returns +false+. Otherwise returns the + # result of the block, +nil+ if no callbacks have been set, or +true+ + # if callbacks have been set but no block is given. + # + # run_callbacks :save do + # save + # end + def run_callbacks(kind, &block) + send "_run_#{kind}_callbacks", &block + end + + private + + def __run_callbacks__(callbacks, &block) + if callbacks.empty? + yield if block_given? + else + runner = callbacks.compile + e = Filters::Environment.new(self, false, nil, block) + runner.call(e).value + end + end + + # A hook invoked every time a before callback is halted. + # This can be overridden in AS::Callback implementors in order + # to provide better debugging/logging. + def halted_callback_hook(filter) + end + + module Conditionals # :nodoc: + class Value + def initialize(&block) + @block = block + end + def call(target, value); @block.call(value); end + end + end + + module Filters + Environment = Struct.new(:target, :halted, :value, :run_block) + + class End + def call(env) + block = env.run_block + env.value = !env.halted && (!block || block.call) + env + end + end + ENDING = End.new + + class Before + def self.build(callback_sequence, user_callback, user_conditions, chain_config, filter) + halted_lambda = chain_config[:terminator] + + if chain_config.key?(:terminator) && user_conditions.any? + halting_and_conditional(callback_sequence, user_callback, user_conditions, halted_lambda, filter) + elsif chain_config.key? :terminator + halting(callback_sequence, user_callback, halted_lambda, filter) + elsif user_conditions.any? + conditional(callback_sequence, user_callback, user_conditions) + else + simple callback_sequence, user_callback + end + end + + def self.halting_and_conditional(callback_sequence, user_callback, user_conditions, halted_lambda, filter) + callback_sequence.before do |env| + target = env.target + value = env.value + halted = env.halted + + if !halted && user_conditions.all? { |c| c.call(target, value) } + result = user_callback.call target, value + env.halted = halted_lambda.call(target, result) + if env.halted + target.send :halted_callback_hook, filter + end + end + + env + end + end + private_class_method :halting_and_conditional + + def self.halting(callback_sequence, user_callback, halted_lambda, filter) + callback_sequence.before do |env| + target = env.target + value = env.value + halted = env.halted + + unless halted + result = user_callback.call target, value + env.halted = halted_lambda.call(target, result) + if env.halted + target.send :halted_callback_hook, filter + end + end + + env + end + end + private_class_method :halting + + def self.conditional(callback_sequence, user_callback, user_conditions) + callback_sequence.before do |env| + target = env.target + value = env.value + + if user_conditions.all? { |c| c.call(target, value) } + user_callback.call target, value + end + + env + end + end + private_class_method :conditional + + def self.simple(callback_sequence, user_callback) + callback_sequence.before do |env| + user_callback.call env.target, env.value + + env + end + end + private_class_method :simple + end + + class After + def self.build(callback_sequence, user_callback, user_conditions, chain_config) + if chain_config[:skip_after_callbacks_if_terminated] + if chain_config.key?(:terminator) && user_conditions.any? + halting_and_conditional(callback_sequence, user_callback, user_conditions) + elsif chain_config.key?(:terminator) + halting(callback_sequence, user_callback) + elsif user_conditions.any? + conditional callback_sequence, user_callback, user_conditions + else + simple callback_sequence, user_callback + end + else + if user_conditions.any? + conditional callback_sequence, user_callback, user_conditions + else + simple callback_sequence, user_callback + end + end + end + + def self.halting_and_conditional(callback_sequence, user_callback, user_conditions) + callback_sequence.after do |env| + target = env.target + value = env.value + halted = env.halted + + if !halted && user_conditions.all? { |c| c.call(target, value) } + user_callback.call target, value + end + + env + end + end + private_class_method :halting_and_conditional + + def self.halting(callback_sequence, user_callback) + callback_sequence.after do |env| + unless env.halted + user_callback.call env.target, env.value + end + + env + end + end + private_class_method :halting + + def self.conditional(callback_sequence, user_callback, user_conditions) + callback_sequence.after do |env| + target = env.target + value = env.value + + if user_conditions.all? { |c| c.call(target, value) } + user_callback.call target, value + end + + env + end + end + private_class_method :conditional + + def self.simple(callback_sequence, user_callback) + callback_sequence.after do |env| + user_callback.call env.target, env.value + + env + end + end + private_class_method :simple + end + + class Around + def self.build(callback_sequence, user_callback, user_conditions, chain_config) + if chain_config.key?(:terminator) && user_conditions.any? + halting_and_conditional(callback_sequence, user_callback, user_conditions) + elsif chain_config.key? :terminator + halting(callback_sequence, user_callback) + elsif user_conditions.any? + conditional(callback_sequence, user_callback, user_conditions) + else + simple(callback_sequence, user_callback) + end + end + + def self.halting_and_conditional(callback_sequence, user_callback, user_conditions) + callback_sequence.around do |env, &run| + target = env.target + value = env.value + halted = env.halted + + if !halted && user_conditions.all? { |c| c.call(target, value) } + user_callback.call(target, value) { + env = run.call env + env.value + } + + env + else + run.call env + end + end + end + private_class_method :halting_and_conditional + + def self.halting(callback_sequence, user_callback) + callback_sequence.around do |env, &run| + target = env.target + value = env.value + + if env.halted + run.call env + else + user_callback.call(target, value) { + env = run.call env + env.value + } + env + end + end + end + private_class_method :halting + + def self.conditional(callback_sequence, user_callback, user_conditions) + callback_sequence.around do |env, &run| + target = env.target + value = env.value + + if user_conditions.all? { |c| c.call(target, value) } + user_callback.call(target, value) { + env = run.call env + env.value + } + env + else + run.call env + end + end + end + private_class_method :conditional + + def self.simple(callback_sequence, user_callback) + callback_sequence.around do |env, &run| + user_callback.call(env.target, env.value) { + env = run.call env + env.value + } + env + end + end + private_class_method :simple + end + end + + class Callback #:nodoc:# + def self.build(chain, filter, kind, options) + new chain.name, filter, kind, options, chain.config + end + + attr_accessor :kind, :name + attr_reader :chain_config + + def initialize(name, filter, kind, options, chain_config) + @chain_config = chain_config + @name = name + @kind = kind + @filter = filter + @key = compute_identifier filter + @if = Array(options[:if]) + @unless = Array(options[:unless]) + end + + def filter; @key; end + def raw_filter; @filter; end + + def merge(chain, new_options) + options = { + :if => @if.dup, + :unless => @unless.dup + } + + options[:if].concat Array(new_options.fetch(:unless, [])) + options[:unless].concat Array(new_options.fetch(:if, [])) + + self.class.build chain, @filter, @kind, options + end + + def matches?(_kind, _filter) + @kind == _kind && filter == _filter + end + + def duplicates?(other) + case @filter + when Symbol, String + matches?(other.kind, other.filter) + else + false + end + end + + # Wraps code with filter + def apply(callback_sequence) + user_conditions = conditions_lambdas + user_callback = make_lambda @filter + + case kind + when :before + Filters::Before.build(callback_sequence, user_callback, user_conditions, chain_config, @filter) + when :after + Filters::After.build(callback_sequence, user_callback, user_conditions, chain_config) + when :around + Filters::Around.build(callback_sequence, user_callback, user_conditions, chain_config) + end + end + + private + + def invert_lambda(l) + lambda { |*args, &blk| !l.call(*args, &blk) } + end + + # Filters support: + # + # Symbols:: A method to call. + # Strings:: Some content to evaluate. + # Procs:: A proc to call with the object. + # Objects:: An object with a before_foo method on it to call. + # + # All of these objects are converted into a lambda and handled + # the same after this point. + def make_lambda(filter) + case filter + when Symbol + lambda { |target, _, &blk| target.send filter, &blk } + when String + l = eval "lambda { |value| #{filter} }" + lambda { |target, value| target.instance_exec(value, &l) } + when Conditionals::Value then filter + when ::Proc + if filter.arity > 1 + return lambda { |target, _, &block| + raise ArgumentError unless block + target.instance_exec(target, block, &filter) + } + end + + if filter.arity <= 0 + lambda { |target, _| target.instance_exec(&filter) } + else + lambda { |target, _| target.instance_exec(target, &filter) } + end + else + scopes = Array(chain_config[:scope]) + method_to_call = scopes.map{ |s| public_send(s) }.join("_") + + lambda { |target, _, &blk| + filter.public_send method_to_call, target, &blk + } + end + end + + def compute_identifier(filter) + case filter + when String, ::Proc + filter.object_id + else + filter + end + end + + def conditions_lambdas + @if.map { |c| make_lambda c } + + @unless.map { |c| invert_lambda make_lambda c } + end + end + + # Execute before and after filters in a sequence instead of + # chaining them with nested lambda calls, see: + # https://github.com/rails/rails/issues/18011 + class CallbackSequence + def initialize(&call) + @call = call + @before = [] + @after = [] + end + + def before(&before) + @before.unshift(before) + self + end + + def after(&after) + @after.push(after) + self + end + + def around(&around) + CallbackSequence.new do |*args| + around.call(*args) { + self.call(*args) + } + end + end + + def call(*args) + @before.each { |b| b.call(*args) } + value = @call.call(*args) + @after.each { |a| a.call(*args) } + value + end + end + + # An Array with a compile method. + class CallbackChain #:nodoc:# + include Enumerable + + attr_reader :name, :config + + def initialize(name, config) + @name = name + @config = { + :scope => [ :kind ] + }.merge!(config) + @chain = [] + @callbacks = nil + @mutex = Mutex.new + end + + def each(&block); @chain.each(&block); end + def index(o); @chain.index(o); end + def empty?; @chain.empty?; end + + def insert(index, o) + @callbacks = nil + @chain.insert(index, o) + end + + def delete(o) + @callbacks = nil + @chain.delete(o) + end + + def clear + @callbacks = nil + @chain.clear + self + end + + def initialize_copy(other) + @callbacks = nil + @chain = other.chain.dup + @mutex = Mutex.new + end + + def compile + @callbacks || @mutex.synchronize do + final_sequence = CallbackSequence.new { |env| Filters::ENDING.call(env) } + @callbacks ||= @chain.reverse.inject(final_sequence) do |callback_sequence, callback| + callback.apply callback_sequence + end + end + end + + def append(*callbacks) + callbacks.each { |c| append_one(c) } + end + + def prepend(*callbacks) + callbacks.each { |c| prepend_one(c) } + end + + protected + def chain; @chain; end + + private + + def append_one(callback) + @callbacks = nil + remove_duplicates(callback) + @chain.push(callback) + end + + def prepend_one(callback) + @callbacks = nil + remove_duplicates(callback) + @chain.unshift(callback) + end + + def remove_duplicates(callback) + @callbacks = nil + @chain.delete_if { |c| callback.duplicates?(c) } + end + end + + module ClassMethods + def normalize_callback_params(filters, block) # :nodoc: + type = CALLBACK_FILTER_TYPES.include?(filters.first) ? filters.shift : :before + options = filters.extract_options! + filters.unshift(block) if block + [type, filters, options.dup] + end + + # This is used internally to append, prepend and skip callbacks to the + # CallbackChain. + def __update_callbacks(name) #:nodoc: + ([self] + ActiveSupport::DescendantsTracker.descendants(self)).reverse_each do |target| + chain = target.get_callbacks name + yield target, chain.dup + end + end + + # Install a callback for the given event. + # + # set_callback :save, :before, :before_meth + # set_callback :save, :after, :after_meth, if: :condition + # set_callback :save, :around, ->(r, block) { stuff; result = block.call; stuff } + # + # The second arguments indicates whether the callback is to be run +:before+, + # +:after+, or +:around+ the event. If omitted, +:before+ is assumed. This + # means the first example above can also be written as: + # + # set_callback :save, :before_meth + # + # The callback can be specified as a symbol naming an instance method; as a + # proc, lambda, or block; as a string to be instance evaluated; or as an + # object that responds to a certain method determined by the :scope + # argument to +define_callbacks+. + # + # If a proc, lambda, or block is given, its body is evaluated in the context + # of the current object. It can also optionally accept the current object as + # an argument. + # + # Before and around callbacks are called in the order that they are set; + # after callbacks are called in the reverse order. + # + # Around callbacks can access the return value from the event, if it + # wasn't halted, from the +yield+ call. + # + # ===== Options + # + # * :if - A symbol, a string or an array of symbols and strings, + # each naming an instance method or a proc; the callback will be called + # only when they all return a true value. + # * :unless - A symbol, a string or an array of symbols and + # strings, each naming an instance method or a proc; the callback will + # be called only when they all return a false value. + # * :prepend - If +true+, the callback will be prepended to the + # existing chain rather than appended. + def set_callback(name, *filter_list, &block) + type, filters, options = normalize_callback_params(filter_list, block) + self_chain = get_callbacks name + mapped = filters.map do |filter| + Callback.build(self_chain, filter, type, options) + end + + __update_callbacks(name) do |target, chain| + options[:prepend] ? chain.prepend(*mapped) : chain.append(*mapped) + target.set_callbacks name, chain + end + end + + # Skip a previously set callback. Like +set_callback+, :if or + # :unless options may be passed in order to control when the + # callback is skipped. + # + # class Writer < Person + # skip_callback :validate, :before, :check_membership, if: -> { self.age > 18 } + # end + def skip_callback(name, *filter_list, &block) + type, filters, options = normalize_callback_params(filter_list, block) + + __update_callbacks(name) do |target, chain| + filters.each do |filter| + filter = chain.find {|c| c.matches?(type, filter) } + + if filter && options.any? + new_filter = filter.merge(chain, options) + chain.insert(chain.index(filter), new_filter) + end + + chain.delete(filter) + end + target.set_callbacks name, chain + end + end + + # Remove all set callbacks for the given event. + def reset_callbacks(name) + callbacks = get_callbacks name + + ActiveSupport::DescendantsTracker.descendants(self).each do |target| + chain = target.get_callbacks(name).dup + callbacks.each { |c| chain.delete(c) } + target.set_callbacks name, chain + end + + self.set_callbacks name, callbacks.dup.clear + end + + # Define sets of events in the object life cycle that support callbacks. + # + # define_callbacks :validate + # define_callbacks :initialize, :save, :destroy + # + # ===== Options + # + # * :terminator - Determines when a before filter will halt the + # callback chain, preventing following callbacks from being called and + # the event from being triggered. This should be a lambda to be executed. + # The current object and the return result of the callback will be called + # with the lambda. + # + # define_callbacks :validate, terminator: ->(target, result) { result == false } + # + # In this example, if any before validate callbacks returns +false+, + # other callbacks are not executed. Defaults to +false+, meaning no value + # halts the chain. + # + # * :skip_after_callbacks_if_terminated - Determines if after + # callbacks should be terminated by the :terminator option. By + # default after callbacks executed no matter if callback chain was + # terminated or not. Option makes sense only when :terminator + # option is specified. + # + # * :scope - Indicates which methods should be executed when an + # object is used as a callback. + # + # class Audit + # def before(caller) + # puts 'Audit: before is called' + # end + # + # def before_save(caller) + # puts 'Audit: before_save is called' + # end + # end + # + # class Account + # include ActiveSupport::Callbacks + # + # define_callbacks :save + # set_callback :save, :before, Audit.new + # + # def save + # run_callbacks :save do + # puts 'save in main' + # end + # end + # end + # + # In the above case whenever you save an account the method + # Audit#before will be called. On the other hand + # + # define_callbacks :save, scope: [:kind, :name] + # + # would trigger Audit#before_save instead. That's constructed + # by calling #{kind}_#{name} on the given instance. In this + # case "kind" is "before" and "name" is "save". In this context +:kind+ + # and +:name+ have special meanings: +:kind+ refers to the kind of + # callback (before/after/around) and +:name+ refers to the method on + # which callbacks are being defined. + # + # A declaration like + # + # define_callbacks :save, scope: [:name] + # + # would call Audit#save. + # + # NOTE: +method_name+ passed to `define_model_callbacks` must not end with + # `!`, `?` or `=`. + def define_callbacks(*names) + options = names.extract_options! + + names.each do |name| + class_attribute "_#{name}_callbacks", instance_writer: false + set_callbacks name, CallbackChain.new(name, options) + + module_eval <<-RUBY, __FILE__, __LINE__ + 1 + def _run_#{name}_callbacks(&block) + __run_callbacks__(_#{name}_callbacks, &block) + end + RUBY + end + end + + protected + + def get_callbacks(name) + send "_#{name}_callbacks" + end + + def set_callbacks(name, callbacks) + send "_#{name}_callbacks=", callbacks + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/concern.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/concern.rb new file mode 100644 index 0000000..2df9fd5 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/concern.rb @@ -0,0 +1,142 @@ +module ActiveSupport + # A typical module looks like this: + # + # module M + # def self.included(base) + # base.extend ClassMethods + # base.class_eval do + # scope :disabled, -> { where(disabled: true) } + # end + # end + # + # module ClassMethods + # ... + # end + # end + # + # By using ActiveSupport::Concern the above module could instead be + # written as: + # + # require 'active_support/concern' + # + # module M + # extend ActiveSupport::Concern + # + # included do + # scope :disabled, -> { where(disabled: true) } + # end + # + # class_methods do + # ... + # end + # end + # + # Moreover, it gracefully handles module dependencies. Given a +Foo+ module + # and a +Bar+ module which depends on the former, we would typically write the + # following: + # + # module Foo + # def self.included(base) + # base.class_eval do + # def self.method_injected_by_foo + # ... + # end + # end + # end + # end + # + # module Bar + # def self.included(base) + # base.method_injected_by_foo + # end + # end + # + # class Host + # include Foo # We need to include this dependency for Bar + # include Bar # Bar is the module that Host really needs + # end + # + # But why should +Host+ care about +Bar+'s dependencies, namely +Foo+? We + # could try to hide these from +Host+ directly including +Foo+ in +Bar+: + # + # module Bar + # include Foo + # def self.included(base) + # base.method_injected_by_foo + # end + # end + # + # class Host + # include Bar + # end + # + # Unfortunately this won't work, since when +Foo+ is included, its base + # is the +Bar+ module, not the +Host+ class. With ActiveSupport::Concern, + # module dependencies are properly resolved: + # + # require 'active_support/concern' + # + # module Foo + # extend ActiveSupport::Concern + # included do + # def self.method_injected_by_foo + # ... + # end + # end + # end + # + # module Bar + # extend ActiveSupport::Concern + # include Foo + # + # included do + # self.method_injected_by_foo + # end + # end + # + # class Host + # include Bar # It works, now Bar takes care of its dependencies + # end + module Concern + class MultipleIncludedBlocks < StandardError #:nodoc: + def initialize + super "Cannot define multiple 'included' blocks for a Concern" + end + end + + def self.extended(base) #:nodoc: + base.instance_variable_set(:@_dependencies, []) + end + + def append_features(base) + if base.instance_variable_defined?(:@_dependencies) + base.instance_variable_get(:@_dependencies) << self + return false + else + return false if base < self + @_dependencies.each { |dep| base.send(:include, dep) } + super + base.extend const_get(:ClassMethods) if const_defined?(:ClassMethods) + base.class_eval(&@_included_block) if instance_variable_defined?(:@_included_block) + end + end + + def included(base = nil, &block) + if base.nil? + raise MultipleIncludedBlocks if instance_variable_defined?(:@_included_block) + + @_included_block = block + else + super + end + end + + def class_methods(&class_methods_module_definition) + mod = const_defined?(:ClassMethods, false) ? + const_get(:ClassMethods) : + const_set(:ClassMethods, Module.new) + + mod.module_eval(&class_methods_module_definition) + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/concurrency/latch.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/concurrency/latch.rb new file mode 100644 index 0000000..1507de4 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/concurrency/latch.rb @@ -0,0 +1,27 @@ +require 'thread' +require 'monitor' + +module ActiveSupport + module Concurrency + class Latch + def initialize(count = 1) + @count = count + @lock = Monitor.new + @cv = @lock.new_cond + end + + def release + @lock.synchronize do + @count -= 1 if @count > 0 + @cv.broadcast if @count.zero? + end + end + + def await + @lock.synchronize do + @cv.wait_while { @count > 0 } + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/configurable.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/configurable.rb new file mode 100644 index 0000000..3dd44e3 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/configurable.rb @@ -0,0 +1,147 @@ +require 'active_support/concern' +require 'active_support/ordered_options' +require 'active_support/core_ext/array/extract_options' + +module ActiveSupport + # Configurable provides a config method to store and retrieve + # configuration options as an OrderedHash. + module Configurable + extend ActiveSupport::Concern + + class Configuration < ActiveSupport::InheritableOptions + def compile_methods! + self.class.compile_methods!(keys) + end + + # Compiles reader methods so we don't have to go through method_missing. + def self.compile_methods!(keys) + keys.reject { |m| method_defined?(m) }.each do |key| + class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def #{key}; _get(#{key.inspect}); end + RUBY + end + end + end + + module ClassMethods + def config + @_config ||= if respond_to?(:superclass) && superclass.respond_to?(:config) + superclass.config.inheritable_copy + else + # create a new "anonymous" class that will host the compiled reader methods + Class.new(Configuration).new + end + end + + def configure + yield config + end + + # Allows you to add shortcut so that you don't have to refer to attribute + # through config. Also look at the example for config to contrast. + # + # Defines both class and instance config accessors. + # + # class User + # include ActiveSupport::Configurable + # config_accessor :allowed_access + # end + # + # User.allowed_access # => nil + # User.allowed_access = false + # User.allowed_access # => false + # + # user = User.new + # user.allowed_access # => false + # user.allowed_access = true + # user.allowed_access # => true + # + # User.allowed_access # => false + # + # The attribute name must be a valid method name in Ruby. + # + # class User + # include ActiveSupport::Configurable + # config_accessor :"1_Badname" + # end + # # => NameError: invalid config attribute name + # + # To opt out of the instance writer method, pass instance_writer: false. + # To opt out of the instance reader method, pass instance_reader: false. + # + # class User + # include ActiveSupport::Configurable + # config_accessor :allowed_access, instance_reader: false, instance_writer: false + # end + # + # User.allowed_access = false + # User.allowed_access # => false + # + # User.new.allowed_access = true # => NoMethodError + # User.new.allowed_access # => NoMethodError + # + # Or pass instance_accessor: false, to opt out both instance methods. + # + # class User + # include ActiveSupport::Configurable + # config_accessor :allowed_access, instance_accessor: false + # end + # + # User.allowed_access = false + # User.allowed_access # => false + # + # User.new.allowed_access = true # => NoMethodError + # User.new.allowed_access # => NoMethodError + # + # Also you can pass a block to set up the attribute with a default value. + # + # class User + # include ActiveSupport::Configurable + # config_accessor :hair_colors do + # [:brown, :black, :blonde, :red] + # end + # end + # + # User.hair_colors # => [:brown, :black, :blonde, :red] + def config_accessor(*names) + options = names.extract_options! + + names.each do |name| + raise NameError.new('invalid config attribute name') unless name =~ /\A[_A-Za-z]\w*\z/ + + reader, reader_line = "def #{name}; config.#{name}; end", __LINE__ + writer, writer_line = "def #{name}=(value); config.#{name} = value; end", __LINE__ + + singleton_class.class_eval reader, __FILE__, reader_line + singleton_class.class_eval writer, __FILE__, writer_line + + unless options[:instance_accessor] == false + class_eval reader, __FILE__, reader_line unless options[:instance_reader] == false + class_eval writer, __FILE__, writer_line unless options[:instance_writer] == false + end + send("#{name}=", yield) if block_given? + end + end + end + + # Reads and writes attributes from a configuration OrderedHash. + # + # require 'active_support/configurable' + # + # class User + # include ActiveSupport::Configurable + # end + # + # user = User.new + # + # user.config.allowed_access = true + # user.config.level = 1 + # + # user.config.allowed_access # => true + # user.config.level # => 1 + def config + @_config ||= self.class.config.inheritable_copy + end + end +end + diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext.rb new file mode 100644 index 0000000..199aa91 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext.rb @@ -0,0 +1,3 @@ +Dir["#{File.dirname(__FILE__)}/core_ext/*.rb"].each do |path| + require path +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/array.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/array.rb new file mode 100644 index 0000000..7d0c1e4 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/array.rb @@ -0,0 +1,6 @@ +require 'active_support/core_ext/array/wrap' +require 'active_support/core_ext/array/access' +require 'active_support/core_ext/array/conversions' +require 'active_support/core_ext/array/extract_options' +require 'active_support/core_ext/array/grouping' +require 'active_support/core_ext/array/prepend_and_append' diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/array/access.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/array/access.rb new file mode 100644 index 0000000..45b89d2 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/array/access.rb @@ -0,0 +1,64 @@ +class Array + # Returns the tail of the array from +position+. + # + # %w( a b c d ).from(0) # => ["a", "b", "c", "d"] + # %w( a b c d ).from(2) # => ["c", "d"] + # %w( a b c d ).from(10) # => [] + # %w().from(0) # => [] + # %w( a b c d ).from(-2) # => ["c", "d"] + # %w( a b c ).from(-10) # => [] + def from(position) + self[position, length] || [] + end + + # Returns the beginning of the array up to +position+. + # + # %w( a b c d ).to(0) # => ["a"] + # %w( a b c d ).to(2) # => ["a", "b", "c"] + # %w( a b c d ).to(10) # => ["a", "b", "c", "d"] + # %w().to(0) # => [] + # %w( a b c d ).to(-2) # => ["a", "b", "c"] + # %w( a b c ).to(-10) # => [] + def to(position) + if position >= 0 + first position + 1 + else + self[0..position] + end + end + + # Equal to self[1]. + # + # %w( a b c d e ).second # => "b" + def second + self[1] + end + + # Equal to self[2]. + # + # %w( a b c d e ).third # => "c" + def third + self[2] + end + + # Equal to self[3]. + # + # %w( a b c d e ).fourth # => "d" + def fourth + self[3] + end + + # Equal to self[4]. + # + # %w( a b c d e ).fifth # => "e" + def fifth + self[4] + end + + # Equal to self[41]. Also known as accessing "the reddit". + # + # (1..42).to_a.forty_two # => 42 + def forty_two + self[41] + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/array/conversions.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/array/conversions.rb new file mode 100644 index 0000000..76ffd23 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/array/conversions.rb @@ -0,0 +1,209 @@ +require 'active_support/xml_mini' +require 'active_support/core_ext/hash/keys' +require 'active_support/core_ext/string/inflections' +require 'active_support/core_ext/object/to_param' +require 'active_support/core_ext/object/to_query' + +class Array + # Converts the array to a comma-separated sentence where the last element is + # joined by the connector word. + # + # You can pass the following options to change the default behavior. If you + # pass an option key that doesn't exist in the list below, it will raise an + # ArgumentError. + # + # ==== Options + # + # * :words_connector - The sign or word used to join the elements + # in arrays with two or more elements (default: ", "). + # * :two_words_connector - The sign or word used to join the elements + # in arrays with two elements (default: " and "). + # * :last_word_connector - The sign or word used to join the last element + # in arrays with three or more elements (default: ", and "). + # * :locale - If +i18n+ is available, you can set a locale and use + # the connector options defined on the 'support.array' namespace in the + # corresponding dictionary file. + # + # ==== Examples + # + # [].to_sentence # => "" + # ['one'].to_sentence # => "one" + # ['one', 'two'].to_sentence # => "one and two" + # ['one', 'two', 'three'].to_sentence # => "one, two, and three" + # + # ['one', 'two'].to_sentence(passing: 'invalid option') + # # => ArgumentError: Unknown key :passing + # + # ['one', 'two'].to_sentence(two_words_connector: '-') + # # => "one-two" + # + # ['one', 'two', 'three'].to_sentence(words_connector: ' or ', last_word_connector: ' or at least ') + # # => "one or two or at least three" + # + # Using :locale option: + # + # # Given this locale dictionary: + # # + # # es: + # # support: + # # array: + # # words_connector: " o " + # # two_words_connector: " y " + # # last_word_connector: " o al menos " + # + # ['uno', 'dos'].to_sentence(locale: :es) + # # => "uno y dos" + # + # ['uno', 'dos', 'tres'].to_sentence(locale: :es) + # # => "uno o dos o al menos tres" + def to_sentence(options = {}) + options.assert_valid_keys(:words_connector, :two_words_connector, :last_word_connector, :locale) + + default_connectors = { + :words_connector => ', ', + :two_words_connector => ' and ', + :last_word_connector => ', and ' + } + if defined?(I18n) + i18n_connectors = I18n.translate(:'support.array', locale: options[:locale], default: {}) + default_connectors.merge!(i18n_connectors) + end + options = default_connectors.merge!(options) + + case length + when 0 + '' + when 1 + self[0].to_s.dup + when 2 + "#{self[0]}#{options[:two_words_connector]}#{self[1]}" + else + "#{self[0...-1].join(options[:words_connector])}#{options[:last_word_connector]}#{self[-1]}" + end + end + + # Extends Array#to_s to convert a collection of elements into a + # comma separated id list if :db argument is given as the format. + # + # Blog.all.to_formatted_s(:db) # => "1,2,3" + def to_formatted_s(format = :default) + case format + when :db + if empty? + 'null' + else + collect { |element| element.id }.join(',') + end + else + to_default_s + end + end + alias_method :to_default_s, :to_s + alias_method :to_s, :to_formatted_s + + # Returns a string that represents the array in XML by invoking +to_xml+ + # on each element. Active Record collections delegate their representation + # in XML to this method. + # + # All elements are expected to respond to +to_xml+, if any of them does + # not then an exception is raised. + # + # The root node reflects the class name of the first element in plural + # if all elements belong to the same type and that's not Hash: + # + # customer.projects.to_xml + # + # + # + # + # 20000.0 + # 1567 + # 2008-04-09 + # ... + # + # + # 57230.0 + # 1567 + # 2008-04-15 + # ... + # + # + # + # Otherwise the root element is "objects": + # + # [{ foo: 1, bar: 2}, { baz: 3}].to_xml + # + # + # + # + # 2 + # 1 + # + # + # 3 + # + # + # + # If the collection is empty the root element is "nil-classes" by default: + # + # [].to_xml + # + # + # + # + # To ensure a meaningful root element use the :root option: + # + # customer_with_no_projects.projects.to_xml(root: 'projects') + # + # + # + # + # By default name of the node for the children of root is root.singularize. + # You can change it with the :children option. + # + # The +options+ hash is passed downwards: + # + # Message.all.to_xml(skip_types: true) + # + # + # + # + # 2008-03-07T09:58:18+01:00 + # 1 + # 1 + # 2008-03-07T09:58:18+01:00 + # 1 + # + # + # + def to_xml(options = {}) + require 'active_support/builder' unless defined?(Builder) + + options = options.dup + options[:indent] ||= 2 + options[:builder] ||= Builder::XmlMarkup.new(indent: options[:indent]) + options[:root] ||= \ + if first.class != Hash && all? { |e| e.is_a?(first.class) } + underscored = ActiveSupport::Inflector.underscore(first.class.name) + ActiveSupport::Inflector.pluralize(underscored).tr('/', '_') + else + 'objects' + end + + builder = options[:builder] + builder.instruct! unless options.delete(:skip_instruct) + + root = ActiveSupport::XmlMini.rename_key(options[:root].to_s, options) + children = options.delete(:children) || root.singularize + attributes = options[:skip_types] ? {} : { type: 'array' } + + if empty? + builder.tag!(root, attributes) + else + builder.tag!(root, attributes) do + each { |value| ActiveSupport::XmlMini.to_tag(children, value, options) } + yield builder if block_given? + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/array/extract_options.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/array/extract_options.rb new file mode 100644 index 0000000..9008a0d --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/array/extract_options.rb @@ -0,0 +1,29 @@ +class Hash + # By default, only instances of Hash itself are extractable. + # Subclasses of Hash may implement this method and return + # true to declare themselves as extractable. If a Hash + # is extractable, Array#extract_options! pops it from + # the Array when it is the last element of the Array. + def extractable_options? + instance_of?(Hash) + end +end + +class Array + # Extracts options from a set of arguments. Removes and returns the last + # element in the array if it's a hash, otherwise returns a blank hash. + # + # def options(*args) + # args.extract_options! + # end + # + # options(1, 2) # => {} + # options(1, 2, a: :b) # => {:a=>:b} + def extract_options! + if last.is_a?(Hash) && last.extractable_options? + pop + else + {} + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/array/grouping.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/array/grouping.rb new file mode 100644 index 0000000..87ae052 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/array/grouping.rb @@ -0,0 +1,116 @@ +class Array + # Splits or iterates over the array in groups of size +number+, + # padding any remaining slots with +fill_with+ unless it is +false+. + # + # %w(1 2 3 4 5 6 7 8 9 10).in_groups_of(3) {|group| p group} + # ["1", "2", "3"] + # ["4", "5", "6"] + # ["7", "8", "9"] + # ["10", nil, nil] + # + # %w(1 2 3 4 5).in_groups_of(2, ' ') {|group| p group} + # ["1", "2"] + # ["3", "4"] + # ["5", " "] + # + # %w(1 2 3 4 5).in_groups_of(2, false) {|group| p group} + # ["1", "2"] + # ["3", "4"] + # ["5"] + def in_groups_of(number, fill_with = nil) + if number.to_i <= 0 + raise ArgumentError, + "Group size must be a positive integer, was #{number.inspect}" + end + + if fill_with == false + collection = self + else + # size % number gives how many extra we have; + # subtracting from number gives how many to add; + # modulo number ensures we don't add group of just fill. + padding = (number - size % number) % number + collection = dup.concat(Array.new(padding, fill_with)) + end + + if block_given? + collection.each_slice(number) { |slice| yield(slice) } + else + collection.each_slice(number).to_a + end + end + + # Splits or iterates over the array in +number+ of groups, padding any + # remaining slots with +fill_with+ unless it is +false+. + # + # %w(1 2 3 4 5 6 7 8 9 10).in_groups(3) {|group| p group} + # ["1", "2", "3", "4"] + # ["5", "6", "7", nil] + # ["8", "9", "10", nil] + # + # %w(1 2 3 4 5 6 7 8 9 10).in_groups(3, ' ') {|group| p group} + # ["1", "2", "3", "4"] + # ["5", "6", "7", " "] + # ["8", "9", "10", " "] + # + # %w(1 2 3 4 5 6 7).in_groups(3, false) {|group| p group} + # ["1", "2", "3"] + # ["4", "5"] + # ["6", "7"] + def in_groups(number, fill_with = nil) + # size.div number gives minor group size; + # size % number gives how many objects need extra accommodation; + # each group hold either division or division + 1 items. + division = size.div number + modulo = size % number + + # create a new array avoiding dup + groups = [] + start = 0 + + number.times do |index| + length = division + (modulo > 0 && modulo > index ? 1 : 0) + groups << last_group = slice(start, length) + last_group << fill_with if fill_with != false && + modulo > 0 && length == division + start += length + end + + if block_given? + groups.each { |g| yield(g) } + else + groups + end + end + + # Divides the array into one or more subarrays based on a delimiting +value+ + # or the result of an optional block. + # + # [1, 2, 3, 4, 5].split(3) # => [[1, 2], [4, 5]] + # (1..10).to_a.split { |i| i % 3 == 0 } # => [[1, 2], [4, 5], [7, 8], [10]] + def split(value = nil) + if block_given? + inject([[]]) do |results, element| + if yield(element) + results << [] + else + results.last << element + end + + results + end + else + results, arr = [[]], self.dup + until arr.empty? + if (idx = arr.index(value)) + results.last.concat(arr.shift(idx)) + arr.shift + results << [] + else + results.last.concat(arr.shift(arr.size)) + end + end + results + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/array/prepend_and_append.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/array/prepend_and_append.rb new file mode 100644 index 0000000..f8d48b6 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/array/prepend_and_append.rb @@ -0,0 +1,7 @@ +class Array + # The human way of thinking about adding stuff to the end of a list is with append. + alias_method :append, :<< + + # The human way of thinking about adding stuff to the beginning of a list is with prepend. + alias_method :prepend, :unshift +end \ No newline at end of file diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/array/wrap.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/array/wrap.rb new file mode 100644 index 0000000..152eb02 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/array/wrap.rb @@ -0,0 +1,45 @@ +class Array + # Wraps its argument in an array unless it is already an array (or array-like). + # + # Specifically: + # + # * If the argument is +nil+ an empty list is returned. + # * Otherwise, if the argument responds to +to_ary+ it is invoked, and its result returned. + # * Otherwise, returns an array with the argument as its single element. + # + # Array.wrap(nil) # => [] + # Array.wrap([1, 2, 3]) # => [1, 2, 3] + # Array.wrap(0) # => [0] + # + # This method is similar in purpose to Kernel#Array, but there are some differences: + # + # * If the argument responds to +to_ary+ the method is invoked. Kernel#Array + # moves on to try +to_a+ if the returned value is +nil+, but Array.wrap returns + # +nil+ right away. + # * If the returned value from +to_ary+ is neither +nil+ nor an +Array+ object, Kernel#Array + # raises an exception, while Array.wrap does not, it just returns the value. + # * It does not call +to_a+ on the argument, but returns an empty array if argument is +nil+. + # + # The second point is easily explained with some enumerables: + # + # Array(foo: :bar) # => [[:foo, :bar]] + # Array.wrap(foo: :bar) # => [{:foo=>:bar}] + # + # There's also a related idiom that uses the splat operator: + # + # [*object] + # + # which returns [] for +nil+, but calls to Array(object) otherwise. + # + # The differences with Kernel#Array explained above + # apply to the rest of objects. + def self.wrap(object) + if object.nil? + [] + elsif object.respond_to?(:to_ary) + object.to_ary || [object] + else + [object] + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/benchmark.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/benchmark.rb new file mode 100644 index 0000000..eb25b2b --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/benchmark.rb @@ -0,0 +1,14 @@ +require 'benchmark' + +class << Benchmark + # Benchmark realtime in milliseconds. + # + # Benchmark.realtime { User.all } + # # => 8.0e-05 + # + # Benchmark.ms { User.all } + # # => 0.074 + def ms + 1000 * realtime { yield } + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/big_decimal.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/big_decimal.rb new file mode 100644 index 0000000..8143113 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/big_decimal.rb @@ -0,0 +1 @@ +require 'active_support/core_ext/big_decimal/conversions' diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/big_decimal/conversions.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/big_decimal/conversions.rb new file mode 100644 index 0000000..843c592 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/big_decimal/conversions.rb @@ -0,0 +1,16 @@ +require 'bigdecimal' +require 'bigdecimal/util' + +class BigDecimal + DEFAULT_STRING_FORMAT = 'F' + def to_formatted_s(*args) + if args[0].is_a?(Symbol) + super + else + format = args[0] || DEFAULT_STRING_FORMAT + _original_to_s(format) + end + end + alias_method :_original_to_s, :to_s + alias_method :to_s, :to_formatted_s +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/big_decimal/yaml_conversions.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/big_decimal/yaml_conversions.rb new file mode 100644 index 0000000..344c425 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/big_decimal/yaml_conversions.rb @@ -0,0 +1,16 @@ +require 'active_support/deprecation' + +ActiveSupport::Deprecation.warn 'core_ext/big_decimal/yaml_conversions is deprecated and will be removed in the future.' + +require 'bigdecimal' +require 'yaml' +require 'active_support/core_ext/big_decimal/conversions' + +class BigDecimal + YAML_MAPPING = { 'Infinity' => '.Inf', '-Infinity' => '-.Inf', 'NaN' => '.NaN' } + + def encode_with(coder) + string = to_s + coder.represent_scalar(nil, YAML_MAPPING[string] || string) + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/class.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/class.rb new file mode 100644 index 0000000..c750a10 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/class.rb @@ -0,0 +1,3 @@ +require 'active_support/core_ext/class/attribute' +require 'active_support/core_ext/class/delegating_attributes' +require 'active_support/core_ext/class/subclasses' diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/class/attribute.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/class/attribute.rb new file mode 100644 index 0000000..f2a221c --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/class/attribute.rb @@ -0,0 +1,127 @@ +require 'active_support/core_ext/kernel/singleton_class' +require 'active_support/core_ext/module/remove_method' +require 'active_support/core_ext/array/extract_options' + +class Class + # Declare a class-level attribute whose value is inheritable by subclasses. + # Subclasses can change their own value and it will not impact parent class. + # + # class Base + # class_attribute :setting + # end + # + # class Subclass < Base + # end + # + # Base.setting = true + # Subclass.setting # => true + # Subclass.setting = false + # Subclass.setting # => false + # Base.setting # => true + # + # In the above case as long as Subclass does not assign a value to setting + # by performing Subclass.setting = _something_ , Subclass.setting + # would read value assigned to parent class. Once Subclass assigns a value then + # the value assigned by Subclass would be returned. + # + # This matches normal Ruby method inheritance: think of writing an attribute + # on a subclass as overriding the reader method. However, you need to be aware + # when using +class_attribute+ with mutable structures as +Array+ or +Hash+. + # In such cases, you don't want to do changes in places but use setters: + # + # Base.setting = [] + # Base.setting # => [] + # Subclass.setting # => [] + # + # # Appending in child changes both parent and child because it is the same object: + # Subclass.setting << :foo + # Base.setting # => [:foo] + # Subclass.setting # => [:foo] + # + # # Use setters to not propagate changes: + # Base.setting = [] + # Subclass.setting += [:foo] + # Base.setting # => [] + # Subclass.setting # => [:foo] + # + # For convenience, an instance predicate method is defined as well. + # To skip it, pass instance_predicate: false. + # + # Subclass.setting? # => false + # + # Instances may overwrite the class value in the same way: + # + # Base.setting = true + # object = Base.new + # object.setting # => true + # object.setting = false + # object.setting # => false + # Base.setting # => true + # + # To opt out of the instance reader method, pass instance_reader: false. + # + # object.setting # => NoMethodError + # object.setting? # => NoMethodError + # + # To opt out of the instance writer method, pass instance_writer: false. + # + # object.setting = false # => NoMethodError + # + # To opt out of both instance methods, pass instance_accessor: false. + def class_attribute(*attrs) + options = attrs.extract_options! + instance_reader = options.fetch(:instance_accessor, true) && options.fetch(:instance_reader, true) + instance_writer = options.fetch(:instance_accessor, true) && options.fetch(:instance_writer, true) + instance_predicate = options.fetch(:instance_predicate, true) + + attrs.each do |name| + define_singleton_method(name) { nil } + define_singleton_method("#{name}?") { !!public_send(name) } if instance_predicate + + ivar = "@#{name}" + + define_singleton_method("#{name}=") do |val| + singleton_class.class_eval do + remove_possible_method(name) + define_method(name) { val } + end + + if singleton_class? + class_eval do + remove_possible_method(name) + define_method(name) do + if instance_variable_defined? ivar + instance_variable_get ivar + else + singleton_class.send name + end + end + end + end + val + end + + if instance_reader + remove_possible_method name + define_method(name) do + if instance_variable_defined?(ivar) + instance_variable_get ivar + else + self.class.public_send name + end + end + define_method("#{name}?") { !!public_send(name) } if instance_predicate + end + + attr_writer name if instance_writer + end + end + + private + + unless respond_to?(:singleton_class?) + def singleton_class? + ancestors.first != self + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/class/attribute_accessors.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/class/attribute_accessors.rb new file mode 100644 index 0000000..84d5e95 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/class/attribute_accessors.rb @@ -0,0 +1,4 @@ +# cattr_* became mattr_* aliases in 7dfbd91b0780fbd6a1dd9bfbc176e10894871d2d, +# but we keep this around for libraries that directly require it knowing they +# want cattr_*. No need to deprecate. +require 'active_support/core_ext/module/attribute_accessors' diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/class/delegating_attributes.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/class/delegating_attributes.rb new file mode 100644 index 0000000..1c305c5 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/class/delegating_attributes.rb @@ -0,0 +1,45 @@ +require 'active_support/core_ext/kernel/singleton_class' +require 'active_support/core_ext/module/remove_method' +require 'active_support/core_ext/module/deprecation' + + +class Class + def superclass_delegating_accessor(name, options = {}) + # Create private _name and _name= methods that can still be used if the public + # methods are overridden. + _superclass_delegating_accessor("_#{name}", options) + + # Generate the public methods name, name=, and name?. + # These methods dispatch to the private _name, and _name= methods, making them + # overridable. + singleton_class.send(:define_method, name) { send("_#{name}") } + singleton_class.send(:define_method, "#{name}?") { !!send("_#{name}") } + singleton_class.send(:define_method, "#{name}=") { |value| send("_#{name}=", value) } + + # If an instance_reader is needed, generate public instance methods name and name?. + if options[:instance_reader] != false + define_method(name) { send("_#{name}") } + define_method("#{name}?") { !!send("#{name}") } + end + end + + deprecate superclass_delegating_accessor: :class_attribute + + private + # Take the object being set and store it in a method. This gives us automatic + # inheritance behavior, without having to store the object in an instance + # variable and look up the superclass chain manually. + def _stash_object_in_method(object, method, instance_reader = true) + singleton_class.remove_possible_method(method) + singleton_class.send(:define_method, method) { object } + remove_possible_method(method) + define_method(method) { object } if instance_reader + end + + def _superclass_delegating_accessor(name, options = {}) + singleton_class.send(:define_method, "#{name}=") do |value| + _stash_object_in_method(value, name, options[:instance_reader] != false) + end + send("#{name}=", nil) + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/class/subclasses.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/class/subclasses.rb new file mode 100644 index 0000000..3c4bfc5 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/class/subclasses.rb @@ -0,0 +1,42 @@ +require 'active_support/core_ext/module/anonymous' +require 'active_support/core_ext/module/reachable' + +class Class + begin + ObjectSpace.each_object(Class.new) {} + + def descendants # :nodoc: + descendants = [] + ObjectSpace.each_object(singleton_class) do |k| + descendants.unshift k unless k == self + end + descendants + end + rescue StandardError # JRuby + def descendants # :nodoc: + descendants = [] + ObjectSpace.each_object(Class) do |k| + descendants.unshift k if k < self + end + descendants.uniq! + descendants + end + end + + # Returns an array with the direct children of +self+. + # + # Integer.subclasses # => [Fixnum, Bignum] + # + # class Foo; end + # class Bar < Foo; end + # class Baz < Bar; end + # + # Foo.subclasses # => [Bar] + def subclasses + subclasses, chain = [], descendants + chain.each do |k| + subclasses << k unless chain.any? { |c| c > k } + end + subclasses + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/date.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/date.rb new file mode 100644 index 0000000..465fedd --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/date.rb @@ -0,0 +1,5 @@ +require 'active_support/core_ext/date/acts_like' +require 'active_support/core_ext/date/calculations' +require 'active_support/core_ext/date/conversions' +require 'active_support/core_ext/date/zones' + diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/date/acts_like.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/date/acts_like.rb new file mode 100644 index 0000000..cd90cee --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/date/acts_like.rb @@ -0,0 +1,8 @@ +require 'active_support/core_ext/object/acts_like' + +class Date + # Duck-types as a Date-like class. See Object#acts_like?. + def acts_like_date? + true + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/date/calculations.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/date/calculations.rb new file mode 100644 index 0000000..c60e833 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/date/calculations.rb @@ -0,0 +1,143 @@ +require 'date' +require 'active_support/duration' +require 'active_support/core_ext/object/acts_like' +require 'active_support/core_ext/date/zones' +require 'active_support/core_ext/time/zones' +require 'active_support/core_ext/date_and_time/calculations' + +class Date + include DateAndTime::Calculations + + class << self + attr_accessor :beginning_of_week_default + + # Returns the week start (e.g. :monday) for the current request, if this has been set (via Date.beginning_of_week=). + # If Date.beginning_of_week has not been set for the current request, returns the week start specified in config.beginning_of_week. + # If no config.beginning_of_week was specified, returns :monday. + def beginning_of_week + Thread.current[:beginning_of_week] || beginning_of_week_default || :monday + end + + # Sets Date.beginning_of_week to a week start (e.g. :monday) for current request/thread. + # + # This method accepts any of the following day symbols: + # :monday, :tuesday, :wednesday, :thursday, :friday, :saturday, :sunday + def beginning_of_week=(week_start) + Thread.current[:beginning_of_week] = find_beginning_of_week!(week_start) + end + + # Returns week start day symbol (e.g. :monday), or raises an ArgumentError for invalid day symbol. + def find_beginning_of_week!(week_start) + raise ArgumentError, "Invalid beginning of week: #{week_start}" unless ::Date::DAYS_INTO_WEEK.key?(week_start) + week_start + end + + # Returns a new Date representing the date 1 day ago (i.e. yesterday's date). + def yesterday + ::Date.current.yesterday + end + + # Returns a new Date representing the date 1 day after today (i.e. tomorrow's date). + def tomorrow + ::Date.current.tomorrow + end + + # Returns Time.zone.today when Time.zone or config.time_zone are set, otherwise just returns Date.today. + def current + ::Time.zone ? ::Time.zone.today : ::Date.today + end + end + + # Converts Date to a Time (or DateTime if necessary) with the time portion set to the beginning of the day (0:00) + # and then subtracts the specified number of seconds. + def ago(seconds) + in_time_zone.since(-seconds) + end + + # Converts Date to a Time (or DateTime if necessary) with the time portion set to the beginning of the day (0:00) + # and then adds the specified number of seconds + def since(seconds) + in_time_zone.since(seconds) + end + alias :in :since + + # Converts Date to a Time (or DateTime if necessary) with the time portion set to the beginning of the day (0:00) + def beginning_of_day + in_time_zone + end + alias :midnight :beginning_of_day + alias :at_midnight :beginning_of_day + alias :at_beginning_of_day :beginning_of_day + + # Converts Date to a Time (or DateTime if necessary) with the time portion set to the middle of the day (12:00) + def middle_of_day + in_time_zone.middle_of_day + end + alias :midday :middle_of_day + alias :noon :middle_of_day + alias :at_midday :middle_of_day + alias :at_noon :middle_of_day + alias :at_middle_of_day :middle_of_day + + # Converts Date to a Time (or DateTime if necessary) with the time portion set to the end of the day (23:59:59) + def end_of_day + in_time_zone.end_of_day + end + alias :at_end_of_day :end_of_day + + def plus_with_duration(other) #:nodoc: + if ActiveSupport::Duration === other + other.since(self) + else + plus_without_duration(other) + end + end + alias_method :plus_without_duration, :+ + alias_method :+, :plus_with_duration + + def minus_with_duration(other) #:nodoc: + if ActiveSupport::Duration === other + plus_with_duration(-other) + else + minus_without_duration(other) + end + end + alias_method :minus_without_duration, :- + alias_method :-, :minus_with_duration + + # Provides precise Date calculations for years, months, and days. The +options+ parameter takes a hash with + # any of these keys: :years, :months, :weeks, :days. + def advance(options) + options = options.dup + d = self + d = d >> options.delete(:years) * 12 if options[:years] + d = d >> options.delete(:months) if options[:months] + d = d + options.delete(:weeks) * 7 if options[:weeks] + d = d + options.delete(:days) if options[:days] + d + end + + # Returns a new Date where one or more of the elements have been changed according to the +options+ parameter. + # The +options+ parameter is a hash with a combination of these keys: :year, :month, :day. + # + # Date.new(2007, 5, 12).change(day: 1) # => Date.new(2007, 5, 1) + # Date.new(2007, 5, 12).change(year: 2005, month: 1) # => Date.new(2005, 1, 12) + def change(options) + ::Date.new( + options.fetch(:year, year), + options.fetch(:month, month), + options.fetch(:day, day) + ) + end + + # Allow Date to be compared with Time by converting to DateTime and relying on the <=> from there. + def compare_with_coercion(other) + if other.is_a?(Time) + self.to_datetime <=> other + else + compare_without_coercion(other) + end + end + alias_method :compare_without_coercion, :<=> + alias_method :<=>, :compare_with_coercion +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/date/conversions.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/date/conversions.rb new file mode 100644 index 0000000..31479a1 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/date/conversions.rb @@ -0,0 +1,94 @@ +require 'date' +require 'active_support/inflector/methods' +require 'active_support/core_ext/date/zones' +require 'active_support/core_ext/module/remove_method' + +class Date + DATE_FORMATS = { + :short => '%e %b', + :long => '%B %e, %Y', + :db => '%Y-%m-%d', + :number => '%Y%m%d', + :long_ordinal => lambda { |date| + day_format = ActiveSupport::Inflector.ordinalize(date.day) + date.strftime("%B #{day_format}, %Y") # => "April 25th, 2007" + }, + :rfc822 => '%e %b %Y', + :iso8601 => lambda { |date| date.iso8601 } + } + + # Ruby 1.9 has Date#to_time which converts to localtime only. + remove_method :to_time + + # Ruby 1.9 has Date#xmlschema which converts to a string without the time + # component. This removal may generate an issue on FreeBSD, that's why we + # need to use remove_possible_method here + remove_possible_method :xmlschema + + # Convert to a formatted string. See DATE_FORMATS for predefined formats. + # + # This method is aliased to to_s. + # + # date = Date.new(2007, 11, 10) # => Sat, 10 Nov 2007 + # + # date.to_formatted_s(:db) # => "2007-11-10" + # date.to_s(:db) # => "2007-11-10" + # + # date.to_formatted_s(:short) # => "10 Nov" + # date.to_formatted_s(:number) # => "20071110" + # date.to_formatted_s(:long) # => "November 10, 2007" + # date.to_formatted_s(:long_ordinal) # => "November 10th, 2007" + # date.to_formatted_s(:rfc822) # => "10 Nov 2007" + # date.to_formatted_s(:iso8601) # => "2007-11-10" + # + # == Adding your own date formats to to_formatted_s + # You can add your own formats to the Date::DATE_FORMATS hash. + # Use the format name as the hash key and either a strftime string + # or Proc instance that takes a date argument as the value. + # + # # config/initializers/date_formats.rb + # Date::DATE_FORMATS[:month_and_year] = '%B %Y' + # Date::DATE_FORMATS[:short_ordinal] = ->(date) { date.strftime("%B #{date.day.ordinalize}") } + def to_formatted_s(format = :default) + if formatter = DATE_FORMATS[format] + if formatter.respond_to?(:call) + formatter.call(self).to_s + else + strftime(formatter) + end + else + to_default_s + end + end + alias_method :to_default_s, :to_s + alias_method :to_s, :to_formatted_s + + # Overrides the default inspect method with a human readable one, e.g., "Mon, 21 Feb 2005" + def readable_inspect + strftime('%a, %d %b %Y') + end + alias_method :default_inspect, :inspect + alias_method :inspect, :readable_inspect + + # Converts a Date instance to a Time, where the time is set to the beginning of the day. + # The timezone can be either :local or :utc (default :local). + # + # date = Date.new(2007, 11, 10) # => Sat, 10 Nov 2007 + # + # date.to_time # => Sat Nov 10 00:00:00 0800 2007 + # date.to_time(:local) # => Sat Nov 10 00:00:00 0800 2007 + # + # date.to_time(:utc) # => Sat Nov 10 00:00:00 UTC 2007 + def to_time(form = :local) + ::Time.send(form, year, month, day) + end + + # Returns a string which represents the time in used time zone as DateTime + # defined by XML Schema: + # + # date = Date.new(2015, 05, 23) # => Sat, 23 May 2015 + # date.xmlschema # => "2015-05-23T00:00:00+04:00" + def xmlschema + in_time_zone.xmlschema + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/date/zones.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/date/zones.rb new file mode 100644 index 0000000..d109b43 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/date/zones.rb @@ -0,0 +1,6 @@ +require 'date' +require 'active_support/core_ext/date_and_time/zones' + +class Date + include DateAndTime::Zones +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/date_and_time/calculations.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/date_and_time/calculations.rb new file mode 100644 index 0000000..76a5bb6 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/date_and_time/calculations.rb @@ -0,0 +1,262 @@ +module DateAndTime + module Calculations + DAYS_INTO_WEEK = { + :monday => 0, + :tuesday => 1, + :wednesday => 2, + :thursday => 3, + :friday => 4, + :saturday => 5, + :sunday => 6 + } + + # Returns a new date/time representing yesterday. + def yesterday + advance(:days => -1) + end + + # Returns a new date/time representing tomorrow. + def tomorrow + advance(:days => 1) + end + + # Returns true if the date/time is today. + def today? + to_date == ::Date.current + end + + # Returns true if the date/time is in the past. + def past? + self < self.class.current + end + + # Returns true if the date/time is in the future. + def future? + self > self.class.current + end + + # Returns a new date/time the specified number of days ago. + def days_ago(days) + advance(:days => -days) + end + + # Returns a new date/time the specified number of days in the future. + def days_since(days) + advance(:days => days) + end + + # Returns a new date/time the specified number of weeks ago. + def weeks_ago(weeks) + advance(:weeks => -weeks) + end + + # Returns a new date/time the specified number of weeks in the future. + def weeks_since(weeks) + advance(:weeks => weeks) + end + + # Returns a new date/time the specified number of months ago. + def months_ago(months) + advance(:months => -months) + end + + # Returns a new date/time the specified number of months in the future. + def months_since(months) + advance(:months => months) + end + + # Returns a new date/time the specified number of years ago. + def years_ago(years) + advance(:years => -years) + end + + # Returns a new date/time the specified number of years in the future. + def years_since(years) + advance(:years => years) + end + + # Returns a new date/time at the start of the month. + # DateTime objects will have a time set to 0:00. + def beginning_of_month + first_hour(change(:day => 1)) + end + alias :at_beginning_of_month :beginning_of_month + + # Returns a new date/time at the start of the quarter. + # Example: 1st January, 1st July, 1st October. + # DateTime objects will have a time set to 0:00. + def beginning_of_quarter + first_quarter_month = [10, 7, 4, 1].detect { |m| m <= month } + beginning_of_month.change(:month => first_quarter_month) + end + alias :at_beginning_of_quarter :beginning_of_quarter + + # Returns a new date/time at the end of the quarter. + # Example: 31st March, 30th June, 30th September. + # DateTime objects will have a time set to 23:59:59. + def end_of_quarter + last_quarter_month = [3, 6, 9, 12].detect { |m| m >= month } + beginning_of_month.change(:month => last_quarter_month).end_of_month + end + alias :at_end_of_quarter :end_of_quarter + + # Return a new date/time at the beginning of the year. + # Example: 1st January. + # DateTime objects will have a time set to 0:00. + def beginning_of_year + change(:month => 1).beginning_of_month + end + alias :at_beginning_of_year :beginning_of_year + + # Returns a new date/time representing the given day in the next week. + # + # today = Date.today # => Thu, 07 May 2015 + # today.next_week # => Mon, 11 May 2015 + # + # The +given_day_in_next_week+ defaults to the beginning of the week + # which is determined by +Date.beginning_of_week+ or +config.beginning_of_week+ + # + # today = Date.today # => Thu, 07 May 2015 + # today.next_week(:friday) # => Fri, 15 May 2015 + # + # when set. +DateTime+ objects have their time set to 0:00. + # + # now = Time.current # => Thu, 07 May 2015 13:31:16 UTC +00:00 + # now.next_week # => Mon, 11 May 2015 00:00:00 UTC +00:00 + def next_week(given_day_in_next_week = Date.beginning_of_week) + first_hour(weeks_since(1).beginning_of_week.days_since(days_span(given_day_in_next_week))) + end + + # Short-hand for months_since(1). + def next_month + months_since(1) + end + + # Short-hand for months_since(3) + def next_quarter + months_since(3) + end + + # Short-hand for years_since(1). + def next_year + years_since(1) + end + + # Returns a new date/time representing the given day in the previous week. + # Week is assumed to start on +start_day+, default is + # +Date.beginning_of_week+ or +config.beginning_of_week+ when set. + # DateTime objects have their time set to 0:00. + def prev_week(start_day = Date.beginning_of_week) + first_hour(weeks_ago(1).beginning_of_week.days_since(days_span(start_day))) + end + alias_method :last_week, :prev_week + + # Short-hand for months_ago(1). + def prev_month + months_ago(1) + end + alias_method :last_month, :prev_month + + # Short-hand for months_ago(3). + def prev_quarter + months_ago(3) + end + alias_method :last_quarter, :prev_quarter + + # Short-hand for years_ago(1). + def prev_year + years_ago(1) + end + alias_method :last_year, :prev_year + + # Returns the number of days to the start of the week on the given day. + # Week is assumed to start on +start_day+, default is + # +Date.beginning_of_week+ or +config.beginning_of_week+ when set. + def days_to_week_start(start_day = Date.beginning_of_week) + start_day_number = DAYS_INTO_WEEK[start_day] + current_day_number = wday != 0 ? wday - 1 : 6 + (current_day_number - start_day_number) % 7 + end + + # Returns a new date/time representing the start of this week on the given day. + # Week is assumed to start on +start_day+, default is + # +Date.beginning_of_week+ or +config.beginning_of_week+ when set. + # +DateTime+ objects have their time set to 0:00. + def beginning_of_week(start_day = Date.beginning_of_week) + result = days_ago(days_to_week_start(start_day)) + acts_like?(:time) ? result.midnight : result + end + alias :at_beginning_of_week :beginning_of_week + + # Returns Monday of this week assuming that week starts on Monday. + # +DateTime+ objects have their time set to 0:00. + def monday + beginning_of_week(:monday) + end + + # Returns a new date/time representing the end of this week on the given day. + # Week is assumed to start on +start_day+, default is + # +Date.beginning_of_week+ or +config.beginning_of_week+ when set. + # DateTime objects have their time set to 23:59:59. + def end_of_week(start_day = Date.beginning_of_week) + last_hour(days_since(6 - days_to_week_start(start_day))) + end + alias :at_end_of_week :end_of_week + + # Returns Sunday of this week assuming that week starts on Monday. + # +DateTime+ objects have their time set to 23:59:59. + def sunday + end_of_week(:monday) + end + + # Returns a new date/time representing the end of the month. + # DateTime objects will have a time set to 23:59:59. + def end_of_month + last_day = ::Time.days_in_month(month, year) + last_hour(days_since(last_day - day)) + end + alias :at_end_of_month :end_of_month + + # Returns a new date/time representing the end of the year. + # DateTime objects will have a time set to 23:59:59. + def end_of_year + change(:month => 12).end_of_month + end + alias :at_end_of_year :end_of_year + + # Returns a Range representing the whole week of the current date/time. + # Week starts on start_day, default is Date.week_start or config.week_start when set. + def all_week(start_day = Date.beginning_of_week) + beginning_of_week(start_day)..end_of_week(start_day) + end + + # Returns a Range representing the whole month of the current date/time. + def all_month + beginning_of_month..end_of_month + end + + # Returns a Range representing the whole quarter of the current date/time. + def all_quarter + beginning_of_quarter..end_of_quarter + end + + # Returns a Range representing the whole year of the current date/time. + def all_year + beginning_of_year..end_of_year + end + + private + + def first_hour(date_or_time) + date_or_time.acts_like?(:time) ? date_or_time.beginning_of_day : date_or_time + end + + def last_hour(date_or_time) + date_or_time.acts_like?(:time) ? date_or_time.end_of_day : date_or_time + end + + def days_span(day) + (DAYS_INTO_WEEK[day] - DAYS_INTO_WEEK[Date.beginning_of_week]) % 7 + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/date_and_time/zones.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/date_and_time/zones.rb new file mode 100644 index 0000000..96c6df9 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/date_and_time/zones.rb @@ -0,0 +1,41 @@ +module DateAndTime + module Zones + # Returns the simultaneous time in Time.zone if a zone is given or + # if Time.zone_default is set. Otherwise, it returns the current time. + # + # Time.zone = 'Hawaii' # => 'Hawaii' + # DateTime.utc(2000).in_time_zone # => Fri, 31 Dec 1999 14:00:00 HST -10:00 + # Date.new(2000).in_time_zone # => Sat, 01 Jan 2000 00:00:00 HST -10:00 + # + # This method is similar to Time#localtime, except that it uses Time.zone as the local zone + # instead of the operating system's time zone. + # + # You can also pass in a TimeZone instance or string that identifies a TimeZone as an argument, + # and the conversion will be based on that zone instead of Time.zone. + # + # Time.utc(2000).in_time_zone('Alaska') # => Fri, 31 Dec 1999 15:00:00 AKST -09:00 + # DateTime.utc(2000).in_time_zone('Alaska') # => Fri, 31 Dec 1999 15:00:00 AKST -09:00 + # Date.new(2000).in_time_zone('Alaska') # => Sat, 01 Jan 2000 00:00:00 AKST -09:00 + def in_time_zone(zone = ::Time.zone) + time_zone = ::Time.find_zone! zone + time = acts_like?(:time) ? self : nil + + if time_zone + time_with_zone(time, time_zone) + else + time || self.to_time + end + end + + private + + def time_with_zone(time, zone) + if time + ActiveSupport::TimeWithZone.new(time.utc? ? time : time.getutc, zone) + else + ActiveSupport::TimeWithZone.new(nil, zone, to_time(:utc)) + end + end + end +end + diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/date_time.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/date_time.rb new file mode 100644 index 0000000..e8a27b9 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/date_time.rb @@ -0,0 +1,4 @@ +require 'active_support/core_ext/date_time/acts_like' +require 'active_support/core_ext/date_time/calculations' +require 'active_support/core_ext/date_time/conversions' +require 'active_support/core_ext/date_time/zones' diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/date_time/acts_like.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/date_time/acts_like.rb new file mode 100644 index 0000000..8fbbe0d --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/date_time/acts_like.rb @@ -0,0 +1,14 @@ +require 'date' +require 'active_support/core_ext/object/acts_like' + +class DateTime + # Duck-types as a Date-like class. See Object#acts_like?. + def acts_like_date? + true + end + + # Duck-types as a Time-like class. See Object#acts_like?. + def acts_like_time? + true + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/date_time/calculations.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/date_time/calculations.rb new file mode 100644 index 0000000..6f69215 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/date_time/calculations.rb @@ -0,0 +1,173 @@ +require 'date' + +class DateTime + class << self + # Returns Time.zone.now.to_datetime when Time.zone or + # config.time_zone are set, otherwise returns + # Time.now.to_datetime. + def current + ::Time.zone ? ::Time.zone.now.to_datetime : ::Time.now.to_datetime + end + end + + # Seconds since midnight: DateTime.now.seconds_since_midnight. + def seconds_since_midnight + sec + (min * 60) + (hour * 3600) + end + + # Returns the number of seconds until 23:59:59. + # + # DateTime.new(2012, 8, 29, 0, 0, 0).seconds_until_end_of_day # => 86399 + # DateTime.new(2012, 8, 29, 12, 34, 56).seconds_until_end_of_day # => 41103 + # DateTime.new(2012, 8, 29, 23, 59, 59).seconds_until_end_of_day # => 0 + def seconds_until_end_of_day + end_of_day.to_i - to_i + end + + # Returns a new DateTime where one or more of the elements have been changed + # according to the +options+ parameter. The time options (:hour, + # :min, :sec) reset cascadingly, so if only the hour is + # passed, then minute and sec is set to 0. If the hour and minute is passed, + # then sec is set to 0. The +options+ parameter takes a hash with any of these + # keys: :year, :month, :day, :hour, + # :min, :sec, :offset, :start. + # + # DateTime.new(2012, 8, 29, 22, 35, 0).change(day: 1) # => DateTime.new(2012, 8, 1, 22, 35, 0) + # DateTime.new(2012, 8, 29, 22, 35, 0).change(year: 1981, day: 1) # => DateTime.new(1981, 8, 1, 22, 35, 0) + # DateTime.new(2012, 8, 29, 22, 35, 0).change(year: 1981, hour: 0) # => DateTime.new(1981, 8, 29, 0, 0, 0) + def change(options) + ::DateTime.civil( + options.fetch(:year, year), + options.fetch(:month, month), + options.fetch(:day, day), + options.fetch(:hour, hour), + options.fetch(:min, options[:hour] ? 0 : min), + options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec + sec_fraction), + options.fetch(:offset, offset), + options.fetch(:start, start) + ) + end + + # Uses Date to provide precise Time calculations for years, months, and days. + # The +options+ parameter takes a hash with any of these keys: :years, + # :months, :weeks, :days, :hours, + # :minutes, :seconds. + def advance(options) + unless options[:weeks].nil? + options[:weeks], partial_weeks = options[:weeks].divmod(1) + options[:days] = options.fetch(:days, 0) + 7 * partial_weeks + end + + unless options[:days].nil? + options[:days], partial_days = options[:days].divmod(1) + options[:hours] = options.fetch(:hours, 0) + 24 * partial_days + end + + d = to_date.advance(options) + datetime_advanced_by_date = change(:year => d.year, :month => d.month, :day => d.day) + seconds_to_advance = \ + options.fetch(:seconds, 0) + + options.fetch(:minutes, 0) * 60 + + options.fetch(:hours, 0) * 3600 + + if seconds_to_advance.zero? + datetime_advanced_by_date + else + datetime_advanced_by_date.since(seconds_to_advance) + end + end + + # Returns a new DateTime representing the time a number of seconds ago. + # Do not use this method in combination with x.months, use months_ago instead! + def ago(seconds) + since(-seconds) + end + + # Returns a new DateTime representing the time a number of seconds since the + # instance time. Do not use this method in combination with x.months, use + # months_since instead! + def since(seconds) + self + Rational(seconds.round, 86400) + end + alias :in :since + + # Returns a new DateTime representing the start of the day (0:00). + def beginning_of_day + change(:hour => 0) + end + alias :midnight :beginning_of_day + alias :at_midnight :beginning_of_day + alias :at_beginning_of_day :beginning_of_day + + # Returns a new DateTime representing the middle of the day (12:00) + def middle_of_day + change(:hour => 12) + end + alias :midday :middle_of_day + alias :noon :middle_of_day + alias :at_midday :middle_of_day + alias :at_noon :middle_of_day + alias :at_middle_of_day :middle_of_day + + # Returns a new DateTime representing the end of the day (23:59:59). + def end_of_day + change(:hour => 23, :min => 59, :sec => 59) + end + alias :at_end_of_day :end_of_day + + # Returns a new DateTime representing the start of the hour (hh:00:00). + def beginning_of_hour + change(:min => 0) + end + alias :at_beginning_of_hour :beginning_of_hour + + # Returns a new DateTime representing the end of the hour (hh:59:59). + def end_of_hour + change(:min => 59, :sec => 59) + end + alias :at_end_of_hour :end_of_hour + + # Returns a new DateTime representing the start of the minute (hh:mm:00). + def beginning_of_minute + change(:sec => 0) + end + alias :at_beginning_of_minute :beginning_of_minute + + # Returns a new DateTime representing the end of the minute (hh:mm:59). + def end_of_minute + change(:sec => 59) + end + alias :at_end_of_minute :end_of_minute + + # Adjusts DateTime to UTC by adding its offset value; offset is set to 0. + # + # DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24)) # => Mon, 21 Feb 2005 10:11:12 -0600 + # DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24)).utc # => Mon, 21 Feb 2005 16:11:12 +0000 + def utc + new_offset(0) + end + alias_method :getutc, :utc + + # Returns +true+ if offset == 0. + def utc? + offset == 0 + end + + # Returns the offset value in seconds. + def utc_offset + (offset * 86400).to_i + end + + # Layers additional behavior on DateTime#<=> so that Time and + # ActiveSupport::TimeWithZone instances can be compared with a DateTime. + def <=>(other) + if other.kind_of?(Infinity) + super + elsif other.respond_to? :to_datetime + super other.to_datetime rescue nil + else + nil + end + end + +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/date_time/conversions.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/date_time/conversions.rb new file mode 100644 index 0000000..2a9c09f --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/date_time/conversions.rb @@ -0,0 +1,103 @@ +require 'date' +require 'active_support/inflector/methods' +require 'active_support/core_ext/time/conversions' +require 'active_support/core_ext/date_time/calculations' +require 'active_support/values/time_zone' + +class DateTime + # Convert to a formatted string. See Time::DATE_FORMATS for predefined formats. + # + # This method is aliased to to_s. + # + # === Examples + # datetime = DateTime.civil(2007, 12, 4, 0, 0, 0, 0) # => Tue, 04 Dec 2007 00:00:00 +0000 + # + # datetime.to_formatted_s(:db) # => "2007-12-04 00:00:00" + # datetime.to_s(:db) # => "2007-12-04 00:00:00" + # datetime.to_s(:number) # => "20071204000000" + # datetime.to_formatted_s(:short) # => "04 Dec 00:00" + # datetime.to_formatted_s(:long) # => "December 04, 2007 00:00" + # datetime.to_formatted_s(:long_ordinal) # => "December 4th, 2007 00:00" + # datetime.to_formatted_s(:rfc822) # => "Tue, 04 Dec 2007 00:00:00 +0000" + # datetime.to_formatted_s(:iso8601) # => "2007-12-04T00:00:00+00:00" + # + # == Adding your own datetime formats to to_formatted_s + # DateTime formats are shared with Time. You can add your own to the + # Time::DATE_FORMATS hash. Use the format name as the hash key and + # either a strftime string or Proc instance that takes a time or + # datetime argument as the value. + # + # # config/initializers/time_formats.rb + # Time::DATE_FORMATS[:month_and_year] = '%B %Y' + # Time::DATE_FORMATS[:short_ordinal] = lambda { |time| time.strftime("%B #{time.day.ordinalize}") } + def to_formatted_s(format = :default) + if formatter = ::Time::DATE_FORMATS[format] + formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter) + else + to_default_s + end + end + alias_method :to_default_s, :to_s if instance_methods(false).include?(:to_s) + alias_method :to_s, :to_formatted_s + + # + # datetime = DateTime.civil(2000, 1, 1, 0, 0, 0, Rational(-6, 24)) + # datetime.formatted_offset # => "-06:00" + # datetime.formatted_offset(false) # => "-0600" + def formatted_offset(colon = true, alternate_utc_string = nil) + utc? && alternate_utc_string || ActiveSupport::TimeZone.seconds_to_utc_offset(utc_offset, colon) + end + + # Overrides the default inspect method with a human readable one, e.g., "Mon, 21 Feb 2005 14:30:00 +0000". + def readable_inspect + to_s(:rfc822) + end + alias_method :default_inspect, :inspect + alias_method :inspect, :readable_inspect + + # Returns DateTime with local offset for given year if format is local else + # offset is zero. + # + # DateTime.civil_from_format :local, 2012 + # # => Sun, 01 Jan 2012 00:00:00 +0300 + # DateTime.civil_from_format :local, 2012, 12, 17 + # # => Mon, 17 Dec 2012 00:00:00 +0000 + def self.civil_from_format(utc_or_local, year, month=1, day=1, hour=0, min=0, sec=0) + if utc_or_local.to_sym == :local + offset = ::Time.local(year, month, day).utc_offset.to_r / 86400 + else + offset = 0 + end + civil(year, month, day, hour, min, sec, offset) + end + + # Converts +self+ to a floating-point number of seconds, including fractional microseconds, since the Unix epoch. + def to_f + seconds_since_unix_epoch.to_f + sec_fraction + end + + # Converts +self+ to an integer number of seconds since the Unix epoch. + def to_i + seconds_since_unix_epoch.to_i + end + + # Returns the fraction of a second as microseconds + def usec + (sec_fraction * 1_000_000).to_i + end + + # Returns the fraction of a second as nanoseconds + def nsec + (sec_fraction * 1_000_000_000).to_i + end + + private + + def offset_in_seconds + (offset * 86400).to_i + end + + def seconds_since_unix_epoch + (jd - 2440588) * 86400 - offset_in_seconds + seconds_since_midnight + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/date_time/zones.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/date_time/zones.rb new file mode 100644 index 0000000..c39f358 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/date_time/zones.rb @@ -0,0 +1,6 @@ +require 'date' +require 'active_support/core_ext/date_and_time/zones' + +class DateTime + include DateAndTime::Zones +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/digest/uuid.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/digest/uuid.rb new file mode 100644 index 0000000..593c51b --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/digest/uuid.rb @@ -0,0 +1,51 @@ +require 'securerandom' + +module Digest + module UUID + DNS_NAMESPACE = "k\xA7\xB8\x10\x9D\xAD\x11\xD1\x80\xB4\x00\xC0O\xD40\xC8" #:nodoc: + URL_NAMESPACE = "k\xA7\xB8\x11\x9D\xAD\x11\xD1\x80\xB4\x00\xC0O\xD40\xC8" #:nodoc: + OID_NAMESPACE = "k\xA7\xB8\x12\x9D\xAD\x11\xD1\x80\xB4\x00\xC0O\xD40\xC8" #:nodoc: + X500_NAMESPACE = "k\xA7\xB8\x14\x9D\xAD\x11\xD1\x80\xB4\x00\xC0O\xD40\xC8" #:nodoc: + + # Generates a v5 non-random UUID (Universally Unique IDentifier). + # + # Using Digest::MD5 generates version 3 UUIDs; Digest::SHA1 generates version 5 UUIDs. + # uuid_from_hash always generates the same UUID for a given name and namespace combination. + # + # See RFC 4122 for details of UUID at: http://www.ietf.org/rfc/rfc4122.txt + def self.uuid_from_hash(hash_class, uuid_namespace, name) + if hash_class == Digest::MD5 + version = 3 + elsif hash_class == Digest::SHA1 + version = 5 + else + raise ArgumentError, "Expected Digest::SHA1 or Digest::MD5, got #{hash_class.name}." + end + + hash = hash_class.new + hash.update(uuid_namespace) + hash.update(name) + + ary = hash.digest.unpack('NnnnnN') + ary[2] = (ary[2] & 0x0FFF) | (version << 12) + ary[3] = (ary[3] & 0x3FFF) | 0x8000 + + "%08x-%04x-%04x-%04x-%04x%08x" % ary + end + + # Convenience method for uuid_from_hash using Digest::MD5. + def self.uuid_v3(uuid_namespace, name) + self.uuid_from_hash(Digest::MD5, uuid_namespace, name) + end + + # Convenience method for uuid_from_hash using Digest::SHA1. + def self.uuid_v5(uuid_namespace, name) + self.uuid_from_hash(Digest::SHA1, uuid_namespace, name) + end + + # Convenience method for SecureRandom.uuid. + def self.uuid_v4 + SecureRandom.uuid + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/enumerable.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/enumerable.rb new file mode 100644 index 0000000..1343beb --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/enumerable.rb @@ -0,0 +1,80 @@ +module Enumerable + # Calculates a sum from the elements. + # + # payments.sum { |p| p.price * p.tax_rate } + # payments.sum(&:price) + # + # The latter is a shortcut for: + # + # payments.inject(0) { |sum, p| sum + p.price } + # + # It can also calculate the sum without the use of a block. + # + # [5, 15, 10].sum # => 30 + # ['foo', 'bar'].sum # => "foobar" + # [[1, 2], [3, 1, 5]].sum => [1, 2, 3, 1, 5] + # + # The default sum of an empty list is zero. You can override this default: + # + # [].sum(Payment.new(0)) { |i| i.amount } # => Payment.new(0) + def sum(identity = 0, &block) + if block_given? + map(&block).sum(identity) + else + inject { |sum, element| sum + element } || identity + end + end + + # Convert an enumerable to a hash. + # + # people.index_by(&:login) + # => { "nextangle" => , "chade-" => , ...} + # people.index_by { |person| "#{person.first_name} #{person.last_name}" } + # => { "Chade- Fowlersburg-e" => , "David Heinemeier Hansson" => , ...} + def index_by + if block_given? + Hash[map { |elem| [yield(elem), elem] }] + else + to_enum(:index_by) { size if respond_to?(:size) } + end + end + + # Returns +true+ if the enumerable has more than 1 element. Functionally + # equivalent to enum.to_a.size > 1. Can be called with a block too, + # much like any?, so people.many? { |p| p.age > 26 } returns +true+ + # if more than one person is over 26. + def many? + cnt = 0 + if block_given? + any? do |element| + cnt += 1 if yield element + cnt > 1 + end + else + any? { (cnt += 1) > 1 } + end + end + + # The negative of the Enumerable#include?. Returns +true+ if the + # collection does not include the object. + def exclude?(object) + !include?(object) + end +end + +class Range #:nodoc: + # Optimize range sum to use arithmetic progression if a block is not given and + # we have a range of numeric values. + def sum(identity = 0) + if block_given? || !(first.is_a?(Integer) && last.is_a?(Integer)) + super + else + actual_last = exclude_end? ? (last - 1) : last + if actual_last >= first + (actual_last - first + 1) * (actual_last + first) / 2 + else + identity + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/file.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/file.rb new file mode 100644 index 0000000..dc24afb --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/file.rb @@ -0,0 +1 @@ +require 'active_support/core_ext/file/atomic' diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/file/atomic.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/file/atomic.rb new file mode 100644 index 0000000..38374af --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/file/atomic.rb @@ -0,0 +1,63 @@ +require 'fileutils' + +class File + # Write to a file atomically. Useful for situations where you don't + # want other processes or threads to see half-written files. + # + # File.atomic_write('important.file') do |file| + # file.write('hello') + # end + # + # If your temp directory is not on the same filesystem as the file you're + # trying to write, you can provide a different temporary directory. + # + # File.atomic_write('/data/something.important', '/data/tmp') do |file| + # file.write('hello') + # end + def self.atomic_write(file_name, temp_dir = Dir.tmpdir) + require 'tempfile' unless defined?(Tempfile) + require 'fileutils' unless defined?(FileUtils) + + temp_file = Tempfile.new(basename(file_name), temp_dir) + temp_file.binmode + yield temp_file + temp_file.close + + if File.exist?(file_name) + # Get original file permissions + old_stat = stat(file_name) + else + # If not possible, probe which are the default permissions in the + # destination directory. + old_stat = probe_stat_in(dirname(file_name)) + end + + # Overwrite original file with temp file + FileUtils.mv(temp_file.path, file_name) + + # Set correct permissions on new file + begin + chown(old_stat.uid, old_stat.gid, file_name) + # This operation will affect filesystem ACL's + chmod(old_stat.mode, file_name) + rescue Errno::EPERM, Errno::EACCES + # Changing file ownership failed, moving on. + end + end + + # Private utility method. + def self.probe_stat_in(dir) #:nodoc: + basename = [ + '.permissions_check', + Thread.current.object_id, + Process.pid, + rand(1000000) + ].join('.') + + file_name = join(dir, basename) + FileUtils.touch(file_name) + stat(file_name) + ensure + FileUtils.rm_f(file_name) if file_name + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/hash.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/hash.rb new file mode 100644 index 0000000..af4d1da --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/hash.rb @@ -0,0 +1,9 @@ +require 'active_support/core_ext/hash/compact' +require 'active_support/core_ext/hash/conversions' +require 'active_support/core_ext/hash/deep_merge' +require 'active_support/core_ext/hash/except' +require 'active_support/core_ext/hash/indifferent_access' +require 'active_support/core_ext/hash/keys' +require 'active_support/core_ext/hash/reverse_merge' +require 'active_support/core_ext/hash/slice' +require 'active_support/core_ext/hash/transform_values' diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/hash/compact.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/hash/compact.rb new file mode 100644 index 0000000..5dc9a05 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/hash/compact.rb @@ -0,0 +1,20 @@ +class Hash + # Returns a hash with non +nil+ values. + # + # hash = { a: true, b: false, c: nil} + # hash.compact # => { a: true, b: false} + # hash # => { a: true, b: false, c: nil} + # { c: nil }.compact # => {} + def compact + self.select { |_, value| !value.nil? } + end + + # Replaces current hash with non +nil+ values. + # + # hash = { a: true, b: false, c: nil} + # hash.compact! # => { a: true, b: false} + # hash # => { a: true, b: false} + def compact! + self.reject! { |_, value| value.nil? } + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/hash/conversions.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/hash/conversions.rb new file mode 100644 index 0000000..2149d44 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/hash/conversions.rb @@ -0,0 +1,243 @@ +require 'active_support/xml_mini' +require 'active_support/time' +require 'active_support/core_ext/object/blank' +require 'active_support/core_ext/object/to_param' +require 'active_support/core_ext/object/to_query' +require 'active_support/core_ext/array/wrap' +require 'active_support/core_ext/hash/reverse_merge' +require 'active_support/core_ext/string/inflections' + +class Hash + # Returns a string containing an XML representation of its receiver: + # + # { foo: 1, bar: 2 }.to_xml + # # => + # # + # # + # # 1 + # # 2 + # # + # + # To do so, the method loops over the pairs and builds nodes that depend on + # the _values_. Given a pair +key+, +value+: + # + # * If +value+ is a hash there's a recursive call with +key+ as :root. + # + # * If +value+ is an array there's a recursive call with +key+ as :root, + # and +key+ singularized as :children. + # + # * If +value+ is a callable object it must expect one or two arguments. Depending + # on the arity, the callable is invoked with the +options+ hash as first argument + # with +key+ as :root, and +key+ singularized as second argument. The + # callable can add nodes by using options[:builder]. + # + # 'foo'.to_xml(lambda { |options, key| options[:builder].b(key) }) + # # => "foo" + # + # * If +value+ responds to +to_xml+ the method is invoked with +key+ as :root. + # + # class Foo + # def to_xml(options) + # options[:builder].bar 'fooing!' + # end + # end + # + # { foo: Foo.new }.to_xml(skip_instruct: true) + # # => + # # + # # fooing! + # # + # + # * Otherwise, a node with +key+ as tag is created with a string representation of + # +value+ as text node. If +value+ is +nil+ an attribute "nil" set to "true" is added. + # Unless the option :skip_types exists and is true, an attribute "type" is + # added as well according to the following mapping: + # + # XML_TYPE_NAMES = { + # "Symbol" => "symbol", + # "Fixnum" => "integer", + # "Bignum" => "integer", + # "BigDecimal" => "decimal", + # "Float" => "float", + # "TrueClass" => "boolean", + # "FalseClass" => "boolean", + # "Date" => "date", + # "DateTime" => "dateTime", + # "Time" => "dateTime" + # } + # + # By default the root node is "hash", but that's configurable via the :root option. + # + # The default XML builder is a fresh instance of Builder::XmlMarkup. You can + # configure your own builder with the :builder option. The method also accepts + # options like :dasherize and friends, they are forwarded to the builder. + def to_xml(options = {}) + require 'active_support/builder' unless defined?(Builder) + + options = options.dup + options[:indent] ||= 2 + options[:root] ||= 'hash' + options[:builder] ||= Builder::XmlMarkup.new(indent: options[:indent]) + + builder = options[:builder] + builder.instruct! unless options.delete(:skip_instruct) + + root = ActiveSupport::XmlMini.rename_key(options[:root].to_s, options) + + builder.tag!(root) do + each { |key, value| ActiveSupport::XmlMini.to_tag(key, value, options) } + yield builder if block_given? + end + end + + class << self + # Returns a Hash containing a collection of pairs when the key is the node name and the value is + # its content + # + # xml = <<-XML + # + # + # 1 + # 2 + # + # XML + # + # hash = Hash.from_xml(xml) + # # => {"hash"=>{"foo"=>1, "bar"=>2}} + # + # +DisallowedType+ is raised if the XML contains attributes with type="yaml" or + # type="symbol". Use Hash.from_trusted_xml to parse this XML. + def from_xml(xml, disallowed_types = nil) + ActiveSupport::XMLConverter.new(xml, disallowed_types).to_h + end + + # Builds a Hash from XML just like Hash.from_xml, but also allows Symbol and YAML. + def from_trusted_xml(xml) + from_xml xml, [] + end + end +end + +module ActiveSupport + class XMLConverter # :nodoc: + class DisallowedType < StandardError + def initialize(type) + super "Disallowed type attribute: #{type.inspect}" + end + end + + DISALLOWED_TYPES = %w(symbol yaml) + + def initialize(xml, disallowed_types = nil) + @xml = normalize_keys(XmlMini.parse(xml)) + @disallowed_types = disallowed_types || DISALLOWED_TYPES + end + + def to_h + deep_to_h(@xml) + end + + private + def normalize_keys(params) + case params + when Hash + Hash[params.map { |k,v| [k.to_s.tr('-', '_'), normalize_keys(v)] } ] + when Array + params.map { |v| normalize_keys(v) } + else + params + end + end + + def deep_to_h(value) + case value + when Hash + process_hash(value) + when Array + process_array(value) + when String + value + else + raise "can't typecast #{value.class.name} - #{value.inspect}" + end + end + + def process_hash(value) + if value.include?('type') && !value['type'].is_a?(Hash) && @disallowed_types.include?(value['type']) + raise DisallowedType, value['type'] + end + + if become_array?(value) + _, entries = Array.wrap(value.detect { |k,v| not v.is_a?(String) }) + if entries.nil? || value['__content__'].try(:empty?) + [] + else + case entries + when Array + entries.collect { |v| deep_to_h(v) } + when Hash + [deep_to_h(entries)] + else + raise "can't typecast #{entries.inspect}" + end + end + elsif become_content?(value) + process_content(value) + + elsif become_empty_string?(value) + '' + elsif become_hash?(value) + xml_value = Hash[value.map { |k,v| [k, deep_to_h(v)] }] + + # Turn { files: { file: # } } into { files: # } so it is compatible with + # how multipart uploaded files from HTML appear + xml_value['file'].is_a?(StringIO) ? xml_value['file'] : xml_value + end + end + + def become_content?(value) + value['type'] == 'file' || (value['__content__'] && (value.keys.size == 1 || value['__content__'].present?)) + end + + def become_array?(value) + value['type'] == 'array' + end + + def become_empty_string?(value) + # { "string" => true } + # No tests fail when the second term is removed. + value['type'] == 'string' && value['nil'] != 'true' + end + + def become_hash?(value) + !nothing?(value) && !garbage?(value) + end + + def nothing?(value) + # blank or nil parsed values are represented by nil + value.blank? || value['nil'] == 'true' + end + + def garbage?(value) + # If the type is the only element which makes it then + # this still makes the value nil, except if type is + # an XML node(where type['value'] is a Hash) + value['type'] && !value['type'].is_a?(::Hash) && value.size == 1 + end + + def process_content(value) + content = value['__content__'] + if parser = ActiveSupport::XmlMini::PARSING[value['type']] + parser.arity == 1 ? parser.call(content) : parser.call(content, value) + else + content + end + end + + def process_array(value) + value.map! { |i| deep_to_h(i) } + value.length > 1 ? value : value.first + end + + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/hash/deep_merge.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/hash/deep_merge.rb new file mode 100644 index 0000000..763d563 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/hash/deep_merge.rb @@ -0,0 +1,38 @@ +class Hash + # Returns a new hash with +self+ and +other_hash+ merged recursively. + # + # h1 = { a: true, b: { c: [1, 2, 3] } } + # h2 = { a: false, b: { x: [3, 4, 5] } } + # + # h1.deep_merge(h2) #=> { a: false, b: { c: [1, 2, 3], x: [3, 4, 5] } } + # + # Like with Hash#merge in the standard library, a block can be provided + # to merge values: + # + # h1 = { a: 100, b: 200, c: { c1: 100 } } + # h2 = { b: 250, c: { c1: 200 } } + # h1.deep_merge(h2) { |key, this_val, other_val| this_val + other_val } + # # => { a: 100, b: 450, c: { c1: 300 } } + def deep_merge(other_hash, &block) + dup.deep_merge!(other_hash, &block) + end + + # Same as +deep_merge+, but modifies +self+. + def deep_merge!(other_hash, &block) + other_hash.each_pair do |current_key, other_value| + this_value = self[current_key] + + self[current_key] = if this_value.is_a?(Hash) && other_value.is_a?(Hash) + this_value.deep_merge(other_value, &block) + else + if block_given? && key?(current_key) + block.call(current_key, this_value, other_value) + else + other_value + end + end + end + + self + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/hash/except.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/hash/except.rb new file mode 100644 index 0000000..6e397ab --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/hash/except.rb @@ -0,0 +1,21 @@ +class Hash + # Returns a hash that includes everything but the given keys. + # hash = { a: true, b: false, c: nil} + # hash.except(:c) # => { a: true, b: false} + # hash # => { a: true, b: false, c: nil} + # + # This is useful for limiting a set of parameters to everything but a few known toggles: + # @person.update(params[:person].except(:admin)) + def except(*keys) + dup.except!(*keys) + end + + # Replaces the hash without the given keys. + # hash = { a: true, b: false, c: nil} + # hash.except!(:c) # => { a: true, b: false} + # hash # => { a: true, b: false } + def except!(*keys) + keys.each { |key| delete(key) } + self + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/hash/indifferent_access.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/hash/indifferent_access.rb new file mode 100644 index 0000000..28cb3e2 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/hash/indifferent_access.rb @@ -0,0 +1,23 @@ +require 'active_support/hash_with_indifferent_access' + +class Hash + + # Returns an ActiveSupport::HashWithIndifferentAccess out of its receiver: + # + # { a: 1 }.with_indifferent_access['a'] # => 1 + def with_indifferent_access + ActiveSupport::HashWithIndifferentAccess.new_from_hash_copying_default(self) + end + + # Called when object is nested under an object that receives + # #with_indifferent_access. This method will be called on the current object + # by the enclosing object and is aliased to #with_indifferent_access by + # default. Subclasses of Hash may overwrite this method to return +self+ if + # converting to an ActiveSupport::HashWithIndifferentAccess would not be + # desirable. + # + # b = { b: 1 } + # { a: b }.with_indifferent_access['a'] # calls b.nested_under_indifferent_access + # # => {"b"=>1} + alias nested_under_indifferent_access with_indifferent_access +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/hash/keys.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/hash/keys.rb new file mode 100644 index 0000000..f4105f6 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/hash/keys.rb @@ -0,0 +1,166 @@ +class Hash + # Returns a new hash with all keys converted using the block operation. + # + # hash = { name: 'Rob', age: '28' } + # + # hash.transform_keys{ |key| key.to_s.upcase } + # # => {"NAME"=>"Rob", "AGE"=>"28"} + def transform_keys + return enum_for(:transform_keys) unless block_given? + result = self.class.new + each_key do |key| + result[yield(key)] = self[key] + end + result + end + + # Destructively convert all keys using the block operations. + # Same as transform_keys but modifies +self+. + def transform_keys! + return enum_for(:transform_keys!) unless block_given? + keys.each do |key| + self[yield(key)] = delete(key) + end + self + end + + # Returns a new hash with all keys converted to strings. + # + # hash = { name: 'Rob', age: '28' } + # + # hash.stringify_keys + # # => {"name"=>"Rob", "age"=>"28"} + def stringify_keys + transform_keys{ |key| key.to_s } + end + + # Destructively convert all keys to strings. Same as + # +stringify_keys+, but modifies +self+. + def stringify_keys! + transform_keys!{ |key| key.to_s } + end + + # Returns a new hash with all keys converted to symbols, as long as + # they respond to +to_sym+. + # + # hash = { 'name' => 'Rob', 'age' => '28' } + # + # hash.symbolize_keys + # # => {:name=>"Rob", :age=>"28"} + def symbolize_keys + transform_keys{ |key| key.to_sym rescue key } + end + alias_method :to_options, :symbolize_keys + + # Destructively convert all keys to symbols, as long as they respond + # to +to_sym+. Same as +symbolize_keys+, but modifies +self+. + def symbolize_keys! + transform_keys!{ |key| key.to_sym rescue key } + end + alias_method :to_options!, :symbolize_keys! + + # Validate all keys in a hash match *valid_keys, raising + # ArgumentError on a mismatch. + # + # Note that keys are treated differently than HashWithIndifferentAccess, + # meaning that string and symbol keys will not match. + # + # { name: 'Rob', years: '28' }.assert_valid_keys(:name, :age) # => raises "ArgumentError: Unknown key: :years. Valid keys are: :name, :age" + # { name: 'Rob', age: '28' }.assert_valid_keys('name', 'age') # => raises "ArgumentError: Unknown key: :name. Valid keys are: 'name', 'age'" + # { name: 'Rob', age: '28' }.assert_valid_keys(:name, :age) # => passes, raises nothing + def assert_valid_keys(*valid_keys) + valid_keys.flatten! + each_key do |k| + unless valid_keys.include?(k) + raise ArgumentError.new("Unknown key: #{k.inspect}. Valid keys are: #{valid_keys.map(&:inspect).join(', ')}") + end + end + end + + # Returns a new hash with all keys converted by the block operation. + # This includes the keys from the root hash and from all + # nested hashes and arrays. + # + # hash = { person: { name: 'Rob', age: '28' } } + # + # hash.deep_transform_keys{ |key| key.to_s.upcase } + # # => {"PERSON"=>{"NAME"=>"Rob", "AGE"=>"28"}} + def deep_transform_keys(&block) + _deep_transform_keys_in_object(self, &block) + end + + # Destructively convert all keys by using the block operation. + # This includes the keys from the root hash and from all + # nested hashes and arrays. + def deep_transform_keys!(&block) + _deep_transform_keys_in_object!(self, &block) + end + + # Returns a new hash with all keys converted to strings. + # This includes the keys from the root hash and from all + # nested hashes and arrays. + # + # hash = { person: { name: 'Rob', age: '28' } } + # + # hash.deep_stringify_keys + # # => {"person"=>{"name"=>"Rob", "age"=>"28"}} + def deep_stringify_keys + deep_transform_keys{ |key| key.to_s } + end + + # Destructively convert all keys to strings. + # This includes the keys from the root hash and from all + # nested hashes and arrays. + def deep_stringify_keys! + deep_transform_keys!{ |key| key.to_s } + end + + # Returns a new hash with all keys converted to symbols, as long as + # they respond to +to_sym+. This includes the keys from the root hash + # and from all nested hashes and arrays. + # + # hash = { 'person' => { 'name' => 'Rob', 'age' => '28' } } + # + # hash.deep_symbolize_keys + # # => {:person=>{:name=>"Rob", :age=>"28"}} + def deep_symbolize_keys + deep_transform_keys{ |key| key.to_sym rescue key } + end + + # Destructively convert all keys to symbols, as long as they respond + # to +to_sym+. This includes the keys from the root hash and from all + # nested hashes and arrays. + def deep_symbolize_keys! + deep_transform_keys!{ |key| key.to_sym rescue key } + end + + private + # support methods for deep transforming nested hashes and arrays + def _deep_transform_keys_in_object(object, &block) + case object + when Hash + object.each_with_object({}) do |(key, value), result| + result[yield(key)] = _deep_transform_keys_in_object(value, &block) + end + when Array + object.map {|e| _deep_transform_keys_in_object(e, &block) } + else + object + end + end + + def _deep_transform_keys_in_object!(object, &block) + case object + when Hash + object.keys.each do |key| + value = object.delete(key) + object[yield(key)] = _deep_transform_keys_in_object!(value, &block) + end + object + when Array + object.map! {|e| _deep_transform_keys_in_object!(e, &block)} + else + object + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/hash/reverse_merge.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/hash/reverse_merge.rb new file mode 100644 index 0000000..fbb4824 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/hash/reverse_merge.rb @@ -0,0 +1,22 @@ +class Hash + # Merges the caller into +other_hash+. For example, + # + # options = options.reverse_merge(size: 25, velocity: 10) + # + # is equivalent to + # + # options = { size: 25, velocity: 10 }.merge(options) + # + # This is particularly useful for initializing an options hash + # with default values. + def reverse_merge(other_hash) + other_hash.merge(self) + end + + # Destructive +reverse_merge+. + def reverse_merge!(other_hash) + # right wins if there is no left + merge!( other_hash ){|key,left,right| left } + end + alias_method :reverse_update, :reverse_merge! +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/hash/slice.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/hash/slice.rb new file mode 100644 index 0000000..41b2279 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/hash/slice.rb @@ -0,0 +1,48 @@ +class Hash + # Slice a hash to include only the given keys. Returns a hash containing + # the given keys. + # + # { a: 1, b: 2, c: 3, d: 4 }.slice(:a, :b) + # # => {:a=>1, :b=>2} + # + # This is useful for limiting an options hash to valid keys before + # passing to a method: + # + # def search(criteria = {}) + # criteria.assert_valid_keys(:mass, :velocity, :time) + # end + # + # search(options.slice(:mass, :velocity, :time)) + # + # If you have an array of keys you want to limit to, you should splat them: + # + # valid_keys = [:mass, :velocity, :time] + # search(options.slice(*valid_keys)) + def slice(*keys) + keys.map! { |key| convert_key(key) } if respond_to?(:convert_key, true) + keys.each_with_object(self.class.new) { |k, hash| hash[k] = self[k] if has_key?(k) } + end + + # Replaces the hash with only the given keys. + # Returns a hash containing the removed key/value pairs. + # + # { a: 1, b: 2, c: 3, d: 4 }.slice!(:a, :b) + # # => {:c=>3, :d=>4} + def slice!(*keys) + keys.map! { |key| convert_key(key) } if respond_to?(:convert_key, true) + omit = slice(*self.keys - keys) + hash = slice(*keys) + hash.default = default + hash.default_proc = default_proc if default_proc + replace(hash) + omit + end + + # Removes and returns the key/value pairs matching the given keys. + # + # { a: 1, b: 2, c: 3, d: 4 }.extract!(:a, :b) # => {:a=>1, :b=>2} + # { a: 1, b: 2 }.extract!(:a, :x) # => {:a=>1} + def extract!(*keys) + keys.each_with_object(self.class.new) { |key, result| result[key] = delete(key) if has_key?(key) } + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/hash/transform_values.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/hash/transform_values.rb new file mode 100644 index 0000000..e9bcce7 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/hash/transform_values.rb @@ -0,0 +1,23 @@ +class Hash + # Returns a new hash with the results of running +block+ once for every value. + # The keys are unchanged. + # + # { a: 1, b: 2, c: 3 }.transform_values { |x| x * 2 } + # # => { a: 2, b: 4, c: 6 } + def transform_values + return enum_for(:transform_values) unless block_given? + result = self.class.new + each do |key, value| + result[key] = yield(value) + end + result + end + + # Destructive +transform_values+ + def transform_values! + return enum_for(:transform_values!) unless block_given? + each do |key, value| + self[key] = yield(value) + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/integer.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/integer.rb new file mode 100644 index 0000000..a44a1b4 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/integer.rb @@ -0,0 +1,3 @@ +require 'active_support/core_ext/integer/multiple' +require 'active_support/core_ext/integer/inflections' +require 'active_support/core_ext/integer/time' diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/integer/inflections.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/integer/inflections.rb new file mode 100644 index 0000000..56f2ed5 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/integer/inflections.rb @@ -0,0 +1,29 @@ +require 'active_support/inflector' + +class Integer + # Ordinalize turns a number into an ordinal string used to denote the + # position in an ordered sequence such as 1st, 2nd, 3rd, 4th. + # + # 1.ordinalize # => "1st" + # 2.ordinalize # => "2nd" + # 1002.ordinalize # => "1002nd" + # 1003.ordinalize # => "1003rd" + # -11.ordinalize # => "-11th" + # -1001.ordinalize # => "-1001st" + def ordinalize + ActiveSupport::Inflector.ordinalize(self) + end + + # Ordinal returns the suffix used to denote the position + # in an ordered sequence such as 1st, 2nd, 3rd, 4th. + # + # 1.ordinal # => "st" + # 2.ordinal # => "nd" + # 1002.ordinal # => "nd" + # 1003.ordinal # => "rd" + # -11.ordinal # => "th" + # -1001.ordinal # => "st" + def ordinal + ActiveSupport::Inflector.ordinal(self) + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/integer/multiple.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/integer/multiple.rb new file mode 100644 index 0000000..c668c7c --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/integer/multiple.rb @@ -0,0 +1,10 @@ +class Integer + # Check whether the integer is evenly divisible by the argument. + # + # 0.multiple_of?(0) # => true + # 6.multiple_of?(5) # => false + # 10.multiple_of?(2) # => true + def multiple_of?(number) + number != 0 ? self % number == 0 : zero? + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/integer/time.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/integer/time.rb new file mode 100644 index 0000000..f0b7382 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/integer/time.rb @@ -0,0 +1,29 @@ +require 'active_support/duration' +require 'active_support/core_ext/numeric/time' + +class Integer + # Enables the use of time calculations and declarations, like 45.minutes + + # 2.hours + 4.years. + # + # These methods use Time#advance for precise date calculations when using + # from_now, +ago+, etc. as well as adding or subtracting their + # results from a Time object. + # + # # equivalent to Time.now.advance(months: 1) + # 1.month.from_now + # + # # equivalent to Time.now.advance(years: 2) + # 2.years.from_now + # + # # equivalent to Time.now.advance(months: 4, years: 5) + # (4.months + 5.years).from_now + def months + ActiveSupport::Duration.new(self * 30.days, [[:months, self]]) + end + alias :month :months + + def years + ActiveSupport::Duration.new(self * 365.25.days, [[:years, self]]) + end + alias :year :years +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/kernel.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/kernel.rb new file mode 100644 index 0000000..293a3b2 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/kernel.rb @@ -0,0 +1,5 @@ +require 'active_support/core_ext/kernel/agnostics' +require 'active_support/core_ext/kernel/concern' +require 'active_support/core_ext/kernel/debugger' if RUBY_VERSION < '2.0.0' +require 'active_support/core_ext/kernel/reporting' +require 'active_support/core_ext/kernel/singleton_class' diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/kernel/agnostics.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/kernel/agnostics.rb new file mode 100644 index 0000000..64837d8 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/kernel/agnostics.rb @@ -0,0 +1,11 @@ +class Object + # Makes backticks behave (somewhat more) similarly on all platforms. + # On win32 `nonexistent_command` raises Errno::ENOENT; on Unix, the + # spawned shell prints a message to stderr and sets $?. We emulate + # Unix on the former but not the latter. + def `(command) #:nodoc: + super + rescue Errno::ENOENT => e + STDERR.puts "#$0: #{e}" + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/kernel/concern.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/kernel/concern.rb new file mode 100644 index 0000000..bf72caa --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/kernel/concern.rb @@ -0,0 +1,10 @@ +require 'active_support/core_ext/module/concerning' + +module Kernel + # A shortcut to define a toplevel concern, not within a module. + # + # See Module::Concerning for more. + def concern(topic, &module_definition) + Object.concern topic, &module_definition + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/kernel/debugger.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/kernel/debugger.rb new file mode 100644 index 0000000..6ff3c87 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/kernel/debugger.rb @@ -0,0 +1,10 @@ +module Kernel + unless respond_to?(:debugger) + # Starts a debugging session if the +debugger+ gem has been loaded (call rails server --debugger to do load it). + def debugger + message = "\n***** Debugger requested, but was not available (ensure the debugger gem is listed in Gemfile/installed as gem): Start server with --debugger to enable *****\n" + defined?(Rails.logger) ? Rails.logger.info(message) : $stderr.puts(message) + end + alias breakpoint debugger unless respond_to?(:breakpoint) + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/kernel/reporting.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/kernel/reporting.rb new file mode 100644 index 0000000..82aa19c --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/kernel/reporting.rb @@ -0,0 +1,125 @@ +require 'rbconfig' +require 'tempfile' +require 'active_support/deprecation' + +module Kernel + # Sets $VERBOSE to nil for the duration of the block and back to its original + # value afterwards. + # + # silence_warnings do + # value = noisy_call # no warning voiced + # end + # + # noisy_call # warning voiced + def silence_warnings + with_warnings(nil) { yield } + end + + # Sets $VERBOSE to +true+ for the duration of the block and back to its + # original value afterwards. + def enable_warnings + with_warnings(true) { yield } + end + + # Sets $VERBOSE for the duration of the block and back to its original + # value afterwards. + def with_warnings(flag) + old_verbose, $VERBOSE = $VERBOSE, flag + yield + ensure + $VERBOSE = old_verbose + end + + # For compatibility + def silence_stderr #:nodoc: + ActiveSupport::Deprecation.warn( + "`#silence_stderr` is deprecated and will be removed in the next release." + ) #not thread-safe + silence_stream(STDERR) { yield } + end + + # Deprecated : this method is not thread safe + # Silences any stream for the duration of the block. + # + # silence_stream(STDOUT) do + # puts 'This will never be seen' + # end + # + # puts 'But this will' + # + # This method is not thread-safe. + def silence_stream(stream) + old_stream = stream.dup + stream.reopen(RbConfig::CONFIG['host_os'] =~ /mswin|mingw/ ? 'NUL:' : '/dev/null') + stream.sync = true + yield + ensure + stream.reopen(old_stream) + old_stream.close + end + + # Blocks and ignores any exception passed as argument if raised within the block. + # + # suppress(ZeroDivisionError) do + # 1/0 + # puts 'This code is NOT reached' + # end + # + # puts 'This code gets executed and nothing related to ZeroDivisionError was seen' + def suppress(*exception_classes) + yield + rescue *exception_classes + end + + # Captures the given stream and returns it: + # + # stream = capture(:stdout) { puts 'notice' } + # stream # => "notice\n" + # + # stream = capture(:stderr) { warn 'error' } + # stream # => "error\n" + # + # even for subprocesses: + # + # stream = capture(:stdout) { system('echo notice') } + # stream # => "notice\n" + # + # stream = capture(:stderr) { system('echo error 1>&2') } + # stream # => "error\n" + def capture(stream) + ActiveSupport::Deprecation.warn( + "`#capture(stream)` is deprecated and will be removed in the next release." + ) #not thread-safe + stream = stream.to_s + captured_stream = Tempfile.new(stream) + stream_io = eval("$#{stream}") + origin_stream = stream_io.dup + stream_io.reopen(captured_stream) + + yield + + stream_io.rewind + return captured_stream.read + ensure + captured_stream.close + captured_stream.unlink + stream_io.reopen(origin_stream) + end + alias :silence :capture + + # Silences both STDOUT and STDERR, even for subprocesses. + # + # quietly { system 'bundle install' } + # + # This method is not thread-safe. + def quietly + ActiveSupport::Deprecation.warn( + "`#quietly` is deprecated and will be removed in the next release." + ) #not thread-safe + silence_stream(STDOUT) do + silence_stream(STDERR) do + yield + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/kernel/singleton_class.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/kernel/singleton_class.rb new file mode 100644 index 0000000..9bbf1bb --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/kernel/singleton_class.rb @@ -0,0 +1,6 @@ +module Kernel + # class_eval on an object acts like singleton_class.class_eval. + def class_eval(*args, &block) + singleton_class.class_eval(*args, &block) + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/load_error.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/load_error.rb new file mode 100644 index 0000000..768b980 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/load_error.rb @@ -0,0 +1,28 @@ +class LoadError + REGEXPS = [ + /^no such file to load -- (.+)$/i, + /^Missing \w+ (?:file\s*)?([^\s]+.rb)$/i, + /^Missing API definition file in (.+)$/i, + /^cannot load such file -- (.+)$/i, + ] + + unless method_defined?(:path) + # Returns the path which was unable to be loaded. + def path + @path ||= begin + REGEXPS.find do |regex| + message =~ regex + end + $1 + end + end + end + + # Returns true if the given path name (except perhaps for the ".rb" + # extension) is the missing file which caused the exception to be raised. + def is_missing?(location) + location.sub(/\.rb$/, '') == path.sub(/\.rb$/, '') + end +end + +MissingSourceFile = LoadError diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/marshal.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/marshal.rb new file mode 100644 index 0000000..56c79c0 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/marshal.rb @@ -0,0 +1,21 @@ +require 'active_support/core_ext/module/aliasing' + +module Marshal + class << self + def load_with_autoloading(source) + load_without_autoloading(source) + rescue ArgumentError, NameError => exc + if exc.message.match(%r|undefined class/module (.+)|) + # try loading the class/module + $1.constantize + # if it is a IO we need to go back to read the object + source.rewind if source.respond_to?(:rewind) + retry + else + raise exc + end + end + + alias_method_chain :load, :autoloading + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/module.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/module.rb new file mode 100644 index 0000000..b4efff8 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/module.rb @@ -0,0 +1,11 @@ +require 'active_support/core_ext/module/aliasing' +require 'active_support/core_ext/module/introspection' +require 'active_support/core_ext/module/anonymous' +require 'active_support/core_ext/module/reachable' +require 'active_support/core_ext/module/attribute_accessors' +require 'active_support/core_ext/module/attr_internal' +require 'active_support/core_ext/module/concerning' +require 'active_support/core_ext/module/delegation' +require 'active_support/core_ext/module/deprecation' +require 'active_support/core_ext/module/remove_method' +require 'active_support/core_ext/module/qualified_const' diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/module/aliasing.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/module/aliasing.rb new file mode 100644 index 0000000..0a6fadf --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/module/aliasing.rb @@ -0,0 +1,69 @@ +class Module + # Encapsulates the common pattern of: + # + # alias_method :foo_without_feature, :foo + # alias_method :foo, :foo_with_feature + # + # With this, you simply do: + # + # alias_method_chain :foo, :feature + # + # And both aliases are set up for you. + # + # Query and bang methods (foo?, foo!) keep the same punctuation: + # + # alias_method_chain :foo?, :feature + # + # is equivalent to + # + # alias_method :foo_without_feature?, :foo? + # alias_method :foo?, :foo_with_feature? + # + # so you can safely chain foo, foo?, foo! and/or foo= with the same feature. + def alias_method_chain(target, feature) + # Strip out punctuation on predicates, bang or writer methods since + # e.g. target?_without_feature is not a valid method name. + aliased_target, punctuation = target.to_s.sub(/([?!=])$/, ''), $1 + yield(aliased_target, punctuation) if block_given? + + with_method = "#{aliased_target}_with_#{feature}#{punctuation}" + without_method = "#{aliased_target}_without_#{feature}#{punctuation}" + + alias_method without_method, target + alias_method target, with_method + + case + when public_method_defined?(without_method) + public target + when protected_method_defined?(without_method) + protected target + when private_method_defined?(without_method) + private target + end + end + + # Allows you to make aliases for attributes, which includes + # getter, setter, and query methods. + # + # class Content < ActiveRecord::Base + # # has a title attribute + # end + # + # class Email < Content + # alias_attribute :subject, :title + # end + # + # e = Email.find(1) + # e.title # => "Superstars" + # e.subject # => "Superstars" + # e.subject? # => true + # e.subject = "Megastars" + # e.title # => "Megastars" + def alias_attribute(new_name, old_name) + module_eval <<-STR, __FILE__, __LINE__ + 1 + def #{new_name}; self.#{old_name}; end # def subject; self.title; end + def #{new_name}?; self.#{old_name}?; end # def subject?; self.title?; end + def #{new_name}=(v); self.#{old_name} = v; end # def subject=(v); self.title = v; end + STR + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/module/anonymous.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/module/anonymous.rb new file mode 100644 index 0000000..b0c7b02 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/module/anonymous.rb @@ -0,0 +1,19 @@ +class Module + # A module may or may not have a name. + # + # module M; end + # M.name # => "M" + # + # m = Module.new + # m.name # => nil + # + # A module gets a name when it is first assigned to a constant. Either + # via the +module+ or +class+ keyword or by an explicit assignment: + # + # m = Module.new # creates an anonymous module + # M = m # => m gets a name here as a side-effect + # m.name # => "M" + def anonymous? + name.nil? + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/module/attr_internal.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/module/attr_internal.rb new file mode 100644 index 0000000..67f0e03 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/module/attr_internal.rb @@ -0,0 +1,39 @@ +class Module + # Declares an attribute reader backed by an internally-named instance variable. + def attr_internal_reader(*attrs) + attrs.each {|attr_name| attr_internal_define(attr_name, :reader)} + end + + # Declares an attribute writer backed by an internally-named instance variable. + def attr_internal_writer(*attrs) + attrs.each {|attr_name| attr_internal_define(attr_name, :writer)} + end + + # Declares an attribute reader and writer backed by an internally-named instance + # variable. + def attr_internal_accessor(*attrs) + attr_internal_reader(*attrs) + attr_internal_writer(*attrs) + end + alias_method :attr_internal, :attr_internal_accessor + + class << self; attr_accessor :attr_internal_naming_format end + self.attr_internal_naming_format = '@_%s' + + private + def attr_internal_ivar_name(attr) + Module.attr_internal_naming_format % attr + end + + def attr_internal_define(attr_name, type) + internal_name = attr_internal_ivar_name(attr_name).sub(/\A@/, '') + # class_eval is necessary on 1.9 or else the methods are made private + class_eval do + # use native attr_* methods as they are faster on some Ruby implementations + send("attr_#{type}", internal_name) + end + attr_name, internal_name = "#{attr_name}=", "#{internal_name}=" if type == :writer + alias_method attr_name, internal_name + remove_method internal_name + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/module/attribute_accessors.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/module/attribute_accessors.rb new file mode 100644 index 0000000..d317df5 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/module/attribute_accessors.rb @@ -0,0 +1,212 @@ +require 'active_support/core_ext/array/extract_options' + +# Extends the module object with class/module and instance accessors for +# class/module attributes, just like the native attr* accessors for instance +# attributes. +class Module + # Defines a class attribute and creates a class and instance reader methods. + # The underlying the class variable is set to +nil+, if it is not previously + # defined. + # + # module HairColors + # mattr_reader :hair_colors + # end + # + # HairColors.hair_colors # => nil + # HairColors.class_variable_set("@@hair_colors", [:brown, :black]) + # HairColors.hair_colors # => [:brown, :black] + # + # The attribute name must be a valid method name in Ruby. + # + # module Foo + # mattr_reader :"1_Badname " + # end + # # => NameError: invalid attribute name + # + # If you want to opt out the creation on the instance reader method, pass + # instance_reader: false or instance_accessor: false. + # + # module HairColors + # mattr_writer :hair_colors, instance_reader: false + # end + # + # class Person + # include HairColors + # end + # + # Person.new.hair_colors # => NoMethodError + # + # + # Also, you can pass a block to set up the attribute with a default value. + # + # module HairColors + # cattr_reader :hair_colors do + # [:brown, :black, :blonde, :red] + # end + # end + # + # class Person + # include HairColors + # end + # + # Person.hair_colors # => [:brown, :black, :blonde, :red] + def mattr_reader(*syms) + options = syms.extract_options! + syms.each do |sym| + raise NameError.new("invalid attribute name: #{sym}") unless sym =~ /^[_A-Za-z]\w*$/ + class_eval(<<-EOS, __FILE__, __LINE__ + 1) + @@#{sym} = nil unless defined? @@#{sym} + + def self.#{sym} + @@#{sym} + end + EOS + + unless options[:instance_reader] == false || options[:instance_accessor] == false + class_eval(<<-EOS, __FILE__, __LINE__ + 1) + def #{sym} + @@#{sym} + end + EOS + end + class_variable_set("@@#{sym}", yield) if block_given? + end + end + alias :cattr_reader :mattr_reader + + # Defines a class attribute and creates a class and instance writer methods to + # allow assignment to the attribute. + # + # module HairColors + # mattr_writer :hair_colors + # end + # + # class Person + # include HairColors + # end + # + # HairColors.hair_colors = [:brown, :black] + # Person.class_variable_get("@@hair_colors") # => [:brown, :black] + # Person.new.hair_colors = [:blonde, :red] + # HairColors.class_variable_get("@@hair_colors") # => [:blonde, :red] + # + # If you want to opt out the instance writer method, pass + # instance_writer: false or instance_accessor: false. + # + # module HairColors + # mattr_writer :hair_colors, instance_writer: false + # end + # + # class Person + # include HairColors + # end + # + # Person.new.hair_colors = [:blonde, :red] # => NoMethodError + # + # Also, you can pass a block to set up the attribute with a default value. + # + # class HairColors + # mattr_writer :hair_colors do + # [:brown, :black, :blonde, :red] + # end + # end + # + # class Person + # include HairColors + # end + # + # Person.class_variable_get("@@hair_colors") # => [:brown, :black, :blonde, :red] + def mattr_writer(*syms) + options = syms.extract_options! + syms.each do |sym| + raise NameError.new("invalid attribute name: #{sym}") unless sym =~ /^[_A-Za-z]\w*$/ + class_eval(<<-EOS, __FILE__, __LINE__ + 1) + @@#{sym} = nil unless defined? @@#{sym} + + def self.#{sym}=(obj) + @@#{sym} = obj + end + EOS + + unless options[:instance_writer] == false || options[:instance_accessor] == false + class_eval(<<-EOS, __FILE__, __LINE__ + 1) + def #{sym}=(obj) + @@#{sym} = obj + end + EOS + end + send("#{sym}=", yield) if block_given? + end + end + alias :cattr_writer :mattr_writer + + # Defines both class and instance accessors for class attributes. + # + # module HairColors + # mattr_accessor :hair_colors + # end + # + # class Person + # include HairColors + # end + # + # Person.hair_colors = [:brown, :black, :blonde, :red] + # Person.hair_colors # => [:brown, :black, :blonde, :red] + # Person.new.hair_colors # => [:brown, :black, :blonde, :red] + # + # If a subclass changes the value then that would also change the value for + # parent class. Similarly if parent class changes the value then that would + # change the value of subclasses too. + # + # class Male < Person + # end + # + # Male.hair_colors << :blue + # Person.hair_colors # => [:brown, :black, :blonde, :red, :blue] + # + # To opt out of the instance writer method, pass instance_writer: false. + # To opt out of the instance reader method, pass instance_reader: false. + # + # module HairColors + # mattr_accessor :hair_colors, instance_writer: false, instance_reader: false + # end + # + # class Person + # include HairColors + # end + # + # Person.new.hair_colors = [:brown] # => NoMethodError + # Person.new.hair_colors # => NoMethodError + # + # Or pass instance_accessor: false, to opt out both instance methods. + # + # module HairColors + # mattr_accessor :hair_colors, instance_accessor: false + # end + # + # class Person + # include HairColors + # end + # + # Person.new.hair_colors = [:brown] # => NoMethodError + # Person.new.hair_colors # => NoMethodError + # + # Also you can pass a block to set up the attribute with a default value. + # + # module HairColors + # mattr_accessor :hair_colors do + # [:brown, :black, :blonde, :red] + # end + # end + # + # class Person + # include HairColors + # end + # + # Person.class_variable_get("@@hair_colors") #=> [:brown, :black, :blonde, :red] + def mattr_accessor(*syms, &blk) + mattr_reader(*syms, &blk) + mattr_writer(*syms, &blk) + end + alias :cattr_accessor :mattr_accessor +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/module/concerning.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/module/concerning.rb new file mode 100644 index 0000000..07a3924 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/module/concerning.rb @@ -0,0 +1,135 @@ +require 'active_support/concern' + +class Module + # = Bite-sized separation of concerns + # + # We often find ourselves with a medium-sized chunk of behavior that we'd + # like to extract, but only mix in to a single class. + # + # Extracting a plain old Ruby object to encapsulate it and collaborate or + # delegate to the original object is often a good choice, but when there's + # no additional state to encapsulate or we're making DSL-style declarations + # about the parent class, introducing new collaborators can obfuscate rather + # than simplify. + # + # The typical route is to just dump everything in a monolithic class, perhaps + # with a comment, as a least-bad alternative. Using modules in separate files + # means tedious sifting to get a big-picture view. + # + # = Dissatisfying ways to separate small concerns + # + # == Using comments: + # + # class Todo + # # Other todo implementation + # # ... + # + # ## Event tracking + # has_many :events + # + # before_create :track_creation + # after_destroy :track_deletion + # + # private + # def track_creation + # # ... + # end + # end + # + # == With an inline module: + # + # Noisy syntax. + # + # class Todo + # # Other todo implementation + # # ... + # + # module EventTracking + # extend ActiveSupport::Concern + # + # included do + # has_many :events + # before_create :track_creation + # after_destroy :track_deletion + # end + # + # private + # def track_creation + # # ... + # end + # end + # include EventTracking + # end + # + # == Mix-in noise exiled to its own file: + # + # Once our chunk of behavior starts pushing the scroll-to-understand it's + # boundary, we give in and move it to a separate file. At this size, the + # overhead feels in good proportion to the size of our extraction, despite + # diluting our at-a-glance sense of how things really work. + # + # class Todo + # # Other todo implementation + # # ... + # + # include TodoEventTracking + # end + # + # = Introducing Module#concerning + # + # By quieting the mix-in noise, we arrive at a natural, low-ceremony way to + # separate bite-sized concerns. + # + # class Todo + # # Other todo implementation + # # ... + # + # concerning :EventTracking do + # included do + # has_many :events + # before_create :track_creation + # after_destroy :track_deletion + # end + # + # private + # def track_creation + # # ... + # end + # end + # end + # + # Todo.ancestors + # # => Todo, Todo::EventTracking, Object + # + # This small step has some wonderful ripple effects. We can + # * grok the behavior of our class in one glance, + # * clean up monolithic junk-drawer classes by separating their concerns, and + # * stop leaning on protected/private for crude "this is internal stuff" modularity. + module Concerning + # Define a new concern and mix it in. + def concerning(topic, &block) + include concern(topic, &block) + end + + # A low-cruft shortcut to define a concern. + # + # concern :EventTracking do + # ... + # end + # + # is equivalent to + # + # module EventTracking + # extend ActiveSupport::Concern + # + # ... + # end + def concern(topic, &module_definition) + const_set topic, Module.new { + extend ::ActiveSupport::Concern + module_eval(&module_definition) + } + end + end + include Concerning +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/module/delegation.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/module/delegation.rb new file mode 100644 index 0000000..6fedf45 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/module/delegation.rb @@ -0,0 +1,217 @@ +require 'set' + +class Module + # Error generated by +delegate+ when a method is called on +nil+ and +allow_nil+ + # option is not used. + class DelegationError < NoMethodError; end + + RUBY_RESERVED_WORDS = Set.new( + %w(alias and BEGIN begin break case class def defined? do else elsif END + end ensure false for if in module next nil not or redo rescue retry + return self super then true undef unless until when while yield) + ).freeze + + # Provides a +delegate+ class method to easily expose contained objects' + # public methods as your own. + # + # ==== Options + # * :to - Specifies the target object + # * :prefix - Prefixes the new method with the target name or a custom prefix + # * :allow_nil - if set to true, prevents a +NoMethodError+ to be raised + # + # The macro receives one or more method names (specified as symbols or + # strings) and the name of the target object via the :to option + # (also a symbol or string). + # + # Delegation is particularly useful with Active Record associations: + # + # class Greeter < ActiveRecord::Base + # def hello + # 'hello' + # end + # + # def goodbye + # 'goodbye' + # end + # end + # + # class Foo < ActiveRecord::Base + # belongs_to :greeter + # delegate :hello, to: :greeter + # end + # + # Foo.new.hello # => "hello" + # Foo.new.goodbye # => NoMethodError: undefined method `goodbye' for # + # + # Multiple delegates to the same target are allowed: + # + # class Foo < ActiveRecord::Base + # belongs_to :greeter + # delegate :hello, :goodbye, to: :greeter + # end + # + # Foo.new.goodbye # => "goodbye" + # + # Methods can be delegated to instance variables, class variables, or constants + # by providing them as a symbols: + # + # class Foo + # CONSTANT_ARRAY = [0,1,2,3] + # @@class_array = [4,5,6,7] + # + # def initialize + # @instance_array = [8,9,10,11] + # end + # delegate :sum, to: :CONSTANT_ARRAY + # delegate :min, to: :@@class_array + # delegate :max, to: :@instance_array + # end + # + # Foo.new.sum # => 6 + # Foo.new.min # => 4 + # Foo.new.max # => 11 + # + # It's also possible to delegate a method to the class by using +:class+: + # + # class Foo + # def self.hello + # "world" + # end + # + # delegate :hello, to: :class + # end + # + # Foo.new.hello # => "world" + # + # Delegates can optionally be prefixed using the :prefix option. If the value + # is true, the delegate methods are prefixed with the name of the object being + # delegated to. + # + # Person = Struct.new(:name, :address) + # + # class Invoice < Struct.new(:client) + # delegate :name, :address, to: :client, prefix: true + # end + # + # john_doe = Person.new('John Doe', 'Vimmersvej 13') + # invoice = Invoice.new(john_doe) + # invoice.client_name # => "John Doe" + # invoice.client_address # => "Vimmersvej 13" + # + # It is also possible to supply a custom prefix. + # + # class Invoice < Struct.new(:client) + # delegate :name, :address, to: :client, prefix: :customer + # end + # + # invoice = Invoice.new(john_doe) + # invoice.customer_name # => 'John Doe' + # invoice.customer_address # => 'Vimmersvej 13' + # + # If the target is +nil+ and does not respond to the delegated method a + # +NoMethodError+ is raised, as with any other value. Sometimes, however, it + # makes sense to be robust to that situation and that is the purpose of the + # :allow_nil option: If the target is not +nil+, or it is and + # responds to the method, everything works as usual. But if it is +nil+ and + # does not respond to the delegated method, +nil+ is returned. + # + # class User < ActiveRecord::Base + # has_one :profile + # delegate :age, to: :profile + # end + # + # User.new.age # raises NoMethodError: undefined method `age' + # + # But if not having a profile yet is fine and should not be an error + # condition: + # + # class User < ActiveRecord::Base + # has_one :profile + # delegate :age, to: :profile, allow_nil: true + # end + # + # User.new.age # nil + # + # Note that if the target is not +nil+ then the call is attempted regardless of the + # :allow_nil option, and thus an exception is still raised if said object + # does not respond to the method: + # + # class Foo + # def initialize(bar) + # @bar = bar + # end + # + # delegate :name, to: :@bar, allow_nil: true + # end + # + # Foo.new("Bar").name # raises NoMethodError: undefined method `name' + # + # The target method must be public, otherwise it will raise +NoMethodError+. + # + def delegate(*methods) + options = methods.pop + unless options.is_a?(Hash) && to = options[:to] + raise ArgumentError, 'Delegation needs a target. Supply an options hash with a :to key as the last argument (e.g. delegate :hello, to: :greeter).' + end + + prefix, allow_nil = options.values_at(:prefix, :allow_nil) + + if prefix == true && to =~ /^[^a-z_]/ + raise ArgumentError, 'Can only automatically set the delegation prefix when delegating to a method.' + end + + method_prefix = \ + if prefix + "#{prefix == true ? to : prefix}_" + else + '' + end + + file, line = caller.first.split(':', 2) + line = line.to_i + + to = to.to_s + to = "self.#{to}" if RUBY_RESERVED_WORDS.include?(to) + + methods.each do |method| + # Attribute writer methods only accept one argument. Makes sure []= + # methods still accept two arguments. + definition = (method =~ /[^\]]=$/) ? 'arg' : '*args, &block' + + # The following generated method calls the target exactly once, storing + # the returned value in a dummy variable. + # + # Reason is twofold: On one hand doing less calls is in general better. + # On the other hand it could be that the target has side-effects, + # whereas conceptually, from the user point of view, the delegator should + # be doing one call. + if allow_nil + method_def = [ + "def #{method_prefix}#{method}(#{definition})", + "_ = #{to}", + "if !_.nil? || nil.respond_to?(:#{method})", + " _.#{method}(#{definition})", + "end", + "end" + ].join ';' + else + exception = %(raise DelegationError, "#{self}##{method_prefix}#{method} delegated to #{to}.#{method}, but #{to} is nil: \#{self.inspect}") + + method_def = [ + "def #{method_prefix}#{method}(#{definition})", + " _ = #{to}", + " _.#{method}(#{definition})", + "rescue NoMethodError => e", + " if _.nil? && e.name == :#{method}", + " #{exception}", + " else", + " raise", + " end", + "end" + ].join ';' + end + + module_eval(method_def, file, line) + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/module/deprecation.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/module/deprecation.rb new file mode 100644 index 0000000..56d670f --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/module/deprecation.rb @@ -0,0 +1,23 @@ +class Module + # deprecate :foo + # deprecate bar: 'message' + # deprecate :foo, :bar, baz: 'warning!', qux: 'gone!' + # + # You can also use custom deprecator instance: + # + # deprecate :foo, deprecator: MyLib::Deprecator.new + # deprecate :foo, bar: "warning!", deprecator: MyLib::Deprecator.new + # + # \Custom deprecators must respond to deprecation_warning(deprecated_method_name, message, caller_backtrace) + # method where you can implement your custom warning behavior. + # + # class MyLib::Deprecator + # def deprecation_warning(deprecated_method_name, message, caller_backtrace = nil) + # message = "#{deprecated_method_name} is deprecated and will be removed from MyLibrary | #{message}" + # Kernel.warn message + # end + # end + def deprecate(*method_names) + ActiveSupport::Deprecation.deprecate_methods(self, *method_names) + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/module/introspection.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/module/introspection.rb new file mode 100644 index 0000000..f1d26ef --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/module/introspection.rb @@ -0,0 +1,62 @@ +require 'active_support/inflector' + +class Module + # Returns the name of the module containing this one. + # + # M::N.parent_name # => "M" + def parent_name + if defined? @parent_name + @parent_name + else + @parent_name = name =~ /::[^:]+\Z/ ? $`.freeze : nil + end + end + + # Returns the module which contains this one according to its name. + # + # module M + # module N + # end + # end + # X = M::N + # + # M::N.parent # => M + # X.parent # => M + # + # The parent of top-level and anonymous modules is Object. + # + # M.parent # => Object + # Module.new.parent # => Object + def parent + parent_name ? ActiveSupport::Inflector.constantize(parent_name) : Object + end + + # Returns all the parents of this module according to its name, ordered from + # nested outwards. The receiver is not contained within the result. + # + # module M + # module N + # end + # end + # X = M::N + # + # M.parents # => [Object] + # M::N.parents # => [M, Object] + # X.parents # => [M, Object] + def parents + parents = [] + if parent_name + parts = parent_name.split('::') + until parts.empty? + parents << ActiveSupport::Inflector.constantize(parts * '::') + parts.pop + end + end + parents << Object unless parents.include? Object + parents + end + + def local_constants #:nodoc: + constants(false) + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/module/method_transplanting.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/module/method_transplanting.rb new file mode 100644 index 0000000..f64efdf --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/module/method_transplanting.rb @@ -0,0 +1,13 @@ +class Module + ### + # TODO: remove this after 1.9 support is dropped + def methods_transplantable? # :nodoc: + x = Module.new { + def foo; end # :nodoc: + } + Module.new { define_method :bar, x.instance_method(:foo) } + true + rescue TypeError + false + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/module/qualified_const.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/module/qualified_const.rb new file mode 100644 index 0000000..6552501 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/module/qualified_const.rb @@ -0,0 +1,52 @@ +require 'active_support/core_ext/string/inflections' + +#-- +# Allows code reuse in the methods below without polluting Module. +#++ +module QualifiedConstUtils + def self.raise_if_absolute(path) + raise NameError.new("wrong constant name #$&") if path =~ /\A::[^:]+/ + end + + def self.names(path) + path.split('::') + end +end + +## +# Extends the API for constants to be able to deal with qualified names. Arguments +# are assumed to be relative to the receiver. +# +#-- +# Qualified names are required to be relative because we are extending existing +# methods that expect constant names, ie, relative paths of length 1. For example, +# Object.const_get('::String') raises NameError and so does qualified_const_get. +#++ +class Module + def qualified_const_defined?(path, search_parents=true) + QualifiedConstUtils.raise_if_absolute(path) + + QualifiedConstUtils.names(path).inject(self) do |mod, name| + return unless mod.const_defined?(name, search_parents) + mod.const_get(name) + end + return true + end + + def qualified_const_get(path) + QualifiedConstUtils.raise_if_absolute(path) + + QualifiedConstUtils.names(path).inject(self) do |mod, name| + mod.const_get(name) + end + end + + def qualified_const_set(path, value) + QualifiedConstUtils.raise_if_absolute(path) + + const_name = path.demodulize + mod_name = path.deconstantize + mod = mod_name.empty? ? self : qualified_const_get(mod_name) + mod.const_set(const_name, value) + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/module/reachable.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/module/reachable.rb new file mode 100644 index 0000000..5d3d0e9 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/module/reachable.rb @@ -0,0 +1,8 @@ +require 'active_support/core_ext/module/anonymous' +require 'active_support/core_ext/string/inflections' + +class Module + def reachable? #:nodoc: + !anonymous? && name.safe_constantize.equal?(self) + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/module/remove_method.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/module/remove_method.rb new file mode 100644 index 0000000..719071d --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/module/remove_method.rb @@ -0,0 +1,12 @@ +class Module + def remove_possible_method(method) + if method_defined?(method) || private_method_defined?(method) + undef_method(method) + end + end + + def redefine_method(method, &block) + remove_possible_method(method) + define_method(method, &block) + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/name_error.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/name_error.rb new file mode 100644 index 0000000..e1ebd4f --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/name_error.rb @@ -0,0 +1,18 @@ +class NameError + # Extract the name of the missing constant from the exception message. + def missing_name + if /undefined local variable or method/ !~ message + $1 if /((::)?([A-Z]\w*)(::[A-Z]\w*)*)$/ =~ message + end + end + + # Was this exception raised because the given name was missing? + def missing_name?(name) + if name.is_a? Symbol + last_name = (missing_name || '').split('::').last + last_name == name.to_s + else + missing_name == name.to_s + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/numeric.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/numeric.rb new file mode 100644 index 0000000..a6bc062 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/numeric.rb @@ -0,0 +1,3 @@ +require 'active_support/core_ext/numeric/bytes' +require 'active_support/core_ext/numeric/time' +require 'active_support/core_ext/numeric/conversions' diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/numeric/bytes.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/numeric/bytes.rb new file mode 100644 index 0000000..deea8e9 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/numeric/bytes.rb @@ -0,0 +1,44 @@ +class Numeric + KILOBYTE = 1024 + MEGABYTE = KILOBYTE * 1024 + GIGABYTE = MEGABYTE * 1024 + TERABYTE = GIGABYTE * 1024 + PETABYTE = TERABYTE * 1024 + EXABYTE = PETABYTE * 1024 + + # Enables the use of byte calculations and declarations, like 45.bytes + 2.6.megabytes + def bytes + self + end + alias :byte :bytes + + def kilobytes + self * KILOBYTE + end + alias :kilobyte :kilobytes + + def megabytes + self * MEGABYTE + end + alias :megabyte :megabytes + + def gigabytes + self * GIGABYTE + end + alias :gigabyte :gigabytes + + def terabytes + self * TERABYTE + end + alias :terabyte :terabytes + + def petabytes + self * PETABYTE + end + alias :petabyte :petabytes + + def exabytes + self * EXABYTE + end + alias :exabyte :exabytes +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/numeric/conversions.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/numeric/conversions.rb new file mode 100644 index 0000000..35fc6c8 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/numeric/conversions.rb @@ -0,0 +1,135 @@ +require 'active_support/core_ext/big_decimal/conversions' +require 'active_support/number_helper' + +class Numeric + + # Provides options for converting numbers into formatted strings. + # Options are provided for phone numbers, currency, percentage, + # precision, positional notation, file size and pretty printing. + # + # ==== Options + # + # For details on which formats use which options, see ActiveSupport::NumberHelper + # + # ==== Examples + # + # Phone Numbers: + # 5551234.to_s(:phone) # => 555-1234 + # 1235551234.to_s(:phone) # => 123-555-1234 + # 1235551234.to_s(:phone, area_code: true) # => (123) 555-1234 + # 1235551234.to_s(:phone, delimiter: ' ') # => 123 555 1234 + # 1235551234.to_s(:phone, area_code: true, extension: 555) # => (123) 555-1234 x 555 + # 1235551234.to_s(:phone, country_code: 1) # => +1-123-555-1234 + # 1235551234.to_s(:phone, country_code: 1, extension: 1343, delimiter: '.') + # # => +1.123.555.1234 x 1343 + # + # Currency: + # 1234567890.50.to_s(:currency) # => $1,234,567,890.50 + # 1234567890.506.to_s(:currency) # => $1,234,567,890.51 + # 1234567890.506.to_s(:currency, precision: 3) # => $1,234,567,890.506 + # 1234567890.506.to_s(:currency, locale: :fr) # => 1 234 567 890,51 € + # -1234567890.50.to_s(:currency, negative_format: '(%u%n)') + # # => ($1,234,567,890.50) + # 1234567890.50.to_s(:currency, unit: '£', separator: ',', delimiter: '') + # # => £1234567890,50 + # 1234567890.50.to_s(:currency, unit: '£', separator: ',', delimiter: '', format: '%n %u') + # # => 1234567890,50 £ + # + # Percentage: + # 100.to_s(:percentage) # => 100.000% + # 100.to_s(:percentage, precision: 0) # => 100% + # 1000.to_s(:percentage, delimiter: '.', separator: ',') # => 1.000,000% + # 302.24398923423.to_s(:percentage, precision: 5) # => 302.24399% + # 1000.to_s(:percentage, locale: :fr) # => 1 000,000% + # 100.to_s(:percentage, format: '%n %') # => 100.000 % + # + # Delimited: + # 12345678.to_s(:delimited) # => 12,345,678 + # 12345678.05.to_s(:delimited) # => 12,345,678.05 + # 12345678.to_s(:delimited, delimiter: '.') # => 12.345.678 + # 12345678.to_s(:delimited, delimiter: ',') # => 12,345,678 + # 12345678.05.to_s(:delimited, separator: ' ') # => 12,345,678 05 + # 12345678.05.to_s(:delimited, locale: :fr) # => 12 345 678,05 + # 98765432.98.to_s(:delimited, delimiter: ' ', separator: ',') + # # => 98 765 432,98 + # + # Rounded: + # 111.2345.to_s(:rounded) # => 111.235 + # 111.2345.to_s(:rounded, precision: 2) # => 111.23 + # 13.to_s(:rounded, precision: 5) # => 13.00000 + # 389.32314.to_s(:rounded, precision: 0) # => 389 + # 111.2345.to_s(:rounded, significant: true) # => 111 + # 111.2345.to_s(:rounded, precision: 1, significant: true) # => 100 + # 13.to_s(:rounded, precision: 5, significant: true) # => 13.000 + # 111.234.to_s(:rounded, locale: :fr) # => 111,234 + # 13.to_s(:rounded, precision: 5, significant: true, strip_insignificant_zeros: true) + # # => 13 + # 389.32314.to_s(:rounded, precision: 4, significant: true) # => 389.3 + # 1111.2345.to_s(:rounded, precision: 2, separator: ',', delimiter: '.') + # # => 1.111,23 + # + # Human-friendly size in Bytes: + # 123.to_s(:human_size) # => 123 Bytes + # 1234.to_s(:human_size) # => 1.21 KB + # 12345.to_s(:human_size) # => 12.1 KB + # 1234567.to_s(:human_size) # => 1.18 MB + # 1234567890.to_s(:human_size) # => 1.15 GB + # 1234567890123.to_s(:human_size) # => 1.12 TB + # 1234567.to_s(:human_size, precision: 2) # => 1.2 MB + # 483989.to_s(:human_size, precision: 2) # => 470 KB + # 1234567.to_s(:human_size, precision: 2, separator: ',') # => 1,2 MB + # 1234567890123.to_s(:human_size, precision: 5) # => "1.1228 TB" + # 524288000.to_s(:human_size, precision: 5) # => "500 MB" + # + # Human-friendly format: + # 123.to_s(:human) # => "123" + # 1234.to_s(:human) # => "1.23 Thousand" + # 12345.to_s(:human) # => "12.3 Thousand" + # 1234567.to_s(:human) # => "1.23 Million" + # 1234567890.to_s(:human) # => "1.23 Billion" + # 1234567890123.to_s(:human) # => "1.23 Trillion" + # 1234567890123456.to_s(:human) # => "1.23 Quadrillion" + # 1234567890123456789.to_s(:human) # => "1230 Quadrillion" + # 489939.to_s(:human, precision: 2) # => "490 Thousand" + # 489939.to_s(:human, precision: 4) # => "489.9 Thousand" + # 1234567.to_s(:human, precision: 4, + # significant: false) # => "1.2346 Million" + # 1234567.to_s(:human, precision: 1, + # separator: ',', + # significant: false) # => "1,2 Million" + def to_formatted_s(format = :default, options = {}) + case format + when :phone + return ActiveSupport::NumberHelper.number_to_phone(self, options) + when :currency + return ActiveSupport::NumberHelper.number_to_currency(self, options) + when :percentage + return ActiveSupport::NumberHelper.number_to_percentage(self, options) + when :delimited + return ActiveSupport::NumberHelper.number_to_delimited(self, options) + when :rounded + return ActiveSupport::NumberHelper.number_to_rounded(self, options) + when :human + return ActiveSupport::NumberHelper.number_to_human(self, options) + when :human_size + return ActiveSupport::NumberHelper.number_to_human_size(self, options) + else + self.to_default_s + end + end + + [Float, Fixnum, Bignum, BigDecimal].each do |klass| + klass.send(:alias_method, :to_default_s, :to_s) + + klass.send(:define_method, :to_s) do |*args| + if args[0].is_a?(Symbol) + format = args[0] + options = args[1] || {} + + self.to_formatted_s(format, options) + else + to_default_s(*args) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/numeric/time.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/numeric/time.rb new file mode 100644 index 0000000..40c1173 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/numeric/time.rb @@ -0,0 +1,54 @@ +require 'active_support/duration' +require 'active_support/core_ext/time/calculations' +require 'active_support/core_ext/time/acts_like' + +class Numeric + # Enables the use of time calculations and declarations, like 45.minutes + 2.hours + 4.years. + # + # These methods use Time#advance for precise date calculations when using from_now, ago, etc. + # as well as adding or subtracting their results from a Time object. For example: + # + # # equivalent to Time.current.advance(months: 1) + # 1.month.from_now + # + # # equivalent to Time.current.advance(years: 2) + # 2.years.from_now + # + # # equivalent to Time.current.advance(months: 4, years: 5) + # (4.months + 5.years).from_now + def seconds + ActiveSupport::Duration.new(self, [[:seconds, self]]) + end + alias :second :seconds + + def minutes + ActiveSupport::Duration.new(self * 60, [[:seconds, self * 60]]) + end + alias :minute :minutes + + def hours + ActiveSupport::Duration.new(self * 3600, [[:seconds, self * 3600]]) + end + alias :hour :hours + + def days + ActiveSupport::Duration.new(self * 24.hours, [[:days, self]]) + end + alias :day :days + + def weeks + ActiveSupport::Duration.new(self * 7.days, [[:days, self * 7]]) + end + alias :week :weeks + + def fortnights + ActiveSupport::Duration.new(self * 2.weeks, [[:days, self * 14]]) + end + alias :fortnight :fortnights + + # Used with the standard time durations, like 1.hour.in_milliseconds -- + # so we can feed them to JavaScript functions like getTime(). + def in_milliseconds + self * 1000 + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/object.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/object.rb new file mode 100644 index 0000000..f1106cc --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/object.rb @@ -0,0 +1,15 @@ +require 'active_support/core_ext/object/acts_like' +require 'active_support/core_ext/object/blank' +require 'active_support/core_ext/object/duplicable' +require 'active_support/core_ext/object/deep_dup' +require 'active_support/core_ext/object/itself' +require 'active_support/core_ext/object/try' +require 'active_support/core_ext/object/inclusion' + +require 'active_support/core_ext/object/conversions' +require 'active_support/core_ext/object/instance_variables' + +require 'active_support/core_ext/object/json' +require 'active_support/core_ext/object/to_param' +require 'active_support/core_ext/object/to_query' +require 'active_support/core_ext/object/with_options' diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/object/acts_like.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/object/acts_like.rb new file mode 100644 index 0000000..3912cc5 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/object/acts_like.rb @@ -0,0 +1,10 @@ +class Object + # A duck-type assistant method. For example, Active Support extends Date + # to define an acts_like_date? method, and extends Time to define + # acts_like_time?. As a result, we can do x.acts_like?(:time) and + # x.acts_like?(:date) to do duck-type-safe comparisons, since classes that + # we want to act like Time simply need to define an acts_like_time? method. + def acts_like?(duck) + respond_to? :"acts_like_#{duck}?" + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/object/blank.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/object/blank.rb new file mode 100644 index 0000000..548c916 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/object/blank.rb @@ -0,0 +1,131 @@ +# encoding: utf-8 + +class Object + # An object is blank if it's false, empty, or a whitespace string. + # For example, +false+, '', ' ', +nil+, [], and {} are all blank. + # + # This simplifies + # + # !address || address.empty? + # + # to + # + # address.blank? + # + # @return [true, false] + def blank? + respond_to?(:empty?) ? !!empty? : !self + end + + # An object is present if it's not blank. + # + # @return [true, false] + def present? + !blank? + end + + # Returns the receiver if it's present otherwise returns +nil+. + # object.presence is equivalent to + # + # object.present? ? object : nil + # + # For example, something like + # + # state = params[:state] if params[:state].present? + # country = params[:country] if params[:country].present? + # region = state || country || 'US' + # + # becomes + # + # region = params[:state].presence || params[:country].presence || 'US' + # + # @return [Object] + def presence + self if present? + end +end + +class NilClass + # +nil+ is blank: + # + # nil.blank? # => true + # + # @return [true] + def blank? + true + end +end + +class FalseClass + # +false+ is blank: + # + # false.blank? # => true + # + # @return [true] + def blank? + true + end +end + +class TrueClass + # +true+ is not blank: + # + # true.blank? # => false + # + # @return [false] + def blank? + false + end +end + +class Array + # An array is blank if it's empty: + # + # [].blank? # => true + # [1,2,3].blank? # => false + # + # @return [true, false] + alias_method :blank?, :empty? +end + +class Hash + # A hash is blank if it's empty: + # + # {}.blank? # => true + # { key: 'value' }.blank? # => false + # + # @return [true, false] + alias_method :blank?, :empty? +end + +class String + BLANK_RE = /\A[[:space:]]*\z/ + + # A string is blank if it's empty or contains whitespaces only: + # + # ''.blank? # => true + # ' '.blank? # => true + # "\t\n\r".blank? # => true + # ' blah '.blank? # => false + # + # Unicode whitespace is supported: + # + # "\u00a0".blank? # => true + # + # @return [true, false] + def blank? + BLANK_RE === self + end +end + +class Numeric #:nodoc: + # No number is blank: + # + # 1.blank? # => false + # 0.blank? # => false + # + # @return [false] + def blank? + false + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/object/conversions.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/object/conversions.rb new file mode 100644 index 0000000..540f7aa --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/object/conversions.rb @@ -0,0 +1,4 @@ +require 'active_support/core_ext/object/to_param' +require 'active_support/core_ext/object/to_query' +require 'active_support/core_ext/array/conversions' +require 'active_support/core_ext/hash/conversions' diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/object/deep_dup.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/object/deep_dup.rb new file mode 100644 index 0000000..2e99f4a --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/object/deep_dup.rb @@ -0,0 +1,46 @@ +require 'active_support/core_ext/object/duplicable' + +class Object + # Returns a deep copy of object if it's duplicable. If it's + # not duplicable, returns +self+. + # + # object = Object.new + # dup = object.deep_dup + # dup.instance_variable_set(:@a, 1) + # + # object.instance_variable_defined?(:@a) # => false + # dup.instance_variable_defined?(:@a) # => true + def deep_dup + duplicable? ? dup : self + end +end + +class Array + # Returns a deep copy of array. + # + # array = [1, [2, 3]] + # dup = array.deep_dup + # dup[1][2] = 4 + # + # array[1][2] # => nil + # dup[1][2] # => 4 + def deep_dup + map { |it| it.deep_dup } + end +end + +class Hash + # Returns a deep copy of hash. + # + # hash = { a: { b: 'b' } } + # dup = hash.deep_dup + # dup[:a][:c] = 'c' + # + # hash[:a][:c] # => nil + # dup[:a][:c] # => "c" + def deep_dup + each_with_object(dup) do |(key, value), hash| + hash[key.deep_dup] = value.deep_dup + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/object/duplicable.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/object/duplicable.rb new file mode 100644 index 0000000..665cb0f --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/object/duplicable.rb @@ -0,0 +1,103 @@ +#-- +# Most objects are cloneable, but not all. For example you can't dup +nil+: +# +# nil.dup # => TypeError: can't dup NilClass +# +# Classes may signal their instances are not duplicable removing +dup+/+clone+ +# or raising exceptions from them. So, to dup an arbitrary object you normally +# use an optimistic approach and are ready to catch an exception, say: +# +# arbitrary_object.dup rescue object +# +# Rails dups objects in a few critical spots where they are not that arbitrary. +# That rescue is very expensive (like 40 times slower than a predicate), and it +# is often triggered. +# +# That's why we hardcode the following cases and check duplicable? instead of +# using that rescue idiom. +#++ +class Object + # Can you safely dup this object? + # + # False for +nil+, +false+, +true+, symbol, number and BigDecimal(in 1.9.x) objects; + # true otherwise. + def duplicable? + true + end +end + +class NilClass + # +nil+ is not duplicable: + # + # nil.duplicable? # => false + # nil.dup # => TypeError: can't dup NilClass + def duplicable? + false + end +end + +class FalseClass + # +false+ is not duplicable: + # + # false.duplicable? # => false + # false.dup # => TypeError: can't dup FalseClass + def duplicable? + false + end +end + +class TrueClass + # +true+ is not duplicable: + # + # true.duplicable? # => false + # true.dup # => TypeError: can't dup TrueClass + def duplicable? + false + end +end + +class Symbol + # Symbols are not duplicable: + # + # :my_symbol.duplicable? # => false + # :my_symbol.dup # => TypeError: can't dup Symbol + def duplicable? + false + end +end + +class Numeric + # Numbers are not duplicable: + # + # 3.duplicable? # => false + # 3.dup # => TypeError: can't dup Fixnum + def duplicable? + false + end +end + +require 'bigdecimal' +class BigDecimal + # Needed to support Ruby 1.9.x, as it doesn't allow dup on BigDecimal, instead + # raises TypeError exception. Checking here on the runtime whether BigDecimal + # will allow dup or not. + begin + BigDecimal.new('4.56').dup + + def duplicable? + true + end + rescue TypeError + # can't dup, so use superclass implementation + end +end + +class Method + # Methods are not duplicable: + # + # method(:puts).duplicable? # => false + # method(:puts).dup # => TypeError: allocator undefined for Method + def duplicable? + false + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/object/inclusion.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/object/inclusion.rb new file mode 100644 index 0000000..55f281b --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/object/inclusion.rb @@ -0,0 +1,27 @@ +class Object + # Returns true if this object is included in the argument. Argument must be + # any object which responds to +#include?+. Usage: + # + # characters = ["Konata", "Kagami", "Tsukasa"] + # "Konata".in?(characters) # => true + # + # This will throw an ArgumentError if the argument doesn't respond + # to +#include?+. + def in?(another_object) + another_object.include?(self) + rescue NoMethodError + raise ArgumentError.new("The parameter passed to #in? must respond to #include?") + end + + # Returns the receiver if it's included in the argument otherwise returns +nil+. + # Argument must be any object which responds to +#include?+. Usage: + # + # params[:bucket_type].presence_in %w( project calendar ) + # + # This will throw an ArgumentError if the argument doesn't respond to +#include?+. + # + # @return [Object] + def presence_in(another_object) + self.in?(another_object) ? self : nil + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/object/instance_variables.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/object/instance_variables.rb new file mode 100644 index 0000000..755e1c6 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/object/instance_variables.rb @@ -0,0 +1,28 @@ +class Object + # Returns a hash with string keys that maps instance variable names without "@" to their + # corresponding values. + # + # class C + # def initialize(x, y) + # @x, @y = x, y + # end + # end + # + # C.new(0, 1).instance_values # => {"x" => 0, "y" => 1} + def instance_values + Hash[instance_variables.map { |name| [name[1..-1], instance_variable_get(name)] }] + end + + # Returns an array of instance variable names as strings including "@". + # + # class C + # def initialize(x, y) + # @x, @y = x, y + # end + # end + # + # C.new(0, 1).instance_variable_names # => ["@y", "@x"] + def instance_variable_names + instance_variables.map { |var| var.to_s } + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/object/itself.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/object/itself.rb new file mode 100644 index 0000000..d71cea6 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/object/itself.rb @@ -0,0 +1,15 @@ +class Object + # TODO: Remove this file when we drop support for Ruby < 2.2 + unless respond_to?(:itself) + # Returns the object itself. + # + # Useful for chaining methods, such as Active Record scopes: + # + # Event.public_send(state.presence_in([ :trashed, :drafted ]) || :itself).order(:created_at) + # + # @return Object + def itself + self + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/object/json.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/object/json.rb new file mode 100644 index 0000000..64dea5f --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/object/json.rb @@ -0,0 +1,197 @@ +# Hack to load json gem first so we can overwrite its to_json. +require 'json' +require 'bigdecimal' +require 'active_support/core_ext/big_decimal/conversions' # for #to_s +require 'active_support/core_ext/hash/except' +require 'active_support/core_ext/hash/slice' +require 'active_support/core_ext/object/instance_variables' +require 'time' +require 'active_support/core_ext/time/conversions' +require 'active_support/core_ext/date_time/conversions' +require 'active_support/core_ext/date/conversions' +require 'active_support/core_ext/module/aliasing' + +# The JSON gem adds a few modules to Ruby core classes containing :to_json definition, overwriting +# their default behavior. That said, we need to define the basic to_json method in all of them, +# otherwise they will always use to_json gem implementation, which is backwards incompatible in +# several cases (for instance, the JSON implementation for Hash does not work) with inheritance +# and consequently classes as ActiveSupport::OrderedHash cannot be serialized to json. +# +# On the other hand, we should avoid conflict with ::JSON.{generate,dump}(obj). Unfortunately, the +# JSON gem's encoder relies on its own to_json implementation to encode objects. Since it always +# passes a ::JSON::State object as the only argument to to_json, we can detect that and forward the +# calls to the original to_json method. +# +# It should be noted that when using ::JSON.{generate,dump} directly, ActiveSupport's encoder is +# bypassed completely. This means that as_json won't be invoked and the JSON gem will simply +# ignore any options it does not natively understand. This also means that ::JSON.{generate,dump} +# should give exactly the same results with or without active support. +[Enumerable, Object, Array, FalseClass, Float, Hash, Integer, NilClass, String, TrueClass].each do |klass| + klass.class_eval do + def to_json_with_active_support_encoder(options = nil) # :nodoc: + if options.is_a?(::JSON::State) + # Called from JSON.{generate,dump}, forward it to JSON gem's to_json + self.to_json_without_active_support_encoder(options) + else + # to_json is being invoked directly, use ActiveSupport's encoder + ActiveSupport::JSON.encode(self, options) + end + end + + alias_method_chain :to_json, :active_support_encoder + end +end + +class Object + def as_json(options = nil) #:nodoc: + if respond_to?(:to_hash) + to_hash.as_json(options) + else + instance_values.as_json(options) + end + end +end + +class Struct #:nodoc: + def as_json(options = nil) + Hash[members.zip(values)].as_json(options) + end +end + +class TrueClass + def as_json(options = nil) #:nodoc: + self + end +end + +class FalseClass + def as_json(options = nil) #:nodoc: + self + end +end + +class NilClass + def as_json(options = nil) #:nodoc: + self + end +end + +class String + def as_json(options = nil) #:nodoc: + self + end +end + +class Symbol + def as_json(options = nil) #:nodoc: + to_s + end +end + +class Numeric + def as_json(options = nil) #:nodoc: + self + end +end + +class Float + # Encoding Infinity or NaN to JSON should return "null". The default returns + # "Infinity" or "NaN" which are not valid JSON. + def as_json(options = nil) #:nodoc: + finite? ? self : nil + end +end + +class BigDecimal + # A BigDecimal would be naturally represented as a JSON number. Most libraries, + # however, parse non-integer JSON numbers directly as floats. Clients using + # those libraries would get in general a wrong number and no way to recover + # other than manually inspecting the string with the JSON code itself. + # + # That's why a JSON string is returned. The JSON literal is not numeric, but + # if the other end knows by contract that the data is supposed to be a + # BigDecimal, it still has the chance to post-process the string and get the + # real value. + def as_json(options = nil) #:nodoc: + finite? ? to_s : nil + end +end + +class Regexp + def as_json(options = nil) #:nodoc: + to_s + end +end + +module Enumerable + def as_json(options = nil) #:nodoc: + to_a.as_json(options) + end +end + +class Range + def as_json(options = nil) #:nodoc: + to_s + end +end + +class Array + def as_json(options = nil) #:nodoc: + map { |v| options ? v.as_json(options.dup) : v.as_json } + end +end + +class Hash + def as_json(options = nil) #:nodoc: + # create a subset of the hash by applying :only or :except + subset = if options + if attrs = options[:only] + slice(*Array(attrs)) + elsif attrs = options[:except] + except(*Array(attrs)) + else + self + end + else + self + end + + Hash[subset.map { |k, v| [k.to_s, options ? v.as_json(options.dup) : v.as_json] }] + end +end + +class Time + def as_json(options = nil) #:nodoc: + if ActiveSupport::JSON::Encoding.use_standard_json_time_format + xmlschema(ActiveSupport::JSON::Encoding.time_precision) + else + %(#{strftime("%Y/%m/%d %H:%M:%S")} #{formatted_offset(false)}) + end + end +end + +class Date + def as_json(options = nil) #:nodoc: + if ActiveSupport::JSON::Encoding.use_standard_json_time_format + strftime("%Y-%m-%d") + else + strftime("%Y/%m/%d") + end + end +end + +class DateTime + def as_json(options = nil) #:nodoc: + if ActiveSupport::JSON::Encoding.use_standard_json_time_format + xmlschema(ActiveSupport::JSON::Encoding.time_precision) + else + strftime('%Y/%m/%d %H:%M:%S %z') + end + end +end + +class Process::Status #:nodoc: + def as_json(options = nil) + { :exitstatus => exitstatus, :pid => pid } + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/object/to_param.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/object/to_param.rb new file mode 100644 index 0000000..684d4ef --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/object/to_param.rb @@ -0,0 +1 @@ +require 'active_support/core_ext/object/to_query' diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/object/to_query.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/object/to_query.rb new file mode 100644 index 0000000..ccd568b --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/object/to_query.rb @@ -0,0 +1,84 @@ +require 'cgi' + +class Object + # Alias of to_s. + def to_param + to_s + end + + # Converts an object into a string suitable for use as a URL query string, + # using the given key as the param name. + def to_query(key) + "#{CGI.escape(key.to_param)}=#{CGI.escape(to_param.to_s)}" + end +end + +class NilClass + # Returns +self+. + def to_param + self + end +end + +class TrueClass + # Returns +self+. + def to_param + self + end +end + +class FalseClass + # Returns +self+. + def to_param + self + end +end + +class Array + # Calls to_param on all its elements and joins the result with + # slashes. This is used by url_for in Action Pack. + def to_param + collect { |e| e.to_param }.join '/' + end + + # Converts an array into a string suitable for use as a URL query string, + # using the given +key+ as the param name. + # + # ['Rails', 'coding'].to_query('hobbies') # => "hobbies%5B%5D=Rails&hobbies%5B%5D=coding" + def to_query(key) + prefix = "#{key}[]" + + if empty? + nil.to_query(prefix) + else + collect { |value| value.to_query(prefix) }.join '&' + end + end +end + +class Hash + # Returns a string representation of the receiver suitable for use as a URL + # query string: + # + # {name: 'David', nationality: 'Danish'}.to_query + # # => "name=David&nationality=Danish" + # + # An optional namespace can be passed to enclose key names: + # + # {name: 'David', nationality: 'Danish'}.to_query('user') + # # => "user%5Bname%5D=David&user%5Bnationality%5D=Danish" + # + # The string pairs "key=value" that conform the query string + # are sorted lexicographically in ascending order. + # + # This method is also aliased as +to_param+. + def to_query(namespace = nil) + collect do |key, value| + unless (value.is_a?(Hash) || value.is_a?(Array)) && value.empty? + value.to_query(namespace ? "#{namespace}[#{key}]" : key) + end + end.compact.sort! * '&' + end + + alias_method :to_param, :to_query +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/object/try.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/object/try.rb new file mode 100644 index 0000000..a737047 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/object/try.rb @@ -0,0 +1,100 @@ +class Object + # Invokes the public method whose name goes as first argument just like + # +public_send+ does, except that if the receiver does not respond to it the + # call returns +nil+ rather than raising an exception. + # + # This method is defined to be able to write + # + # @person.try(:name) + # + # instead of + # + # @person.name if @person + # + # +try+ calls can be chained: + # + # @person.try(:spouse).try(:name) + # + # instead of + # + # @person.spouse.name if @person && @person.spouse + # + # +try+ will also return +nil+ if the receiver does not respond to the method: + # + # @person.try(:non_existing_method) #=> nil + # + # instead of + # + # @person.non_existing_method if @person.respond_to?(:non_existing_method) #=> nil + # + # +try+ returns +nil+ when called on +nil+ regardless of whether it responds + # to the method: + # + # nil.try(:to_i) # => nil, rather than 0 + # + # Arguments and blocks are forwarded to the method if invoked: + # + # @posts.try(:each_slice, 2) do |a, b| + # ... + # end + # + # The number of arguments in the signature must match. If the object responds + # to the method the call is attempted and +ArgumentError+ is still raised + # in case of argument mismatch. + # + # If +try+ is called without arguments it yields the receiver to a given + # block unless it is +nil+: + # + # @person.try do |p| + # ... + # end + # + # You can also call try with a block without accepting an argument, and the block + # will be instance_eval'ed instead: + # + # @person.try { upcase.truncate(50) } + # + # Please also note that +try+ is defined on +Object+. Therefore, it won't work + # with instances of classes that do not have +Object+ among their ancestors, + # like direct subclasses of +BasicObject+. For example, using +try+ with + # +SimpleDelegator+ will delegate +try+ to the target instead of calling it on + # the delegator itself. + def try(*a, &b) + try!(*a, &b) if a.empty? || respond_to?(a.first) + end + + # Same as #try, but will raise a NoMethodError exception if the receiver is not +nil+ and + # does not implement the tried method. + + def try!(*a, &b) + if a.empty? && block_given? + if b.arity == 0 + instance_eval(&b) + else + yield self + end + else + public_send(*a, &b) + end + end +end + +class NilClass + # Calling +try+ on +nil+ always returns +nil+. + # It becomes especially helpful when navigating through associations that may return +nil+. + # + # nil.try(:name) # => nil + # + # Without +try+ + # @person && @person.children.any? && @person.children.first.name + # + # With +try+ + # @person.try(:children).try(:first).try(:name) + def try(*args) + nil + end + + def try!(*args) + nil + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/object/with_options.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/object/with_options.rb new file mode 100644 index 0000000..7d38e1d --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/object/with_options.rb @@ -0,0 +1,69 @@ +require 'active_support/option_merger' + +class Object + # An elegant way to factor duplication out of options passed to a series of + # method calls. Each method called in the block, with the block variable as + # the receiver, will have its options merged with the default +options+ hash + # provided. Each method called on the block variable must take an options + # hash as its final argument. + # + # Without with_options>, this code contains duplication: + # + # class Account < ActiveRecord::Base + # has_many :customers, dependent: :destroy + # has_many :products, dependent: :destroy + # has_many :invoices, dependent: :destroy + # has_many :expenses, dependent: :destroy + # end + # + # Using with_options, we can remove the duplication: + # + # class Account < ActiveRecord::Base + # with_options dependent: :destroy do |assoc| + # assoc.has_many :customers + # assoc.has_many :products + # assoc.has_many :invoices + # assoc.has_many :expenses + # end + # end + # + # It can also be used with an explicit receiver: + # + # I18n.with_options locale: user.locale, scope: 'newsletter' do |i18n| + # subject i18n.t :subject + # body i18n.t :body, user_name: user.name + # end + # + # When you don't pass an explicit receiver, it executes the whole block + # in merging options context: + # + # class Account < ActiveRecord::Base + # with_options dependent: :destroy do + # has_many :customers + # has_many :products + # has_many :invoices + # has_many :expenses + # end + # end + # + # with_options can also be nested since the call is forwarded to its receiver. + # + # NOTE: Each nesting level will merge inherited defaults in addition to their own. + # + # class Post < ActiveRecord::Base + # with_options if: :persisted?, length: { minimum: 50 } do + # validates :content, if: -> { content.present? } + # end + # end + # + # The code is equivalent to: + # + # validates :content, length: { minimum: 50 }, if: -> { content.present? } + # + # Hence the inherited default for `if` key is ignored. + # + def with_options(options, &block) + option_merger = ActiveSupport::OptionMerger.new(self, options) + block.arity.zero? ? option_merger.instance_eval(&block) : block.call(option_merger) + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/range.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/range.rb new file mode 100644 index 0000000..9368e81 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/range.rb @@ -0,0 +1,4 @@ +require 'active_support/core_ext/range/conversions' +require 'active_support/core_ext/range/include_range' +require 'active_support/core_ext/range/overlaps' +require 'active_support/core_ext/range/each' diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/range/conversions.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/range/conversions.rb new file mode 100644 index 0000000..b1a1278 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/range/conversions.rb @@ -0,0 +1,19 @@ +class Range + RANGE_FORMATS = { + :db => Proc.new { |start, stop| "BETWEEN '#{start.to_s(:db)}' AND '#{stop.to_s(:db)}'" } + } + + # Gives a human readable format of the range. + # + # (1..100).to_formatted_s # => "1..100" + def to_formatted_s(format = :default) + if formatter = RANGE_FORMATS[format] + formatter.call(first, last) + else + to_default_s + end + end + + alias_method :to_default_s, :to_s + alias_method :to_s, :to_formatted_s +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/range/each.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/range/each.rb new file mode 100644 index 0000000..ecef78f --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/range/each.rb @@ -0,0 +1,23 @@ +require 'active_support/core_ext/module/aliasing' + +class Range #:nodoc: + + def each_with_time_with_zone(&block) + ensure_iteration_allowed + each_without_time_with_zone(&block) + end + alias_method_chain :each, :time_with_zone + + def step_with_time_with_zone(n = 1, &block) + ensure_iteration_allowed + step_without_time_with_zone(n, &block) + end + alias_method_chain :step, :time_with_zone + + private + def ensure_iteration_allowed + if first.is_a?(Time) + raise TypeError, "can't iterate from #{first.class}" + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/range/include_range.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/range/include_range.rb new file mode 100644 index 0000000..3a07401 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/range/include_range.rb @@ -0,0 +1,23 @@ +require 'active_support/core_ext/module/aliasing' + +class Range + # Extends the default Range#include? to support range comparisons. + # (1..5).include?(1..5) # => true + # (1..5).include?(2..3) # => true + # (1..5).include?(2..6) # => false + # + # The native Range#include? behavior is untouched. + # ('a'..'f').include?('c') # => true + # (5..9).include?(11) # => false + def include_with_range?(value) + if value.is_a?(::Range) + # 1...10 includes 1..9 but it does not include 1..10. + operator = exclude_end? && !value.exclude_end? ? :< : :<= + include_without_range?(value.first) && value.last.send(operator, last) + else + include_without_range?(value) + end + end + + alias_method_chain :include?, :range +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/range/overlaps.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/range/overlaps.rb new file mode 100644 index 0000000..603657c --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/range/overlaps.rb @@ -0,0 +1,8 @@ +class Range + # Compare two ranges and see if they overlap each other + # (1..5).overlaps?(4..6) # => true + # (1..5).overlaps?(7..9) # => false + def overlaps?(other) + cover?(other.first) || other.cover?(first) + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/regexp.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/regexp.rb new file mode 100644 index 0000000..784145f --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/regexp.rb @@ -0,0 +1,5 @@ +class Regexp #:nodoc: + def multiline? + options & MULTILINE == MULTILINE + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/string.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/string.rb new file mode 100644 index 0000000..c656db2 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/string.rb @@ -0,0 +1,13 @@ +require 'active_support/core_ext/string/conversions' +require 'active_support/core_ext/string/filters' +require 'active_support/core_ext/string/multibyte' +require 'active_support/core_ext/string/starts_ends_with' +require 'active_support/core_ext/string/inflections' +require 'active_support/core_ext/string/access' +require 'active_support/core_ext/string/behavior' +require 'active_support/core_ext/string/output_safety' +require 'active_support/core_ext/string/exclude' +require 'active_support/core_ext/string/strip' +require 'active_support/core_ext/string/inquiry' +require 'active_support/core_ext/string/indent' +require 'active_support/core_ext/string/zones' diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/string/access.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/string/access.rb new file mode 100644 index 0000000..ebd0dd3 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/string/access.rb @@ -0,0 +1,104 @@ +class String + # If you pass a single Fixnum, returns a substring of one character at that + # position. The first character of the string is at position 0, the next at + # position 1, and so on. If a range is supplied, a substring containing + # characters at offsets given by the range is returned. In both cases, if an + # offset is negative, it is counted from the end of the string. Returns nil + # if the initial offset falls outside the string. Returns an empty string if + # the beginning of the range is greater than the end of the string. + # + # str = "hello" + # str.at(0) # => "h" + # str.at(1..3) # => "ell" + # str.at(-2) # => "l" + # str.at(-2..-1) # => "lo" + # str.at(5) # => nil + # str.at(5..-1) # => "" + # + # If a Regexp is given, the matching portion of the string is returned. + # If a String is given, that given string is returned if it occurs in + # the string. In both cases, nil is returned if there is no match. + # + # str = "hello" + # str.at(/lo/) # => "lo" + # str.at(/ol/) # => nil + # str.at("lo") # => "lo" + # str.at("ol") # => nil + def at(position) + self[position] + end + + # Returns a substring from the given position to the end of the string. + # If the position is negative, it is counted from the end of the string. + # + # str = "hello" + # str.from(0) # => "hello" + # str.from(3) # => "lo" + # str.from(-2) # => "lo" + # + # You can mix it with +to+ method and do fun things like: + # + # str = "hello" + # str.from(0).to(-1) # => "hello" + # str.from(1).to(-2) # => "ell" + def from(position) + self[position..-1] + end + + # Returns a substring from the beginning of the string to the given position. + # If the position is negative, it is counted from the end of the string. + # + # str = "hello" + # str.to(0) # => "h" + # str.to(3) # => "hell" + # str.to(-2) # => "hell" + # + # You can mix it with +from+ method and do fun things like: + # + # str = "hello" + # str.from(0).to(-1) # => "hello" + # str.from(1).to(-2) # => "ell" + def to(position) + self[0..position] + end + + # Returns the first character. If a limit is supplied, returns a substring + # from the beginning of the string until it reaches the limit value. If the + # given limit is greater than or equal to the string length, returns a copy of self. + # + # str = "hello" + # str.first # => "h" + # str.first(1) # => "h" + # str.first(2) # => "he" + # str.first(0) # => "" + # str.first(6) # => "hello" + def first(limit = 1) + if limit == 0 + '' + elsif limit >= size + self.dup + else + to(limit - 1) + end + end + + # Returns the last character of the string. If a limit is supplied, returns a substring + # from the end of the string until it reaches the limit value (counting backwards). If + # the given limit is greater than or equal to the string length, returns a copy of self. + # + # str = "hello" + # str.last # => "o" + # str.last(1) # => "o" + # str.last(2) # => "lo" + # str.last(0) # => "" + # str.last(6) # => "hello" + def last(limit = 1) + if limit == 0 + '' + elsif limit >= size + self.dup + else + from(-limit) + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/string/behavior.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/string/behavior.rb new file mode 100644 index 0000000..4aa9600 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/string/behavior.rb @@ -0,0 +1,6 @@ +class String + # Enable more predictable duck-typing on String-like classes. See Object#acts_like?. + def acts_like_string? + true + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/string/conversions.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/string/conversions.rb new file mode 100644 index 0000000..3e0cb8a --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/string/conversions.rb @@ -0,0 +1,56 @@ +require 'date' +require 'active_support/core_ext/time/calculations' + +class String + # Converts a string to a Time value. + # The +form+ can be either :utc or :local (default :local). + # + # The time is parsed using Time.parse method. + # If +form+ is :local, then the time is in the system timezone. + # If the date part is missing then the current date is used and if + # the time part is missing then it is assumed to be 00:00:00. + # + # "13-12-2012".to_time # => 2012-12-13 00:00:00 +0100 + # "06:12".to_time # => 2012-12-13 06:12:00 +0100 + # "2012-12-13 06:12".to_time # => 2012-12-13 06:12:00 +0100 + # "2012-12-13T06:12".to_time # => 2012-12-13 06:12:00 +0100 + # "2012-12-13T06:12".to_time(:utc) # => 2012-12-13 05:12:00 UTC + # "12/13/2012".to_time # => ArgumentError: argument out of range + def to_time(form = :local) + parts = Date._parse(self, false) + return if parts.empty? + + now = Time.now + time = Time.new( + parts.fetch(:year, now.year), + parts.fetch(:mon, now.month), + parts.fetch(:mday, now.day), + parts.fetch(:hour, 0), + parts.fetch(:min, 0), + parts.fetch(:sec, 0) + parts.fetch(:sec_fraction, 0), + parts.fetch(:offset, form == :utc ? 0 : nil) + ) + + form == :utc ? time.utc : time.getlocal + end + + # Converts a string to a Date value. + # + # "1-1-2012".to_date # => Sun, 01 Jan 2012 + # "01/01/2012".to_date # => Sun, 01 Jan 2012 + # "2012-12-13".to_date # => Thu, 13 Dec 2012 + # "12/13/2012".to_date # => ArgumentError: invalid date + def to_date + ::Date.parse(self, false) unless blank? + end + + # Converts a string to a DateTime value. + # + # "1-1-2012".to_datetime # => Sun, 01 Jan 2012 00:00:00 +0000 + # "01/01/2012 23:59:59".to_datetime # => Sun, 01 Jan 2012 23:59:59 +0000 + # "2012-12-13 12:50".to_datetime # => Thu, 13 Dec 2012 12:50:00 +0000 + # "12/13/2012".to_datetime # => ArgumentError: invalid date + def to_datetime + ::DateTime.parse(self, false) unless blank? + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/string/exclude.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/string/exclude.rb new file mode 100644 index 0000000..0ac684f --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/string/exclude.rb @@ -0,0 +1,11 @@ +class String + # The inverse of String#include?. Returns true if the string + # does not include the other string. + # + # "hello".exclude? "lo" # => false + # "hello".exclude? "ol" # => true + # "hello".exclude? ?h # => false + def exclude?(string) + !include?(string) + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/string/filters.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/string/filters.rb new file mode 100644 index 0000000..7461d03 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/string/filters.rb @@ -0,0 +1,103 @@ +class String + # Returns the string, first removing all whitespace on both ends of + # the string, and then changing remaining consecutive whitespace + # groups into one space each. + # + # Note that it handles both ASCII and Unicode whitespace. + # + # %{ Multi-line + # string }.squish # => "Multi-line string" + # " foo bar \n \t boo".squish # => "foo bar boo" + def squish + dup.squish! + end + + # Performs a destructive squish. See String#squish. + # str = " foo bar \n \t boo" + # str.squish! # => "foo bar boo" + # str # => "foo bar boo" + def squish! + gsub!(/\A[[:space:]]+/, '') + gsub!(/[[:space:]]+\z/, '') + gsub!(/[[:space:]]+/, ' ') + self + end + + # Returns a new string with all occurrences of the patterns removed. + # str = "foo bar test" + # str.remove(" test") # => "foo bar" + # str.remove(" test", /bar/) # => "foo " + # str # => "foo bar test" + def remove(*patterns) + dup.remove!(*patterns) + end + + # Alters the string by removing all occurrences of the patterns. + # str = "foo bar test" + # str.remove!(" test", /bar/) # => "foo " + # str # => "foo " + def remove!(*patterns) + patterns.each do |pattern| + gsub! pattern, "" + end + + self + end + + # Truncates a given +text+ after a given length if +text+ is longer than length: + # + # 'Once upon a time in a world far far away'.truncate(27) + # # => "Once upon a time in a wo..." + # + # Pass a string or regexp :separator to truncate +text+ at a natural break: + # + # 'Once upon a time in a world far far away'.truncate(27, separator: ' ') + # # => "Once upon a time in a..." + # + # 'Once upon a time in a world far far away'.truncate(27, separator: /\s/) + # # => "Once upon a time in a..." + # + # The last characters will be replaced with the :omission string (defaults to "...") + # for a total length not exceeding length: + # + # 'And they found that many people were sleeping better.'.truncate(25, omission: '... (continued)') + # # => "And they f... (continued)" + def truncate(truncate_at, options = {}) + return dup unless length > truncate_at + + omission = options[:omission] || '...' + length_with_room_for_omission = truncate_at - omission.length + stop = \ + if options[:separator] + rindex(options[:separator], length_with_room_for_omission) || length_with_room_for_omission + else + length_with_room_for_omission + end + + "#{self[0, stop]}#{omission}" + end + + # Truncates a given +text+ after a given number of words (words_count): + # + # 'Once upon a time in a world far far away'.truncate_words(4) + # # => "Once upon a time..." + # + # Pass a string or regexp :separator to specify a different separator of words: + # + # 'Once
    upon
    a
    time
    in
    a
    world'.truncate_words(5, separator: '
    ') + # # => "Once
    upon
    a
    time
    in..." + # + # The last characters will be replaced with the :omission string (defaults to "..."): + # + # 'And they found that many people were sleeping better.'.truncate_words(5, omission: '... (continued)') + # # => "And they found that many... (continued)" + def truncate_words(words_count, options = {}) + sep = options[:separator] || /\s+/ + sep = Regexp.escape(sep.to_s) unless Regexp === sep + if self =~ /\A((?>.+?#{sep}){#{words_count - 1}}.+?)#{sep}.*/m + $1 + (options[:omission] || '...') + else + dup + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/string/indent.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/string/indent.rb new file mode 100644 index 0000000..ce3a69c --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/string/indent.rb @@ -0,0 +1,43 @@ +class String + # Same as +indent+, except it indents the receiver in-place. + # + # Returns the indented string, or +nil+ if there was nothing to indent. + def indent!(amount, indent_string=nil, indent_empty_lines=false) + indent_string = indent_string || self[/^[ \t]/] || ' ' + re = indent_empty_lines ? /^/ : /^(?!$)/ + gsub!(re, indent_string * amount) + end + + # Indents the lines in the receiver: + # + # < + # def some_method + # some_code + # end + # + # The second argument, +indent_string+, specifies which indent string to + # use. The default is +nil+, which tells the method to make a guess by + # peeking at the first indented line, and fallback to a space if there is + # none. + # + # " foo".indent(2) # => " foo" + # "foo\n\t\tbar".indent(2) # => "\t\tfoo\n\t\t\t\tbar" + # "foo".indent(2, "\t") # => "\t\tfoo" + # + # While +indent_string+ is typically one space or tab, it may be any string. + # + # The third argument, +indent_empty_lines+, is a flag that says whether + # empty lines should be indented. Default is false. + # + # "foo\n\nbar".indent(2) # => " foo\n\n bar" + # "foo\n\nbar".indent(2, nil, true) # => " foo\n \n bar" + # + def indent(amount, indent_string=nil, indent_empty_lines=false) + dup.tap {|_| _.indent!(amount, indent_string, indent_empty_lines)} + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/string/inflections.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/string/inflections.rb new file mode 100644 index 0000000..38d567c --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/string/inflections.rb @@ -0,0 +1,217 @@ +require 'active_support/inflector/methods' +require 'active_support/inflector/transliterate' + +# String inflections define new methods on the String class to transform names for different purposes. +# For instance, you can figure out the name of a table from the name of a class. +# +# 'ScaleScore'.tableize # => "scale_scores" +# +class String + # Returns the plural form of the word in the string. + # + # If the optional parameter +count+ is specified, + # the singular form will be returned if count == 1. + # For any other value of +count+ the plural will be returned. + # + # If the optional parameter +locale+ is specified, + # the word will be pluralized as a word of that language. + # By default, this parameter is set to :en. + # You must define your own inflection rules for languages other than English. + # + # 'post'.pluralize # => "posts" + # 'octopus'.pluralize # => "octopi" + # 'sheep'.pluralize # => "sheep" + # 'words'.pluralize # => "words" + # 'the blue mailman'.pluralize # => "the blue mailmen" + # 'CamelOctopus'.pluralize # => "CamelOctopi" + # 'apple'.pluralize(1) # => "apple" + # 'apple'.pluralize(2) # => "apples" + # 'ley'.pluralize(:es) # => "leyes" + # 'ley'.pluralize(1, :es) # => "ley" + def pluralize(count = nil, locale = :en) + locale = count if count.is_a?(Symbol) + if count == 1 + self.dup + else + ActiveSupport::Inflector.pluralize(self, locale) + end + end + + # The reverse of +pluralize+, returns the singular form of a word in a string. + # + # If the optional parameter +locale+ is specified, + # the word will be singularized as a word of that language. + # By default, this parameter is set to :en. + # You must define your own inflection rules for languages other than English. + # + # 'posts'.singularize # => "post" + # 'octopi'.singularize # => "octopus" + # 'sheep'.singularize # => "sheep" + # 'word'.singularize # => "word" + # 'the blue mailmen'.singularize # => "the blue mailman" + # 'CamelOctopi'.singularize # => "CamelOctopus" + # 'leyes'.singularize(:es) # => "ley" + def singularize(locale = :en) + ActiveSupport::Inflector.singularize(self, locale) + end + + # +constantize+ tries to find a declared constant with the name specified + # in the string. It raises a NameError when the name is not in CamelCase + # or is not initialized. See ActiveSupport::Inflector.constantize + # + # 'Module'.constantize # => Module + # 'Class'.constantize # => Class + # 'blargle'.constantize # => NameError: wrong constant name blargle + def constantize + ActiveSupport::Inflector.constantize(self) + end + + # +safe_constantize+ tries to find a declared constant with the name specified + # in the string. It returns nil when the name is not in CamelCase + # or is not initialized. See ActiveSupport::Inflector.safe_constantize + # + # 'Module'.safe_constantize # => Module + # 'Class'.safe_constantize # => Class + # 'blargle'.safe_constantize # => nil + def safe_constantize + ActiveSupport::Inflector.safe_constantize(self) + end + + # By default, +camelize+ converts strings to UpperCamelCase. If the argument to camelize + # is set to :lower then camelize produces lowerCamelCase. + # + # +camelize+ will also convert '/' to '::' which is useful for converting paths to namespaces. + # + # 'active_record'.camelize # => "ActiveRecord" + # 'active_record'.camelize(:lower) # => "activeRecord" + # 'active_record/errors'.camelize # => "ActiveRecord::Errors" + # 'active_record/errors'.camelize(:lower) # => "activeRecord::Errors" + def camelize(first_letter = :upper) + case first_letter + when :upper + ActiveSupport::Inflector.camelize(self, true) + when :lower + ActiveSupport::Inflector.camelize(self, false) + end + end + alias_method :camelcase, :camelize + + # Capitalizes all the words and replaces some characters in the string to create + # a nicer looking title. +titleize+ is meant for creating pretty output. It is not + # used in the Rails internals. + # + # +titleize+ is also aliased as +titlecase+. + # + # 'man from the boondocks'.titleize # => "Man From The Boondocks" + # 'x-men: the last stand'.titleize # => "X Men: The Last Stand" + def titleize + ActiveSupport::Inflector.titleize(self) + end + alias_method :titlecase, :titleize + + # The reverse of +camelize+. Makes an underscored, lowercase form from the expression in the string. + # + # +underscore+ will also change '::' to '/' to convert namespaces to paths. + # + # 'ActiveModel'.underscore # => "active_model" + # 'ActiveModel::Errors'.underscore # => "active_model/errors" + def underscore + ActiveSupport::Inflector.underscore(self) + end + + # Replaces underscores with dashes in the string. + # + # 'puni_puni'.dasherize # => "puni-puni" + def dasherize + ActiveSupport::Inflector.dasherize(self) + end + + # Removes the module part from the constant expression in the string. + # + # 'ActiveRecord::CoreExtensions::String::Inflections'.demodulize # => "Inflections" + # 'Inflections'.demodulize # => "Inflections" + # '::Inflections'.demodulize # => "Inflections" + # ''.demodulize # => '' + # + # See also +deconstantize+. + def demodulize + ActiveSupport::Inflector.demodulize(self) + end + + # Removes the rightmost segment from the constant expression in the string. + # + # 'Net::HTTP'.deconstantize # => "Net" + # '::Net::HTTP'.deconstantize # => "::Net" + # 'String'.deconstantize # => "" + # '::String'.deconstantize # => "" + # ''.deconstantize # => "" + # + # See also +demodulize+. + def deconstantize + ActiveSupport::Inflector.deconstantize(self) + end + + # Replaces special characters in a string so that it may be used as part of a 'pretty' URL. + # + # class Person + # def to_param + # "#{id}-#{name.parameterize}" + # end + # end + # + # @person = Person.find(1) + # # => # + # + # <%= link_to(@person.name, person_path) %> + # # => Donald E. Knuth + def parameterize(sep = '-') + ActiveSupport::Inflector.parameterize(self, sep) + end + + # Creates the name of a table like Rails does for models to table names. This method + # uses the +pluralize+ method on the last word in the string. + # + # 'RawScaledScorer'.tableize # => "raw_scaled_scorers" + # 'egg_and_ham'.tableize # => "egg_and_hams" + # 'fancyCategory'.tableize # => "fancy_categories" + def tableize + ActiveSupport::Inflector.tableize(self) + end + + # Create a class name from a plural table name like Rails does for table names to models. + # Note that this returns a string and not a class. (To convert to an actual class + # follow +classify+ with +constantize+.) + # + # 'egg_and_hams'.classify # => "EggAndHam" + # 'posts'.classify # => "Post" + def classify + ActiveSupport::Inflector.classify(self) + end + + # Capitalizes the first word, turns underscores into spaces, and strips a + # trailing '_id' if present. + # Like +titleize+, this is meant for creating pretty output. + # + # The capitalization of the first word can be turned off by setting the + # optional parameter +capitalize+ to false. + # By default, this parameter is true. + # + # 'employee_salary'.humanize # => "Employee salary" + # 'author_id'.humanize # => "Author" + # 'author_id'.humanize(capitalize: false) # => "author" + # '_id'.humanize # => "Id" + def humanize(options = {}) + ActiveSupport::Inflector.humanize(self, options) + end + + # Creates a foreign key name from a class name. + # +separate_class_name_and_id_with_underscore+ sets whether + # the method should put '_' between the name and 'id'. + # + # 'Message'.foreign_key # => "message_id" + # 'Message'.foreign_key(false) # => "messageid" + # 'Admin::Post'.foreign_key # => "post_id" + def foreign_key(separate_class_name_and_id_with_underscore = true) + ActiveSupport::Inflector.foreign_key(self, separate_class_name_and_id_with_underscore) + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/string/inquiry.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/string/inquiry.rb new file mode 100644 index 0000000..1dcd949 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/string/inquiry.rb @@ -0,0 +1,13 @@ +require 'active_support/string_inquirer' + +class String + # Wraps the current string in the ActiveSupport::StringInquirer class, + # which gives you a prettier way to test for equality. + # + # env = 'production'.inquiry + # env.production? # => true + # env.development? # => false + def inquiry + ActiveSupport::StringInquirer.new(self) + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/string/multibyte.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/string/multibyte.rb new file mode 100644 index 0000000..a124202 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/string/multibyte.rb @@ -0,0 +1,49 @@ +# encoding: utf-8 +require 'active_support/multibyte' + +class String + # == Multibyte proxy + # + # +mb_chars+ is a multibyte safe proxy for string methods. + # + # It creates and returns an instance of the ActiveSupport::Multibyte::Chars class which + # encapsulates the original string. A Unicode safe version of all the String methods are defined on this proxy + # class. If the proxy class doesn't respond to a certain method, it's forwarded to the encapsulated string. + # + # name = 'Claus Müller' + # name.reverse # => "rell??M sualC" + # name.length # => 13 + # + # name.mb_chars.reverse.to_s # => "rellüM sualC" + # name.mb_chars.length # => 12 + # + # == Method chaining + # + # All the methods on the Chars proxy which normally return a string will return a Chars object. This allows + # method chaining on the result of any of these methods. + # + # name.mb_chars.reverse.length # => 12 + # + # == Interoperability and configuration + # + # The Chars object tries to be as interchangeable with String objects as possible: sorting and comparing between + # String and Char work like expected. The bang! methods change the internal string representation in the Chars + # object. Interoperability problems can be resolved easily with a +to_s+ call. + # + # For more information about the methods defined on the Chars proxy see ActiveSupport::Multibyte::Chars. For + # information about how to change the default Multibyte behavior see ActiveSupport::Multibyte. + def mb_chars + ActiveSupport::Multibyte.proxy_class.new(self) + end + + def is_utf8? + case encoding + when Encoding::UTF_8 + valid_encoding? + when Encoding::ASCII_8BIT, Encoding::US_ASCII + dup.force_encoding(Encoding::UTF_8).valid_encoding? + else + false + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/string/output_safety.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/string/output_safety.rb new file mode 100644 index 0000000..edd8c98 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/string/output_safety.rb @@ -0,0 +1,262 @@ +require 'erb' +require 'active_support/core_ext/kernel/singleton_class' +require 'active_support/deprecation' + +class ERB + module Util + HTML_ESCAPE = { '&' => '&', '>' => '>', '<' => '<', '"' => '"', "'" => ''' } + JSON_ESCAPE = { '&' => '\u0026', '>' => '\u003e', '<' => '\u003c', "\u2028" => '\u2028', "\u2029" => '\u2029' } + HTML_ESCAPE_REGEXP = /[&"'><]/ + HTML_ESCAPE_ONCE_REGEXP = /["><']|&(?!([a-zA-Z]+|(#\d+)|(#[xX][\dA-Fa-f]+));)/ + JSON_ESCAPE_REGEXP = /[\u2028\u2029&><]/u + + # A utility method for escaping HTML tag characters. + # This method is also aliased as h. + # + # In your ERB templates, use this method to escape any unsafe content. For example: + # <%=h @person.name %> + # + # puts html_escape('is a > 0 & a < 10?') + # # => is a > 0 & a < 10? + def html_escape(s) + unwrapped_html_escape(s).html_safe + end + + # Aliasing twice issues a warning "discarding old...". Remove first to avoid it. + remove_method(:h) + alias h html_escape + + module_function :h + + singleton_class.send(:remove_method, :html_escape) + module_function :html_escape + + # HTML escapes strings but doesn't wrap them with an ActiveSupport::SafeBuffer. + # This method is not for public consumption! Seriously! + def unwrapped_html_escape(s) # :nodoc: + s = s.to_s + if s.html_safe? + s + else + s.gsub(HTML_ESCAPE_REGEXP, HTML_ESCAPE) + end + end + module_function :unwrapped_html_escape + + # A utility method for escaping HTML without affecting existing escaped entities. + # + # html_escape_once('1 < 2 & 3') + # # => "1 < 2 & 3" + # + # html_escape_once('<< Accept & Checkout') + # # => "<< Accept & Checkout" + def html_escape_once(s) + result = s.to_s.gsub(HTML_ESCAPE_ONCE_REGEXP, HTML_ESCAPE) + s.html_safe? ? result.html_safe : result + end + + module_function :html_escape_once + + # A utility method for escaping HTML entities in JSON strings. Specifically, the + # &, > and < characters are replaced with their equivalent unicode escaped form - + # \u0026, \u003e, and \u003c. The Unicode sequences \u2028 and \u2029 are also + # escaped as they are treated as newline characters in some JavaScript engines. + # These sequences have identical meaning as the original characters inside the + # context of a JSON string, so assuming the input is a valid and well-formed + # JSON value, the output will have equivalent meaning when parsed: + # + # json = JSON.generate({ name: ""}) + # # => "{\"name\":\"\"}" + # + # json_escape(json) + # # => "{\"name\":\"\\u003C/script\\u003E\\u003Cscript\\u003Ealert('PWNED!!!')\\u003C/script\\u003E\"}" + # + # JSON.parse(json) == JSON.parse(json_escape(json)) + # # => true + # + # The intended use case for this method is to escape JSON strings before including + # them inside a script tag to avoid XSS vulnerability: + # + # + # + # It is necessary to +raw+ the result of +json_escape+, so that quotation marks + # don't get converted to " entities. +json_escape+ doesn't + # automatically flag the result as HTML safe, since the raw value is unsafe to + # use inside HTML attributes. + # + # If you need to output JSON elsewhere in your HTML, you can just do something + # like this, as any unsafe characters (including quotation marks) will be + # automatically escaped for you: + # + #
    ...
    + # + # WARNING: this helper only works with valid JSON. Using this on non-JSON values + # will open up serious XSS vulnerabilities. For example, if you replace the + # +current_user.to_json+ in the example above with user input instead, the browser + # will happily eval() that string as JavaScript. + # + # The escaping performed in this method is identical to those performed in the + # Active Support JSON encoder when +ActiveSupport.escape_html_entities_in_json+ is + # set to true. Because this transformation is idempotent, this helper can be + # applied even if +ActiveSupport.escape_html_entities_in_json+ is already true. + # + # Therefore, when you are unsure if +ActiveSupport.escape_html_entities_in_json+ + # is enabled, or if you are unsure where your JSON string originated from, it + # is recommended that you always apply this helper (other libraries, such as the + # JSON gem, do not provide this kind of protection by default; also some gems + # might override +to_json+ to bypass Active Support's encoder). + def json_escape(s) + result = s.to_s.gsub(JSON_ESCAPE_REGEXP, JSON_ESCAPE) + s.html_safe? ? result.html_safe : result + end + + module_function :json_escape + end +end + +class Object + def html_safe? + false + end +end + +class Numeric + def html_safe? + true + end +end + +module ActiveSupport #:nodoc: + class SafeBuffer < String + UNSAFE_STRING_METHODS = %w( + capitalize chomp chop delete downcase gsub lstrip next reverse rstrip + slice squeeze strip sub succ swapcase tr tr_s upcase + ) + + alias_method :original_concat, :concat + private :original_concat + + class SafeConcatError < StandardError + def initialize + super 'Could not concatenate to the buffer because it is not html safe.' + end + end + + def [](*args) + if args.size < 2 + super + else + if html_safe? + new_safe_buffer = super + + if new_safe_buffer + new_safe_buffer.instance_variable_set :@html_safe, true + end + + new_safe_buffer + else + to_str[*args] + end + end + end + + def safe_concat(value) + raise SafeConcatError unless html_safe? + original_concat(value) + end + + def initialize(*) + @html_safe = true + super + end + + def initialize_copy(other) + super + @html_safe = other.html_safe? + end + + def clone_empty + self[0, 0] + end + + def concat(value) + super(html_escape_interpolated_argument(value)) + end + alias << concat + + def prepend(value) + super(html_escape_interpolated_argument(value)) + end + + def prepend!(value) + ActiveSupport::Deprecation.deprecation_warning "ActiveSupport::SafeBuffer#prepend!", :prepend + prepend value + end + + def +(other) + dup.concat(other) + end + + def %(args) + case args + when Hash + escaped_args = Hash[args.map { |k,arg| [k, html_escape_interpolated_argument(arg)] }] + else + escaped_args = Array(args).map { |arg| html_escape_interpolated_argument(arg) } + end + + self.class.new(super(escaped_args)) + end + + def html_safe? + defined?(@html_safe) && @html_safe + end + + def to_s + self + end + + def to_param + to_str + end + + def encode_with(coder) + coder.represent_object nil, to_str + end + + UNSAFE_STRING_METHODS.each do |unsafe_method| + if unsafe_method.respond_to?(unsafe_method) + class_eval <<-EOT, __FILE__, __LINE__ + 1 + def #{unsafe_method}(*args, &block) # def capitalize(*args, &block) + to_str.#{unsafe_method}(*args, &block) # to_str.capitalize(*args, &block) + end # end + + def #{unsafe_method}!(*args) # def capitalize!(*args) + @html_safe = false # @html_safe = false + super # super + end # end + EOT + end + end + + private + + def html_escape_interpolated_argument(arg) + (!html_safe? || arg.html_safe?) ? arg : + arg.to_s.gsub(ERB::Util::HTML_ESCAPE_REGEXP, ERB::Util::HTML_ESCAPE) + end + end +end + +class String + # Marks a string as trusted safe. It will be inserted into HTML with no + # additional escaping performed. It is your responsibilty to ensure that the + # string contains no malicious content. This method is equivalent to the + # `raw` helper in views. It is recommended that you use `sanitize` instead of + # this method. It should never be called on user input. + def html_safe + ActiveSupport::SafeBuffer.new(self) + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/string/starts_ends_with.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/string/starts_ends_with.rb new file mode 100644 index 0000000..641acf6 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/string/starts_ends_with.rb @@ -0,0 +1,4 @@ +class String + alias_method :starts_with?, :start_with? + alias_method :ends_with?, :end_with? +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/string/strip.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/string/strip.rb new file mode 100644 index 0000000..086c610 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/string/strip.rb @@ -0,0 +1,26 @@ +require 'active_support/core_ext/object/try' + +class String + # Strips indentation in heredocs. + # + # For example in + # + # if options[:usage] + # puts <<-USAGE.strip_heredoc + # This command does such and such. + # + # Supported options are: + # -h This message + # ... + # USAGE + # end + # + # the user would see the usage message aligned against the left margin. + # + # Technically, it looks for the least indented line in the whole string, and removes + # that amount of leading whitespace. + def strip_heredoc + indent = scan(/^[ \t]*(?=\S)/).min.try(:size) || 0 + gsub(/^[ \t]{#{indent}}/, '') + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/string/zones.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/string/zones.rb new file mode 100644 index 0000000..510c884 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/string/zones.rb @@ -0,0 +1,14 @@ +require 'active_support/core_ext/string/conversions' +require 'active_support/core_ext/time/zones' + +class String + # Converts String to a TimeWithZone in the current zone if Time.zone or Time.zone_default + # is set, otherwise converts String to a Time via String#to_time + def in_time_zone(zone = ::Time.zone) + if zone + ::Time.find_zone!(zone).parse(self) + else + to_time + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/struct.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/struct.rb new file mode 100644 index 0000000..c2c3004 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/struct.rb @@ -0,0 +1,6 @@ +# Backport of Struct#to_h from Ruby 2.0 +class Struct # :nodoc: + def to_h + Hash[members.zip(values)] + end +end unless Struct.instance_methods.include?(:to_h) diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/thread.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/thread.rb new file mode 100644 index 0000000..4cd6634 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/thread.rb @@ -0,0 +1,86 @@ +class Thread + LOCK = Mutex.new # :nodoc: + + # Returns the value of a thread local variable that has been set. Note that + # these are different than fiber local values. + # + # Thread local values are carried along with threads, and do not respect + # fibers. For example: + # + # Thread.new { + # Thread.current.thread_variable_set("foo", "bar") # set a thread local + # Thread.current["foo"] = "bar" # set a fiber local + # + # Fiber.new { + # Fiber.yield [ + # Thread.current.thread_variable_get("foo"), # get the thread local + # Thread.current["foo"], # get the fiber local + # ] + # }.resume + # }.join.value # => ['bar', nil] + # + # The value "bar" is returned for the thread local, where +nil+ is returned + # for the fiber local. The fiber is executed in the same thread, so the + # thread local values are available. + def thread_variable_get(key) + _locals[key.to_sym] + end + + # Sets a thread local with +key+ to +value+. Note that these are local to + # threads, and not to fibers. Please see Thread#thread_variable_get for + # more information. + def thread_variable_set(key, value) + _locals[key.to_sym] = value + end + + # Returns an array of the names of the thread-local variables (as Symbols). + # + # thr = Thread.new do + # Thread.current.thread_variable_set(:cat, 'meow') + # Thread.current.thread_variable_set("dog", 'woof') + # end + # thr.join # => # + # thr.thread_variables # => [:dog, :cat] + # + # Note that these are not fiber local variables. Please see Thread#thread_variable_get + # for more details. + def thread_variables + _locals.keys + end + + # Returns true if the given string (or symbol) exists as a + # thread-local variable. + # + # me = Thread.current + # me.thread_variable_set(:oliver, "a") + # me.thread_variable?(:oliver) # => true + # me.thread_variable?(:stanley) # => false + # + # Note that these are not fiber local variables. Please see Thread#thread_variable_get + # for more details. + def thread_variable?(key) + _locals.has_key?(key.to_sym) + end + + # Freezes the thread so that thread local variables cannot be set via + # Thread#thread_variable_set, nor can fiber local variables be set. + # + # me = Thread.current + # me.freeze + # me.thread_variable_set(:oliver, "a") #=> RuntimeError: can't modify frozen thread locals + # me[:oliver] = "a" #=> RuntimeError: can't modify frozen thread locals + def freeze + _locals.freeze + super + end + + private + + def _locals + if defined?(@_locals) + @_locals + else + LOCK.synchronize { @_locals ||= {} } + end + end +end unless Thread.instance_methods.include?(:thread_variable_set) diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/time.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/time.rb new file mode 100644 index 0000000..32cffe2 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/time.rb @@ -0,0 +1,5 @@ +require 'active_support/core_ext/time/acts_like' +require 'active_support/core_ext/time/calculations' +require 'active_support/core_ext/time/conversions' +require 'active_support/core_ext/time/marshal' +require 'active_support/core_ext/time/zones' diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/time/acts_like.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/time/acts_like.rb new file mode 100644 index 0000000..3f853b7 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/time/acts_like.rb @@ -0,0 +1,8 @@ +require 'active_support/core_ext/object/acts_like' + +class Time + # Duck-types as a Time-like class. See Object#acts_like?. + def acts_like_time? + true + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/time/calculations.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/time/calculations.rb new file mode 100644 index 0000000..63efe76 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/time/calculations.rb @@ -0,0 +1,272 @@ +require 'active_support/duration' +require 'active_support/core_ext/time/conversions' +require 'active_support/time_with_zone' +require 'active_support/core_ext/time/zones' +require 'active_support/core_ext/date_and_time/calculations' +require 'active_support/core_ext/date/calculations' + +class Time + include DateAndTime::Calculations + + COMMON_YEAR_DAYS_IN_MONTH = [nil, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] + + class << self + # Overriding case equality method so that it returns true for ActiveSupport::TimeWithZone instances + def ===(other) + super || (self == Time && other.is_a?(ActiveSupport::TimeWithZone)) + end + + # Return the number of days in the given month. + # If no year is specified, it will use the current year. + def days_in_month(month, year = now.year) + if month == 2 && ::Date.gregorian_leap?(year) + 29 + else + COMMON_YEAR_DAYS_IN_MONTH[month] + end + end + + # Returns Time.zone.now when Time.zone or config.time_zone are set, otherwise just returns Time.now. + def current + ::Time.zone ? ::Time.zone.now : ::Time.now + end + + # Layers additional behavior on Time.at so that ActiveSupport::TimeWithZone and DateTime + # instances can be used when called with a single argument + def at_with_coercion(*args) + return at_without_coercion(*args) if args.size != 1 + + # Time.at can be called with a time or numerical value + time_or_number = args.first + + if time_or_number.is_a?(ActiveSupport::TimeWithZone) || time_or_number.is_a?(DateTime) + at_without_coercion(time_or_number.to_f).getlocal + else + at_without_coercion(time_or_number) + end + end + alias_method :at_without_coercion, :at + alias_method :at, :at_with_coercion + end + + # Seconds since midnight: Time.now.seconds_since_midnight + def seconds_since_midnight + to_i - change(:hour => 0).to_i + (usec / 1.0e+6) + end + + # Returns the number of seconds until 23:59:59. + # + # Time.new(2012, 8, 29, 0, 0, 0).seconds_until_end_of_day # => 86399 + # Time.new(2012, 8, 29, 12, 34, 56).seconds_until_end_of_day # => 41103 + # Time.new(2012, 8, 29, 23, 59, 59).seconds_until_end_of_day # => 0 + def seconds_until_end_of_day + end_of_day.to_i - to_i + end + + # Returns a new Time where one or more of the elements have been changed according + # to the +options+ parameter. The time options (:hour, :min, + # :sec, :usec, :nsec) reset cascadingly, so if only + # the hour is passed, then minute, sec, usec and nsec is set to 0. If the hour + # and minute is passed, then sec, usec and nsec is set to 0. The +options+ + # parameter takes a hash with any of these keys: :year, :month, + # :day, :hour, :min, :sec, :usec + # :nsec. Path either :usec or :nsec, not both. + # + # Time.new(2012, 8, 29, 22, 35, 0).change(day: 1) # => Time.new(2012, 8, 1, 22, 35, 0) + # Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, day: 1) # => Time.new(1981, 8, 1, 22, 35, 0) + # Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, hour: 0) # => Time.new(1981, 8, 29, 0, 0, 0) + def change(options) + new_year = options.fetch(:year, year) + new_month = options.fetch(:month, month) + new_day = options.fetch(:day, day) + new_hour = options.fetch(:hour, hour) + new_min = options.fetch(:min, options[:hour] ? 0 : min) + new_sec = options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec) + + if new_nsec = options[:nsec] + raise ArgumentError, "Can't change both :nsec and :usec at the same time: #{options.inspect}" if options[:usec] + new_usec = Rational(new_nsec, 1000) + else + new_usec = options.fetch(:usec, (options[:hour] || options[:min] || options[:sec]) ? 0 : Rational(nsec, 1000)) + end + + if utc? + ::Time.utc(new_year, new_month, new_day, new_hour, new_min, new_sec, new_usec) + elsif zone + ::Time.local(new_year, new_month, new_day, new_hour, new_min, new_sec, new_usec) + else + raise ArgumentError, 'argument out of range' if new_usec >= 1000000 + ::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec + (new_usec.to_r / 1000000), utc_offset) + end + end + + # Uses Date to provide precise Time calculations for years, months, and days + # according to the proleptic Gregorian calendar. The +options+ parameter + # takes a hash with any of these keys: :years, :months, + # :weeks, :days, :hours, :minutes, + # :seconds. + # + # Time.new(2015, 8, 1, 14, 35, 0).advance(seconds: 1) # => 2015-08-01 14:35:01 -0700 + # Time.new(2015, 8, 1, 14, 35, 0).advance(minutes: 1) # => 2015-08-01 14:36:00 -0700 + # Time.new(2015, 8, 1, 14, 35, 0).advance(hours: 1) # => 2015-08-01 15:35:00 -0700 + # Time.new(2015, 8, 1, 14, 35, 0).advance(days: 1) # => 2015-08-02 14:35:00 -0700 + # Time.new(2015, 8, 1, 14, 35, 0).advance(weeks: 1) # => 2015-08-08 14:35:00 -0700 + def advance(options) + unless options[:weeks].nil? + options[:weeks], partial_weeks = options[:weeks].divmod(1) + options[:days] = options.fetch(:days, 0) + 7 * partial_weeks + end + + unless options[:days].nil? + options[:days], partial_days = options[:days].divmod(1) + options[:hours] = options.fetch(:hours, 0) + 24 * partial_days + end + + d = to_date.advance(options) + d = d.gregorian if d.julian? + time_advanced_by_date = change(:year => d.year, :month => d.month, :day => d.day) + seconds_to_advance = \ + options.fetch(:seconds, 0) + + options.fetch(:minutes, 0) * 60 + + options.fetch(:hours, 0) * 3600 + + if seconds_to_advance.zero? + time_advanced_by_date + else + time_advanced_by_date.since(seconds_to_advance) + end + end + + # Returns a new Time representing the time a number of seconds ago, this is basically a wrapper around the Numeric extension + def ago(seconds) + since(-seconds) + end + + # Returns a new Time representing the time a number of seconds since the instance time + def since(seconds) + self + seconds + rescue + to_datetime.since(seconds) + end + alias :in :since + + # Returns a new Time representing the start of the day (0:00) + def beginning_of_day + #(self - seconds_since_midnight).change(usec: 0) + change(:hour => 0) + end + alias :midnight :beginning_of_day + alias :at_midnight :beginning_of_day + alias :at_beginning_of_day :beginning_of_day + + # Returns a new Time representing the middle of the day (12:00) + def middle_of_day + change(:hour => 12) + end + alias :midday :middle_of_day + alias :noon :middle_of_day + alias :at_midday :middle_of_day + alias :at_noon :middle_of_day + alias :at_middle_of_day :middle_of_day + + # Returns a new Time representing the end of the day, 23:59:59.999999 (.999999999 in ruby1.9) + def end_of_day + change( + :hour => 23, + :min => 59, + :sec => 59, + :usec => Rational(999999999, 1000) + ) + end + alias :at_end_of_day :end_of_day + + # Returns a new Time representing the start of the hour (x:00) + def beginning_of_hour + change(:min => 0) + end + alias :at_beginning_of_hour :beginning_of_hour + + # Returns a new Time representing the end of the hour, x:59:59.999999 (.999999999 in ruby1.9) + def end_of_hour + change( + :min => 59, + :sec => 59, + :usec => Rational(999999999, 1000) + ) + end + alias :at_end_of_hour :end_of_hour + + # Returns a new Time representing the start of the minute (x:xx:00) + def beginning_of_minute + change(:sec => 0) + end + alias :at_beginning_of_minute :beginning_of_minute + + # Returns a new Time representing the end of the minute, x:xx:59.999999 (.999999999 in ruby1.9) + def end_of_minute + change( + :sec => 59, + :usec => Rational(999999999, 1000) + ) + end + alias :at_end_of_minute :end_of_minute + + # Returns a Range representing the whole day of the current time. + def all_day + beginning_of_day..end_of_day + end + + def plus_with_duration(other) #:nodoc: + if ActiveSupport::Duration === other + other.since(self) + else + plus_without_duration(other) + end + end + alias_method :plus_without_duration, :+ + alias_method :+, :plus_with_duration + + def minus_with_duration(other) #:nodoc: + if ActiveSupport::Duration === other + other.until(self) + else + minus_without_duration(other) + end + end + alias_method :minus_without_duration, :- + alias_method :-, :minus_with_duration + + # Time#- can also be used to determine the number of seconds between two Time instances. + # We're layering on additional behavior so that ActiveSupport::TimeWithZone instances + # are coerced into values that Time#- will recognize + def minus_with_coercion(other) + other = other.comparable_time if other.respond_to?(:comparable_time) + other.is_a?(DateTime) ? to_f - other.to_f : minus_without_coercion(other) + end + alias_method :minus_without_coercion, :- + alias_method :-, :minus_with_coercion + + # Layers additional behavior on Time#<=> so that DateTime and ActiveSupport::TimeWithZone instances + # can be chronologically compared with a Time + def compare_with_coercion(other) + # we're avoiding Time#to_datetime cause it's expensive + if other.is_a?(Time) + compare_without_coercion(other.to_time) + else + to_datetime <=> other + end + end + alias_method :compare_without_coercion, :<=> + alias_method :<=>, :compare_with_coercion + + # Layers additional behavior on Time#eql? so that ActiveSupport::TimeWithZone instances + # can be eql? to an equivalent Time + def eql_with_coercion(other) + # if other is an ActiveSupport::TimeWithZone, coerce a Time instance from it so we can do eql? comparison + other = other.comparable_time if other.respond_to?(:comparable_time) + eql_without_coercion(other) + end + alias_method :eql_without_coercion, :eql? + alias_method :eql?, :eql_with_coercion + +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/time/conversions.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/time/conversions.rb new file mode 100644 index 0000000..dbf1f2f --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/time/conversions.rb @@ -0,0 +1,65 @@ +require 'active_support/inflector/methods' +require 'active_support/values/time_zone' + +class Time + DATE_FORMATS = { + :db => '%Y-%m-%d %H:%M:%S', + :number => '%Y%m%d%H%M%S', + :nsec => '%Y%m%d%H%M%S%9N', + :time => '%H:%M', + :short => '%d %b %H:%M', + :long => '%B %d, %Y %H:%M', + :long_ordinal => lambda { |time| + day_format = ActiveSupport::Inflector.ordinalize(time.day) + time.strftime("%B #{day_format}, %Y %H:%M") + }, + :rfc822 => lambda { |time| + offset_format = time.formatted_offset(false) + time.strftime("%a, %d %b %Y %H:%M:%S #{offset_format}") + }, + :iso8601 => lambda { |time| time.iso8601 } + } + + # Converts to a formatted string. See DATE_FORMATS for built-in formats. + # + # This method is aliased to to_s. + # + # time = Time.now # => Thu Jan 18 06:10:17 CST 2007 + # + # time.to_formatted_s(:time) # => "06:10" + # time.to_s(:time) # => "06:10" + # + # time.to_formatted_s(:db) # => "2007-01-18 06:10:17" + # time.to_formatted_s(:number) # => "20070118061017" + # time.to_formatted_s(:short) # => "18 Jan 06:10" + # time.to_formatted_s(:long) # => "January 18, 2007 06:10" + # time.to_formatted_s(:long_ordinal) # => "January 18th, 2007 06:10" + # time.to_formatted_s(:rfc822) # => "Thu, 18 Jan 2007 06:10:17 -0600" + # time.to_formatted_s(:iso8601) # => "2007-01-18T06:10:17-06:00" + # + # == Adding your own time formats to +to_formatted_s+ + # You can add your own formats to the Time::DATE_FORMATS hash. + # Use the format name as the hash key and either a strftime string + # or Proc instance that takes a time argument as the value. + # + # # config/initializers/time_formats.rb + # Time::DATE_FORMATS[:month_and_year] = '%B %Y' + # Time::DATE_FORMATS[:short_ordinal] = ->(time) { time.strftime("%B #{time.day.ordinalize}") } + def to_formatted_s(format = :default) + if formatter = DATE_FORMATS[format] + formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter) + else + to_default_s + end + end + alias_method :to_default_s, :to_s + alias_method :to_s, :to_formatted_s + + # Returns the UTC offset as an +HH:MM formatted string. + # + # Time.local(2000).formatted_offset # => "-06:00" + # Time.local(2000).formatted_offset(false) # => "-0600" + def formatted_offset(colon = true, alternate_utc_string = nil) + utc? && alternate_utc_string || ActiveSupport::TimeZone.seconds_to_utc_offset(utc_offset, colon) + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/time/marshal.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/time/marshal.rb new file mode 100644 index 0000000..497c4c3 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/time/marshal.rb @@ -0,0 +1,30 @@ +# Ruby 1.9.2 adds utc_offset and zone to Time, but marshaling only +# preserves utc_offset. Preserve zone also, even though it may not +# work in some edge cases. +if Time.local(2010).zone != Marshal.load(Marshal.dump(Time.local(2010))).zone + class Time + class << self + alias_method :_load_without_zone, :_load + def _load(marshaled_time) + time = _load_without_zone(marshaled_time) + time.instance_eval do + if zone = defined?(@_zone) && remove_instance_variable('@_zone') + ary = to_a + ary[0] += subsec if ary[0] == sec + ary[-1] = zone + utc? ? Time.utc(*ary) : Time.local(*ary) + else + self + end + end + end + end + + alias_method :_dump_without_zone, :_dump + def _dump(*args) + obj = dup + obj.instance_variable_set('@_zone', zone) + obj.send :_dump_without_zone, *args + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/time/zones.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/time/zones.rb new file mode 100644 index 0000000..64c3b72 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/time/zones.rb @@ -0,0 +1,79 @@ +require 'active_support/time_with_zone' +require 'active_support/core_ext/time/acts_like' +require 'active_support/core_ext/date_and_time/zones' + +class Time + include DateAndTime::Zones + class << self + attr_accessor :zone_default + + # Returns the TimeZone for the current request, if this has been set (via Time.zone=). + # If Time.zone has not been set for the current request, returns the TimeZone specified in config.time_zone. + def zone + Thread.current[:time_zone] || zone_default + end + + # Sets Time.zone to a TimeZone object for the current request/thread. + # + # This method accepts any of the following: + # + # * A Rails TimeZone object. + # * An identifier for a Rails TimeZone object (e.g., "Eastern Time (US & Canada)", -5.hours). + # * A TZInfo::Timezone object. + # * An identifier for a TZInfo::Timezone object (e.g., "America/New_York"). + # + # Here's an example of how you might set Time.zone on a per request basis and reset it when the request is done. + # current_user.time_zone just needs to return a string identifying the user's preferred time zone: + # + # class ApplicationController < ActionController::Base + # around_filter :set_time_zone + # + # def set_time_zone + # if logged_in? + # Time.use_zone(current_user.time_zone) { yield } + # else + # yield + # end + # end + # end + def zone=(time_zone) + Thread.current[:time_zone] = find_zone!(time_zone) + end + + # Allows override of Time.zone locally inside supplied block; resets Time.zone to existing value when done. + def use_zone(time_zone) + new_zone = find_zone!(time_zone) + begin + old_zone, ::Time.zone = ::Time.zone, new_zone + yield + ensure + ::Time.zone = old_zone + end + end + + # Returns a TimeZone instance or nil, or raises an ArgumentError for invalid timezones. + def find_zone!(time_zone) + if !time_zone || time_zone.is_a?(ActiveSupport::TimeZone) + time_zone + else + # lookup timezone based on identifier (unless we've been passed a TZInfo::Timezone) + unless time_zone.respond_to?(:period_for_local) + time_zone = ActiveSupport::TimeZone[time_zone] || TZInfo::Timezone.get(time_zone) + end + + # Return if a TimeZone instance, or wrap in a TimeZone instance if a TZInfo::Timezone + if time_zone.is_a?(ActiveSupport::TimeZone) + time_zone + else + ActiveSupport::TimeZone.create(time_zone.name, nil, time_zone) + end + end + rescue TZInfo::InvalidTimezoneIdentifier + raise ArgumentError, "Invalid Timezone: #{time_zone}" + end + + def find_zone(time_zone) + find_zone!(time_zone) rescue nil + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/uri.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/uri.rb new file mode 100644 index 0000000..bfe0832 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/core_ext/uri.rb @@ -0,0 +1,26 @@ +# encoding: utf-8 + +require 'uri' +str = "\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E" # Ni-ho-nn-go in UTF-8, means Japanese. +parser = URI::Parser.new + +unless str == parser.unescape(parser.escape(str)) + URI::Parser.class_eval do + remove_method :unescape + def unescape(str, escaped = /%[a-fA-F\d]{2}/) + # TODO: Are we actually sure that ASCII == UTF-8? + # YK: My initial experiments say yes, but let's be sure please + enc = str.encoding + enc = Encoding::UTF_8 if enc == Encoding::US_ASCII + str.gsub(escaped) { [$&[1, 2].hex].pack('C') }.force_encoding(enc) + end + end +end + +module URI + class << self + def parser + @parser ||= URI::Parser.new + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/dependencies.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/dependencies.rb new file mode 100644 index 0000000..65a370d --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/dependencies.rb @@ -0,0 +1,762 @@ +require 'set' +require 'thread' +require 'thread_safe' +require 'pathname' +require 'active_support/core_ext/module/aliasing' +require 'active_support/core_ext/module/attribute_accessors' +require 'active_support/core_ext/module/introspection' +require 'active_support/core_ext/module/anonymous' +require 'active_support/core_ext/module/qualified_const' +require 'active_support/core_ext/object/blank' +require 'active_support/core_ext/kernel/reporting' +require 'active_support/core_ext/load_error' +require 'active_support/core_ext/name_error' +require 'active_support/core_ext/string/starts_ends_with' +require 'active_support/inflector' + +module ActiveSupport #:nodoc: + module Dependencies #:nodoc: + extend self + + # Should we turn on Ruby warnings on the first load of dependent files? + mattr_accessor :warnings_on_first_load + self.warnings_on_first_load = false + + # All files ever loaded. + mattr_accessor :history + self.history = Set.new + + # All files currently loaded. + mattr_accessor :loaded + self.loaded = Set.new + + # Stack of files being loaded. + mattr_accessor :loading + self.loading = [] + + # Should we load files or require them? + mattr_accessor :mechanism + self.mechanism = ENV['NO_RELOAD'] ? :require : :load + + # The set of directories from which we may automatically load files. Files + # under these directories will be reloaded on each request in development mode, + # unless the directory also appears in autoload_once_paths. + mattr_accessor :autoload_paths + self.autoload_paths = [] + + # The set of directories from which automatically loaded constants are loaded + # only once. All directories in this set must also be present in +autoload_paths+. + mattr_accessor :autoload_once_paths + self.autoload_once_paths = [] + + # An array of qualified constant names that have been loaded. Adding a name + # to this array will cause it to be unloaded the next time Dependencies are + # cleared. + mattr_accessor :autoloaded_constants + self.autoloaded_constants = [] + + # An array of constant names that need to be unloaded on every request. Used + # to allow arbitrary constants to be marked for unloading. + mattr_accessor :explicitly_unloadable_constants + self.explicitly_unloadable_constants = [] + + # The logger is used for generating information on the action run-time + # (including benchmarking) if available. Can be set to nil for no logging. + # Compatible with both Ruby's own Logger and Log4r loggers. + mattr_accessor :logger + + # Set to +true+ to enable logging of const_missing and file loads. + mattr_accessor :log_activity + self.log_activity = false + + # The WatchStack keeps a stack of the modules being watched as files are + # loaded. If a file in the process of being loaded (parent.rb) triggers the + # load of another file (child.rb) the stack will ensure that child.rb + # handles the new constants. + # + # If child.rb is being autoloaded, its constants will be added to + # autoloaded_constants. If it was being `require`d, they will be discarded. + # + # This is handled by walking back up the watch stack and adding the constants + # found by child.rb to the list of original constants in parent.rb. + class WatchStack + include Enumerable + + # @watching is a stack of lists of constants being watched. For instance, + # if parent.rb is autoloaded, the stack will look like [[Object]]. If + # parent.rb then requires namespace/child.rb, the stack will look like + # [[Object], [Namespace]]. + + def initialize + @watching = [] + @stack = Hash.new { |h,k| h[k] = [] } + end + + def each(&block) + @stack.each(&block) + end + + def watching? + !@watching.empty? + end + + # Returns a list of new constants found since the last call to + # watch_namespaces. + def new_constants + constants = [] + + # Grab the list of namespaces that we're looking for new constants under + @watching.last.each do |namespace| + # Retrieve the constants that were present under the namespace when watch_namespaces + # was originally called + original_constants = @stack[namespace].last + + mod = Inflector.constantize(namespace) if Dependencies.qualified_const_defined?(namespace) + next unless mod.is_a?(Module) + + # Get a list of the constants that were added + new_constants = mod.local_constants - original_constants + + # self[namespace] returns an Array of the constants that are being evaluated + # for that namespace. For instance, if parent.rb requires child.rb, the first + # element of self[Object] will be an Array of the constants that were present + # before parent.rb was required. The second element will be an Array of the + # constants that were present before child.rb was required. + @stack[namespace].each do |namespace_constants| + namespace_constants.concat(new_constants) + end + + # Normalize the list of new constants, and add them to the list we will return + new_constants.each do |suffix| + constants << ([namespace, suffix] - ["Object"]).join("::") + end + end + constants + ensure + # A call to new_constants is always called after a call to watch_namespaces + pop_modules(@watching.pop) + end + + # Add a set of modules to the watch stack, remembering the initial + # constants. + def watch_namespaces(namespaces) + @watching << namespaces.map do |namespace| + module_name = Dependencies.to_constant_name(namespace) + original_constants = Dependencies.qualified_const_defined?(module_name) ? + Inflector.constantize(module_name).local_constants : [] + + @stack[module_name] << original_constants + module_name + end + end + + private + def pop_modules(modules) + modules.each { |mod| @stack[mod].pop } + end + end + + # An internal stack used to record which constants are loaded by any block. + mattr_accessor :constant_watch_stack + self.constant_watch_stack = WatchStack.new + + # Module includes this module. + module ModuleConstMissing #:nodoc: + def self.append_features(base) + base.class_eval do + # Emulate #exclude via an ivar + return if defined?(@_const_missing) && @_const_missing + @_const_missing = instance_method(:const_missing) + remove_method(:const_missing) + end + super + end + + def self.exclude_from(base) + base.class_eval do + define_method :const_missing, @_const_missing + @_const_missing = nil + end + end + + def const_missing(const_name) + from_mod = anonymous? ? guess_for_anonymous(const_name) : self + Dependencies.load_missing_constant(from_mod, const_name) + end + + # We assume that the name of the module reflects the nesting + # (unless it can be proven that is not the case) and the path to the file + # that defines the constant. Anonymous modules cannot follow these + # conventions and therefore we assume that the user wants to refer to a + # top-level constant. + def guess_for_anonymous(const_name) + if Object.const_defined?(const_name) + raise NameError.new "#{const_name} cannot be autoloaded from an anonymous class or module", const_name + else + Object + end + end + + def unloadable(const_desc = self) + super(const_desc) + end + end + + # Object includes this module. + module Loadable #:nodoc: + def self.exclude_from(base) + base.class_eval do + define_method(:load, Kernel.instance_method(:load)) + private :load + end + end + + def require_or_load(file_name) + Dependencies.require_or_load(file_name) + end + + # Interprets a file using mechanism and marks its defined + # constants as autoloaded. file_name can be either a string or + # respond to to_path. + # + # Use this method in code that absolutely needs a certain constant to be + # defined at that point. A typical use case is to make constant name + # resolution deterministic for constants with the same relative name in + # different namespaces whose evaluation would depend on load order + # otherwise. + def require_dependency(file_name, message = "No such file to load -- %s") + file_name = file_name.to_path if file_name.respond_to?(:to_path) + unless file_name.is_a?(String) + raise ArgumentError, "the file name must either be a String or implement #to_path -- you passed #{file_name.inspect}" + end + + Dependencies.depend_on(file_name, message) + end + + def load_dependency(file) + if Dependencies.load? && ActiveSupport::Dependencies.constant_watch_stack.watching? + Dependencies.new_constants_in(Object) { yield } + else + yield + end + rescue Exception => exception # errors from loading file + exception.blame_file! file if exception.respond_to? :blame_file! + raise + end + + # Mark the given constant as unloadable. Unloadable constants are removed + # each time dependencies are cleared. + # + # Note that marking a constant for unloading need only be done once. Setup + # or init scripts may list each unloadable constant that may need unloading; + # each constant will be removed for every subsequent clear, as opposed to + # for the first clear. + # + # The provided constant descriptor may be a (non-anonymous) module or class, + # or a qualified constant name as a string or symbol. + # + # Returns +true+ if the constant was not previously marked for unloading, + # +false+ otherwise. + def unloadable(const_desc) + Dependencies.mark_for_unload const_desc + end + + private + + def load(file, wrap = false) + result = false + load_dependency(file) { result = super } + result + end + + def require(file) + result = false + load_dependency(file) { result = super } + result + end + end + + # Exception file-blaming. + module Blamable #:nodoc: + def blame_file!(file) + (@blamed_files ||= []).unshift file + end + + def blamed_files + @blamed_files ||= [] + end + + def describe_blame + return nil if blamed_files.empty? + "This error occurred while loading the following files:\n #{blamed_files.join "\n "}" + end + + def copy_blame!(exc) + @blamed_files = exc.blamed_files.clone + self + end + end + + def hook! + Object.class_eval { include Loadable } + Module.class_eval { include ModuleConstMissing } + Exception.class_eval { include Blamable } + end + + def unhook! + ModuleConstMissing.exclude_from(Module) + Loadable.exclude_from(Object) + end + + def load? + mechanism == :load + end + + def depend_on(file_name, message = "No such file to load -- %s.rb") + path = search_for_file(file_name) + require_or_load(path || file_name) + rescue LoadError => load_error + if file_name = load_error.message[/ -- (.*?)(\.rb)?$/, 1] + load_error.message.replace(message % file_name) + load_error.copy_blame!(load_error) + end + raise + end + + def clear + log_call + loaded.clear + loading.clear + remove_unloadable_constants! + end + + def require_or_load(file_name, const_path = nil) + log_call file_name, const_path + file_name = $` if file_name =~ /\.rb\z/ + expanded = File.expand_path(file_name) + return if loaded.include?(expanded) + + # Record that we've seen this file *before* loading it to avoid an + # infinite loop with mutual dependencies. + loaded << expanded + loading << expanded + + begin + if load? + log "loading #{file_name}" + + # Enable warnings if this file has not been loaded before and + # warnings_on_first_load is set. + load_args = ["#{file_name}.rb"] + load_args << const_path unless const_path.nil? + + if !warnings_on_first_load or history.include?(expanded) + result = load_file(*load_args) + else + enable_warnings { result = load_file(*load_args) } + end + else + log "requiring #{file_name}" + result = require file_name + end + rescue Exception + loaded.delete expanded + raise + ensure + loading.pop + end + + # Record history *after* loading so first load gets warnings. + history << expanded + result + end + + # Is the provided constant path defined? + def qualified_const_defined?(path) + Object.qualified_const_defined?(path.sub(/^::/, ''), false) + end + + # Given +path+, a filesystem path to a ruby file, return an array of + # constant paths which would cause Dependencies to attempt to load this + # file. + def loadable_constants_for_path(path, bases = autoload_paths) + path = $` if path =~ /\.rb\z/ + expanded_path = File.expand_path(path) + paths = [] + + bases.each do |root| + expanded_root = File.expand_path(root) + next unless %r{\A#{Regexp.escape(expanded_root)}(/|\\)} =~ expanded_path + + nesting = expanded_path[(expanded_root.size)..-1] + nesting = nesting[1..-1] if nesting && nesting[0] == ?/ + next if nesting.blank? + + paths << nesting.camelize + end + + paths.uniq! + paths + end + + # Search for a file in autoload_paths matching the provided suffix. + def search_for_file(path_suffix) + path_suffix = path_suffix.sub(/(\.rb)?$/, ".rb") + + autoload_paths.each do |root| + path = File.join(root, path_suffix) + return path if File.file? path + end + nil # Gee, I sure wish we had first_match ;-) + end + + # Does the provided path_suffix correspond to an autoloadable module? + # Instead of returning a boolean, the autoload base for this module is + # returned. + def autoloadable_module?(path_suffix) + autoload_paths.each do |load_path| + return load_path if File.directory? File.join(load_path, path_suffix) + end + nil + end + + def load_once_path?(path) + # to_s works around a ruby1.9 issue where String#starts_with?(Pathname) + # will raise a TypeError: no implicit conversion of Pathname into String + autoload_once_paths.any? { |base| path.starts_with? base.to_s } + end + + # Attempt to autoload the provided module name by searching for a directory + # matching the expected path suffix. If found, the module is created and + # assigned to +into+'s constants with the name +const_name+. Provided that + # the directory was loaded from a reloadable base path, it is added to the + # set of constants that are to be unloaded. + def autoload_module!(into, const_name, qualified_name, path_suffix) + return nil unless base_path = autoloadable_module?(path_suffix) + mod = Module.new + into.const_set const_name, mod + autoloaded_constants << qualified_name unless autoload_once_paths.include?(base_path) + mod + end + + # Load the file at the provided path. +const_paths+ is a set of qualified + # constant names. When loading the file, Dependencies will watch for the + # addition of these constants. Each that is defined will be marked as + # autoloaded, and will be removed when Dependencies.clear is next called. + # + # If the second parameter is left off, then Dependencies will construct a + # set of names that the file at +path+ may define. See + # +loadable_constants_for_path+ for more details. + def load_file(path, const_paths = loadable_constants_for_path(path)) + log_call path, const_paths + const_paths = [const_paths].compact unless const_paths.is_a? Array + parent_paths = const_paths.collect { |const_path| const_path[/.*(?=::)/] || ::Object } + + result = nil + newly_defined_paths = new_constants_in(*parent_paths) do + result = Kernel.load path + end + + autoloaded_constants.concat newly_defined_paths unless load_once_path?(path) + autoloaded_constants.uniq! + log "loading #{path} defined #{newly_defined_paths * ', '}" unless newly_defined_paths.empty? + result + end + + # Returns the constant path for the provided parent and constant name. + def qualified_name_for(mod, name) + mod_name = to_constant_name mod + mod_name == "Object" ? name.to_s : "#{mod_name}::#{name}" + end + + # Load the constant named +const_name+ which is missing from +from_mod+. If + # it is not possible to load the constant into from_mod, try its parent + # module using +const_missing+. + def load_missing_constant(from_mod, const_name) + log_call from_mod, const_name + + unless qualified_const_defined?(from_mod.name) && Inflector.constantize(from_mod.name).equal?(from_mod) + raise ArgumentError, "A copy of #{from_mod} has been removed from the module tree but is still active!" + end + + qualified_name = qualified_name_for from_mod, const_name + path_suffix = qualified_name.underscore + + file_path = search_for_file(path_suffix) + + if file_path + expanded = File.expand_path(file_path) + expanded.sub!(/\.rb\z/, '') + + if loading.include?(expanded) + raise "Circular dependency detected while autoloading constant #{qualified_name}" + else + require_or_load(expanded, qualified_name) + raise LoadError, "Unable to autoload constant #{qualified_name}, expected #{file_path} to define it" unless from_mod.const_defined?(const_name, false) + return from_mod.const_get(const_name) + end + elsif mod = autoload_module!(from_mod, const_name, qualified_name, path_suffix) + return mod + elsif (parent = from_mod.parent) && parent != from_mod && + ! from_mod.parents.any? { |p| p.const_defined?(const_name, false) } + # If our parents do not have a constant named +const_name+ then we are free + # to attempt to load upwards. If they do have such a constant, then this + # const_missing must be due to from_mod::const_name, which should not + # return constants from from_mod's parents. + begin + # Since Ruby does not pass the nesting at the point the unknown + # constant triggered the callback we cannot fully emulate constant + # name lookup and need to make a trade-off: we are going to assume + # that the nesting in the body of Foo::Bar is [Foo::Bar, Foo] even + # though it might not be. Counterexamples are + # + # class Foo::Bar + # Module.nesting # => [Foo::Bar] + # end + # + # or + # + # module M::N + # module S::T + # Module.nesting # => [S::T, M::N] + # end + # end + # + # for example. + return parent.const_missing(const_name) + rescue NameError => e + raise unless e.missing_name? qualified_name_for(parent, const_name) + end + end + + name_error = NameError.new("uninitialized constant #{qualified_name}", const_name) + name_error.set_backtrace(caller.reject {|l| l.starts_with? __FILE__ }) + raise name_error + end + + # Remove the constants that have been autoloaded, and those that have been + # marked for unloading. Before each constant is removed a callback is sent + # to its class/module if it implements +before_remove_const+. + # + # The callback implementation should be restricted to cleaning up caches, etc. + # as the environment will be in an inconsistent state, e.g. other constants + # may have already been unloaded and not accessible. + def remove_unloadable_constants! + autoloaded_constants.each { |const| remove_constant const } + autoloaded_constants.clear + Reference.clear! + explicitly_unloadable_constants.each { |const| remove_constant const } + end + + class ClassCache + def initialize + @store = ThreadSafe::Cache.new + end + + def empty? + @store.empty? + end + + def key?(key) + @store.key?(key) + end + + def get(key) + key = key.name if key.respond_to?(:name) + @store[key] ||= Inflector.constantize(key) + end + alias :[] :get + + def safe_get(key) + key = key.name if key.respond_to?(:name) + @store[key] ||= Inflector.safe_constantize(key) + end + + def store(klass) + return self unless klass.respond_to?(:name) + raise(ArgumentError, 'anonymous classes cannot be cached') if klass.name.empty? + @store[klass.name] = klass + self + end + + def clear! + @store.clear + end + end + + Reference = ClassCache.new + + # Store a reference to a class +klass+. + def reference(klass) + Reference.store klass + end + + # Get the reference for class named +name+. + # Raises an exception if referenced class does not exist. + def constantize(name) + Reference.get(name) + end + + # Get the reference for class named +name+ if one exists. + # Otherwise returns +nil+. + def safe_constantize(name) + Reference.safe_get(name) + end + + # Determine if the given constant has been automatically loaded. + def autoloaded?(desc) + return false if desc.is_a?(Module) && desc.anonymous? + name = to_constant_name desc + return false unless qualified_const_defined? name + return autoloaded_constants.include?(name) + end + + # Will the provided constant descriptor be unloaded? + def will_unload?(const_desc) + autoloaded?(const_desc) || + explicitly_unloadable_constants.include?(to_constant_name(const_desc)) + end + + # Mark the provided constant name for unloading. This constant will be + # unloaded on each request, not just the next one. + def mark_for_unload(const_desc) + name = to_constant_name const_desc + if explicitly_unloadable_constants.include? name + false + else + explicitly_unloadable_constants << name + true + end + end + + # Run the provided block and detect the new constants that were loaded during + # its execution. Constants may only be regarded as 'new' once -- so if the + # block calls +new_constants_in+ again, then the constants defined within the + # inner call will not be reported in this one. + # + # If the provided block does not run to completion, and instead raises an + # exception, any new constants are regarded as being only partially defined + # and will be removed immediately. + def new_constants_in(*descs) + log_call(*descs) + + constant_watch_stack.watch_namespaces(descs) + aborting = true + + begin + yield # Now yield to the code that is to define new constants. + aborting = false + ensure + new_constants = constant_watch_stack.new_constants + + log "New constants: #{new_constants * ', '}" + return new_constants unless aborting + + log "Error during loading, removing partially loaded constants " + new_constants.each { |c| remove_constant(c) }.clear + end + + [] + end + + # Convert the provided const desc to a qualified constant name (as a string). + # A module, class, symbol, or string may be provided. + def to_constant_name(desc) #:nodoc: + case desc + when String then desc.sub(/^::/, '') + when Symbol then desc.to_s + when Module + desc.name || + raise(ArgumentError, "Anonymous modules have no name to be referenced by") + else raise TypeError, "Not a valid constant descriptor: #{desc.inspect}" + end + end + + def remove_constant(const) #:nodoc: + # Normalize ::Foo, ::Object::Foo, Object::Foo, Object::Object::Foo, etc. as Foo. + normalized = const.to_s.sub(/\A::/, '') + normalized.sub!(/\A(Object::)+/, '') + + constants = normalized.split('::') + to_remove = constants.pop + + # Remove the file path from the loaded list. + file_path = search_for_file(const.underscore) + if file_path + expanded = File.expand_path(file_path) + expanded.sub!(/\.rb\z/, '') + self.loaded.delete(expanded) + end + + if constants.empty? + parent = Object + else + # This method is robust to non-reachable constants. + # + # Non-reachable constants may be passed if some of the parents were + # autoloaded and already removed. It is easier to do a sanity check + # here than require the caller to be clever. We check the parent + # rather than the very const argument because we do not want to + # trigger Kernel#autoloads, see the comment below. + parent_name = constants.join('::') + return unless qualified_const_defined?(parent_name) + parent = constantize(parent_name) + end + + log "removing constant #{const}" + + # In an autoloaded user.rb like this + # + # autoload :Foo, 'foo' + # + # class User < ActiveRecord::Base + # end + # + # we correctly register "Foo" as being autoloaded. But if the app does + # not use the "Foo" constant we need to be careful not to trigger + # loading "foo.rb" ourselves. While #const_defined? and #const_get? do + # require the file, #autoload? and #remove_const don't. + # + # We are going to remove the constant nonetheless ---which exists as + # far as Ruby is concerned--- because if the user removes the macro + # call from a class or module that were not autoloaded, as in the + # example above with Object, accessing to that constant must err. + unless parent.autoload?(to_remove) + begin + constantized = parent.const_get(to_remove, false) + rescue NameError + log "the constant #{const} is not reachable anymore, skipping" + return + else + constantized.before_remove_const if constantized.respond_to?(:before_remove_const) + end + end + + begin + parent.instance_eval { remove_const to_remove } + rescue NameError + log "the constant #{const} is not reachable anymore, skipping" + end + end + + protected + def log_call(*args) + if log_activity? + arg_str = args.collect { |arg| arg.inspect } * ', ' + /in `([a-z_\?\!]+)'/ =~ caller(1).first + selector = $1 || '' + log "called #{selector}(#{arg_str})" + end + end + + def log(msg) + logger.debug "Dependencies: #{msg}" if log_activity? + end + + def log_activity? + logger && log_activity + end + end +end + +ActiveSupport::Dependencies.hook! diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/dependencies/autoload.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/dependencies/autoload.rb new file mode 100644 index 0000000..13036d5 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/dependencies/autoload.rb @@ -0,0 +1,77 @@ +require "active_support/inflector/methods" + +module ActiveSupport + # Autoload and eager load conveniences for your library. + # + # This module allows you to define autoloads based on + # Rails conventions (i.e. no need to define the path + # it is automatically guessed based on the filename) + # and also define a set of constants that needs to be + # eager loaded: + # + # module MyLib + # extend ActiveSupport::Autoload + # + # autoload :Model + # + # eager_autoload do + # autoload :Cache + # end + # end + # + # Then your library can be eager loaded by simply calling: + # + # MyLib.eager_load! + module Autoload + def self.extended(base) # :nodoc: + base.class_eval do + @_autoloads = {} + @_under_path = nil + @_at_path = nil + @_eager_autoload = false + end + end + + def autoload(const_name, path = @_at_path) + unless path + full = [name, @_under_path, const_name.to_s].compact.join("::") + path = Inflector.underscore(full) + end + + if @_eager_autoload + @_autoloads[const_name] = path + end + + super const_name, path + end + + def autoload_under(path) + @_under_path, old_path = path, @_under_path + yield + ensure + @_under_path = old_path + end + + def autoload_at(path) + @_at_path, old_path = path, @_at_path + yield + ensure + @_at_path = old_path + end + + def eager_autoload + old_eager, @_eager_autoload = @_eager_autoload, true + yield + ensure + @_eager_autoload = old_eager + end + + def eager_load! + @_autoloads.each_value { |file| require file } + end + + def autoloads + @_autoloads + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/deprecation.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/deprecation.rb new file mode 100644 index 0000000..46e9996 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/deprecation.rb @@ -0,0 +1,43 @@ +require 'singleton' + +module ActiveSupport + # \Deprecation specifies the API used by Rails to deprecate methods, instance + # variables, objects and constants. + class Deprecation + # active_support.rb sets an autoload for ActiveSupport::Deprecation. + # + # If these requires were at the top of the file the constant would not be + # defined by the time their files were loaded. Since some of them reopen + # ActiveSupport::Deprecation its autoload would be triggered, resulting in + # a circular require warning for active_support/deprecation.rb. + # + # So, we define the constant first, and load dependencies later. + require 'active_support/deprecation/instance_delegator' + require 'active_support/deprecation/behaviors' + require 'active_support/deprecation/reporting' + require 'active_support/deprecation/method_wrappers' + require 'active_support/deprecation/proxy_wrappers' + require 'active_support/core_ext/module/deprecation' + + include Singleton + include InstanceDelegator + include Behavior + include Reporting + include MethodWrapper + + # The version number in which the deprecated behavior will be removed, by default. + attr_accessor :deprecation_horizon + + # It accepts two parameters on initialization. The first is a version of library + # and the second is a library name + # + # ActiveSupport::Deprecation.new('2.0', 'MyLibrary') + def initialize(deprecation_horizon = '5.0', gem_name = 'Rails') + self.gem_name = gem_name + self.deprecation_horizon = deprecation_horizon + # By default, warnings are not silenced and debugging is off. + self.silenced = false + self.debug = false + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/deprecation/behaviors.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/deprecation/behaviors.rb new file mode 100644 index 0000000..9f9dca8 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/deprecation/behaviors.rb @@ -0,0 +1,76 @@ +require "active_support/notifications" + +module ActiveSupport + class DeprecationException < StandardError + end + + class Deprecation + # Default warning behaviors per Rails.env. + DEFAULT_BEHAVIORS = { + raise: ->(message, callstack) { + e = DeprecationException.new(message) + e.set_backtrace(callstack) + raise e + }, + + stderr: ->(message, callstack) { + $stderr.puts(message) + $stderr.puts callstack.join("\n ") if debug + }, + + log: ->(message, callstack) { + logger = + if defined?(Rails.logger) && Rails.logger + Rails.logger + else + require 'active_support/logger' + ActiveSupport::Logger.new($stderr) + end + logger.warn message + logger.debug callstack.join("\n ") if debug + }, + + notify: ->(message, callstack) { + ActiveSupport::Notifications.instrument("deprecation.rails", + :message => message, :callstack => callstack) + }, + + silence: ->(message, callstack) {}, + } + + module Behavior + # Whether to print a backtrace along with the warning. + attr_accessor :debug + + # Returns the current behavior or if one isn't set, defaults to +:stderr+. + def behavior + @behavior ||= [DEFAULT_BEHAVIORS[:stderr]] + end + + # Sets the behavior to the specified value. Can be a single value, array, + # or an object that responds to +call+. + # + # Available behaviors: + # + # [+raise+] Raise ActiveSupport::DeprecationException. + # [+stderr+] Log all deprecation warnings to +$stderr+. + # [+log+] Log all deprecation warnings to +Rails.logger+. + # [+notify+] Use +ActiveSupport::Notifications+ to notify +deprecation.rails+. + # [+silence+] Do nothing. + # + # Setting behaviors only affects deprecations that happen after boot time. + # Deprecation warnings raised by gems are not affected by this setting + # because they happen before Rails boots up. + # + # ActiveSupport::Deprecation.behavior = :stderr + # ActiveSupport::Deprecation.behavior = [:stderr, :log] + # ActiveSupport::Deprecation.behavior = MyCustomHandler + # ActiveSupport::Deprecation.behavior = ->(message, callstack) { + # # custom stuff + # } + def behavior=(behavior) + @behavior = Array(behavior).map { |b| DEFAULT_BEHAVIORS[b] || b } + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/deprecation/instance_delegator.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/deprecation/instance_delegator.rb new file mode 100644 index 0000000..8472a58 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/deprecation/instance_delegator.rb @@ -0,0 +1,24 @@ +require 'active_support/core_ext/kernel/singleton_class' +require 'active_support/core_ext/module/delegation' + +module ActiveSupport + class Deprecation + module InstanceDelegator # :nodoc: + def self.included(base) + base.extend(ClassMethods) + base.public_class_method :new + end + + module ClassMethods # :nodoc: + def include(included_module) + included_module.instance_methods.each { |m| method_added(m) } + super + end + + def method_added(method_name) + singleton_class.delegate(method_name, to: :instance) + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/deprecation/method_wrappers.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/deprecation/method_wrappers.rb new file mode 100644 index 0000000..cab8a1b --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/deprecation/method_wrappers.rb @@ -0,0 +1,44 @@ +require 'active_support/core_ext/module/aliasing' +require 'active_support/core_ext/array/extract_options' + +module ActiveSupport + class Deprecation + module MethodWrapper + # Declare that a method has been deprecated. + # + # module Fred + # extend self + # + # def foo; end + # def bar; end + # def baz; end + # end + # + # ActiveSupport::Deprecation.deprecate_methods(Fred, :foo, bar: :qux, baz: 'use Bar#baz instead') + # # => [:foo, :bar, :baz] + # + # Fred.foo + # # => "DEPRECATION WARNING: foo is deprecated and will be removed from Rails 4.1." + # + # Fred.bar + # # => "DEPRECATION WARNING: bar is deprecated and will be removed from Rails 4.1 (use qux instead)." + # + # Fred.baz + # # => "DEPRECATION WARNING: baz is deprecated and will be removed from Rails 4.1 (use Bar#baz instead)." + def deprecate_methods(target_module, *method_names) + options = method_names.extract_options! + deprecator = options.delete(:deprecator) || ActiveSupport::Deprecation.instance + method_names += options.keys + + method_names.each do |method_name| + target_module.alias_method_chain(method_name, :deprecation) do |target, punctuation| + target_module.send(:define_method, "#{target}_with_deprecation#{punctuation}") do |*args, &block| + deprecator.deprecation_warning(method_name, options[method_name]) + send(:"#{target}_without_deprecation#{punctuation}", *args, &block) + end + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/deprecation/proxy_wrappers.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/deprecation/proxy_wrappers.rb new file mode 100644 index 0000000..a03a66b --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/deprecation/proxy_wrappers.rb @@ -0,0 +1,126 @@ +require 'active_support/inflector/methods' + +module ActiveSupport + class Deprecation + class DeprecationProxy #:nodoc: + def self.new(*args, &block) + object = args.first + + return object unless object + super + end + + instance_methods.each { |m| undef_method m unless m =~ /^__|^object_id$/ } + + # Don't give a deprecation warning on inspect since test/unit and error + # logs rely on it for diagnostics. + def inspect + target.inspect + end + + private + def method_missing(called, *args, &block) + warn caller, called, args + target.__send__(called, *args, &block) + end + end + + # This DeprecatedObjectProxy transforms object to deprecated object. + # + # @old_object = DeprecatedObjectProxy.new(Object.new, "Don't use this object anymore!") + # @old_object = DeprecatedObjectProxy.new(Object.new, "Don't use this object anymore!", deprecator_instance) + # + # When someone executes any method except +inspect+ on proxy object this will + # trigger +warn+ method on +deprecator_instance+. + # + # Default deprecator is ActiveSupport::Deprecation + class DeprecatedObjectProxy < DeprecationProxy + def initialize(object, message, deprecator = ActiveSupport::Deprecation.instance) + @object = object + @message = message + @deprecator = deprecator + end + + private + def target + @object + end + + def warn(callstack, called, args) + @deprecator.warn(@message, callstack) + end + end + + # This DeprecatedInstanceVariableProxy transforms instance variable to + # deprecated instance variable. + # + # class Example + # def initialize(deprecator) + # @request = ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.new(self, :request, :@request, deprecator) + # @_request = :a_request + # end + # + # def request + # @_request + # end + # + # def old_request + # @request + # end + # end + # + # When someone execute any method on @request variable this will trigger + # +warn+ method on +deprecator_instance+ and will fetch @_request + # variable via +request+ method and execute the same method on non-proxy + # instance variable. + # + # Default deprecator is ActiveSupport::Deprecation. + class DeprecatedInstanceVariableProxy < DeprecationProxy + def initialize(instance, method, var = "@#{method}", deprecator = ActiveSupport::Deprecation.instance) + @instance = instance + @method = method + @var = var + @deprecator = deprecator + end + + private + def target + @instance.__send__(@method) + end + + def warn(callstack, called, args) + @deprecator.warn("#{@var} is deprecated! Call #{@method}.#{called} instead of #{@var}.#{called}. Args: #{args.inspect}", callstack) + end + end + + # This DeprecatedConstantProxy transforms constant to deprecated constant. + # + # OLD_CONST = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('OLD_CONST', 'NEW_CONST') + # OLD_CONST = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('OLD_CONST', 'NEW_CONST', deprecator_instance) + # + # When someone use old constant this will trigger +warn+ method on + # +deprecator_instance+. + # + # Default deprecator is ActiveSupport::Deprecation. + class DeprecatedConstantProxy < DeprecationProxy + def initialize(old_const, new_const, deprecator = ActiveSupport::Deprecation.instance) + @old_const = old_const + @new_const = new_const + @deprecator = deprecator + end + + def class + target.class + end + + private + def target + ActiveSupport::Inflector.constantize(@new_const.to_s) + end + + def warn(callstack, called, args) + @deprecator.warn("#{@old_const} is deprecated! Use #{@new_const} instead.", callstack) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/deprecation/reporting.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/deprecation/reporting.rb new file mode 100644 index 0000000..a7d265d --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/deprecation/reporting.rb @@ -0,0 +1,94 @@ +module ActiveSupport + class Deprecation + module Reporting + # Whether to print a message (silent mode) + attr_accessor :silenced + # Name of gem where method is deprecated + attr_accessor :gem_name + + # Outputs a deprecation warning to the output configured by + # ActiveSupport::Deprecation.behavior. + # + # ActiveSupport::Deprecation.warn('something broke!') + # # => "DEPRECATION WARNING: something broke! (called from your_code.rb:1)" + def warn(message = nil, callstack = nil) + return if silenced + + callstack ||= caller(2) + deprecation_message(callstack, message).tap do |m| + behavior.each { |b| b.call(m, callstack) } + end + end + + # Silence deprecation warnings within the block. + # + # ActiveSupport::Deprecation.warn('something broke!') + # # => "DEPRECATION WARNING: something broke! (called from your_code.rb:1)" + # + # ActiveSupport::Deprecation.silence do + # ActiveSupport::Deprecation.warn('something broke!') + # end + # # => nil + def silence + old_silenced, @silenced = @silenced, true + yield + ensure + @silenced = old_silenced + end + + def deprecation_warning(deprecated_method_name, message = nil, caller_backtrace = nil) + caller_backtrace ||= caller(2) + deprecated_method_warning(deprecated_method_name, message).tap do |msg| + warn(msg, caller_backtrace) + end + end + + private + # Outputs a deprecation warning message + # + # ActiveSupport::Deprecation.deprecated_method_warning(:method_name) + # # => "method_name is deprecated and will be removed from Rails #{deprecation_horizon}" + # ActiveSupport::Deprecation.deprecated_method_warning(:method_name, :another_method) + # # => "method_name is deprecated and will be removed from Rails #{deprecation_horizon} (use another_method instead)" + # ActiveSupport::Deprecation.deprecated_method_warning(:method_name, "Optional message") + # # => "method_name is deprecated and will be removed from Rails #{deprecation_horizon} (Optional message)" + def deprecated_method_warning(method_name, message = nil) + warning = "#{method_name} is deprecated and will be removed from #{gem_name} #{deprecation_horizon}" + case message + when Symbol then "#{warning} (use #{message} instead)" + when String then "#{warning} (#{message})" + else warning + end + end + + def deprecation_message(callstack, message = nil) + message ||= "You are using deprecated behavior which will be removed from the next major or minor release." + message += '.' unless message =~ /\.$/ + "DEPRECATION WARNING: #{message} #{deprecation_caller_message(callstack)}" + end + + def deprecation_caller_message(callstack) + file, line, method = extract_callstack(callstack) + if file + if line && method + "(called from #{method} at #{file}:#{line})" + else + "(called from #{file}:#{line})" + end + end + end + + def extract_callstack(callstack) + rails_gem_root = File.expand_path("../../../../..", __FILE__) + "/" + offending_line = callstack.find { |line| !line.start_with?(rails_gem_root) } || callstack.first + if offending_line + if md = offending_line.match(/^(.+?):(\d+)(?::in `(.*?)')?/) + md.captures + else + offending_line + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/descendants_tracker.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/descendants_tracker.rb new file mode 100644 index 0000000..27861e0 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/descendants_tracker.rb @@ -0,0 +1,60 @@ +module ActiveSupport + # This module provides an internal implementation to track descendants + # which is faster than iterating through ObjectSpace. + module DescendantsTracker + @@direct_descendants = {} + + class << self + def direct_descendants(klass) + @@direct_descendants[klass] || [] + end + + def descendants(klass) + arr = [] + accumulate_descendants(klass, arr) + arr + end + + def clear + if defined? ActiveSupport::Dependencies + @@direct_descendants.each do |klass, descendants| + if ActiveSupport::Dependencies.autoloaded?(klass) + @@direct_descendants.delete(klass) + else + descendants.reject! { |v| ActiveSupport::Dependencies.autoloaded?(v) } + end + end + else + @@direct_descendants.clear + end + end + + # This is the only method that is not thread safe, but is only ever called + # during the eager loading phase. + def store_inherited(klass, descendant) + (@@direct_descendants[klass] ||= []) << descendant + end + + private + def accumulate_descendants(klass, acc) + if direct_descendants = @@direct_descendants[klass] + acc.concat(direct_descendants) + direct_descendants.each { |direct_descendant| accumulate_descendants(direct_descendant, acc) } + end + end + end + + def inherited(base) + DescendantsTracker.store_inherited(self, base) + super + end + + def direct_descendants + DescendantsTracker.direct_descendants(self) + end + + def descendants + DescendantsTracker.descendants(self) + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/duration.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/duration.rb new file mode 100644 index 0000000..d5e4021 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/duration.rb @@ -0,0 +1,160 @@ +require 'active_support/core_ext/array/conversions' +require 'active_support/core_ext/object/acts_like' + +module ActiveSupport + # Provides accurate date and time measurements using Date#advance and + # Time#advance, respectively. It mainly supports the methods on Numeric. + # + # 1.month.ago # equivalent to Time.now.advance(months: -1) + class Duration + attr_accessor :value, :parts + + def initialize(value, parts) #:nodoc: + @value, @parts = value, parts + end + + # Adds another Duration or a Numeric to this Duration. Numeric values + # are treated as seconds. + def +(other) + if Duration === other + Duration.new(value + other.value, @parts + other.parts) + else + Duration.new(value + other, @parts + [[:seconds, other]]) + end + end + + # Subtracts another Duration or a Numeric from this Duration. Numeric + # values are treated as seconds. + def -(other) + self + (-other) + end + + def -@ #:nodoc: + Duration.new(-value, parts.map { |type,number| [type, -number] }) + end + + def is_a?(klass) #:nodoc: + Duration == klass || value.is_a?(klass) + end + alias :kind_of? :is_a? + + def instance_of?(klass) # :nodoc: + Duration == klass || value.instance_of?(klass) + end + + # Returns +true+ if +other+ is also a Duration instance with the + # same +value+, or if other == value. + def ==(other) + if Duration === other + other.value == value + else + other == value + end + end + + def to_s + @value.to_s + end + + # Returns the number of seconds that this Duration represents. + # + # 1.minute.to_i # => 60 + # 1.hour.to_i # => 3600 + # 1.day.to_i # => 86400 + # + # Note that this conversion makes some assumptions about the + # duration of some periods, e.g. months are always 30 days + # and years are 365.25 days: + # + # # equivalent to 30.days.to_i + # 1.month.to_i # => 2592000 + # + # # equivalent to 365.25.days.to_i + # 1.year.to_i # => 31557600 + # + # In such cases, Ruby's core + # Date[http://ruby-doc.org/stdlib/libdoc/date/rdoc/Date.html] and + # Time[http://ruby-doc.org/stdlib/libdoc/time/rdoc/Time.html] should be used for precision + # date and time arithmetic. + def to_i + @value.to_i + end + + # Returns +true+ if +other+ is also a Duration instance, which has the + # same parts as this one. + def eql?(other) + Duration === other && other.value.eql?(value) + end + + def hash + @value.hash + end + + def self.===(other) #:nodoc: + other.is_a?(Duration) + rescue ::NoMethodError + false + end + + # Calculates a new Time or Date that is as far in the future + # as this Duration represents. + def since(time = ::Time.current) + sum(1, time) + end + alias :from_now :since + + # Calculates a new Time or Date that is as far in the past + # as this Duration represents. + def ago(time = ::Time.current) + sum(-1, time) + end + alias :until :ago + + def inspect #:nodoc: + parts. + reduce(::Hash.new(0)) { |h,(l,r)| h[l] += r; h }. + sort_by {|unit, _ | [:years, :months, :days, :minutes, :seconds].index(unit)}. + map {|unit, val| "#{val} #{val == 1 ? unit.to_s.chop : unit.to_s}"}. + to_sentence(locale: ::I18n.default_locale) + end + + def as_json(options = nil) #:nodoc: + to_i + end + + def respond_to_missing?(method, include_private=false) #:nodoc + @value.respond_to?(method, include_private) + end + + delegate :<=>, to: :value + + protected + + def sum(sign, time = ::Time.current) #:nodoc: + parts.inject(time) do |t,(type,number)| + if t.acts_like?(:time) || t.acts_like?(:date) + if type == :seconds + t.since(sign * number) + else + t.advance(type => sign * number) + end + else + raise ::ArgumentError, "expected a time or date, got #{time.inspect}" + end + end + end + + private + + # We define it as a workaround to Ruby 2.0.0-p353 bug. + # For more information, check rails/rails#13055. + # Remove it when we drop support for 2.0.0-p353. + def ===(other) #:nodoc: + value === other + end + + def method_missing(method, *args, &block) #:nodoc: + value.send(method, *args, &block) + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/file_update_checker.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/file_update_checker.rb new file mode 100644 index 0000000..78b627c --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/file_update_checker.rb @@ -0,0 +1,137 @@ +module ActiveSupport + # FileUpdateChecker specifies the API used by Rails to watch files + # and control reloading. The API depends on four methods: + # + # * +initialize+ which expects two parameters and one block as + # described below. + # + # * +updated?+ which returns a boolean if there were updates in + # the filesystem or not. + # + # * +execute+ which executes the given block on initialization + # and updates the latest watched files and timestamp. + # + # * +execute_if_updated+ which just executes the block if it was updated. + # + # After initialization, a call to +execute_if_updated+ must execute + # the block only if there was really a change in the filesystem. + # + # This class is used by Rails to reload the I18n framework whenever + # they are changed upon a new request. + # + # i18n_reloader = ActiveSupport::FileUpdateChecker.new(paths) do + # I18n.reload! + # end + # + # ActionDispatch::Reloader.to_prepare do + # i18n_reloader.execute_if_updated + # end + class FileUpdateChecker + # It accepts two parameters on initialization. The first is an array + # of files and the second is an optional hash of directories. The hash must + # have directories as keys and the value is an array of extensions to be + # watched under that directory. + # + # This method must also receive a block that will be called once a path + # changes. The array of files and list of directories cannot be changed + # after FileUpdateChecker has been initialized. + def initialize(files, dirs={}, &block) + @files = files.freeze + @glob = compile_glob(dirs) + @block = block + + @watched = nil + @updated_at = nil + + @last_watched = watched + @last_update_at = updated_at(@last_watched) + end + + # Check if any of the entries were updated. If so, the watched and/or + # updated_at values are cached until the block is executed via +execute+ + # or +execute_if_updated+. + def updated? + current_watched = watched + if @last_watched.size != current_watched.size + @watched = current_watched + true + else + current_updated_at = updated_at(current_watched) + if @last_update_at < current_updated_at + @watched = current_watched + @updated_at = current_updated_at + true + else + false + end + end + end + + # Executes the given block and updates the latest watched files and + # timestamp. + def execute + @last_watched = watched + @last_update_at = updated_at(@last_watched) + @block.call + ensure + @watched = nil + @updated_at = nil + end + + # Execute the block given if updated. + def execute_if_updated + if updated? + execute + true + else + false + end + end + + private + + def watched + @watched || begin + all = @files.select { |f| File.exist?(f) } + all.concat(Dir[@glob]) if @glob + all + end + end + + def updated_at(paths) + @updated_at || max_mtime(paths) || Time.at(0) + end + + # This method returns the maximum mtime of the files in +paths+, or +nil+ + # if the array is empty. + # + # Files with a mtime in the future are ignored. Such abnormal situation + # can happen for example if the user changes the clock by hand. It is + # healthy to consider this edge case because with mtimes in the future + # reloading is not triggered. + def max_mtime(paths) + time_now = Time.now + paths.map {|path| File.mtime(path)}.reject {|mtime| time_now < mtime}.max + end + + def compile_glob(hash) + hash.freeze # Freeze so changes aren't accidentally pushed + return if hash.empty? + + globs = hash.map do |key, value| + "#{escape(key)}/**/*#{compile_ext(value)}" + end + "{#{globs.join(",")}}" + end + + def escape(key) + key.gsub(',','\,') + end + + def compile_ext(array) + array = Array(array) + return if array.empty? + ".{#{array.join(",")}}" + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/gem_version.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/gem_version.rb new file mode 100644 index 0000000..466b3de --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/gem_version.rb @@ -0,0 +1,15 @@ +module ActiveSupport + # Returns the version of the currently loaded Active Support as a Gem::Version + def self.gem_version + Gem::Version.new VERSION::STRING + end + + module VERSION + MAJOR = 4 + MINOR = 2 + TINY = 6 + PRE = nil + + STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".") + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/gzip.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/gzip.rb new file mode 100644 index 0000000..b837c87 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/gzip.rb @@ -0,0 +1,36 @@ +require 'zlib' +require 'stringio' + +module ActiveSupport + # A convenient wrapper for the zlib standard library that allows + # compression/decompression of strings with gzip. + # + # gzip = ActiveSupport::Gzip.compress('compress me!') + # # => "\x1F\x8B\b\x00o\x8D\xCDO\x00\x03K\xCE\xCF-(J-.V\xC8MU\x04\x00R>n\x83\f\x00\x00\x00" + # + # ActiveSupport::Gzip.decompress(gzip) + # # => "compress me!" + module Gzip + class Stream < StringIO + def initialize(*) + super + set_encoding "BINARY" + end + def close; rewind; end + end + + # Decompresses a gzipped string. + def self.decompress(source) + Zlib::GzipReader.new(StringIO.new(source)).read + end + + # Compresses a string using gzip. + def self.compress(source, level=Zlib::DEFAULT_COMPRESSION, strategy=Zlib::DEFAULT_STRATEGY) + output = Stream.new + gz = Zlib::GzipWriter.new(output, level, strategy) + gz.write(source) + gz.close + output.string + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/hash_with_indifferent_access.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/hash_with_indifferent_access.rb new file mode 100644 index 0000000..63690a1 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/hash_with_indifferent_access.rb @@ -0,0 +1,291 @@ +require 'active_support/core_ext/hash/keys' +require 'active_support/core_ext/hash/reverse_merge' + +module ActiveSupport + # Implements a hash where keys :foo and "foo" are considered + # to be the same. + # + # rgb = ActiveSupport::HashWithIndifferentAccess.new + # + # rgb[:black] = '#000000' + # rgb[:black] # => '#000000' + # rgb['black'] # => '#000000' + # + # rgb['white'] = '#FFFFFF' + # rgb[:white] # => '#FFFFFF' + # rgb['white'] # => '#FFFFFF' + # + # Internally symbols are mapped to strings when used as keys in the entire + # writing interface (calling []=, merge, etc). This + # mapping belongs to the public interface. For example, given: + # + # hash = ActiveSupport::HashWithIndifferentAccess.new(a: 1) + # + # You are guaranteed that the key is returned as a string: + # + # hash.keys # => ["a"] + # + # Technically other types of keys are accepted: + # + # hash = ActiveSupport::HashWithIndifferentAccess.new(a: 1) + # hash[0] = 0 + # hash # => {"a"=>1, 0=>0} + # + # but this class is intended for use cases where strings or symbols are the + # expected keys and it is convenient to understand both as the same. For + # example the +params+ hash in Ruby on Rails. + # + # Note that core extensions define Hash#with_indifferent_access: + # + # rgb = { black: '#000000', white: '#FFFFFF' }.with_indifferent_access + # + # which may be handy. + class HashWithIndifferentAccess < Hash + # Returns +true+ so that Array#extract_options! finds members of + # this class. + def extractable_options? + true + end + + def with_indifferent_access + dup + end + + def nested_under_indifferent_access + self + end + + def initialize(constructor = {}) + if constructor.respond_to?(:to_hash) + super() + update(constructor) + else + super(constructor) + end + end + + def default(key = nil) + if key.is_a?(Symbol) && include?(key = key.to_s) + self[key] + else + super + end + end + + def self.new_from_hash_copying_default(hash) + hash = hash.to_hash + new(hash).tap do |new_hash| + new_hash.default = hash.default + new_hash.default_proc = hash.default_proc if hash.default_proc + end + end + + def self.[](*args) + new.merge!(Hash[*args]) + end + + alias_method :regular_writer, :[]= unless method_defined?(:regular_writer) + alias_method :regular_update, :update unless method_defined?(:regular_update) + + # Assigns a new value to the hash: + # + # hash = ActiveSupport::HashWithIndifferentAccess.new + # hash[:key] = 'value' + # + # This value can be later fetched using either +:key+ or +'key'+. + def []=(key, value) + regular_writer(convert_key(key), convert_value(value, for: :assignment)) + end + + alias_method :store, :[]= + + # Updates the receiver in-place, merging in the hash passed as argument: + # + # hash_1 = ActiveSupport::HashWithIndifferentAccess.new + # hash_1[:key] = 'value' + # + # hash_2 = ActiveSupport::HashWithIndifferentAccess.new + # hash_2[:key] = 'New Value!' + # + # hash_1.update(hash_2) # => {"key"=>"New Value!"} + # + # The argument can be either an + # ActiveSupport::HashWithIndifferentAccess or a regular +Hash+. + # In either case the merge respects the semantics of indifferent access. + # + # If the argument is a regular hash with keys +:key+ and +"key"+ only one + # of the values end up in the receiver, but which one is unspecified. + # + # When given a block, the value for duplicated keys will be determined + # by the result of invoking the block with the duplicated key, the value + # in the receiver, and the value in +other_hash+. The rules for duplicated + # keys follow the semantics of indifferent access: + # + # hash_1[:key] = 10 + # hash_2['key'] = 12 + # hash_1.update(hash_2) { |key, old, new| old + new } # => {"key"=>22} + def update(other_hash) + if other_hash.is_a? HashWithIndifferentAccess + super(other_hash) + else + other_hash.to_hash.each_pair do |key, value| + if block_given? && key?(key) + value = yield(convert_key(key), self[key], value) + end + regular_writer(convert_key(key), convert_value(value)) + end + self + end + end + + alias_method :merge!, :update + + # Checks the hash for a key matching the argument passed in: + # + # hash = ActiveSupport::HashWithIndifferentAccess.new + # hash['key'] = 'value' + # hash.key?(:key) # => true + # hash.key?('key') # => true + def key?(key) + super(convert_key(key)) + end + + alias_method :include?, :key? + alias_method :has_key?, :key? + alias_method :member?, :key? + + # Same as Hash#fetch where the key passed as argument can be + # either a string or a symbol: + # + # counters = ActiveSupport::HashWithIndifferentAccess.new + # counters[:foo] = 1 + # + # counters.fetch('foo') # => 1 + # counters.fetch(:bar, 0) # => 0 + # counters.fetch(:bar) { |key| 0 } # => 0 + # counters.fetch(:zoo) # => KeyError: key not found: "zoo" + def fetch(key, *extras) + super(convert_key(key), *extras) + end + + # Returns an array of the values at the specified indices: + # + # hash = ActiveSupport::HashWithIndifferentAccess.new + # hash[:a] = 'x' + # hash[:b] = 'y' + # hash.values_at('a', 'b') # => ["x", "y"] + def values_at(*indices) + indices.collect { |key| self[convert_key(key)] } + end + + # Returns a shallow copy of the hash. + # + # hash = ActiveSupport::HashWithIndifferentAccess.new({ a: { b: 'b' } }) + # dup = hash.dup + # dup[:a][:c] = 'c' + # + # hash[:a][:c] # => nil + # dup[:a][:c] # => "c" + def dup + self.class.new(self).tap do |new_hash| + set_defaults(new_hash) + end + end + + # This method has the same semantics of +update+, except it does not + # modify the receiver but rather returns a new hash with indifferent + # access with the result of the merge. + def merge(hash, &block) + self.dup.update(hash, &block) + end + + # Like +merge+ but the other way around: Merges the receiver into the + # argument and returns a new hash with indifferent access as result: + # + # hash = ActiveSupport::HashWithIndifferentAccess.new + # hash['a'] = nil + # hash.reverse_merge(a: 0, b: 1) # => {"a"=>nil, "b"=>1} + def reverse_merge(other_hash) + super(self.class.new_from_hash_copying_default(other_hash)) + end + + # Same semantics as +reverse_merge+ but modifies the receiver in-place. + def reverse_merge!(other_hash) + replace(reverse_merge( other_hash )) + end + + # Replaces the contents of this hash with other_hash. + # + # h = { "a" => 100, "b" => 200 } + # h.replace({ "c" => 300, "d" => 400 }) # => {"c"=>300, "d"=>400} + def replace(other_hash) + super(self.class.new_from_hash_copying_default(other_hash)) + end + + # Removes the specified key from the hash. + def delete(key) + super(convert_key(key)) + end + + def stringify_keys!; self end + def deep_stringify_keys!; self end + def stringify_keys; dup end + def deep_stringify_keys; dup end + undef :symbolize_keys! + undef :deep_symbolize_keys! + def symbolize_keys; to_hash.symbolize_keys! end + def deep_symbolize_keys; to_hash.deep_symbolize_keys! end + def to_options!; self end + + def select(*args, &block) + dup.tap { |hash| hash.select!(*args, &block) } + end + + def reject(*args, &block) + dup.tap { |hash| hash.reject!(*args, &block) } + end + + # Convert to a regular hash with string keys. + def to_hash + _new_hash = Hash.new + set_defaults(_new_hash) + + each do |key, value| + _new_hash[key] = convert_value(value, for: :to_hash) + end + _new_hash + end + + protected + def convert_key(key) + key.kind_of?(Symbol) ? key.to_s : key + end + + def convert_value(value, options = {}) + if value.is_a? Hash + if options[:for] == :to_hash + value.to_hash + else + value.nested_under_indifferent_access + end + elsif value.is_a?(Array) + if options[:for] != :assignment || value.frozen? + value = value.dup + end + value.map! { |e| convert_value(e, options) } + else + value + end + end + + def set_defaults(target) + if default_proc + target.default_proc = default_proc.dup + else + target.default = default + end + end + end +end + +HashWithIndifferentAccess = ActiveSupport::HashWithIndifferentAccess diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/i18n.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/i18n.rb new file mode 100644 index 0000000..6cc9819 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/i18n.rb @@ -0,0 +1,13 @@ +require 'active_support/core_ext/hash/deep_merge' +require 'active_support/core_ext/hash/except' +require 'active_support/core_ext/hash/slice' +begin + require 'i18n' +rescue LoadError => e + $stderr.puts "The i18n gem is not available. Please add it to your Gemfile and run bundle install" + raise e +end +require 'active_support/lazy_load_hooks' + +ActiveSupport.run_load_hooks(:i18n) +I18n.load_path << "#{File.dirname(__FILE__)}/locale/en.yml" diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/i18n_railtie.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/i18n_railtie.rb new file mode 100644 index 0000000..affcfb7 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/i18n_railtie.rb @@ -0,0 +1,94 @@ +require "active_support" +require "active_support/file_update_checker" +require "active_support/core_ext/array/wrap" + +module I18n + class Railtie < Rails::Railtie + config.i18n = ActiveSupport::OrderedOptions.new + config.i18n.railties_load_path = [] + config.i18n.load_path = [] + config.i18n.fallbacks = ActiveSupport::OrderedOptions.new + + # Set the i18n configuration after initialization since a lot of + # configuration is still usually done in application initializers. + config.after_initialize do |app| + I18n::Railtie.initialize_i18n(app) + end + + # Trigger i18n config before any eager loading has happened + # so it's ready if any classes require it when eager loaded. + config.before_eager_load do |app| + I18n::Railtie.initialize_i18n(app) + end + + protected + + @i18n_inited = false + + # Setup i18n configuration. + def self.initialize_i18n(app) + return if @i18n_inited + + fallbacks = app.config.i18n.delete(:fallbacks) + + # Avoid issues with setting the default_locale by disabling available locales + # check while configuring. + enforce_available_locales = app.config.i18n.delete(:enforce_available_locales) + enforce_available_locales = I18n.enforce_available_locales if enforce_available_locales.nil? + I18n.enforce_available_locales = false + + app.config.i18n.each do |setting, value| + case setting + when :railties_load_path + app.config.i18n.load_path.unshift(*value) + when :load_path + I18n.load_path += value + else + I18n.send("#{setting}=", value) + end + end + + init_fallbacks(fallbacks) if fallbacks && validate_fallbacks(fallbacks) + + # Restore available locales check so it will take place from now on. + I18n.enforce_available_locales = enforce_available_locales + + reloader = ActiveSupport::FileUpdateChecker.new(I18n.load_path.dup){ I18n.reload! } + app.reloaders << reloader + ActionDispatch::Reloader.to_prepare { reloader.execute_if_updated } + reloader.execute + + @i18n_inited = true + end + + def self.include_fallbacks_module + I18n.backend.class.send(:include, I18n::Backend::Fallbacks) + end + + def self.init_fallbacks(fallbacks) + include_fallbacks_module + + args = case fallbacks + when ActiveSupport::OrderedOptions + [*(fallbacks[:defaults] || []) << fallbacks[:map]].compact + when Hash, Array + Array.wrap(fallbacks) + else # TrueClass + [] + end + + I18n.fallbacks = I18n::Locale::Fallbacks.new(*args) + end + + def self.validate_fallbacks(fallbacks) + case fallbacks + when ActiveSupport::OrderedOptions + !fallbacks.empty? + when TrueClass, Array, Hash + true + else + raise "Unexpected fallback type #{fallbacks.inspect}" + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/inflections.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/inflections.rb new file mode 100644 index 0000000..2ca1124 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/inflections.rb @@ -0,0 +1,70 @@ +require 'active_support/inflector/inflections' + +#-- +# Defines the standard inflection rules. These are the starting point for +# new projects and are not considered complete. The current set of inflection +# rules is frozen. This means, we do not change them to become more complete. +# This is a safety measure to keep existing applications from breaking. +#++ +module ActiveSupport + Inflector.inflections(:en) do |inflect| + inflect.plural(/$/, 's') + inflect.plural(/s$/i, 's') + inflect.plural(/^(ax|test)is$/i, '\1es') + inflect.plural(/(octop|vir)us$/i, '\1i') + inflect.plural(/(octop|vir)i$/i, '\1i') + inflect.plural(/(alias|status)$/i, '\1es') + inflect.plural(/(bu)s$/i, '\1ses') + inflect.plural(/(buffal|tomat)o$/i, '\1oes') + inflect.plural(/([ti])um$/i, '\1a') + inflect.plural(/([ti])a$/i, '\1a') + inflect.plural(/sis$/i, 'ses') + inflect.plural(/(?:([^f])fe|([lr])f)$/i, '\1\2ves') + inflect.plural(/(hive)$/i, '\1s') + inflect.plural(/([^aeiouy]|qu)y$/i, '\1ies') + inflect.plural(/(x|ch|ss|sh)$/i, '\1es') + inflect.plural(/(matr|vert|ind)(?:ix|ex)$/i, '\1ices') + inflect.plural(/^(m|l)ouse$/i, '\1ice') + inflect.plural(/^(m|l)ice$/i, '\1ice') + inflect.plural(/^(ox)$/i, '\1en') + inflect.plural(/^(oxen)$/i, '\1') + inflect.plural(/(quiz)$/i, '\1zes') + + inflect.singular(/s$/i, '') + inflect.singular(/(ss)$/i, '\1') + inflect.singular(/(n)ews$/i, '\1ews') + inflect.singular(/([ti])a$/i, '\1um') + inflect.singular(/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)(sis|ses)$/i, '\1sis') + inflect.singular(/(^analy)(sis|ses)$/i, '\1sis') + inflect.singular(/([^f])ves$/i, '\1fe') + inflect.singular(/(hive)s$/i, '\1') + inflect.singular(/(tive)s$/i, '\1') + inflect.singular(/([lr])ves$/i, '\1f') + inflect.singular(/([^aeiouy]|qu)ies$/i, '\1y') + inflect.singular(/(s)eries$/i, '\1eries') + inflect.singular(/(m)ovies$/i, '\1ovie') + inflect.singular(/(x|ch|ss|sh)es$/i, '\1') + inflect.singular(/^(m|l)ice$/i, '\1ouse') + inflect.singular(/(bus)(es)?$/i, '\1') + inflect.singular(/(o)es$/i, '\1') + inflect.singular(/(shoe)s$/i, '\1') + inflect.singular(/(cris|test)(is|es)$/i, '\1is') + inflect.singular(/^(a)x[ie]s$/i, '\1xis') + inflect.singular(/(octop|vir)(us|i)$/i, '\1us') + inflect.singular(/(alias|status)(es)?$/i, '\1') + inflect.singular(/^(ox)en/i, '\1') + inflect.singular(/(vert|ind)ices$/i, '\1ex') + inflect.singular(/(matr)ices$/i, '\1ix') + inflect.singular(/(quiz)zes$/i, '\1') + inflect.singular(/(database)s$/i, '\1') + + inflect.irregular('person', 'people') + inflect.irregular('man', 'men') + inflect.irregular('child', 'children') + inflect.irregular('sex', 'sexes') + inflect.irregular('move', 'moves') + inflect.irregular('zombie', 'zombies') + + inflect.uncountable(%w(equipment information rice money species series fish sheep jeans police)) + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/inflector.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/inflector.rb new file mode 100644 index 0000000..215a60e --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/inflector.rb @@ -0,0 +1,7 @@ +# in case active_support/inflector is required without the rest of active_support +require 'active_support/inflector/inflections' +require 'active_support/inflector/transliterate' +require 'active_support/inflector/methods' + +require 'active_support/inflections' +require 'active_support/core_ext/string/inflections' diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/inflector/inflections.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/inflector/inflections.rb new file mode 100644 index 0000000..486838b --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/inflector/inflections.rb @@ -0,0 +1,211 @@ +require 'thread_safe' +require 'active_support/core_ext/array/prepend_and_append' +require 'active_support/i18n' + +module ActiveSupport + module Inflector + extend self + + # A singleton instance of this class is yielded by Inflector.inflections, + # which can then be used to specify additional inflection rules. If passed + # an optional locale, rules for other languages can be specified. The + # default locale is :en. Only rules for English are provided. + # + # ActiveSupport::Inflector.inflections(:en) do |inflect| + # inflect.plural /^(ox)$/i, '\1\2en' + # inflect.singular /^(ox)en/i, '\1' + # + # inflect.irregular 'octopus', 'octopi' + # + # inflect.uncountable 'equipment' + # end + # + # New rules are added at the top. So in the example above, the irregular + # rule for octopus will now be the first of the pluralization and + # singularization rules that is runs. This guarantees that your rules run + # before any of the rules that may already have been loaded. + class Inflections + @__instance__ = ThreadSafe::Cache.new + + def self.instance(locale = :en) + @__instance__[locale] ||= new + end + + attr_reader :plurals, :singulars, :uncountables, :humans, :acronyms, :acronym_regex + + def initialize + @plurals, @singulars, @uncountables, @humans, @acronyms, @acronym_regex = [], [], [], [], {}, /(?=a)b/ + end + + # Private, for the test suite. + def initialize_dup(orig) # :nodoc: + %w(plurals singulars uncountables humans acronyms acronym_regex).each do |scope| + instance_variable_set("@#{scope}", orig.send(scope).dup) + end + end + + # Specifies a new acronym. An acronym must be specified as it will appear + # in a camelized string. An underscore string that contains the acronym + # will retain the acronym when passed to +camelize+, +humanize+, or + # +titleize+. A camelized string that contains the acronym will maintain + # the acronym when titleized or humanized, and will convert the acronym + # into a non-delimited single lowercase word when passed to +underscore+. + # + # acronym 'HTML' + # titleize 'html' # => 'HTML' + # camelize 'html' # => 'HTML' + # underscore 'MyHTML' # => 'my_html' + # + # The acronym, however, must occur as a delimited unit and not be part of + # another word for conversions to recognize it: + # + # acronym 'HTTP' + # camelize 'my_http_delimited' # => 'MyHTTPDelimited' + # camelize 'https' # => 'Https', not 'HTTPs' + # underscore 'HTTPS' # => 'http_s', not 'https' + # + # acronym 'HTTPS' + # camelize 'https' # => 'HTTPS' + # underscore 'HTTPS' # => 'https' + # + # Note: Acronyms that are passed to +pluralize+ will no longer be + # recognized, since the acronym will not occur as a delimited unit in the + # pluralized result. To work around this, you must specify the pluralized + # form as an acronym as well: + # + # acronym 'API' + # camelize(pluralize('api')) # => 'Apis' + # + # acronym 'APIs' + # camelize(pluralize('api')) # => 'APIs' + # + # +acronym+ may be used to specify any word that contains an acronym or + # otherwise needs to maintain a non-standard capitalization. The only + # restriction is that the word must begin with a capital letter. + # + # acronym 'RESTful' + # underscore 'RESTful' # => 'restful' + # underscore 'RESTfulController' # => 'restful_controller' + # titleize 'RESTfulController' # => 'RESTful Controller' + # camelize 'restful' # => 'RESTful' + # camelize 'restful_controller' # => 'RESTfulController' + # + # acronym 'McDonald' + # underscore 'McDonald' # => 'mcdonald' + # camelize 'mcdonald' # => 'McDonald' + def acronym(word) + @acronyms[word.downcase] = word + @acronym_regex = /#{@acronyms.values.join("|")}/ + end + + # Specifies a new pluralization rule and its replacement. The rule can + # either be a string or a regular expression. The replacement should + # always be a string that may include references to the matched data from + # the rule. + def plural(rule, replacement) + @uncountables.delete(rule) if rule.is_a?(String) + @uncountables.delete(replacement) + @plurals.prepend([rule, replacement]) + end + + # Specifies a new singularization rule and its replacement. The rule can + # either be a string or a regular expression. The replacement should + # always be a string that may include references to the matched data from + # the rule. + def singular(rule, replacement) + @uncountables.delete(rule) if rule.is_a?(String) + @uncountables.delete(replacement) + @singulars.prepend([rule, replacement]) + end + + # Specifies a new irregular that applies to both pluralization and + # singularization at the same time. This can only be used for strings, not + # regular expressions. You simply pass the irregular in singular and + # plural form. + # + # irregular 'octopus', 'octopi' + # irregular 'person', 'people' + def irregular(singular, plural) + @uncountables.delete(singular) + @uncountables.delete(plural) + + s0 = singular[0] + srest = singular[1..-1] + + p0 = plural[0] + prest = plural[1..-1] + + if s0.upcase == p0.upcase + plural(/(#{s0})#{srest}$/i, '\1' + prest) + plural(/(#{p0})#{prest}$/i, '\1' + prest) + + singular(/(#{s0})#{srest}$/i, '\1' + srest) + singular(/(#{p0})#{prest}$/i, '\1' + srest) + else + plural(/#{s0.upcase}(?i)#{srest}$/, p0.upcase + prest) + plural(/#{s0.downcase}(?i)#{srest}$/, p0.downcase + prest) + plural(/#{p0.upcase}(?i)#{prest}$/, p0.upcase + prest) + plural(/#{p0.downcase}(?i)#{prest}$/, p0.downcase + prest) + + singular(/#{s0.upcase}(?i)#{srest}$/, s0.upcase + srest) + singular(/#{s0.downcase}(?i)#{srest}$/, s0.downcase + srest) + singular(/#{p0.upcase}(?i)#{prest}$/, s0.upcase + srest) + singular(/#{p0.downcase}(?i)#{prest}$/, s0.downcase + srest) + end + end + + # Specifies words that are uncountable and should not be inflected. + # + # uncountable 'money' + # uncountable 'money', 'information' + # uncountable %w( money information rice ) + def uncountable(*words) + @uncountables += words.flatten.map(&:downcase) + end + + # Specifies a humanized form of a string by a regular expression rule or + # by a string mapping. When using a regular expression based replacement, + # the normal humanize formatting is called after the replacement. When a + # string is used, the human form should be specified as desired (example: + # 'The name', not 'the_name'). + # + # human /_cnt$/i, '\1_count' + # human 'legacy_col_person_name', 'Name' + def human(rule, replacement) + @humans.prepend([rule, replacement]) + end + + # Clears the loaded inflections within a given scope (default is + # :all). Give the scope as a symbol of the inflection type, the + # options are: :plurals, :singulars, :uncountables, + # :humans. + # + # clear :all + # clear :plurals + def clear(scope = :all) + case scope + when :all + @plurals, @singulars, @uncountables, @humans = [], [], [], [] + else + instance_variable_set "@#{scope}", [] + end + end + end + + # Yields a singleton instance of Inflector::Inflections so you can specify + # additional inflector rules. If passed an optional locale, rules for other + # languages can be specified. If not specified, defaults to :en. + # Only rules for English are provided. + # + # ActiveSupport::Inflector.inflections(:en) do |inflect| + # inflect.uncountable 'rails' + # end + def inflections(locale = :en) + if block_given? + yield Inflections.instance(locale) + else + Inflections.instance(locale) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/inflector/methods.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/inflector/methods.rb new file mode 100644 index 0000000..74b3a7c --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/inflector/methods.rb @@ -0,0 +1,383 @@ +# encoding: utf-8 + +require 'active_support/inflections' + +module ActiveSupport + # The Inflector transforms words from singular to plural, class names to table + # names, modularized class names to ones without, and class names to foreign + # keys. The default inflections for pluralization, singularization, and + # uncountable words are kept in inflections.rb. + # + # The Rails core team has stated patches for the inflections library will not + # be accepted in order to avoid breaking legacy applications which may be + # relying on errant inflections. If you discover an incorrect inflection and + # require it for your application or wish to define rules for languages other + # than English, please correct or add them yourself (explained below). + module Inflector + extend self + + # Returns the plural form of the word in the string. + # + # If passed an optional +locale+ parameter, the word will be + # pluralized using rules defined for that language. By default, + # this parameter is set to :en. + # + # 'post'.pluralize # => "posts" + # 'octopus'.pluralize # => "octopi" + # 'sheep'.pluralize # => "sheep" + # 'words'.pluralize # => "words" + # 'CamelOctopus'.pluralize # => "CamelOctopi" + # 'ley'.pluralize(:es) # => "leyes" + def pluralize(word, locale = :en) + apply_inflections(word, inflections(locale).plurals) + end + + # The reverse of +pluralize+, returns the singular form of a word in a + # string. + # + # If passed an optional +locale+ parameter, the word will be + # singularized using rules defined for that language. By default, + # this parameter is set to :en. + # + # 'posts'.singularize # => "post" + # 'octopi'.singularize # => "octopus" + # 'sheep'.singularize # => "sheep" + # 'word'.singularize # => "word" + # 'CamelOctopi'.singularize # => "CamelOctopus" + # 'leyes'.singularize(:es) # => "ley" + def singularize(word, locale = :en) + apply_inflections(word, inflections(locale).singulars) + end + + # By default, +camelize+ converts strings to UpperCamelCase. If the argument + # to +camelize+ is set to :lower then +camelize+ produces + # lowerCamelCase. + # + # +camelize+ will also convert '/' to '::' which is useful for converting + # paths to namespaces. + # + # 'active_model'.camelize # => "ActiveModel" + # 'active_model'.camelize(:lower) # => "activeModel" + # 'active_model/errors'.camelize # => "ActiveModel::Errors" + # 'active_model/errors'.camelize(:lower) # => "activeModel::Errors" + # + # As a rule of thumb you can think of +camelize+ as the inverse of + # +underscore+, though there are cases where that does not hold: + # + # 'SSLError'.underscore.camelize # => "SslError" + def camelize(term, uppercase_first_letter = true) + string = term.to_s + if uppercase_first_letter + string = string.sub(/^[a-z\d]*/) { inflections.acronyms[$&] || $&.capitalize } + else + string = string.sub(/^(?:#{inflections.acronym_regex}(?=\b|[A-Z_])|\w)/) { $&.downcase } + end + string.gsub!(/(?:_|(\/))([a-z\d]*)/i) { "#{$1}#{inflections.acronyms[$2] || $2.capitalize}" } + string.gsub!(/\//, '::') + string + end + + # Makes an underscored, lowercase form from the expression in the string. + # + # Changes '::' to '/' to convert namespaces to paths. + # + # 'ActiveModel'.underscore # => "active_model" + # 'ActiveModel::Errors'.underscore # => "active_model/errors" + # + # As a rule of thumb you can think of +underscore+ as the inverse of + # +camelize+, though there are cases where that does not hold: + # + # 'SSLError'.underscore.camelize # => "SslError" + def underscore(camel_cased_word) + return camel_cased_word unless camel_cased_word =~ /[A-Z-]|::/ + word = camel_cased_word.to_s.gsub(/::/, '/') + word.gsub!(/(?:(?<=([A-Za-z\d]))|\b)(#{inflections.acronym_regex})(?=\b|[^a-z])/) { "#{$1 && '_'}#{$2.downcase}" } + word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2') + word.gsub!(/([a-z\d])([A-Z])/,'\1_\2') + word.tr!("-", "_") + word.downcase! + word + end + + # Tweaks an attribute name for display to end users. + # + # Specifically, +humanize+ performs these transformations: + # + # * Applies human inflection rules to the argument. + # * Deletes leading underscores, if any. + # * Removes a "_id" suffix if present. + # * Replaces underscores with spaces, if any. + # * Downcases all words except acronyms. + # * Capitalizes the first word. + # + # The capitalization of the first word can be turned off by setting the + # +:capitalize+ option to false (default is true). + # + # humanize('employee_salary') # => "Employee salary" + # humanize('author_id') # => "Author" + # humanize('author_id', capitalize: false) # => "author" + # humanize('_id') # => "Id" + # + # If "SSL" was defined to be an acronym: + # + # humanize('ssl_error') # => "SSL error" + # + def humanize(lower_case_and_underscored_word, options = {}) + result = lower_case_and_underscored_word.to_s.dup + + inflections.humans.each { |(rule, replacement)| break if result.sub!(rule, replacement) } + + result.sub!(/\A_+/, '') + result.sub!(/_id\z/, '') + result.tr!('_', ' ') + + result.gsub!(/([a-z\d]*)/i) do |match| + "#{inflections.acronyms[match] || match.downcase}" + end + + if options.fetch(:capitalize, true) + result.sub!(/\A\w/) { |match| match.upcase } + end + + result + end + + # Capitalizes all the words and replaces some characters in the string to + # create a nicer looking title. +titleize+ is meant for creating pretty + # output. It is not used in the Rails internals. + # + # +titleize+ is also aliased as +titlecase+. + # + # 'man from the boondocks'.titleize # => "Man From The Boondocks" + # 'x-men: the last stand'.titleize # => "X Men: The Last Stand" + # 'TheManWithoutAPast'.titleize # => "The Man Without A Past" + # 'raiders_of_the_lost_ark'.titleize # => "Raiders Of The Lost Ark" + def titleize(word) + humanize(underscore(word)).gsub(/\b(? "raw_scaled_scorers" + # 'egg_and_ham'.tableize # => "egg_and_hams" + # 'fancyCategory'.tableize # => "fancy_categories" + def tableize(class_name) + pluralize(underscore(class_name)) + end + + # Create a class name from a plural table name like Rails does for table + # names to models. Note that this returns a string and not a Class (To + # convert to an actual class follow +classify+ with +constantize+). + # + # 'egg_and_hams'.classify # => "EggAndHam" + # 'posts'.classify # => "Post" + # + # Singular names are not handled correctly: + # + # 'calculus'.classify # => "Calculu" + def classify(table_name) + # strip out any leading schema name + camelize(singularize(table_name.to_s.sub(/.*\./, ''))) + end + + # Replaces underscores with dashes in the string. + # + # 'puni_puni'.dasherize # => "puni-puni" + def dasherize(underscored_word) + underscored_word.tr('_', '-') + end + + # Removes the module part from the expression in the string. + # + # 'ActiveRecord::CoreExtensions::String::Inflections'.demodulize # => "Inflections" + # 'Inflections'.demodulize # => "Inflections" + # '::Inflections'.demodulize # => "Inflections" + # ''.demodulize # => "" + # + # See also +deconstantize+. + def demodulize(path) + path = path.to_s + if i = path.rindex('::') + path[(i+2)..-1] + else + path + end + end + + # Removes the rightmost segment from the constant expression in the string. + # + # 'Net::HTTP'.deconstantize # => "Net" + # '::Net::HTTP'.deconstantize # => "::Net" + # 'String'.deconstantize # => "" + # '::String'.deconstantize # => "" + # ''.deconstantize # => "" + # + # See also +demodulize+. + def deconstantize(path) + path.to_s[0, path.rindex('::') || 0] # implementation based on the one in facets' Module#spacename + end + + # Creates a foreign key name from a class name. + # +separate_class_name_and_id_with_underscore+ sets whether + # the method should put '_' between the name and 'id'. + # + # 'Message'.foreign_key # => "message_id" + # 'Message'.foreign_key(false) # => "messageid" + # 'Admin::Post'.foreign_key # => "post_id" + def foreign_key(class_name, separate_class_name_and_id_with_underscore = true) + underscore(demodulize(class_name)) + (separate_class_name_and_id_with_underscore ? "_id" : "id") + end + + # Tries to find a constant with the name specified in the argument string. + # + # 'Module'.constantize # => Module + # 'Test::Unit'.constantize # => Test::Unit + # + # The name is assumed to be the one of a top-level constant, no matter + # whether it starts with "::" or not. No lexical context is taken into + # account: + # + # C = 'outside' + # module M + # C = 'inside' + # C # => 'inside' + # 'C'.constantize # => 'outside', same as ::C + # end + # + # NameError is raised when the name is not in CamelCase or the constant is + # unknown. + def constantize(camel_cased_word) + names = camel_cased_word.split('::') + + # Trigger a built-in NameError exception including the ill-formed constant in the message. + Object.const_get(camel_cased_word) if names.empty? + + # Remove the first blank element in case of '::ClassName' notation. + names.shift if names.size > 1 && names.first.empty? + + names.inject(Object) do |constant, name| + if constant == Object + constant.const_get(name) + else + candidate = constant.const_get(name) + next candidate if constant.const_defined?(name, false) + next candidate unless Object.const_defined?(name) + + # Go down the ancestors to check if it is owned directly. The check + # stops when we reach Object or the end of ancestors tree. + constant = constant.ancestors.inject do |const, ancestor| + break const if ancestor == Object + break ancestor if ancestor.const_defined?(name, false) + const + end + + # owner is in Object, so raise + constant.const_get(name, false) + end + end + end + + # Tries to find a constant with the name specified in the argument string. + # + # 'Module'.safe_constantize # => Module + # 'Test::Unit'.safe_constantize # => Test::Unit + # + # The name is assumed to be the one of a top-level constant, no matter + # whether it starts with "::" or not. No lexical context is taken into + # account: + # + # C = 'outside' + # module M + # C = 'inside' + # C # => 'inside' + # 'C'.safe_constantize # => 'outside', same as ::C + # end + # + # +nil+ is returned when the name is not in CamelCase or the constant (or + # part of it) is unknown. + # + # 'blargle'.safe_constantize # => nil + # 'UnknownModule'.safe_constantize # => nil + # 'UnknownModule::Foo::Bar'.safe_constantize # => nil + def safe_constantize(camel_cased_word) + constantize(camel_cased_word) + rescue NameError => e + raise if e.name && !(camel_cased_word.to_s.split("::").include?(e.name.to_s) || + e.name.to_s == camel_cased_word.to_s) + rescue ArgumentError => e + raise unless e.message =~ /not missing constant #{const_regexp(camel_cased_word)}\!$/ + end + + # Returns the suffix that should be added to a number to denote the position + # in an ordered sequence such as 1st, 2nd, 3rd, 4th. + # + # ordinal(1) # => "st" + # ordinal(2) # => "nd" + # ordinal(1002) # => "nd" + # ordinal(1003) # => "rd" + # ordinal(-11) # => "th" + # ordinal(-1021) # => "st" + def ordinal(number) + abs_number = number.to_i.abs + + if (11..13).include?(abs_number % 100) + "th" + else + case abs_number % 10 + when 1; "st" + when 2; "nd" + when 3; "rd" + else "th" + end + end + end + + # Turns a number into an ordinal string used to denote the position in an + # ordered sequence such as 1st, 2nd, 3rd, 4th. + # + # ordinalize(1) # => "1st" + # ordinalize(2) # => "2nd" + # ordinalize(1002) # => "1002nd" + # ordinalize(1003) # => "1003rd" + # ordinalize(-11) # => "-11th" + # ordinalize(-1021) # => "-1021st" + def ordinalize(number) + "#{number}#{ordinal(number)}" + end + + private + + # Mounts a regular expression, returned as a string to ease interpolation, + # that will match part by part the given constant. + # + # const_regexp("Foo::Bar::Baz") # => "Foo(::Bar(::Baz)?)?" + # const_regexp("::") # => "::" + def const_regexp(camel_cased_word) #:nodoc: + parts = camel_cased_word.split("::") + + return Regexp.escape(camel_cased_word) if parts.blank? + + last = parts.pop + + parts.reverse.inject(last) do |acc, part| + part.empty? ? acc : "#{part}(::#{acc})?" + end + end + + # Applies inflection rules for +singularize+ and +pluralize+. + # + # apply_inflections('post', inflections.plurals) # => "posts" + # apply_inflections('posts', inflections.singulars) # => "post" + def apply_inflections(word, rules) + result = word.to_s.dup + + if word.empty? || inflections.uncountables.include?(result.downcase[/\b\w+\Z/]) + result + else + rules.each { |(rule, replacement)| break if result.sub!(rule, replacement) } + result + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/inflector/transliterate.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/inflector/transliterate.rb new file mode 100644 index 0000000..1cde417 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/inflector/transliterate.rb @@ -0,0 +1,97 @@ +# encoding: utf-8 +require 'active_support/core_ext/string/multibyte' +require 'active_support/i18n' + +module ActiveSupport + module Inflector + + # Replaces non-ASCII characters with an ASCII approximation, or if none + # exists, a replacement character which defaults to "?". + # + # transliterate('Ærøskøbing') + # # => "AEroskobing" + # + # Default approximations are provided for Western/Latin characters, + # e.g, "ø", "ñ", "é", "ß", etc. + # + # This method is I18n aware, so you can set up custom approximations for a + # locale. This can be useful, for example, to transliterate German's "ü" + # and "ö" to "ue" and "oe", or to add support for transliterating Russian + # to ASCII. + # + # In order to make your custom transliterations available, you must set + # them as the i18n.transliterate.rule i18n key: + # + # # Store the transliterations in locales/de.yml + # i18n: + # transliterate: + # rule: + # ü: "ue" + # ö: "oe" + # + # # Or set them using Ruby + # I18n.backend.store_translations(:de, i18n: { + # transliterate: { + # rule: { + # 'ü' => 'ue', + # 'ö' => 'oe' + # } + # } + # }) + # + # The value for i18n.transliterate.rule can be a simple Hash that + # maps characters to ASCII approximations as shown above, or, for more + # complex requirements, a Proc: + # + # I18n.backend.store_translations(:de, i18n: { + # transliterate: { + # rule: ->(string) { MyTransliterator.transliterate(string) } + # } + # }) + # + # Now you can have different transliterations for each locale: + # + # I18n.locale = :en + # transliterate('Jürgen') + # # => "Jurgen" + # + # I18n.locale = :de + # transliterate('Jürgen') + # # => "Juergen" + def transliterate(string, replacement = "?") + I18n.transliterate(ActiveSupport::Multibyte::Unicode.normalize( + ActiveSupport::Multibyte::Unicode.tidy_bytes(string), :c), + :replacement => replacement) + end + + # Replaces special characters in a string so that it may be used as part of + # a 'pretty' URL. + # + # class Person + # def to_param + # "#{id}-#{name.parameterize}" + # end + # end + # + # @person = Person.find(1) + # # => # + # + # <%= link_to(@person.name, person_path(@person)) %> + # # => Donald E. Knuth + def parameterize(string, sep = '-') + # replace accented chars with their ascii equivalents + parameterized_string = transliterate(string) + # Turn unwanted chars into the separator + parameterized_string.gsub!(/[^a-z0-9\-_]+/i, sep) + unless sep.nil? || sep.empty? + re_sep = Regexp.escape(sep) + # No more than one of the separator in a row. + parameterized_string.gsub!(/#{re_sep}{2,}/, sep) + # Remove leading/trailing separator. + parameterized_string.gsub!(/^#{re_sep}|#{re_sep}$/i, '') + end + parameterized_string.downcase + end + + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/json.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/json.rb new file mode 100644 index 0000000..3e1d9b1 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/json.rb @@ -0,0 +1,2 @@ +require 'active_support/json/decoding' +require 'active_support/json/encoding' diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/json/decoding.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/json/decoding.rb new file mode 100644 index 0000000..35548f3 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/json/decoding.rb @@ -0,0 +1,73 @@ +require 'active_support/core_ext/module/attribute_accessors' +require 'active_support/core_ext/module/delegation' +require 'json' + +module ActiveSupport + # Look for and parse json strings that look like ISO 8601 times. + mattr_accessor :parse_json_times + + module JSON + # matches YAML-formatted dates + DATE_REGEX = /^(?:\d{4}-\d{2}-\d{2}|\d{4}-\d{1,2}-\d{1,2}[T \t]+\d{1,2}:\d{2}:\d{2}(\.[0-9]*)?(([ \t]*)Z|[-+]\d{2}?(:\d{2})?))$/ + + class << self + # Parses a JSON string (JavaScript Object Notation) into a hash. + # See http://www.json.org for more info. + # + # ActiveSupport::JSON.decode("{\"team\":\"rails\",\"players\":\"36\"}") + # => {"team" => "rails", "players" => "36"} + def decode(json, options = {}) + if options.present? + raise ArgumentError, "In Rails 4.1, ActiveSupport::JSON.decode no longer " \ + "accepts an options hash for MultiJSON. MultiJSON reached its end of life " \ + "and has been removed." + end + + data = ::JSON.parse(json, quirks_mode: true) + + if ActiveSupport.parse_json_times + convert_dates_from(data) + else + data + end + end + + # Returns the class of the error that will be raised when there is an + # error in decoding JSON. Using this method means you won't directly + # depend on the ActiveSupport's JSON implementation, in case it changes + # in the future. + # + # begin + # obj = ActiveSupport::JSON.decode(some_string) + # rescue ActiveSupport::JSON.parse_error + # Rails.logger.warn("Attempted to decode invalid JSON: #{some_string}") + # end + def parse_error + ::JSON::ParserError + end + + private + + def convert_dates_from(data) + case data + when nil + nil + when DATE_REGEX + begin + DateTime.parse(data) + rescue ArgumentError + data + end + when Array + data.map! { |d| convert_dates_from(d) } + when Hash + data.each do |key, value| + data[key] = convert_dates_from(value) + end + else + data + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/json/encoding.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/json/encoding.rb new file mode 100644 index 0000000..931a0cf --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/json/encoding.rb @@ -0,0 +1,177 @@ +require 'active_support/core_ext/object/json' +require 'active_support/core_ext/module/delegation' +require 'active_support/deprecation' + +module ActiveSupport + class << self + delegate :use_standard_json_time_format, :use_standard_json_time_format=, + :time_precision, :time_precision=, + :escape_html_entities_in_json, :escape_html_entities_in_json=, + :encode_big_decimal_as_string, :encode_big_decimal_as_string=, + :json_encoder, :json_encoder=, + :to => :'ActiveSupport::JSON::Encoding' + end + + module JSON + # Dumps objects in JSON (JavaScript Object Notation). + # See http://www.json.org for more info. + # + # ActiveSupport::JSON.encode({ team: 'rails', players: '36' }) + # # => "{\"team\":\"rails\",\"players\":\"36\"}" + def self.encode(value, options = nil) + Encoding.json_encoder.new(options).encode(value) + end + + module Encoding #:nodoc: + class JSONGemEncoder #:nodoc: + attr_reader :options + + def initialize(options = nil) + @options = options || {} + end + + # Encode the given object into a JSON string + def encode(value) + stringify jsonify value.as_json(options.dup) + end + + private + # Rails does more escaping than the JSON gem natively does (we + # escape \u2028 and \u2029 and optionally >, <, & to work around + # certain browser problems). + ESCAPED_CHARS = { + "\u2028" => '\u2028', + "\u2029" => '\u2029', + '>' => '\u003e', + '<' => '\u003c', + '&' => '\u0026', + } + + ESCAPE_REGEX_WITH_HTML_ENTITIES = /[\u2028\u2029><&]/u + ESCAPE_REGEX_WITHOUT_HTML_ENTITIES = /[\u2028\u2029]/u + + # This class wraps all the strings we see and does the extra escaping + class EscapedString < String #:nodoc: + def to_json(*) + if Encoding.escape_html_entities_in_json + super.gsub ESCAPE_REGEX_WITH_HTML_ENTITIES, ESCAPED_CHARS + else + super.gsub ESCAPE_REGEX_WITHOUT_HTML_ENTITIES, ESCAPED_CHARS + end + end + + def to_s + self + end + end + + # Mark these as private so we don't leak encoding-specific constructs + private_constant :ESCAPED_CHARS, :ESCAPE_REGEX_WITH_HTML_ENTITIES, + :ESCAPE_REGEX_WITHOUT_HTML_ENTITIES, :EscapedString + + # Convert an object into a "JSON-ready" representation composed of + # primitives like Hash, Array, String, Numeric, and true/false/nil. + # Recursively calls #as_json to the object to recursively build a + # fully JSON-ready object. + # + # This allows developers to implement #as_json without having to + # worry about what base types of objects they are allowed to return + # or having to remember to call #as_json recursively. + # + # Note: the +options+ hash passed to +object.to_json+ is only passed + # to +object.as_json+, not any of this method's recursive +#as_json+ + # calls. + def jsonify(value) + case value + when String + EscapedString.new(value) + when Numeric, NilClass, TrueClass, FalseClass + value + when Hash + Hash[value.map { |k, v| [jsonify(k), jsonify(v)] }] + when Array + value.map { |v| jsonify(v) } + else + jsonify value.as_json + end + end + + # Encode a "jsonified" Ruby data structure using the JSON gem + def stringify(jsonified) + ::JSON.generate(jsonified, quirks_mode: true, max_nesting: false) + end + end + + class << self + # If true, use ISO 8601 format for dates and times. Otherwise, fall back + # to the Active Support legacy format. + attr_accessor :use_standard_json_time_format + + # If true, encode >, <, & as escaped unicode sequences (e.g. > as \u003e) + # as a safety measure. + attr_accessor :escape_html_entities_in_json + + # Sets the precision of encoded time values. + # Defaults to 3 (equivalent to millisecond precision) + attr_accessor :time_precision + + # Sets the encoder used by Rails to encode Ruby objects into JSON strings + # in +Object#to_json+ and +ActiveSupport::JSON.encode+. + attr_accessor :json_encoder + + def encode_big_decimal_as_string=(as_string) + message = \ + "The JSON encoder in Rails 4.1 no longer supports encoding BigDecimals as JSON numbers. Instead, " \ + "the new encoder will always encode them as strings.\n\n" \ + "You are seeing this error because you have 'active_support.encode_big_decimal_as_string' in " \ + "your configuration file. If you have been setting this to true, you can safely remove it from " \ + "your configuration. Otherwise, you should add the 'activesupport-json_encoder' gem to your " \ + "Gemfile in order to restore this functionality." + + raise NotImplementedError, message + end + + def encode_big_decimal_as_string + message = \ + "The JSON encoder in Rails 4.1 no longer supports encoding BigDecimals as JSON numbers. Instead, " \ + "the new encoder will always encode them as strings.\n\n" \ + "You are seeing this error because you are trying to check the value of the related configuration, " \ + "`active_support.encode_big_decimal_as_string`. If your application depends on this option, you should " \ + "add the 'activesupport-json_encoder' gem to your Gemfile. For now, this option will always be true. " \ + "In the future, it will be removed from Rails, so you should stop checking its value." + + ActiveSupport::Deprecation.warn message + + true + end + + # Deprecate CircularReferenceError + def const_missing(name) + if name == :CircularReferenceError + message = "The JSON encoder in Rails 4.1 no longer offers protection from circular references. " \ + "You are seeing this warning because you are rescuing from (or otherwise referencing) " \ + "ActiveSupport::Encoding::CircularReferenceError. In the future, this error will be " \ + "removed from Rails. You should remove these rescue blocks from your code and ensure " \ + "that your data structures are free of circular references so they can be properly " \ + "serialized into JSON.\n\n" \ + "For example, the following Hash contains a circular reference to itself:\n" \ + " h = {}\n" \ + " h['circular'] = h\n" \ + "In this case, calling h.to_json would not work properly." + + ActiveSupport::Deprecation.warn message + + SystemStackError + else + super + end + end + end + + self.use_standard_json_time_format = true + self.escape_html_entities_in_json = true + self.json_encoder = JSONGemEncoder + self.time_precision = 3 + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/key_generator.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/key_generator.rb new file mode 100644 index 0000000..51d2da3 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/key_generator.rb @@ -0,0 +1,73 @@ +require 'thread_safe' +require 'openssl' + +module ActiveSupport + # KeyGenerator is a simple wrapper around OpenSSL's implementation of PBKDF2 + # It can be used to derive a number of keys for various purposes from a given secret. + # This lets Rails applications have a single secure secret, but avoid reusing that + # key in multiple incompatible contexts. + class KeyGenerator + def initialize(secret, options = {}) + @secret = secret + # The default iterations are higher than required for our key derivation uses + # on the off chance someone uses this for password storage + @iterations = options[:iterations] || 2**16 + end + + # Returns a derived key suitable for use. The default key_size is chosen + # to be compatible with the default settings of ActiveSupport::MessageVerifier. + # i.e. OpenSSL::Digest::SHA1#block_length + def generate_key(salt, key_size=64) + OpenSSL::PKCS5.pbkdf2_hmac_sha1(@secret, salt, @iterations, key_size) + end + end + + # CachingKeyGenerator is a wrapper around KeyGenerator which allows users to avoid + # re-executing the key generation process when it's called using the same salt and + # key_size + class CachingKeyGenerator + def initialize(key_generator) + @key_generator = key_generator + @cache_keys = ThreadSafe::Cache.new + end + + # Returns a derived key suitable for use. The default key_size is chosen + # to be compatible with the default settings of ActiveSupport::MessageVerifier. + # i.e. OpenSSL::Digest::SHA1#block_length + def generate_key(salt, key_size=64) + @cache_keys["#{salt}#{key_size}"] ||= @key_generator.generate_key(salt, key_size) + end + end + + class LegacyKeyGenerator # :nodoc: + SECRET_MIN_LENGTH = 30 # Characters + + def initialize(secret) + ensure_secret_secure(secret) + @secret = secret + end + + def generate_key(salt) + @secret + end + + private + + # To prevent users from using something insecure like "Password" we make sure that the + # secret they've provided is at least 30 characters in length. + def ensure_secret_secure(secret) + if secret.blank? + raise ArgumentError, "A secret is required to generate an integrity hash " \ + "for cookie session data. Set a secret_key_base of at least " \ + "#{SECRET_MIN_LENGTH} characters in config/secrets.yml." + end + + if secret.length < SECRET_MIN_LENGTH + raise ArgumentError, "Secret should be something secure, " \ + "like \"#{SecureRandom.hex(16)}\". The value you " \ + "provided, \"#{secret}\", is shorter than the minimum length " \ + "of #{SECRET_MIN_LENGTH} characters." + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/lazy_load_hooks.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/lazy_load_hooks.rb new file mode 100644 index 0000000..e2b8f0f --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/lazy_load_hooks.rb @@ -0,0 +1,48 @@ +module ActiveSupport + # lazy_load_hooks allows Rails to lazily load a lot of components and thus + # making the app boot faster. Because of this feature now there is no need to + # require ActiveRecord::Base at boot time purely to apply + # configuration. Instead a hook is registered that applies configuration once + # ActiveRecord::Base is loaded. Here ActiveRecord::Base is + # used as example but this feature can be applied elsewhere too. + # + # Here is an example where +on_load+ method is called to register a hook. + # + # initializer 'active_record.initialize_timezone' do + # ActiveSupport.on_load(:active_record) do + # self.time_zone_aware_attributes = true + # self.default_timezone = :utc + # end + # end + # + # When the entirety of +activerecord/lib/active_record/base.rb+ has been + # evaluated then +run_load_hooks+ is invoked. The very last line of + # +activerecord/lib/active_record/base.rb+ is: + # + # ActiveSupport.run_load_hooks(:active_record, ActiveRecord::Base) + @load_hooks = Hash.new { |h,k| h[k] = [] } + @loaded = Hash.new { |h,k| h[k] = [] } + + def self.on_load(name, options = {}, &block) + @loaded[name].each do |base| + execute_hook(base, options, block) + end + + @load_hooks[name] << [block, options] + end + + def self.execute_hook(base, options, block) + if options[:yield] + block.call(base) + else + base.instance_eval(&block) + end + end + + def self.run_load_hooks(name, base = Object) + @loaded[name] << base + @load_hooks[name].each do |hook, options| + execute_hook(base, options, hook) + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/locale/en.yml b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/locale/en.yml new file mode 100644 index 0000000..a4563ac --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/locale/en.yml @@ -0,0 +1,133 @@ +en: + date: + formats: + # Use the strftime parameters for formats. + # When no format has been given, it uses default. + # You can provide other formats here if you like! + default: "%Y-%m-%d" + short: "%b %d" + long: "%B %d, %Y" + + day_names: [Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday] + abbr_day_names: [Sun, Mon, Tue, Wed, Thu, Fri, Sat] + + # Don't forget the nil at the beginning; there's no such thing as a 0th month + month_names: [~, January, February, March, April, May, June, July, August, September, October, November, December] + abbr_month_names: [~, Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec] + # Used in date_select and datetime_select. + order: + - year + - month + - day + + time: + formats: + default: "%a, %d %b %Y %H:%M:%S %z" + short: "%d %b %H:%M" + long: "%B %d, %Y %H:%M" + am: "am" + pm: "pm" + +# Used in array.to_sentence. + support: + array: + words_connector: ", " + two_words_connector: " and " + last_word_connector: ", and " + number: + # Used in NumberHelper.number_to_delimited() + # These are also the defaults for 'currency', 'percentage', 'precision', and 'human' + format: + # Sets the separator between the units, for more precision (e.g. 1.0 / 2.0 == 0.5) + separator: "." + # Delimits thousands (e.g. 1,000,000 is a million) (always in groups of three) + delimiter: "," + # Number of decimals, behind the separator (the number 1 with a precision of 2 gives: 1.00) + precision: 3 + # If set to true, precision will mean the number of significant digits instead + # of the number of decimal digits (1234 with precision 2 becomes 1200, 1.23543 becomes 1.2) + significant: false + # If set, the zeros after the decimal separator will always be stripped (eg.: 1.200 will be 1.2) + strip_insignificant_zeros: false + + # Used in NumberHelper.number_to_currency() + currency: + format: + # Where is the currency sign? %u is the currency unit, %n the number (default: $5.00) + format: "%u%n" + unit: "$" + # These five are to override number.format and are optional + separator: "." + delimiter: "," + precision: 2 + significant: false + strip_insignificant_zeros: false + + # Used in NumberHelper.number_to_percentage() + percentage: + format: + # These five are to override number.format and are optional + # separator: + delimiter: "" + # precision: + # significant: false + # strip_insignificant_zeros: false + format: "%n%" + + # Used in NumberHelper.number_to_rounded() + precision: + format: + # These five are to override number.format and are optional + # separator: + delimiter: "" + # precision: + # significant: false + # strip_insignificant_zeros: false + + # Used in NumberHelper.number_to_human_size() and NumberHelper.number_to_human() + human: + format: + # These five are to override number.format and are optional + # separator: + delimiter: "" + precision: 3 + significant: true + strip_insignificant_zeros: true + # Used in number_to_human_size() + storage_units: + # Storage units output formatting. + # %u is the storage unit, %n is the number (default: 2 MB) + format: "%n %u" + units: + byte: + one: "Byte" + other: "Bytes" + kb: "KB" + mb: "MB" + gb: "GB" + tb: "TB" + # Used in NumberHelper.number_to_human() + decimal_units: + format: "%n %u" + # Decimal units output formatting + # By default we will only quantify some of the exponents + # but the commented ones might be defined or overridden + # by the user. + units: + # femto: Quadrillionth + # pico: Trillionth + # nano: Billionth + # micro: Millionth + # mili: Thousandth + # centi: Hundredth + # deci: Tenth + unit: "" + # ten: + # one: Ten + # other: Tens + # hundred: Hundred + thousand: Thousand + million: Million + billion: Billion + trillion: Trillion + quadrillion: Quadrillion diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/log_subscriber.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/log_subscriber.rb new file mode 100644 index 0000000..e95dc5a --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/log_subscriber.rb @@ -0,0 +1,109 @@ +require 'active_support/core_ext/module/attribute_accessors' +require 'active_support/core_ext/class/attribute' +require 'active_support/subscriber' + +module ActiveSupport + # ActiveSupport::LogSubscriber is an object set to consume + # ActiveSupport::Notifications with the sole purpose of logging them. + # The log subscriber dispatches notifications to a registered object based + # on its given namespace. + # + # An example would be Active Record log subscriber responsible for logging + # queries: + # + # module ActiveRecord + # class LogSubscriber < ActiveSupport::LogSubscriber + # def sql(event) + # "#{event.payload[:name]} (#{event.duration}) #{event.payload[:sql]}" + # end + # end + # end + # + # And it's finally registered as: + # + # ActiveRecord::LogSubscriber.attach_to :active_record + # + # Since we need to know all instance methods before attaching the log + # subscriber, the line above should be called after your + # ActiveRecord::LogSubscriber definition. + # + # After configured, whenever a "sql.active_record" notification is published, + # it will properly dispatch the event (ActiveSupport::Notifications::Event) to + # the sql method. + # + # Log subscriber also has some helpers to deal with logging and automatically + # flushes all logs when the request finishes (via action_dispatch.callback + # notification) in a Rails environment. + class LogSubscriber < Subscriber + # Embed in a String to clear all previous ANSI sequences. + CLEAR = "\e[0m" + BOLD = "\e[1m" + + # Colors + BLACK = "\e[30m" + RED = "\e[31m" + GREEN = "\e[32m" + YELLOW = "\e[33m" + BLUE = "\e[34m" + MAGENTA = "\e[35m" + CYAN = "\e[36m" + WHITE = "\e[37m" + + mattr_accessor :colorize_logging + self.colorize_logging = true + + class << self + def logger + @logger ||= if defined?(Rails) && Rails.respond_to?(:logger) + Rails.logger + end + end + + attr_writer :logger + + def log_subscribers + subscribers + end + + # Flush all log_subscribers' logger. + def flush_all! + logger.flush if logger.respond_to?(:flush) + end + end + + def logger + LogSubscriber.logger + end + + def start(name, id, payload) + super if logger + end + + def finish(name, id, payload) + super if logger + rescue Exception => e + logger.error "Could not log #{name.inspect} event. #{e.class}: #{e.message} #{e.backtrace}" + end + + protected + + %w(info debug warn error fatal unknown).each do |level| + class_eval <<-METHOD, __FILE__, __LINE__ + 1 + def #{level}(progname = nil, &block) + logger.#{level}(progname, &block) if logger + end + METHOD + end + + # Set color by using a string or one of the defined constants. If a third + # option is set to +true+, it also adds bold to the string. This is based + # on the Highline implementation and will automatically append CLEAR to the + # end of the returned String. + def color(text, color, bold=false) + return text unless colorize_logging + color = self.class.const_get(color.upcase) if color.is_a?(Symbol) + bold = bold ? BOLD : "" + "#{bold}#{color}#{text}#{CLEAR}" + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/log_subscriber/test_helper.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/log_subscriber/test_helper.rb new file mode 100644 index 0000000..75f353f --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/log_subscriber/test_helper.rb @@ -0,0 +1,104 @@ +require 'active_support/log_subscriber' +require 'active_support/logger' +require 'active_support/notifications' + +module ActiveSupport + class LogSubscriber + # Provides some helpers to deal with testing log subscribers by setting up + # notifications. Take for instance Active Record subscriber tests: + # + # class SyncLogSubscriberTest < ActiveSupport::TestCase + # include ActiveSupport::LogSubscriber::TestHelper + # + # def setup + # ActiveRecord::LogSubscriber.attach_to(:active_record) + # end + # + # def test_basic_query_logging + # Developer.all.to_a + # wait + # assert_equal 1, @logger.logged(:debug).size + # assert_match(/Developer Load/, @logger.logged(:debug).last) + # assert_match(/SELECT \* FROM "developers"/, @logger.logged(:debug).last) + # end + # end + # + # All you need to do is to ensure that your log subscriber is added to + # Rails::Subscriber, as in the second line of the code above. The test + # helpers are responsible for setting up the queue, subscriptions and + # turning colors in logs off. + # + # The messages are available in the @logger instance, which is a logger with + # limited powers (it actually does not send anything to your output), and + # you can collect them doing @logger.logged(level), where level is the level + # used in logging, like info, debug, warn and so on. + module TestHelper + def setup + @logger = MockLogger.new + @notifier = ActiveSupport::Notifications::Fanout.new + + ActiveSupport::LogSubscriber.colorize_logging = false + + @old_notifier = ActiveSupport::Notifications.notifier + set_logger(@logger) + ActiveSupport::Notifications.notifier = @notifier + end + + def teardown + set_logger(nil) + ActiveSupport::Notifications.notifier = @old_notifier + end + + class MockLogger + include ActiveSupport::Logger::Severity + + attr_reader :flush_count + attr_accessor :level + + def initialize(level = DEBUG) + @flush_count = 0 + @level = level + @logged = Hash.new { |h,k| h[k] = [] } + end + + def method_missing(level, message = nil) + if block_given? + @logged[level] << yield + else + @logged[level] << message + end + end + + def logged(level) + @logged[level].compact.map { |l| l.to_s.strip } + end + + def flush + @flush_count += 1 + end + + ActiveSupport::Logger::Severity.constants.each do |severity| + class_eval <<-EOT, __FILE__, __LINE__ + 1 + def #{severity.downcase}? + #{severity} >= @level + end + EOT + end + end + + # Wait notifications to be published. + def wait + @notifier.wait + end + + # Overwrite if you use another logger in your log subscriber. + # + # def logger + # ActiveRecord::Base.logger = @logger + # end + def set_logger(logger) + ActiveSupport::LogSubscriber.logger = logger + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/logger.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/logger.rb new file mode 100644 index 0000000..b82a621 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/logger.rb @@ -0,0 +1,71 @@ +require 'active_support/core_ext/module/attribute_accessors' +require 'active_support/logger_silence' +require 'logger' + +module ActiveSupport + class Logger < ::Logger + include LoggerSilence + + # Broadcasts logs to multiple loggers. + def self.broadcast(logger) # :nodoc: + Module.new do + define_method(:add) do |*args, &block| + logger.add(*args, &block) + super(*args, &block) + end + + define_method(:<<) do |x| + logger << x + super(x) + end + + define_method(:close) do + logger.close + super() + end + + define_method(:progname=) do |name| + logger.progname = name + super(name) + end + + define_method(:formatter=) do |formatter| + logger.formatter = formatter + super(formatter) + end + + define_method(:level=) do |level| + logger.level = level + super(level) + end + end + end + + def initialize(*args) + super + @formatter = SimpleFormatter.new + after_initialize if respond_to? :after_initialize + end + + def add(severity, message = nil, progname = nil, &block) + return true if @logdev.nil? || (severity || UNKNOWN) < level + super + end + + Logger::Severity.constants.each do |severity| + class_eval(<<-EOT, __FILE__, __LINE__ + 1) + def #{severity.downcase}? # def debug? + Logger::#{severity} >= level # DEBUG >= level + end # end + EOT + end + + # Simple formatter which only displays the message. + class SimpleFormatter < ::Logger::Formatter + # This method is invoked when a log event occurs + def call(severity, timestamp, progname, msg) + "#{String === msg ? msg : msg.inspect}\n" + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/logger_silence.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/logger_silence.rb new file mode 100644 index 0000000..d5dc81b --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/logger_silence.rb @@ -0,0 +1,45 @@ +require 'active_support/concern' +require 'thread_safe' + +module LoggerSilence + extend ActiveSupport::Concern + + included do + cattr_accessor :silencer + attr_reader :local_levels + self.silencer = true + end + + + def after_initialize + @local_levels = ThreadSafe::Cache.new(:initial_capacity => 2) + end + + def local_log_id + Thread.current.__id__ + end + + def level + local_levels[local_log_id] || super + end + + # Silences the logger for the duration of the block. + def silence(temporary_level = Logger::ERROR) + if silencer + begin + old_local_level = local_levels[local_log_id] + local_levels[local_log_id] = temporary_level + + yield self + ensure + if old_local_level + local_levels[local_log_id] = old_local_level + else + local_levels.delete(local_log_id) + end + end + else + yield self + end + end +end \ No newline at end of file diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/message_encryptor.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/message_encryptor.rb new file mode 100644 index 0000000..92ab6fe --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/message_encryptor.rb @@ -0,0 +1,107 @@ +require 'openssl' +require 'base64' +require 'active_support/core_ext/array/extract_options' + +module ActiveSupport + # MessageEncryptor is a simple way to encrypt values which get stored + # somewhere you don't trust. + # + # The cipher text and initialization vector are base64 encoded and returned + # to you. + # + # This can be used in situations similar to the MessageVerifier, but + # where you don't want users to be able to determine the value of the payload. + # + # salt = SecureRandom.random_bytes(64) + # key = ActiveSupport::KeyGenerator.new('password').generate_key(salt) # => "\x89\xE0\x156\xAC..." + # crypt = ActiveSupport::MessageEncryptor.new(key) # => # + # encrypted_data = crypt.encrypt_and_sign('my secret data') # => "NlFBTTMwOUV5UlA1QlNEN2xkY2d6eThYWWh..." + # crypt.decrypt_and_verify(encrypted_data) # => "my secret data" + class MessageEncryptor + module NullSerializer #:nodoc: + def self.load(value) + value + end + + def self.dump(value) + value + end + end + + class InvalidMessage < StandardError; end + OpenSSLCipherError = OpenSSL::Cipher::CipherError + + # Initialize a new MessageEncryptor. +secret+ must be at least as long as + # the cipher key size. For the default 'aes-256-cbc' cipher, this is 256 + # bits. If you are using a user-entered secret, you can generate a suitable + # key with OpenSSL::Digest::SHA256.new(user_secret).digest or + # similar. + # + # Options: + # * :cipher - Cipher to use. Can be any cipher returned by + # OpenSSL::Cipher.ciphers. Default is 'aes-256-cbc'. + # * :digest - String of digest to use for signing. Default is +SHA1+. + # * :serializer - Object serializer to use. Default is +Marshal+. + def initialize(secret, *signature_key_or_options) + options = signature_key_or_options.extract_options! + sign_secret = signature_key_or_options.first + @secret = secret + @sign_secret = sign_secret + @cipher = options[:cipher] || 'aes-256-cbc' + @verifier = MessageVerifier.new(@sign_secret || @secret, digest: options[:digest] || 'SHA1', serializer: NullSerializer) + @serializer = options[:serializer] || Marshal + end + + # Encrypt and sign a message. We need to sign the message in order to avoid + # padding attacks. Reference: http://www.limited-entropy.com/padding-oracle-attacks. + def encrypt_and_sign(value) + verifier.generate(_encrypt(value)) + end + + # Decrypt and verify a message. We need to verify the message in order to + # avoid padding attacks. Reference: http://www.limited-entropy.com/padding-oracle-attacks. + def decrypt_and_verify(value) + _decrypt(verifier.verify(value)) + end + + private + + def _encrypt(value) + cipher = new_cipher + cipher.encrypt + cipher.key = @secret + + # Rely on OpenSSL for the initialization vector + iv = cipher.random_iv + + encrypted_data = cipher.update(@serializer.dump(value)) + encrypted_data << cipher.final + + "#{::Base64.strict_encode64 encrypted_data}--#{::Base64.strict_encode64 iv}" + end + + def _decrypt(encrypted_message) + cipher = new_cipher + encrypted_data, iv = encrypted_message.split("--").map {|v| ::Base64.strict_decode64(v)} + + cipher.decrypt + cipher.key = @secret + cipher.iv = iv + + decrypted_data = cipher.update(encrypted_data) + decrypted_data << cipher.final + + @serializer.load(decrypted_data) + rescue OpenSSLCipherError, TypeError, ArgumentError + raise InvalidMessage + end + + def new_cipher + OpenSSL::Cipher::Cipher.new(@cipher) + end + + def verifier + @verifier + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/message_verifier.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/message_verifier.rb new file mode 100644 index 0000000..9067b3d --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/message_verifier.rb @@ -0,0 +1,72 @@ +require 'base64' +require 'active_support/core_ext/object/blank' +require 'active_support/security_utils' + +module ActiveSupport + # +MessageVerifier+ makes it easy to generate and verify messages which are + # signed to prevent tampering. + # + # This is useful for cases like remember-me tokens and auto-unsubscribe links + # where the session store isn't suitable or available. + # + # Remember Me: + # cookies[:remember_me] = @verifier.generate([@user.id, 2.weeks.from_now]) + # + # In the authentication filter: + # + # id, time = @verifier.verify(cookies[:remember_me]) + # if time < Time.now + # self.current_user = User.find(id) + # end + # + # By default it uses Marshal to serialize the message. If you want to use + # another serialization method, you can set the serializer in the options + # hash upon initialization: + # + # @verifier = ActiveSupport::MessageVerifier.new('s3Krit', serializer: YAML) + class MessageVerifier + class InvalidSignature < StandardError; end + + def initialize(secret, options = {}) + raise ArgumentError, 'Secret should not be nil.' unless secret + @secret = secret + @digest = options[:digest] || 'SHA1' + @serializer = options[:serializer] || Marshal + end + + def verify(signed_message) + raise InvalidSignature if signed_message.nil? || !signed_message.valid_encoding? || signed_message.blank? + + data, digest = signed_message.split("--") + if data.present? && digest.present? && ActiveSupport::SecurityUtils.secure_compare(digest, generate_digest(data)) + begin + @serializer.load(decode(data)) + rescue ArgumentError => argument_error + raise InvalidSignature if argument_error.message =~ %r{invalid base64} + raise + end + else + raise InvalidSignature + end + end + + def generate(value) + data = encode(@serializer.dump(value)) + "#{data}--#{generate_digest(data)}" + end + + private + def encode(data) + ::Base64.strict_encode64(data) + end + + def decode(data) + ::Base64.strict_decode64(data) + end + + def generate_digest(data) + require 'openssl' unless defined?(OpenSSL) + OpenSSL::HMAC.hexdigest(OpenSSL::Digest.const_get(@digest).new, @secret, data) + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/multibyte.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/multibyte.rb new file mode 100644 index 0000000..ffebd9a --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/multibyte.rb @@ -0,0 +1,21 @@ +module ActiveSupport #:nodoc: + module Multibyte + autoload :Chars, 'active_support/multibyte/chars' + autoload :Unicode, 'active_support/multibyte/unicode' + + # The proxy class returned when calling mb_chars. You can use this accessor + # to configure your own proxy class so you can support other encodings. See + # the ActiveSupport::Multibyte::Chars implementation for an example how to + # do this. + # + # ActiveSupport::Multibyte.proxy_class = CharsForUTF32 + def self.proxy_class=(klass) + @proxy_class = klass + end + + # Returns the current proxy class. + def self.proxy_class + @proxy_class ||= ActiveSupport::Multibyte::Chars + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/multibyte/chars.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/multibyte/chars.rb new file mode 100644 index 0000000..9b3cfd1 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/multibyte/chars.rb @@ -0,0 +1,222 @@ +# encoding: utf-8 +require 'active_support/json' +require 'active_support/core_ext/string/access' +require 'active_support/core_ext/string/behavior' +require 'active_support/core_ext/module/delegation' + +module ActiveSupport #:nodoc: + module Multibyte #:nodoc: + # Chars enables you to work transparently with UTF-8 encoding in the Ruby + # String class without having extensive knowledge about the encoding. A + # Chars object accepts a string upon initialization and proxies String + # methods in an encoding safe manner. All the normal String methods are also + # implemented on the proxy. + # + # String methods are proxied through the Chars object, and can be accessed + # through the +mb_chars+ method. Methods which would normally return a + # String object now return a Chars object so methods can be chained. + # + # 'The Perfect String '.mb_chars.downcase.strip.normalize # => "the perfect string" + # + # Chars objects are perfectly interchangeable with String objects as long as + # no explicit class checks are made. If certain methods do explicitly check + # the class, call +to_s+ before you pass chars objects to them. + # + # bad.explicit_checking_method 'T'.mb_chars.downcase.to_s + # + # The default Chars implementation assumes that the encoding of the string + # is UTF-8, if you want to handle different encodings you can write your own + # multibyte string handler and configure it through + # ActiveSupport::Multibyte.proxy_class. + # + # class CharsForUTF32 + # def size + # @wrapped_string.size / 4 + # end + # + # def self.accepts?(string) + # string.length % 4 == 0 + # end + # end + # + # ActiveSupport::Multibyte.proxy_class = CharsForUTF32 + class Chars + include Comparable + attr_reader :wrapped_string + alias to_s wrapped_string + alias to_str wrapped_string + + delegate :<=>, :=~, :acts_like_string?, :to => :wrapped_string + + # Creates a new Chars instance by wrapping _string_. + def initialize(string) + @wrapped_string = string + @wrapped_string.force_encoding(Encoding::UTF_8) unless @wrapped_string.frozen? + end + + # Forward all undefined methods to the wrapped string. + def method_missing(method, *args, &block) + result = @wrapped_string.__send__(method, *args, &block) + if method.to_s =~ /!$/ + self if result + else + result.kind_of?(String) ? chars(result) : result + end + end + + # Returns +true+ if _obj_ responds to the given method. Private methods + # are included in the search only if the optional second parameter + # evaluates to +true+. + def respond_to_missing?(method, include_private) + @wrapped_string.respond_to?(method, include_private) + end + + # Returns +true+ when the proxy class can handle the string. Returns + # +false+ otherwise. + def self.consumes?(string) + string.encoding == Encoding::UTF_8 + end + + # Works just like String#split, with the exception that the items + # in the resulting list are Chars instances instead of String. This makes + # chaining methods easier. + # + # 'Café périferôl'.mb_chars.split(/é/).map { |part| part.upcase.to_s } # => ["CAF", " P", "RIFERÔL"] + def split(*args) + @wrapped_string.split(*args).map { |i| self.class.new(i) } + end + + # Works like String#slice!, but returns an instance of + # Chars, or nil if the string was not modified. + def slice!(*args) + chars(@wrapped_string.slice!(*args)) + end + + # Reverses all characters in the string. + # + # 'Café'.mb_chars.reverse.to_s # => 'éfaC' + def reverse + chars(Unicode.unpack_graphemes(@wrapped_string).reverse.flatten.pack('U*')) + end + + # Limits the byte size of the string to a number of bytes without breaking + # characters. Usable when the storage for a string is limited for some + # reason. + # + # 'ã“ã‚“ã«ã¡ã¯'.mb_chars.limit(7).to_s # => "ã“ã‚“" + def limit(limit) + slice(0...translate_offset(limit)) + end + + # Converts characters in the string to uppercase. + # + # 'Laurent, où sont les tests ?'.mb_chars.upcase.to_s # => "LAURENT, OÙ SONT LES TESTS ?" + def upcase + chars Unicode.upcase(@wrapped_string) + end + + # Converts characters in the string to lowercase. + # + # 'VÄšDA A VÃZKUM'.mb_chars.downcase.to_s # => "vÄ›da a výzkum" + def downcase + chars Unicode.downcase(@wrapped_string) + end + + # Converts characters in the string to the opposite case. + # + # 'El Cañón".mb_chars.swapcase.to_s # => "eL cAÑÓN" + def swapcase + chars Unicode.swapcase(@wrapped_string) + end + + # Converts the first character to uppercase and the remainder to lowercase. + # + # 'über'.mb_chars.capitalize.to_s # => "Ãœber" + def capitalize + (slice(0) || chars('')).upcase + (slice(1..-1) || chars('')).downcase + end + + # Capitalizes the first letter of every word, when possible. + # + # "ÉL QUE SE ENTERÓ".mb_chars.titleize # => "Él Que Se Enteró" + # "日本語".mb_chars.titleize # => "日本語" + def titleize + chars(downcase.to_s.gsub(/\b('?\S)/u) { Unicode.upcase($1)}) + end + alias_method :titlecase, :titleize + + # Returns the KC normalization of the string by default. NFKC is + # considered the best normalization form for passing strings to databases + # and validations. + # + # * form - The form you want to normalize in. Should be one of the following: + # :c, :kc, :d, or :kd. Default is + # ActiveSupport::Multibyte::Unicode.default_normalization_form + def normalize(form = nil) + chars(Unicode.normalize(@wrapped_string, form)) + end + + # Performs canonical decomposition on all the characters. + # + # 'é'.length # => 2 + # 'é'.mb_chars.decompose.to_s.length # => 3 + def decompose + chars(Unicode.decompose(:canonical, @wrapped_string.codepoints.to_a).pack('U*')) + end + + # Performs composition on all the characters. + # + # 'é'.length # => 3 + # 'é'.mb_chars.compose.to_s.length # => 2 + def compose + chars(Unicode.compose(@wrapped_string.codepoints.to_a).pack('U*')) + end + + # Returns the number of grapheme clusters in the string. + # + # 'कà¥à¤·à¤¿'.mb_chars.length # => 4 + # 'कà¥à¤·à¤¿'.mb_chars.grapheme_length # => 3 + def grapheme_length + Unicode.unpack_graphemes(@wrapped_string).length + end + + # Replaces all ISO-8859-1 or CP1252 characters by their UTF-8 equivalent + # resulting in a valid UTF-8 string. + # + # Passing +true+ will forcibly tidy all bytes, assuming that the string's + # encoding is entirely CP1252 or ISO-8859-1. + def tidy_bytes(force = false) + chars(Unicode.tidy_bytes(@wrapped_string, force)) + end + + def as_json(options = nil) #:nodoc: + to_s.as_json(options) + end + + %w(capitalize downcase reverse tidy_bytes upcase).each do |method| + define_method("#{method}!") do |*args| + @wrapped_string = send(method, *args).to_s + self + end + end + + protected + + def translate_offset(byte_offset) #:nodoc: + return nil if byte_offset.nil? + return 0 if @wrapped_string == '' + + begin + @wrapped_string.byteslice(0...byte_offset).unpack('U*').length + rescue ArgumentError + byte_offset -= 1 + retry + end + end + + def chars(string) #:nodoc: + self.class.new(string) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/multibyte/unicode.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/multibyte/unicode.rb new file mode 100644 index 0000000..7ab6293 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/multibyte/unicode.rb @@ -0,0 +1,390 @@ +# encoding: utf-8 +module ActiveSupport + module Multibyte + module Unicode + + extend self + + # A list of all available normalization forms. + # See http://www.unicode.org/reports/tr15/tr15-29.html for more + # information about normalization. + NORMALIZATION_FORMS = [:c, :kc, :d, :kd] + + # The Unicode version that is supported by the implementation + UNICODE_VERSION = '7.0.0' + + # The default normalization used for operations that require + # normalization. It can be set to any of the normalizations + # in NORMALIZATION_FORMS. + # + # ActiveSupport::Multibyte::Unicode.default_normalization_form = :c + attr_accessor :default_normalization_form + @default_normalization_form = :kc + + # Hangul character boundaries and properties + HANGUL_SBASE = 0xAC00 + HANGUL_LBASE = 0x1100 + HANGUL_VBASE = 0x1161 + HANGUL_TBASE = 0x11A7 + HANGUL_LCOUNT = 19 + HANGUL_VCOUNT = 21 + HANGUL_TCOUNT = 28 + HANGUL_NCOUNT = HANGUL_VCOUNT * HANGUL_TCOUNT + HANGUL_SCOUNT = 11172 + HANGUL_SLAST = HANGUL_SBASE + HANGUL_SCOUNT + HANGUL_JAMO_FIRST = 0x1100 + HANGUL_JAMO_LAST = 0x11FF + + # All the unicode whitespace + WHITESPACE = [ + (0x0009..0x000D).to_a, # White_Space # Cc [5] .. + 0x0020, # White_Space # Zs SPACE + 0x0085, # White_Space # Cc + 0x00A0, # White_Space # Zs NO-BREAK SPACE + 0x1680, # White_Space # Zs OGHAM SPACE MARK + (0x2000..0x200A).to_a, # White_Space # Zs [11] EN QUAD..HAIR SPACE + 0x2028, # White_Space # Zl LINE SEPARATOR + 0x2029, # White_Space # Zp PARAGRAPH SEPARATOR + 0x202F, # White_Space # Zs NARROW NO-BREAK SPACE + 0x205F, # White_Space # Zs MEDIUM MATHEMATICAL SPACE + 0x3000, # White_Space # Zs IDEOGRAPHIC SPACE + ].flatten.freeze + + # BOM (byte order mark) can also be seen as whitespace, it's a + # non-rendering character used to distinguish between little and big + # endian. This is not an issue in utf-8, so it must be ignored. + LEADERS_AND_TRAILERS = WHITESPACE + [65279] # ZERO-WIDTH NO-BREAK SPACE aka BOM + + # Returns a regular expression pattern that matches the passed Unicode + # codepoints. + def self.codepoints_to_pattern(array_of_codepoints) #:nodoc: + array_of_codepoints.collect{ |e| [e].pack 'U*' }.join('|') + end + TRAILERS_PAT = /(#{codepoints_to_pattern(LEADERS_AND_TRAILERS)})+\Z/u + LEADERS_PAT = /\A(#{codepoints_to_pattern(LEADERS_AND_TRAILERS)})+/u + + # Detect whether the codepoint is in a certain character class. Returns + # +true+ when it's in the specified character class and +false+ otherwise. + # Valid character classes are: :cr, :lf, :l, + # :v, :lv, :lvt and :t. + # + # Primarily used by the grapheme cluster support. + def in_char_class?(codepoint, classes) + classes.detect { |c| database.boundary[c] === codepoint } ? true : false + end + + # Unpack the string at grapheme boundaries. Returns a list of character + # lists. + # + # Unicode.unpack_graphemes('कà¥à¤·à¤¿') # => [[2325, 2381], [2359], [2367]] + # Unicode.unpack_graphemes('Café') # => [[67], [97], [102], [233]] + def unpack_graphemes(string) + codepoints = string.codepoints.to_a + unpacked = [] + pos = 0 + marker = 0 + eoc = codepoints.length + while(pos < eoc) + pos += 1 + previous = codepoints[pos-1] + current = codepoints[pos] + if ( + # CR X LF + ( previous == database.boundary[:cr] and current == database.boundary[:lf] ) or + # L X (L|V|LV|LVT) + ( database.boundary[:l] === previous and in_char_class?(current, [:l,:v,:lv,:lvt]) ) or + # (LV|V) X (V|T) + ( in_char_class?(previous, [:lv,:v]) and in_char_class?(current, [:v,:t]) ) or + # (LVT|T) X (T) + ( in_char_class?(previous, [:lvt,:t]) and database.boundary[:t] === current ) or + # X Extend + (database.boundary[:extend] === current) + ) + else + unpacked << codepoints[marker..pos-1] + marker = pos + end + end + unpacked + end + + # Reverse operation of unpack_graphemes. + # + # Unicode.pack_graphemes(Unicode.unpack_graphemes('कà¥à¤·à¤¿')) # => 'कà¥à¤·à¤¿' + def pack_graphemes(unpacked) + unpacked.flatten.pack('U*') + end + + # Re-order codepoints so the string becomes canonical. + def reorder_characters(codepoints) + length = codepoints.length- 1 + pos = 0 + while pos < length do + cp1, cp2 = database.codepoints[codepoints[pos]], database.codepoints[codepoints[pos+1]] + if (cp1.combining_class > cp2.combining_class) && (cp2.combining_class > 0) + codepoints[pos..pos+1] = cp2.code, cp1.code + pos += (pos > 0 ? -1 : 1) + else + pos += 1 + end + end + codepoints + end + + # Decompose composed characters to the decomposed form. + def decompose(type, codepoints) + codepoints.inject([]) do |decomposed, cp| + # if it's a hangul syllable starter character + if HANGUL_SBASE <= cp and cp < HANGUL_SLAST + sindex = cp - HANGUL_SBASE + ncp = [] # new codepoints + ncp << HANGUL_LBASE + sindex / HANGUL_NCOUNT + ncp << HANGUL_VBASE + (sindex % HANGUL_NCOUNT) / HANGUL_TCOUNT + tindex = sindex % HANGUL_TCOUNT + ncp << (HANGUL_TBASE + tindex) unless tindex == 0 + decomposed.concat ncp + # if the codepoint is decomposable in with the current decomposition type + elsif (ncp = database.codepoints[cp].decomp_mapping) and (!database.codepoints[cp].decomp_type || type == :compatibility) + decomposed.concat decompose(type, ncp.dup) + else + decomposed << cp + end + end + end + + # Compose decomposed characters to the composed form. + def compose(codepoints) + pos = 0 + eoa = codepoints.length - 1 + starter_pos = 0 + starter_char = codepoints[0] + previous_combining_class = -1 + while pos < eoa + pos += 1 + lindex = starter_char - HANGUL_LBASE + # -- Hangul + if 0 <= lindex and lindex < HANGUL_LCOUNT + vindex = codepoints[starter_pos+1] - HANGUL_VBASE rescue vindex = -1 + if 0 <= vindex and vindex < HANGUL_VCOUNT + tindex = codepoints[starter_pos+2] - HANGUL_TBASE rescue tindex = -1 + if 0 <= tindex and tindex < HANGUL_TCOUNT + j = starter_pos + 2 + eoa -= 2 + else + tindex = 0 + j = starter_pos + 1 + eoa -= 1 + end + codepoints[starter_pos..j] = (lindex * HANGUL_VCOUNT + vindex) * HANGUL_TCOUNT + tindex + HANGUL_SBASE + end + starter_pos += 1 + starter_char = codepoints[starter_pos] + # -- Other characters + else + current_char = codepoints[pos] + current = database.codepoints[current_char] + if current.combining_class > previous_combining_class + if ref = database.composition_map[starter_char] + composition = ref[current_char] + else + composition = nil + end + unless composition.nil? + codepoints[starter_pos] = composition + starter_char = composition + codepoints.delete_at pos + eoa -= 1 + pos -= 1 + previous_combining_class = -1 + else + previous_combining_class = current.combining_class + end + else + previous_combining_class = current.combining_class + end + if current.combining_class == 0 + starter_pos = pos + starter_char = codepoints[pos] + end + end + end + codepoints + end + + # Ruby >= 2.1 has String#scrub, which is faster than the workaround used for < 2.1. + # Rubinius' String#scrub, however, doesn't support ASCII-incompatible chars. + if '<3'.respond_to?(:scrub) && !defined?(Rubinius) + # Replaces all ISO-8859-1 or CP1252 characters by their UTF-8 equivalent + # resulting in a valid UTF-8 string. + # + # Passing +true+ will forcibly tidy all bytes, assuming that the string's + # encoding is entirely CP1252 or ISO-8859-1. + def tidy_bytes(string, force = false) + return string if string.empty? + return recode_windows1252_chars(string) if force + string.scrub { |bad| recode_windows1252_chars(bad) } + end + else + def tidy_bytes(string, force = false) + return string if string.empty? + return recode_windows1252_chars(string) if force + + # We can't transcode to the same format, so we choose a nearly-identical encoding. + # We're going to 'transcode' bytes from UTF-8 when possible, then fall back to + # CP1252 when we get errors. The final string will be 'converted' back to UTF-8 + # before returning. + reader = Encoding::Converter.new(Encoding::UTF_8, Encoding::UTF_16LE) + + source = string.dup + out = ''.force_encoding(Encoding::UTF_16LE) + + loop do + reader.primitive_convert(source, out) + _, _, _, error_bytes, _ = reader.primitive_errinfo + break if error_bytes.nil? + out << error_bytes.encode(Encoding::UTF_16LE, Encoding::Windows_1252, invalid: :replace, undef: :replace) + end + + reader.finish + + out.encode!(Encoding::UTF_8) + end + end + + # Returns the KC normalization of the string by default. NFKC is + # considered the best normalization form for passing strings to databases + # and validations. + # + # * string - The string to perform normalization on. + # * form - The form you want to normalize in. Should be one of + # the following: :c, :kc, :d, or :kd. + # Default is ActiveSupport::Multibyte.default_normalization_form. + def normalize(string, form=nil) + form ||= @default_normalization_form + # See http://www.unicode.org/reports/tr15, Table 1 + codepoints = string.codepoints.to_a + case form + when :d + reorder_characters(decompose(:canonical, codepoints)) + when :c + compose(reorder_characters(decompose(:canonical, codepoints))) + when :kd + reorder_characters(decompose(:compatibility, codepoints)) + when :kc + compose(reorder_characters(decompose(:compatibility, codepoints))) + else + raise ArgumentError, "#{form} is not a valid normalization variant", caller + end.pack('U*') + end + + def downcase(string) + apply_mapping string, :lowercase_mapping + end + + def upcase(string) + apply_mapping string, :uppercase_mapping + end + + def swapcase(string) + apply_mapping string, :swapcase_mapping + end + + # Holds data about a codepoint in the Unicode database. + class Codepoint + attr_accessor :code, :combining_class, :decomp_type, :decomp_mapping, :uppercase_mapping, :lowercase_mapping + + # Initializing Codepoint object with default values + def initialize + @combining_class = 0 + @uppercase_mapping = 0 + @lowercase_mapping = 0 + end + + def swapcase_mapping + uppercase_mapping > 0 ? uppercase_mapping : lowercase_mapping + end + end + + # Holds static data from the Unicode database. + class UnicodeDatabase + ATTRIBUTES = :codepoints, :composition_exclusion, :composition_map, :boundary, :cp1252 + + attr_writer(*ATTRIBUTES) + + def initialize + @codepoints = Hash.new(Codepoint.new) + @composition_exclusion = [] + @composition_map = {} + @boundary = {} + @cp1252 = {} + end + + # Lazy load the Unicode database so it's only loaded when it's actually used + ATTRIBUTES.each do |attr_name| + class_eval(<<-EOS, __FILE__, __LINE__ + 1) + def #{attr_name} # def codepoints + load # load + @#{attr_name} # @codepoints + end # end + EOS + end + + # Loads the Unicode database and returns all the internal objects of + # UnicodeDatabase. + def load + begin + @codepoints, @composition_exclusion, @composition_map, @boundary, @cp1252 = File.open(self.class.filename, 'rb') { |f| Marshal.load f.read } + rescue => e + raise IOError.new("Couldn't load the Unicode tables for UTF8Handler (#{e.message}), ActiveSupport::Multibyte is unusable") + end + + # Redefine the === method so we can write shorter rules for grapheme cluster breaks + @boundary.each do |k,_| + @boundary[k].instance_eval do + def ===(other) + detect { |i| i === other } ? true : false + end + end if @boundary[k].kind_of?(Array) + end + + # define attr_reader methods for the instance variables + class << self + attr_reader(*ATTRIBUTES) + end + end + + # Returns the directory in which the data files are stored. + def self.dirname + File.dirname(__FILE__) + '/../values/' + end + + # Returns the filename for the data file for this version. + def self.filename + File.expand_path File.join(dirname, "unicode_tables.dat") + end + end + + private + + def apply_mapping(string, mapping) #:nodoc: + database.codepoints + string.each_codepoint.map do |codepoint| + cp = database.codepoints[codepoint] + if cp and (ncp = cp.send(mapping)) and ncp > 0 + ncp + else + codepoint + end + end.pack('U*') + end + + def recode_windows1252_chars(string) + string.encode(Encoding::UTF_8, Encoding::Windows_1252, invalid: :replace, undef: :replace) + end + + def database + @database ||= UnicodeDatabase.new + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/notifications.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/notifications.rb new file mode 100644 index 0000000..b9f8e1a --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/notifications.rb @@ -0,0 +1,212 @@ +require 'active_support/notifications/instrumenter' +require 'active_support/notifications/fanout' +require 'active_support/per_thread_registry' + +module ActiveSupport + # = Notifications + # + # ActiveSupport::Notifications provides an instrumentation API for + # Ruby. + # + # == Instrumenters + # + # To instrument an event you just need to do: + # + # ActiveSupport::Notifications.instrument('render', extra: :information) do + # render text: 'Foo' + # end + # + # That first executes the block and then notifies all subscribers once done. + # + # In the example above +render+ is the name of the event, and the rest is called + # the _payload_. The payload is a mechanism that allows instrumenters to pass + # extra information to subscribers. Payloads consist of a hash whose contents + # are arbitrary and generally depend on the event. + # + # == Subscribers + # + # You can consume those events and the information they provide by registering + # a subscriber. + # + # ActiveSupport::Notifications.subscribe('render') do |name, start, finish, id, payload| + # name # => String, name of the event (such as 'render' from above) + # start # => Time, when the instrumented block started execution + # finish # => Time, when the instrumented block ended execution + # id # => String, unique ID for this notification + # payload # => Hash, the payload + # end + # + # For instance, let's store all "render" events in an array: + # + # events = [] + # + # ActiveSupport::Notifications.subscribe('render') do |*args| + # events << ActiveSupport::Notifications::Event.new(*args) + # end + # + # That code returns right away, you are just subscribing to "render" events. + # The block is saved and will be called whenever someone instruments "render": + # + # ActiveSupport::Notifications.instrument('render', extra: :information) do + # render text: 'Foo' + # end + # + # event = events.first + # event.name # => "render" + # event.duration # => 10 (in milliseconds) + # event.payload # => { extra: :information } + # + # The block in the subscribe call gets the name of the event, start + # timestamp, end timestamp, a string with a unique identifier for that event + # (something like "535801666f04d0298cd6"), and a hash with the payload, in + # that order. + # + # If an exception happens during that particular instrumentation the payload will + # have a key :exception with an array of two elements as value: a string with + # the name of the exception class, and the exception message. + # + # As the previous example depicts, the class ActiveSupport::Notifications::Event + # is able to take the arguments as they come and provide an object-oriented + # interface to that data. + # + # It is also possible to pass an object as the second parameter passed to the + # subscribe method instead of a block: + # + # module ActionController + # class PageRequest + # def call(name, started, finished, unique_id, payload) + # Rails.logger.debug ['notification:', name, started, finished, unique_id, payload].join(' ') + # end + # end + # end + # + # ActiveSupport::Notifications.subscribe('process_action.action_controller', ActionController::PageRequest.new) + # + # resulting in the following output within the logs including a hash with the payload: + # + # notification: process_action.action_controller 2012-04-13 01:08:35 +0300 2012-04-13 01:08:35 +0300 af358ed7fab884532ec7 { + # controller: "Devise::SessionsController", + # action: "new", + # params: {"action"=>"new", "controller"=>"devise/sessions"}, + # format: :html, + # method: "GET", + # path: "/login/sign_in", + # status: 200, + # view_runtime: 279.3080806732178, + # db_runtime: 40.053 + # } + # + # You can also subscribe to all events whose name matches a certain regexp: + # + # ActiveSupport::Notifications.subscribe(/render/) do |*args| + # ... + # end + # + # and even pass no argument to subscribe, in which case you are subscribing + # to all events. + # + # == Temporary Subscriptions + # + # Sometimes you do not want to subscribe to an event for the entire life of + # the application. There are two ways to unsubscribe. + # + # WARNING: The instrumentation framework is designed for long-running subscribers, + # use this feature sparingly because it wipes some internal caches and that has + # a negative impact on performance. + # + # === Subscribe While a Block Runs + # + # You can subscribe to some event temporarily while some block runs. For + # example, in + # + # callback = lambda {|*args| ... } + # ActiveSupport::Notifications.subscribed(callback, "sql.active_record") do + # ... + # end + # + # the callback will be called for all "sql.active_record" events instrumented + # during the execution of the block. The callback is unsubscribed automatically + # after that. + # + # === Manual Unsubscription + # + # The +subscribe+ method returns a subscriber object: + # + # subscriber = ActiveSupport::Notifications.subscribe("render") do |*args| + # ... + # end + # + # To prevent that block from being called anymore, just unsubscribe passing + # that reference: + # + # ActiveSupport::Notifications.unsubscribe(subscriber) + # + # You can also unsubscribe by passing the name of the subscriber object. Note + # that this will unsubscribe all subscriptions with the given name: + # + # ActiveSupport::Notifications.unsubscribe("render") + # + # == Default Queue + # + # Notifications ships with a queue implementation that consumes and publishes events + # to all log subscribers. You can use any queue implementation you want. + # + module Notifications + class << self + attr_accessor :notifier + + def publish(name, *args) + notifier.publish(name, *args) + end + + def instrument(name, payload = {}) + if notifier.listening?(name) + instrumenter.instrument(name, payload) { yield payload if block_given? } + else + yield payload if block_given? + end + end + + def subscribe(*args, &block) + notifier.subscribe(*args, &block) + end + + def subscribed(callback, *args, &block) + subscriber = subscribe(*args, &callback) + yield + ensure + unsubscribe(subscriber) + end + + def unsubscribe(subscriber_or_name) + notifier.unsubscribe(subscriber_or_name) + end + + def instrumenter + InstrumentationRegistry.instance.instrumenter_for(notifier) + end + end + + # This class is a registry which holds all of the +Instrumenter+ objects + # in a particular thread local. To access the +Instrumenter+ object for a + # particular +notifier+, you can call the following method: + # + # InstrumentationRegistry.instrumenter_for(notifier) + # + # The instrumenters for multiple notifiers are held in a single instance of + # this class. + class InstrumentationRegistry # :nodoc: + extend ActiveSupport::PerThreadRegistry + + def initialize + @registry = {} + end + + def instrumenter_for(notifier) + @registry[notifier] ||= Instrumenter.new(notifier) + end + end + + self.notifier = Fanout.new + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/notifications/fanout.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/notifications/fanout.rb new file mode 100644 index 0000000..0131fe2 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/notifications/fanout.rb @@ -0,0 +1,157 @@ +require 'mutex_m' +require 'thread_safe' + +module ActiveSupport + module Notifications + # This is a default queue implementation that ships with Notifications. + # It just pushes events to all registered log subscribers. + # + # This class is thread safe. All methods are reentrant. + class Fanout + include Mutex_m + + def initialize + @subscribers = [] + @listeners_for = ThreadSafe::Cache.new + super + end + + def subscribe(pattern = nil, block = Proc.new) + subscriber = Subscribers.new pattern, block + synchronize do + @subscribers << subscriber + @listeners_for.clear + end + subscriber + end + + def unsubscribe(subscriber_or_name) + synchronize do + case subscriber_or_name + when String + @subscribers.reject! { |s| s.matches?(subscriber_or_name) } + else + @subscribers.delete(subscriber_or_name) + end + + @listeners_for.clear + end + end + + def start(name, id, payload) + listeners_for(name).each { |s| s.start(name, id, payload) } + end + + def finish(name, id, payload) + listeners_for(name).each { |s| s.finish(name, id, payload) } + end + + def publish(name, *args) + listeners_for(name).each { |s| s.publish(name, *args) } + end + + def listeners_for(name) + # this is correctly done double-checked locking (ThreadSafe::Cache's lookups have volatile semantics) + @listeners_for[name] || synchronize do + # use synchronisation when accessing @subscribers + @listeners_for[name] ||= @subscribers.select { |s| s.subscribed_to?(name) } + end + end + + def listening?(name) + listeners_for(name).any? + end + + # This is a sync queue, so there is no waiting. + def wait + end + + module Subscribers # :nodoc: + def self.new(pattern, listener) + if listener.respond_to?(:start) and listener.respond_to?(:finish) + subscriber = Evented.new pattern, listener + else + subscriber = Timed.new pattern, listener + end + + unless pattern + AllMessages.new(subscriber) + else + subscriber + end + end + + class Evented #:nodoc: + def initialize(pattern, delegate) + @pattern = pattern + @delegate = delegate + @can_publish = delegate.respond_to?(:publish) + end + + def publish(name, *args) + if @can_publish + @delegate.publish name, *args + end + end + + def start(name, id, payload) + @delegate.start name, id, payload + end + + def finish(name, id, payload) + @delegate.finish name, id, payload + end + + def subscribed_to?(name) + @pattern === name + end + + def matches?(name) + @pattern && @pattern === name + end + end + + class Timed < Evented # :nodoc: + def publish(name, *args) + @delegate.call name, *args + end + + def start(name, id, payload) + timestack = Thread.current[:_timestack] ||= [] + timestack.push Time.now + end + + def finish(name, id, payload) + timestack = Thread.current[:_timestack] + started = timestack.pop + @delegate.call(name, started, Time.now, id, payload) + end + end + + class AllMessages # :nodoc: + def initialize(delegate) + @delegate = delegate + end + + def start(name, id, payload) + @delegate.start name, id, payload + end + + def finish(name, id, payload) + @delegate.finish name, id, payload + end + + def publish(name, *args) + @delegate.publish name, *args + end + + def subscribed_to?(name) + true + end + + alias :matches? :=== + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/notifications/instrumenter.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/notifications/instrumenter.rb new file mode 100644 index 0000000..3a244b3 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/notifications/instrumenter.rb @@ -0,0 +1,73 @@ +require 'securerandom' + +module ActiveSupport + module Notifications + # Instrumenters are stored in a thread local. + class Instrumenter + attr_reader :id + + def initialize(notifier) + @id = unique_id + @notifier = notifier + end + + # Instrument the given block by measuring the time taken to execute it + # and publish it. Notice that events get sent even if an error occurs + # in the passed-in block. + def instrument(name, payload={}) + start name, payload + begin + yield payload + rescue Exception => e + payload[:exception] = [e.class.name, e.message] + raise e + ensure + finish name, payload + end + end + + # Send a start notification with +name+ and +payload+. + def start(name, payload) + @notifier.start name, @id, payload + end + + # Send a finish notification with +name+ and +payload+. + def finish(name, payload) + @notifier.finish name, @id, payload + end + + private + + def unique_id + SecureRandom.hex(10) + end + end + + class Event + attr_reader :name, :time, :transaction_id, :payload, :children + attr_accessor :end + + def initialize(name, start, ending, transaction_id, payload) + @name = name + @payload = payload.dup + @time = start + @transaction_id = transaction_id + @end = ending + @children = [] + @duration = nil + end + + def duration + @duration ||= 1000.0 * (self.end - time) + end + + def <<(event) + @children << event + end + + def parent_of?(event) + @children.include? event + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/number_helper.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/number_helper.rb new file mode 100644 index 0000000..34439ee --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/number_helper.rb @@ -0,0 +1,345 @@ +module ActiveSupport + module NumberHelper + extend ActiveSupport::Autoload + + eager_autoload do + autoload :NumberConverter + autoload :NumberToRoundedConverter + autoload :NumberToDelimitedConverter + autoload :NumberToHumanConverter + autoload :NumberToHumanSizeConverter + autoload :NumberToPhoneConverter + autoload :NumberToCurrencyConverter + autoload :NumberToPercentageConverter + end + + extend self + + # Formats a +number+ into a US phone number (e.g., (555) + # 123-9876). You can customize the format in the +options+ hash. + # + # ==== Options + # + # * :area_code - Adds parentheses around the area code. + # * :delimiter - Specifies the delimiter to use + # (defaults to "-"). + # * :extension - Specifies an extension to add to the + # end of the generated number. + # * :country_code - Sets the country code for the phone + # number. + # ==== Examples + # + # number_to_phone(5551234) # => 555-1234 + # number_to_phone('5551234') # => 555-1234 + # number_to_phone(1235551234) # => 123-555-1234 + # number_to_phone(1235551234, area_code: true) # => (123) 555-1234 + # number_to_phone(1235551234, delimiter: ' ') # => 123 555 1234 + # number_to_phone(1235551234, area_code: true, extension: 555) # => (123) 555-1234 x 555 + # number_to_phone(1235551234, country_code: 1) # => +1-123-555-1234 + # number_to_phone('123a456') # => 123a456 + # + # number_to_phone(1235551234, country_code: 1, extension: 1343, delimiter: '.') + # # => +1.123.555.1234 x 1343 + def number_to_phone(number, options = {}) + NumberToPhoneConverter.convert(number, options) + end + + # Formats a +number+ into a currency string (e.g., $13.65). You + # can customize the format in the +options+ hash. + # + # ==== Options + # + # * :locale - Sets the locale to be used for formatting + # (defaults to current locale). + # * :precision - Sets the level of precision (defaults + # to 2). + # * :unit - Sets the denomination of the currency + # (defaults to "$"). + # * :separator - Sets the separator between the units + # (defaults to "."). + # * :delimiter - Sets the thousands delimiter (defaults + # to ","). + # * :format - Sets the format for non-negative numbers + # (defaults to "%u%n"). Fields are %u for the + # currency, and %n for the number. + # * :negative_format - Sets the format for negative + # numbers (defaults to prepending an hyphen to the formatted + # number given by :format). Accepts the same fields + # than :format, except %n is here the + # absolute value of the number. + # + # ==== Examples + # + # number_to_currency(1234567890.50) # => $1,234,567,890.50 + # number_to_currency(1234567890.506) # => $1,234,567,890.51 + # number_to_currency(1234567890.506, precision: 3) # => $1,234,567,890.506 + # number_to_currency(1234567890.506, locale: :fr) # => 1 234 567 890,51 € + # number_to_currency('123a456') # => $123a456 + # + # number_to_currency(-1234567890.50, negative_format: '(%u%n)') + # # => ($1,234,567,890.50) + # number_to_currency(1234567890.50, unit: '£', separator: ',', delimiter: '') + # # => £1234567890,50 + # number_to_currency(1234567890.50, unit: '£', separator: ',', delimiter: '', format: '%n %u') + # # => 1234567890,50 £ + def number_to_currency(number, options = {}) + NumberToCurrencyConverter.convert(number, options) + end + + # Formats a +number+ as a percentage string (e.g., 65%). You can + # customize the format in the +options+ hash. + # + # ==== Options + # + # * :locale - Sets the locale to be used for formatting + # (defaults to current locale). + # * :precision - Sets the precision of the number + # (defaults to 3). + # * :significant - If +true+, precision will be the # + # of significant_digits. If +false+, the # of fractional + # digits (defaults to +false+). + # * :separator - Sets the separator between the + # fractional and integer digits (defaults to "."). + # * :delimiter - Sets the thousands delimiter (defaults + # to ""). + # * :strip_insignificant_zeros - If +true+ removes + # insignificant zeros after the decimal separator (defaults to + # +false+). + # * :format - Specifies the format of the percentage + # string The number field is %n (defaults to "%n%"). + # + # ==== Examples + # + # number_to_percentage(100) # => 100.000% + # number_to_percentage('98') # => 98.000% + # number_to_percentage(100, precision: 0) # => 100% + # number_to_percentage(1000, delimiter: '.', separator: ',') # => 1.000,000% + # number_to_percentage(302.24398923423, precision: 5) # => 302.24399% + # number_to_percentage(1000, locale: :fr) # => 1 000,000% + # number_to_percentage('98a') # => 98a% + # number_to_percentage(100, format: '%n %') # => 100 % + def number_to_percentage(number, options = {}) + NumberToPercentageConverter.convert(number, options) + end + + # Formats a +number+ with grouped thousands using +delimiter+ + # (e.g., 12,324). You can customize the format in the +options+ + # hash. + # + # ==== Options + # + # * :locale - Sets the locale to be used for formatting + # (defaults to current locale). + # * :delimiter - Sets the thousands delimiter (defaults + # to ","). + # * :separator - Sets the separator between the + # fractional and integer digits (defaults to "."). + # + # ==== Examples + # + # number_to_delimited(12345678) # => 12,345,678 + # number_to_delimited('123456') # => 123,456 + # number_to_delimited(12345678.05) # => 12,345,678.05 + # number_to_delimited(12345678, delimiter: '.') # => 12.345.678 + # number_to_delimited(12345678, delimiter: ',') # => 12,345,678 + # number_to_delimited(12345678.05, separator: ' ') # => 12,345,678 05 + # number_to_delimited(12345678.05, locale: :fr) # => 12 345 678,05 + # number_to_delimited('112a') # => 112a + # number_to_delimited(98765432.98, delimiter: ' ', separator: ',') + # # => 98 765 432,98 + def number_to_delimited(number, options = {}) + NumberToDelimitedConverter.convert(number, options) + end + + # Formats a +number+ with the specified level of + # :precision (e.g., 112.32 has a precision of 2 if + # +:significant+ is +false+, and 5 if +:significant+ is +true+). + # You can customize the format in the +options+ hash. + # + # ==== Options + # + # * :locale - Sets the locale to be used for formatting + # (defaults to current locale). + # * :precision - Sets the precision of the number + # (defaults to 3). + # * :significant - If +true+, precision will be the # + # of significant_digits. If +false+, the # of fractional + # digits (defaults to +false+). + # * :separator - Sets the separator between the + # fractional and integer digits (defaults to "."). + # * :delimiter - Sets the thousands delimiter (defaults + # to ""). + # * :strip_insignificant_zeros - If +true+ removes + # insignificant zeros after the decimal separator (defaults to + # +false+). + # + # ==== Examples + # + # number_to_rounded(111.2345) # => 111.235 + # number_to_rounded(111.2345, precision: 2) # => 111.23 + # number_to_rounded(13, precision: 5) # => 13.00000 + # number_to_rounded(389.32314, precision: 0) # => 389 + # number_to_rounded(111.2345, significant: true) # => 111 + # number_to_rounded(111.2345, precision: 1, significant: true) # => 100 + # number_to_rounded(13, precision: 5, significant: true) # => 13.000 + # number_to_rounded(111.234, locale: :fr) # => 111,234 + # + # number_to_rounded(13, precision: 5, significant: true, strip_insignificant_zeros: true) + # # => 13 + # + # number_to_rounded(389.32314, precision: 4, significant: true) # => 389.3 + # number_to_rounded(1111.2345, precision: 2, separator: ',', delimiter: '.') + # # => 1.111,23 + def number_to_rounded(number, options = {}) + NumberToRoundedConverter.convert(number, options) + end + + # Formats the bytes in +number+ into a more understandable + # representation (e.g., giving it 1500 yields 1.5 KB). This + # method is useful for reporting file sizes to users. You can + # customize the format in the +options+ hash. + # + # See number_to_human if you want to pretty-print a + # generic number. + # + # ==== Options + # + # * :locale - Sets the locale to be used for formatting + # (defaults to current locale). + # * :precision - Sets the precision of the number + # (defaults to 3). + # * :significant - If +true+, precision will be the # + # of significant_digits. If +false+, the # of fractional + # digits (defaults to +true+) + # * :separator - Sets the separator between the + # fractional and integer digits (defaults to "."). + # * :delimiter - Sets the thousands delimiter (defaults + # to ""). + # * :strip_insignificant_zeros - If +true+ removes + # insignificant zeros after the decimal separator (defaults to + # +true+) + # * :prefix - If +:si+ formats the number using the SI + # prefix (defaults to :binary) + # + # ==== Examples + # + # number_to_human_size(123) # => 123 Bytes + # number_to_human_size(1234) # => 1.21 KB + # number_to_human_size(12345) # => 12.1 KB + # number_to_human_size(1234567) # => 1.18 MB + # number_to_human_size(1234567890) # => 1.15 GB + # number_to_human_size(1234567890123) # => 1.12 TB + # number_to_human_size(1234567, precision: 2) # => 1.2 MB + # number_to_human_size(483989, precision: 2) # => 470 KB + # number_to_human_size(1234567, precision: 2, separator: ',') # => 1,2 MB + # number_to_human_size(1234567890123, precision: 5) # => "1.1228 TB" + # number_to_human_size(524288000, precision: 5) # => "500 MB" + def number_to_human_size(number, options = {}) + NumberToHumanSizeConverter.convert(number, options) + end + + # Pretty prints (formats and approximates) a number in a way it + # is more readable by humans (eg.: 1200000000 becomes "1.2 + # Billion"). This is useful for numbers that can get very large + # (and too hard to read). + # + # See number_to_human_size if you want to print a file + # size. + # + # You can also define your own unit-quantifier names if you want + # to use other decimal units (eg.: 1500 becomes "1.5 + # kilometers", 0.150 becomes "150 milliliters", etc). You may + # define a wide range of unit quantifiers, even fractional ones + # (centi, deci, mili, etc). + # + # ==== Options + # + # * :locale - Sets the locale to be used for formatting + # (defaults to current locale). + # * :precision - Sets the precision of the number + # (defaults to 3). + # * :significant - If +true+, precision will be the # + # of significant_digits. If +false+, the # of fractional + # digits (defaults to +true+) + # * :separator - Sets the separator between the + # fractional and integer digits (defaults to "."). + # * :delimiter - Sets the thousands delimiter (defaults + # to ""). + # * :strip_insignificant_zeros - If +true+ removes + # insignificant zeros after the decimal separator (defaults to + # +true+) + # * :units - A Hash of unit quantifier names. Or a + # string containing an i18n scope where to find this hash. It + # might have the following keys: + # * *integers*: :unit, :ten, + # :hundred, :thousand, :million, + # :billion, :trillion, + # :quadrillion + # * *fractionals*: :deci, :centi, + # :mili, :micro, :nano, + # :pico, :femto + # * :format - Sets the format of the output string + # (defaults to "%n %u"). The field types are: + # * %u - The quantifier (ex.: 'thousand') + # * %n - The number + # + # ==== Examples + # + # number_to_human(123) # => "123" + # number_to_human(1234) # => "1.23 Thousand" + # number_to_human(12345) # => "12.3 Thousand" + # number_to_human(1234567) # => "1.23 Million" + # number_to_human(1234567890) # => "1.23 Billion" + # number_to_human(1234567890123) # => "1.23 Trillion" + # number_to_human(1234567890123456) # => "1.23 Quadrillion" + # number_to_human(1234567890123456789) # => "1230 Quadrillion" + # number_to_human(489939, precision: 2) # => "490 Thousand" + # number_to_human(489939, precision: 4) # => "489.9 Thousand" + # number_to_human(1234567, precision: 4, + # significant: false) # => "1.2346 Million" + # number_to_human(1234567, precision: 1, + # separator: ',', + # significant: false) # => "1,2 Million" + # + # number_to_human(500000000, precision: 5) # => "500 Million" + # number_to_human(12345012345, significant: false) # => "12.345 Billion" + # + # Non-significant zeros after the decimal separator are stripped + # out by default (set :strip_insignificant_zeros to + # +false+ to change that): + # + # number_to_human(12.00001) # => "12" + # number_to_human(12.00001, strip_insignificant_zeros: false) # => "12.0" + # + # ==== Custom Unit Quantifiers + # + # You can also use your own custom unit quantifiers: + # number_to_human(500000, units: { unit: 'ml', thousand: 'lt' }) # => "500 lt" + # + # If in your I18n locale you have: + # + # distance: + # centi: + # one: "centimeter" + # other: "centimeters" + # unit: + # one: "meter" + # other: "meters" + # thousand: + # one: "kilometer" + # other: "kilometers" + # billion: "gazillion-distance" + # + # Then you could do: + # + # number_to_human(543934, units: :distance) # => "544 kilometers" + # number_to_human(54393498, units: :distance) # => "54400 kilometers" + # number_to_human(54393498000, units: :distance) # => "54.4 gazillion-distance" + # number_to_human(343, units: :distance, precision: 1) # => "300 meters" + # number_to_human(1, units: :distance) # => "1 meter" + # number_to_human(0.34, units: :distance) # => "34 centimeters" + def number_to_human(number, options = {}) + NumberToHumanConverter.convert(number, options) + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/number_helper/number_converter.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/number_helper/number_converter.rb new file mode 100644 index 0000000..9d976f1 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/number_helper/number_converter.rb @@ -0,0 +1,182 @@ +require 'active_support/core_ext/big_decimal/conversions' +require 'active_support/core_ext/object/blank' +require 'active_support/core_ext/hash/keys' +require 'active_support/i18n' +require 'active_support/core_ext/class/attribute' + +module ActiveSupport + module NumberHelper + class NumberConverter # :nodoc: + # Default and i18n option namespace per class + class_attribute :namespace + + # Does the object need a number that is a valid float? + class_attribute :validate_float + + attr_reader :number, :opts + + DEFAULTS = { + # Used in number_to_delimited + # These are also the defaults for 'currency', 'percentage', 'precision', and 'human' + format: { + # Sets the separator between the units, for more precision (e.g. 1.0 / 2.0 == 0.5) + separator: ".", + # Delimits thousands (e.g. 1,000,000 is a million) (always in groups of three) + delimiter: ",", + # Number of decimals, behind the separator (the number 1 with a precision of 2 gives: 1.00) + precision: 3, + # If set to true, precision will mean the number of significant digits instead + # of the number of decimal digits (1234 with precision 2 becomes 1200, 1.23543 becomes 1.2) + significant: false, + # If set, the zeros after the decimal separator will always be stripped (eg.: 1.200 will be 1.2) + strip_insignificant_zeros: false + }, + + # Used in number_to_currency + currency: { + format: { + format: "%u%n", + negative_format: "-%u%n", + unit: "$", + # These five are to override number.format and are optional + separator: ".", + delimiter: ",", + precision: 2, + significant: false, + strip_insignificant_zeros: false + } + }, + + # Used in number_to_percentage + percentage: { + format: { + delimiter: "", + format: "%n%" + } + }, + + # Used in number_to_rounded + precision: { + format: { + delimiter: "" + } + }, + + # Used in number_to_human_size and number_to_human + human: { + format: { + # These five are to override number.format and are optional + delimiter: "", + precision: 3, + significant: true, + strip_insignificant_zeros: true + }, + # Used in number_to_human_size + storage_units: { + # Storage units output formatting. + # %u is the storage unit, %n is the number (default: 2 MB) + format: "%n %u", + units: { + byte: "Bytes", + kb: "KB", + mb: "MB", + gb: "GB", + tb: "TB" + } + }, + # Used in number_to_human + decimal_units: { + format: "%n %u", + # Decimal units output formatting + # By default we will only quantify some of the exponents + # but the commented ones might be defined or overridden + # by the user. + units: { + # femto: Quadrillionth + # pico: Trillionth + # nano: Billionth + # micro: Millionth + # mili: Thousandth + # centi: Hundredth + # deci: Tenth + unit: "", + # ten: + # one: Ten + # other: Tens + # hundred: Hundred + thousand: "Thousand", + million: "Million", + billion: "Billion", + trillion: "Trillion", + quadrillion: "Quadrillion" + } + } + } + } + + def self.convert(number, options) + new(number, options).execute + end + + def initialize(number, options) + @number = number + @opts = options.symbolize_keys + end + + def execute + if !number + nil + elsif validate_float? && !valid_float? + number + else + convert + end + end + + private + + def options + @options ||= format_options.merge(opts) + end + + def format_options #:nodoc: + default_format_options.merge!(i18n_format_options) + end + + def default_format_options #:nodoc: + options = DEFAULTS[:format].dup + options.merge!(DEFAULTS[namespace][:format]) if namespace + options + end + + def i18n_format_options #:nodoc: + locale = opts[:locale] + options = I18n.translate(:'number.format', locale: locale, default: {}).dup + + if namespace + options.merge!(I18n.translate(:"number.#{namespace}.format", locale: locale, default: {})) + end + + options + end + + def translate_number_value_with_default(key, i18n_options = {}) #:nodoc: + I18n.translate(key, { default: default_value(key), scope: :number }.merge!(i18n_options)) + end + + def translate_in_locale(key, i18n_options = {}) + translate_number_value_with_default(key, { locale: options[:locale] }.merge(i18n_options)) + end + + def default_value(key) + key.split('.').reduce(DEFAULTS) { |defaults, k| defaults[k.to_sym] } + end + + def valid_float? #:nodoc: + Float(number) + rescue ArgumentError, TypeError + false + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/number_helper/number_to_currency_converter.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/number_helper/number_to_currency_converter.rb new file mode 100644 index 0000000..fb5adb5 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/number_helper/number_to_currency_converter.rb @@ -0,0 +1,46 @@ +module ActiveSupport + module NumberHelper + class NumberToCurrencyConverter < NumberConverter # :nodoc: + self.namespace = :currency + + def convert + number = self.number.to_s.strip + format = options[:format] + + if is_negative?(number) + format = options[:negative_format] + number = absolute_value(number) + end + + rounded_number = NumberToRoundedConverter.convert(number, options) + format.gsub(/%n/, rounded_number).gsub(/%u/, options[:unit]) + end + + private + + def is_negative?(number) + number.to_f.phase != 0 + end + + def absolute_value(number) + number.respond_to?("abs") ? number.abs : number.sub(/\A-/, '') + end + + def options + @options ||= begin + defaults = default_format_options.merge(i18n_opts) + # Override negative format if format options is given + defaults[:negative_format] = "-#{opts[:format]}" if opts[:format] + defaults.merge!(opts) + end + end + + def i18n_opts + # Set International negative format if not exists + i18n = i18n_format_options + i18n[:negative_format] ||= "-#{i18n[:format]}" if i18n[:format] + i18n + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/number_helper/number_to_delimited_converter.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/number_helper/number_to_delimited_converter.rb new file mode 100644 index 0000000..d85cc08 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/number_helper/number_to_delimited_converter.rb @@ -0,0 +1,23 @@ +module ActiveSupport + module NumberHelper + class NumberToDelimitedConverter < NumberConverter #:nodoc: + self.validate_float = true + + DELIMITED_REGEX = /(\d)(?=(\d\d\d)+(?!\d))/ + + def convert + parts.join(options[:separator]) + end + + private + + def parts + left, right = number.to_s.split('.') + left.gsub!(DELIMITED_REGEX) do |digit_to_delimit| + "#{digit_to_delimit}#{options[:delimiter]}" + end + [left, right].compact + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/number_helper/number_to_human_converter.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/number_helper/number_to_human_converter.rb new file mode 100644 index 0000000..9a3dc52 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/number_helper/number_to_human_converter.rb @@ -0,0 +1,66 @@ +module ActiveSupport + module NumberHelper + class NumberToHumanConverter < NumberConverter # :nodoc: + DECIMAL_UNITS = { 0 => :unit, 1 => :ten, 2 => :hundred, 3 => :thousand, 6 => :million, 9 => :billion, 12 => :trillion, 15 => :quadrillion, + -1 => :deci, -2 => :centi, -3 => :mili, -6 => :micro, -9 => :nano, -12 => :pico, -15 => :femto } + INVERTED_DECIMAL_UNITS = DECIMAL_UNITS.invert + + self.namespace = :human + self.validate_float = true + + def convert # :nodoc: + @number = Float(number) + + # for backwards compatibility with those that didn't add strip_insignificant_zeros to their locale files + unless options.key?(:strip_insignificant_zeros) + options[:strip_insignificant_zeros] = true + end + + units = opts[:units] + exponent = calculate_exponent(units) + @number = number / (10 ** exponent) + + unit = determine_unit(units, exponent) + + rounded_number = NumberToRoundedConverter.convert(number, options) + format.gsub(/%n/, rounded_number).gsub(/%u/, unit).strip + end + + private + + def format + options[:format] || translate_in_locale('human.decimal_units.format') + end + + def determine_unit(units, exponent) + exp = DECIMAL_UNITS[exponent] + case units + when Hash + units[exp] || '' + when String, Symbol + I18n.translate("#{units}.#{exp}", :locale => options[:locale], :count => number.to_i) + else + translate_in_locale("human.decimal_units.units.#{exp}", count: number.to_i) + end + end + + def calculate_exponent(units) + exponent = number != 0 ? Math.log10(number.abs).floor : 0 + unit_exponents(units).find { |e| exponent >= e } || 0 + end + + def unit_exponents(units) + case units + when Hash + units + when String, Symbol + I18n.translate(units.to_s, :locale => options[:locale], :raise => true) + when nil + translate_in_locale("human.decimal_units.units", raise: true) + else + raise ArgumentError, ":units must be a Hash or String translation scope." + end.keys.map { |e_name| INVERTED_DECIMAL_UNITS[e_name] }.sort_by { |e| -e } + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/number_helper/number_to_human_size_converter.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/number_helper/number_to_human_size_converter.rb new file mode 100644 index 0000000..78d2c9a --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/number_helper/number_to_human_size_converter.rb @@ -0,0 +1,58 @@ +module ActiveSupport + module NumberHelper + class NumberToHumanSizeConverter < NumberConverter #:nodoc: + STORAGE_UNITS = [:byte, :kb, :mb, :gb, :tb] + + self.namespace = :human + self.validate_float = true + + def convert + @number = Float(number) + + # for backwards compatibility with those that didn't add strip_insignificant_zeros to their locale files + unless options.key?(:strip_insignificant_zeros) + options[:strip_insignificant_zeros] = true + end + + if smaller_than_base? + number_to_format = number.to_i.to_s + else + human_size = number / (base ** exponent) + number_to_format = NumberToRoundedConverter.convert(human_size, options) + end + conversion_format.gsub(/%n/, number_to_format).gsub(/%u/, unit) + end + + private + + def conversion_format + translate_number_value_with_default('human.storage_units.format', :locale => options[:locale], :raise => true) + end + + def unit + translate_number_value_with_default(storage_unit_key, :locale => options[:locale], :count => number.to_i, :raise => true) + end + + def storage_unit_key + key_end = smaller_than_base? ? 'byte' : STORAGE_UNITS[exponent] + "human.storage_units.units.#{key_end}" + end + + def exponent + max = STORAGE_UNITS.size - 1 + exp = (Math.log(number) / Math.log(base)).to_i + exp = max if exp > max # avoid overflow for the highest unit + exp + end + + def smaller_than_base? + number.to_i < base + end + + def base + opts[:prefix] == :si ? 1000 : 1024 + end + end + end +end + diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/number_helper/number_to_percentage_converter.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/number_helper/number_to_percentage_converter.rb new file mode 100644 index 0000000..1af294a --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/number_helper/number_to_percentage_converter.rb @@ -0,0 +1,12 @@ +module ActiveSupport + module NumberHelper + class NumberToPercentageConverter < NumberConverter # :nodoc: + self.namespace = :percentage + + def convert + rounded_number = NumberToRoundedConverter.convert(number, options) + options[:format].gsub(/%n/, rounded_number) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/number_helper/number_to_phone_converter.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/number_helper/number_to_phone_converter.rb new file mode 100644 index 0000000..af2ee56 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/number_helper/number_to_phone_converter.rb @@ -0,0 +1,49 @@ +module ActiveSupport + module NumberHelper + class NumberToPhoneConverter < NumberConverter #:nodoc: + def convert + str = country_code(opts[:country_code]) + str << convert_to_phone_number(number.to_s.strip) + str << phone_ext(opts[:extension]) + end + + private + + def convert_to_phone_number(number) + if opts[:area_code] + convert_with_area_code(number) + else + convert_without_area_code(number) + end + end + + def convert_with_area_code(number) + number.gsub!(/(\d{1,3})(\d{3})(\d{4}$)/,"(\\1) \\2#{delimiter}\\3") + number + end + + def convert_without_area_code(number) + number.gsub!(/(\d{0,3})(\d{3})(\d{4})$/,"\\1#{delimiter}\\2#{delimiter}\\3") + number.slice!(0, 1) if start_with_delimiter?(number) + number + end + + def start_with_delimiter?(number) + delimiter.present? && number.start_with?(delimiter) + end + + def delimiter + opts[:delimiter] || "-" + end + + def country_code(code) + code.blank? ? "" : "+#{code}#{delimiter}" + end + + def phone_ext(ext) + ext.blank? ? "" : " x #{ext}" + end + end + end +end + diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/number_helper/number_to_rounded_converter.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/number_helper/number_to_rounded_converter.rb new file mode 100644 index 0000000..65e9b35 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/number_helper/number_to_rounded_converter.rb @@ -0,0 +1,87 @@ +module ActiveSupport + module NumberHelper + class NumberToRoundedConverter < NumberConverter # :nodoc: + self.namespace = :precision + self.validate_float = true + + def convert + precision = options.delete :precision + significant = options.delete :significant + + case number + when Float, String + @number = BigDecimal(number.to_s) + when Rational + @number = BigDecimal(number, digit_count(number.to_i) + precision) + else + @number = number.to_d + end + + if significant && precision > 0 + digits, rounded_number = digits_and_rounded_number(precision) + precision -= digits + precision = 0 if precision < 0 # don't let it be negative + else + rounded_number = number.round(precision) + rounded_number = rounded_number.to_i if precision == 0 && rounded_number.finite? + rounded_number = rounded_number.abs if rounded_number.zero? # prevent showing negative zeros + end + + formatted_string = + if BigDecimal === rounded_number && rounded_number.finite? + s = rounded_number.to_s('F') + '0'*precision + a, b = s.split('.', 2) + a + '.' + b[0, precision] + else + "%00.#{precision}f" % rounded_number + end + + delimited_number = NumberToDelimitedConverter.convert(formatted_string, options) + format_number(delimited_number) + end + + private + + def digits_and_rounded_number(precision) + if zero? + [1, 0] + else + digits = digit_count(number) + multiplier = 10 ** (digits - precision) + rounded_number = calculate_rounded_number(multiplier) + digits = digit_count(rounded_number) # After rounding, the number of digits may have changed + [digits, rounded_number] + end + end + + def calculate_rounded_number(multiplier) + (number / BigDecimal.new(multiplier.to_f.to_s)).round * multiplier + end + + def digit_count(number) + number.zero? ? 1 : (Math.log10(absolute_number(number)) + 1).floor + end + + def strip_insignificant_zeros + options[:strip_insignificant_zeros] + end + + def format_number(number) + if strip_insignificant_zeros + escaped_separator = Regexp.escape(options[:separator]) + number.sub(/(#{escaped_separator})(\d*[1-9])?0+\z/, '\1\2').sub(/#{escaped_separator}\z/, '') + else + number + end + end + + def absolute_number(number) + number.respond_to?(:abs) ? number.abs : number.to_d.abs + end + + def zero? + number.respond_to?(:zero?) ? number.zero? : number.to_d.zero? + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/option_merger.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/option_merger.rb new file mode 100644 index 0000000..dea84e4 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/option_merger.rb @@ -0,0 +1,25 @@ +require 'active_support/core_ext/hash/deep_merge' + +module ActiveSupport + class OptionMerger #:nodoc: + instance_methods.each do |method| + undef_method(method) if method !~ /^(__|instance_eval|class|object_id)/ + end + + def initialize(context, options) + @context, @options = context, options + end + + private + def method_missing(method, *arguments, &block) + if arguments.first.is_a?(Proc) + proc = arguments.pop + arguments << lambda { |*args| @options.deep_merge(proc.call(*args)) } + else + arguments << (arguments.last.respond_to?(:to_hash) ? @options.deep_merge(arguments.pop) : @options.dup) + end + + @context.__send__(method, *arguments, &block) + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/ordered_hash.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/ordered_hash.rb new file mode 100644 index 0000000..4680d5a --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/ordered_hash.rb @@ -0,0 +1,48 @@ +require 'yaml' + +YAML.add_builtin_type("omap") do |type, val| + ActiveSupport::OrderedHash[val.map{ |v| v.to_a.first }] +end + +module ActiveSupport + # ActiveSupport::OrderedHash implements a hash that preserves + # insertion order. + # + # oh = ActiveSupport::OrderedHash.new + # oh[:a] = 1 + # oh[:b] = 2 + # oh.keys # => [:a, :b], this order is guaranteed + # + # Also, maps the +omap+ feature for YAML files + # (See http://yaml.org/type/omap.html) to support ordered items + # when loading from yaml. + # + # ActiveSupport::OrderedHash is namespaced to prevent conflicts + # with other implementations. + class OrderedHash < ::Hash + def to_yaml_type + "!tag:yaml.org,2002:omap" + end + + def encode_with(coder) + coder.represent_seq '!omap', map { |k,v| { k => v } } + end + + def select(*args, &block) + dup.tap { |hash| hash.select!(*args, &block) } + end + + def reject(*args, &block) + dup.tap { |hash| hash.reject!(*args, &block) } + end + + def nested_under_indifferent_access + self + end + + # Returns true to make sure that this hash is extractable via Array#extract_options! + def extractable_options? + true + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/ordered_options.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/ordered_options.rb new file mode 100644 index 0000000..a33e2c5 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/ordered_options.rb @@ -0,0 +1,67 @@ +module ActiveSupport + # Usually key value pairs are handled something like this: + # + # h = {} + # h[:boy] = 'John' + # h[:girl] = 'Mary' + # h[:boy] # => 'John' + # h[:girl] # => 'Mary' + # + # Using +OrderedOptions+, the above code could be reduced to: + # + # h = ActiveSupport::OrderedOptions.new + # h.boy = 'John' + # h.girl = 'Mary' + # h.boy # => 'John' + # h.girl # => 'Mary' + class OrderedOptions < Hash + alias_method :_get, :[] # preserve the original #[] method + protected :_get # make it protected + + def []=(key, value) + super(key.to_sym, value) + end + + def [](key) + super(key.to_sym) + end + + def method_missing(name, *args) + name_string = name.to_s + if name_string.chomp!('=') + self[name_string] = args.first + else + self[name] + end + end + + def respond_to_missing?(name, include_private) + true + end + end + + # +InheritableOptions+ provides a constructor to build an +OrderedOptions+ + # hash inherited from another hash. + # + # Use this if you already have some hash and you want to create a new one based on it. + # + # h = ActiveSupport::InheritableOptions.new({ girl: 'Mary', boy: 'John' }) + # h.girl # => 'Mary' + # h.boy # => 'John' + class InheritableOptions < OrderedOptions + def initialize(parent = nil) + if parent.kind_of?(OrderedOptions) + # use the faster _get when dealing with OrderedOptions + super() { |h,k| parent._get(k) } + elsif parent + super() { |h,k| parent[k] } + else + super() + end + end + + def inheritable_copy + self.class.new(self) + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/per_thread_registry.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/per_thread_registry.rb new file mode 100644 index 0000000..a909a65 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/per_thread_registry.rb @@ -0,0 +1,55 @@ +require 'active_support/core_ext/module/delegation' + +module ActiveSupport + # This module is used to encapsulate access to thread local variables. + # + # Instead of polluting the thread locals namespace: + # + # Thread.current[:connection_handler] + # + # you define a class that extends this module: + # + # module ActiveRecord + # class RuntimeRegistry + # extend ActiveSupport::PerThreadRegistry + # + # attr_accessor :connection_handler + # end + # end + # + # and invoke the declared instance accessors as class methods. So + # + # ActiveRecord::RuntimeRegistry.connection_handler = connection_handler + # + # sets a connection handler local to the current thread, and + # + # ActiveRecord::RuntimeRegistry.connection_handler + # + # returns a connection handler local to the current thread. + # + # This feature is accomplished by instantiating the class and storing the + # instance as a thread local keyed by the class name. In the example above + # a key "ActiveRecord::RuntimeRegistry" is stored in Thread.current. + # The class methods proxy to said thread local instance. + # + # If the class has an initializer, it must accept no arguments. + module PerThreadRegistry + def self.extended(object) + object.instance_variable_set '@per_thread_registry_key', object.name.freeze + end + + def instance + Thread.current[@per_thread_registry_key] ||= new + end + + protected + def method_missing(name, *args, &block) # :nodoc: + # Caches the method definition as a singleton method of the receiver. + # + # By letting #delegate handle it, we avoid an enclosure that'll capture args. + singleton_class.delegate name, to: :instance + + send(name, *args, &block) + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/proxy_object.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/proxy_object.rb new file mode 100644 index 0000000..20a0fd8 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/proxy_object.rb @@ -0,0 +1,13 @@ +module ActiveSupport + # A class with no predefined methods that behaves similarly to Builder's + # BlankSlate. Used for proxy classes. + class ProxyObject < ::BasicObject + undef_method :== + undef_method :equal? + + # Let ActiveSupport::ProxyObject at least raise exceptions. + def raise(*args) + ::Object.send(:raise, *args) + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/rails.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/rails.rb new file mode 100644 index 0000000..b05c3ff --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/rails.rb @@ -0,0 +1,27 @@ +# This is private interface. +# +# Rails components cherry pick from Active Support as needed, but there are a +# few features that are used for sure some way or another and it is not worth +# to put individual requires absolutely everywhere. Think blank? for example. +# +# This file is loaded by every Rails component except Active Support itself, +# but it does not belong to the Rails public interface. It is internal to +# Rails and can change anytime. + +# Defines Object#blank? and Object#present?. +require 'active_support/core_ext/object/blank' + +# Rails own autoload, eager_load, etc. +require 'active_support/dependencies/autoload' + +# Support for ClassMethods and the included macro. +require 'active_support/concern' + +# Defines Class#class_attribute. +require 'active_support/core_ext/class/attribute' + +# Defines Module#delegate. +require 'active_support/core_ext/module/delegation' + +# Defines ActiveSupport::Deprecation. +require 'active_support/deprecation' diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/railtie.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/railtie.rb new file mode 100644 index 0000000..133aa6a --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/railtie.rb @@ -0,0 +1,46 @@ +require "active_support" +require "active_support/i18n_railtie" + +module ActiveSupport + class Railtie < Rails::Railtie # :nodoc: + config.active_support = ActiveSupport::OrderedOptions.new + + config.eager_load_namespaces << ActiveSupport + + initializer "active_support.deprecation_behavior" do |app| + if deprecation = app.config.active_support.deprecation + ActiveSupport::Deprecation.behavior = deprecation + end + end + + # Sets the default value for Time.zone + # If assigned value cannot be matched to a TimeZone, an exception will be raised. + initializer "active_support.initialize_time_zone" do |app| + require 'active_support/core_ext/time/zones' + zone_default = Time.find_zone!(app.config.time_zone) + + unless zone_default + raise 'Value assigned to config.time_zone not recognized. ' \ + 'Run "rake -D time" for a list of tasks for finding appropriate time zone names.' + end + + Time.zone_default = zone_default + end + + # Sets the default week start + # If assigned value is not a valid day symbol (e.g. :sunday, :monday, ...), an exception will be raised. + initializer "active_support.initialize_beginning_of_week" do |app| + require 'active_support/core_ext/date/calculations' + beginning_of_week_default = Date.find_beginning_of_week!(app.config.beginning_of_week) + + Date.beginning_of_week_default = beginning_of_week_default + end + + initializer "active_support.set_configs" do |app| + app.config.active_support.each do |k, v| + k = "#{k}=" + ActiveSupport.send(k, v) if ActiveSupport.respond_to? k + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/rescuable.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/rescuable.rb new file mode 100644 index 0000000..a7eba91 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/rescuable.rb @@ -0,0 +1,119 @@ +require 'active_support/concern' +require 'active_support/core_ext/class/attribute' +require 'active_support/core_ext/string/inflections' +require 'active_support/core_ext/array/extract_options' + +module ActiveSupport + # Rescuable module adds support for easier exception handling. + module Rescuable + extend Concern + + included do + class_attribute :rescue_handlers + self.rescue_handlers = [] + end + + module ClassMethods + # Rescue exceptions raised in controller actions. + # + # rescue_from receives a series of exception classes or class + # names, and a trailing :with option with the name of a method + # or a Proc object to be called to handle them. Alternatively a block can + # be given. + # + # Handlers that take one argument will be called with the exception, so + # that the exception can be inspected when dealing with it. + # + # Handlers are inherited. They are searched from right to left, from + # bottom to top, and up the hierarchy. The handler of the first class for + # which exception.is_a?(klass) holds true is the one invoked, if + # any. + # + # class ApplicationController < ActionController::Base + # rescue_from User::NotAuthorized, with: :deny_access # self defined exception + # rescue_from ActiveRecord::RecordInvalid, with: :show_errors + # + # rescue_from 'MyAppError::Base' do |exception| + # render xml: exception, status: 500 + # end + # + # protected + # def deny_access + # ... + # end + # + # def show_errors(exception) + # exception.record.new_record? ? ... + # end + # end + # + # Exceptions raised inside exception handlers are not propagated up. + def rescue_from(*klasses, &block) + options = klasses.extract_options! + + unless options.has_key?(:with) + if block_given? + options[:with] = block + else + raise ArgumentError, "Need a handler. Supply an options hash that has a :with key as the last argument." + end + end + + klasses.each do |klass| + key = if klass.is_a?(Class) && klass <= Exception + klass.name + elsif klass.is_a?(String) + klass + else + raise ArgumentError, "#{klass} is neither an Exception nor a String" + end + + # put the new handler at the end because the list is read in reverse + self.rescue_handlers += [[key, options[:with]]] + end + end + end + + # Tries to rescue the exception by looking up and calling a registered handler. + def rescue_with_handler(exception) + if handler = handler_for_rescue(exception) + handler.arity != 0 ? handler.call(exception) : handler.call + true # don't rely on the return value of the handler + end + end + + def handler_for_rescue(exception) + # We go from right to left because pairs are pushed onto rescue_handlers + # as rescue_from declarations are found. + _, rescuer = self.class.rescue_handlers.reverse.detect do |klass_name, handler| + # The purpose of allowing strings in rescue_from is to support the + # declaration of handler associations for exception classes whose + # definition is yet unknown. + # + # Since this loop needs the constants it would be inconsistent to + # assume they should exist at this point. An early raised exception + # could trigger some other handler and the array could include + # precisely a string whose corresponding constant has not yet been + # seen. This is why we are tolerant to unknown constants. + # + # Note that this tolerance only matters if the exception was given as + # a string, otherwise a NameError will be raised by the interpreter + # itself when rescue_from CONSTANT is executed. + klass = self.class.const_get(klass_name) rescue nil + klass ||= klass_name.constantize rescue nil + exception.is_a?(klass) if klass + end + + case rescuer + when Symbol + method(rescuer) + when Proc + if rescuer.arity == 0 + Proc.new { instance_exec(&rescuer) } + else + Proc.new { |_exception| instance_exec(_exception, &rescuer) } + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/security_utils.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/security_utils.rb new file mode 100644 index 0000000..9be8613 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/security_utils.rb @@ -0,0 +1,27 @@ +require 'digest' + +module ActiveSupport + module SecurityUtils + # Constant time string comparison. + # + # The values compared should be of fixed length, such as strings + # that have already been processed by HMAC. This should not be used + # on variable length plaintext strings because it could leak length info + # via timing attacks. + def secure_compare(a, b) + return false unless a.bytesize == b.bytesize + + l = a.unpack "C#{a.bytesize}" + + res = 0 + b.each_byte { |byte| res |= byte ^ l.shift } + res == 0 + end + module_function :secure_compare + + def variable_size_secure_compare(a, b) # :nodoc: + secure_compare(::Digest::SHA256.hexdigest(a), ::Digest::SHA256.hexdigest(b)) + end + module_function :variable_size_secure_compare + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/string_inquirer.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/string_inquirer.rb new file mode 100644 index 0000000..45271c9 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/string_inquirer.rb @@ -0,0 +1,26 @@ +module ActiveSupport + # Wrapping a string in this class gives you a prettier way to test + # for equality. The value returned by Rails.env is wrapped + # in a StringInquirer object so instead of calling this: + # + # Rails.env == 'production' + # + # you can call this: + # + # Rails.env.production? + class StringInquirer < String + private + + def respond_to_missing?(method_name, include_private = false) + method_name[-1] == '?' + end + + def method_missing(method_name, *arguments) + if method_name[-1] == '?' + self == method_name[0..-2] + else + super + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/subscriber.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/subscriber.rb new file mode 100644 index 0000000..98be78b --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/subscriber.rb @@ -0,0 +1,125 @@ +require 'active_support/per_thread_registry' + +module ActiveSupport + # ActiveSupport::Subscriber is an object set to consume + # ActiveSupport::Notifications. The subscriber dispatches notifications to + # a registered object based on its given namespace. + # + # An example would be Active Record subscriber responsible for collecting + # statistics about queries: + # + # module ActiveRecord + # class StatsSubscriber < ActiveSupport::Subscriber + # def sql(event) + # Statsd.timing("sql.#{event.payload[:name]}", event.duration) + # end + # end + # end + # + # And it's finally registered as: + # + # ActiveRecord::StatsSubscriber.attach_to :active_record + # + # Since we need to know all instance methods before attaching the log + # subscriber, the line above should be called after your subscriber definition. + # + # After configured, whenever a "sql.active_record" notification is published, + # it will properly dispatch the event (ActiveSupport::Notifications::Event) to + # the +sql+ method. + class Subscriber + class << self + + # Attach the subscriber to a namespace. + def attach_to(namespace, subscriber=new, notifier=ActiveSupport::Notifications) + @namespace = namespace + @subscriber = subscriber + @notifier = notifier + + subscribers << subscriber + + # Add event subscribers for all existing methods on the class. + subscriber.public_methods(false).each do |event| + add_event_subscriber(event) + end + end + + # Adds event subscribers for all new methods added to the class. + def method_added(event) + # Only public methods are added as subscribers, and only if a notifier + # has been set up. This means that subscribers will only be set up for + # classes that call #attach_to. + if public_method_defined?(event) && notifier + add_event_subscriber(event) + end + end + + def subscribers + @@subscribers ||= [] + end + + protected + + attr_reader :subscriber, :notifier, :namespace + + def add_event_subscriber(event) + return if %w{ start finish }.include?(event.to_s) + + pattern = "#{event}.#{namespace}" + + # don't add multiple subscribers (eg. if methods are redefined) + return if subscriber.patterns.include?(pattern) + + subscriber.patterns << pattern + notifier.subscribe(pattern, subscriber) + end + end + + attr_reader :patterns # :nodoc: + + def initialize + @queue_key = [self.class.name, object_id].join "-" + @patterns = [] + super + end + + def start(name, id, payload) + e = ActiveSupport::Notifications::Event.new(name, Time.now, nil, id, payload) + parent = event_stack.last + parent << e if parent + + event_stack.push e + end + + def finish(name, id, payload) + finished = Time.now + event = event_stack.pop + event.end = finished + event.payload.merge!(payload) + + method = name.split('.').first + send(method, event) + end + + private + + def event_stack + SubscriberQueueRegistry.instance.get_queue(@queue_key) + end + end + + # This is a registry for all the event stacks kept for subscribers. + # + # See the documentation of ActiveSupport::PerThreadRegistry + # for further details. + class SubscriberQueueRegistry # :nodoc: + extend PerThreadRegistry + + def initialize + @registry = {} + end + + def get_queue(queue_key) + @registry[queue_key] ||= [] + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/tagged_logging.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/tagged_logging.rb new file mode 100644 index 0000000..d5c2222 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/tagged_logging.rb @@ -0,0 +1,76 @@ +require 'active_support/core_ext/module/delegation' +require 'active_support/core_ext/object/blank' +require 'logger' +require 'active_support/logger' + +module ActiveSupport + # Wraps any standard Logger object to provide tagging capabilities. + # + # logger = ActiveSupport::TaggedLogging.new(Logger.new(STDOUT)) + # logger.tagged('BCX') { logger.info 'Stuff' } # Logs "[BCX] Stuff" + # logger.tagged('BCX', "Jason") { logger.info 'Stuff' } # Logs "[BCX] [Jason] Stuff" + # logger.tagged('BCX') { logger.tagged('Jason') { logger.info 'Stuff' } } # Logs "[BCX] [Jason] Stuff" + # + # This is used by the default Rails.logger as configured by Railties to make + # it easy to stamp log lines with subdomains, request ids, and anything else + # to aid debugging of multi-user production applications. + module TaggedLogging + module Formatter # :nodoc: + # This method is invoked when a log event occurs. + def call(severity, timestamp, progname, msg) + super(severity, timestamp, progname, "#{tags_text}#{msg}") + end + + def tagged(*tags) + new_tags = push_tags(*tags) + yield self + ensure + pop_tags(new_tags.size) + end + + def push_tags(*tags) + tags.flatten.reject(&:blank?).tap do |new_tags| + current_tags.concat new_tags + end + end + + def pop_tags(size = 1) + current_tags.pop size + end + + def clear_tags! + current_tags.clear + end + + def current_tags + Thread.current[:activesupport_tagged_logging_tags] ||= [] + end + + private + def tags_text + tags = current_tags + if tags.any? + tags.collect { |tag| "[#{tag}] " }.join + end + end + end + + def self.new(logger) + # Ensure we set a default formatter so we aren't extending nil! + logger.formatter ||= ActiveSupport::Logger::SimpleFormatter.new + logger.formatter.extend Formatter + logger.extend(self) + end + + delegate :push_tags, :pop_tags, :clear_tags!, to: :formatter + + def tagged(*tags) + formatter.tagged(*tags) { yield self } + end + + def flush + clear_tags! + super if defined?(super) + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/test_case.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/test_case.rb new file mode 100644 index 0000000..98b6845 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/test_case.rb @@ -0,0 +1,100 @@ +gem 'minitest' # make sure we get the gem, not stdlib +require 'minitest' +require 'active_support/testing/tagged_logging' +require 'active_support/testing/setup_and_teardown' +require 'active_support/testing/assertions' +require 'active_support/testing/deprecation' +require 'active_support/testing/declarative' +require 'active_support/testing/isolation' +require 'active_support/testing/constant_lookup' +require 'active_support/testing/time_helpers' +require 'active_support/core_ext/kernel/reporting' +require 'active_support/deprecation' + +module ActiveSupport + class TestCase < ::Minitest::Test + Assertion = Minitest::Assertion + + class << self + # Sets the order in which test cases are run. + # + # ActiveSupport::TestCase.test_order = :random # => :random + # + # Valid values are: + # * +:random+ (to run tests in random order) + # * +:parallel+ (to run tests in parallel) + # * +:sorted+ (to run tests alphabetically by method name) + # * +:alpha+ (equivalent to +:sorted+) + def test_order=(new_order) + ActiveSupport.test_order = new_order + end + + # Returns the order in which test cases are run. + # + # ActiveSupport::TestCase.test_order # => :sorted + # + # Possible values are +:random+, +:parallel+, +:alpha+, +:sorted+. + # Defaults to +:sorted+. + def test_order + test_order = ActiveSupport.test_order + + if test_order.nil? + ActiveSupport::Deprecation.warn "You did not specify a value for the " \ + "configuration option `active_support.test_order`. In Rails 5, " \ + "the default value of this option will change from `:sorted` to " \ + "`:random`.\n" \ + "To disable this warning and keep the current behavior, you can add " \ + "the following line to your `config/environments/test.rb`:\n" \ + "\n" \ + " Rails.application.configure do\n" \ + " config.active_support.test_order = :sorted\n" \ + " end\n" \ + "\n" \ + "Alternatively, you can opt into the future behavior by setting this " \ + "option to `:random`." + + test_order = :sorted + self.test_order = test_order + end + + test_order + end + + alias :my_tests_are_order_dependent! :i_suck_and_my_tests_are_order_dependent! + end + + alias_method :method_name, :name + + include ActiveSupport::Testing::TaggedLogging + include ActiveSupport::Testing::SetupAndTeardown + include ActiveSupport::Testing::Assertions + include ActiveSupport::Testing::Deprecation + include ActiveSupport::Testing::TimeHelpers + extend ActiveSupport::Testing::Declarative + + # test/unit backwards compatibility methods + alias :assert_raise :assert_raises + alias :assert_not_empty :refute_empty + alias :assert_not_equal :refute_equal + alias :assert_not_in_delta :refute_in_delta + alias :assert_not_in_epsilon :refute_in_epsilon + alias :assert_not_includes :refute_includes + alias :assert_not_instance_of :refute_instance_of + alias :assert_not_kind_of :refute_kind_of + alias :assert_no_match :refute_match + alias :assert_not_nil :refute_nil + alias :assert_not_operator :refute_operator + alias :assert_not_predicate :refute_predicate + alias :assert_not_respond_to :refute_respond_to + alias :assert_not_same :refute_same + + # Fails if the block raises an exception. + # + # assert_nothing_raised do + # ... + # end + def assert_nothing_raised(*args) + yield + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/testing/assertions.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/testing/assertions.rb new file mode 100644 index 0000000..11cca82 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/testing/assertions.rb @@ -0,0 +1,97 @@ +require 'active_support/core_ext/object/blank' + +module ActiveSupport + module Testing + module Assertions + # Assert that an expression is not truthy. Passes if object is + # +nil+ or +false+. "Truthy" means "considered true in a conditional" + # like if foo. + # + # assert_not nil # => true + # assert_not false # => true + # assert_not 'foo' # => Expected "foo" to be nil or false + # + # An error message can be specified. + # + # assert_not foo, 'foo should be false' + def assert_not(object, message = nil) + message ||= "Expected #{mu_pp(object)} to be nil or false" + assert !object, message + end + + # Test numeric difference between the return value of an expression as a + # result of what is evaluated in the yielded block. + # + # assert_difference 'Article.count' do + # post :create, article: {...} + # end + # + # An arbitrary expression is passed in and evaluated. + # + # assert_difference 'assigns(:article).comments(:reload).size' do + # post :create, comment: {...} + # end + # + # An arbitrary positive or negative difference can be specified. + # The default is 1. + # + # assert_difference 'Article.count', -1 do + # post :delete, id: ... + # end + # + # An array of expressions can also be passed in and evaluated. + # + # assert_difference [ 'Article.count', 'Post.count' ], 2 do + # post :create, article: {...} + # end + # + # A lambda or a list of lambdas can be passed in and evaluated: + # + # assert_difference ->{ Article.count }, 2 do + # post :create, article: {...} + # end + # + # assert_difference [->{ Article.count }, ->{ Post.count }], 2 do + # post :create, article: {...} + # end + # + # An error message can be specified. + # + # assert_difference 'Article.count', -1, 'An Article should be destroyed' do + # post :delete, id: ... + # end + def assert_difference(expression, difference = 1, message = nil, &block) + expressions = Array(expression) + + exps = expressions.map { |e| + e.respond_to?(:call) ? e : lambda { eval(e, block.binding) } + } + before = exps.map { |e| e.call } + + yield + + expressions.zip(exps).each_with_index do |(code, e), i| + error = "#{code.inspect} didn't change by #{difference}" + error = "#{message}.\n#{error}" if message + assert_equal(before[i] + difference, e.call, error) + end + end + + # Assertion that the numeric result of evaluating an expression is not + # changed before and after invoking the passed in block. + # + # assert_no_difference 'Article.count' do + # post :create, article: invalid_attributes + # end + # + # An error message can be specified. + # + # assert_no_difference 'Article.count', 'An Article should not be created' do + # post :create, article: invalid_attributes + # end + def assert_no_difference(expression, message = nil, &block) + assert_difference expression, 0, message, &block + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/testing/autorun.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/testing/autorun.rb new file mode 100644 index 0000000..5aa5f46 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/testing/autorun.rb @@ -0,0 +1,5 @@ +gem 'minitest' + +require 'minitest' + +Minitest.autorun diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/testing/constant_lookup.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/testing/constant_lookup.rb new file mode 100644 index 0000000..07d477c --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/testing/constant_lookup.rb @@ -0,0 +1,50 @@ +require "active_support/concern" +require "active_support/inflector" + +module ActiveSupport + module Testing + # Resolves a constant from a minitest spec name. + # + # Given the following spec-style test: + # + # describe WidgetsController, :index do + # describe "authenticated user" do + # describe "returns widgets" do + # it "has a controller that exists" do + # assert_kind_of WidgetsController, @controller + # end + # end + # end + # end + # + # The test will have the following name: + # + # "WidgetsController::index::authenticated user::returns widgets" + # + # The constant WidgetsController can be resolved from the name. + # The following code will resolve the constant: + # + # controller = determine_constant_from_test_name(name) do |constant| + # Class === constant && constant < ::ActionController::Metal + # end + module ConstantLookup + extend ::ActiveSupport::Concern + + module ClassMethods # :nodoc: + def determine_constant_from_test_name(test_name) + names = test_name.split "::" + while names.size > 0 do + names.last.sub!(/Test$/, "") + begin + constant = names.join("::").safe_constantize + break(constant) if yield(constant) + ensure + names.pop + end + end + end + end + + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/testing/declarative.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/testing/declarative.rb new file mode 100644 index 0000000..0bf3643 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/testing/declarative.rb @@ -0,0 +1,26 @@ +module ActiveSupport + module Testing + module Declarative + unless defined?(Spec) + # Helper to define a test method using a String. Under the hood, it replaces + # spaces with underscores and defines the test method. + # + # test "verify something" do + # ... + # end + def test(name, &block) + test_name = "test_#{name.gsub(/\s+/,'_')}".to_sym + defined = method_defined? test_name + raise "#{test_name} is already defined in #{self}" if defined + if block_given? + define_method(test_name, &block) + else + define_method(test_name) do + flunk "No implementation provided for #{name}" + end + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/testing/deprecation.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/testing/deprecation.rb new file mode 100644 index 0000000..6c94c61 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/testing/deprecation.rb @@ -0,0 +1,35 @@ +require 'active_support/deprecation' + +module ActiveSupport + module Testing + module Deprecation #:nodoc: + def assert_deprecated(match = nil, &block) + result, warnings = collect_deprecations(&block) + assert !warnings.empty?, "Expected a deprecation warning within the block but received none" + if match + match = Regexp.new(Regexp.escape(match)) unless match.is_a?(Regexp) + assert warnings.any? { |w| w =~ match }, "No deprecation warning matched #{match}: #{warnings.join(', ')}" + end + result + end + + def assert_not_deprecated(&block) + result, deprecations = collect_deprecations(&block) + assert deprecations.empty?, "Expected no deprecation warning within the block but received #{deprecations.size}: \n #{deprecations * "\n "}" + result + end + + def collect_deprecations + old_behavior = ActiveSupport::Deprecation.behavior + deprecations = [] + ActiveSupport::Deprecation.behavior = Proc.new do |message, callstack| + deprecations << message + end + result = yield + [result, deprecations] + ensure + ActiveSupport::Deprecation.behavior = old_behavior + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/testing/isolation.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/testing/isolation.rb new file mode 100644 index 0000000..68bda35 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/testing/isolation.rb @@ -0,0 +1,101 @@ +require 'rbconfig' + +module ActiveSupport + module Testing + module Isolation + require 'thread' + + def self.included(klass) #:nodoc: + klass.class_eval do + parallelize_me! + end + end + + def self.forking_env? + !ENV["NO_FORK"] && ((RbConfig::CONFIG['host_os'] !~ /mswin|mingw/) && (RUBY_PLATFORM !~ /java/)) + end + + @@class_setup_mutex = Mutex.new + + def _run_class_setup # class setup method should only happen in parent + @@class_setup_mutex.synchronize do + unless defined?(@@ran_class_setup) || ENV['ISOLATION_TEST'] + self.class.setup if self.class.respond_to?(:setup) + @@ran_class_setup = true + end + end + end + + def run + serialized = run_in_isolation do + super + end + + Marshal.load(serialized) + end + + module Forking + def run_in_isolation(&blk) + read, write = IO.pipe + read.binmode + write.binmode + + pid = fork do + read.close + yield + write.puts [Marshal.dump(self.dup)].pack("m") + exit! + end + + write.close + result = read.read + Process.wait2(pid) + return result.unpack("m")[0] + end + end + + module Subprocess + ORIG_ARGV = ARGV.dup unless defined?(ORIG_ARGV) + + # Crazy H4X to get this working in windows / jruby with + # no forking. + def run_in_isolation(&blk) + require "tempfile" + + if ENV["ISOLATION_TEST"] + yield + File.open(ENV["ISOLATION_OUTPUT"], "w") do |file| + file.puts [Marshal.dump(self.dup)].pack("m") + end + exit! + else + Tempfile.open("isolation") do |tmpfile| + env = { + ISOLATION_TEST: self.class.name, + ISOLATION_OUTPUT: tmpfile.path + } + + load_paths = $-I.map {|p| "-I\"#{File.expand_path(p)}\"" }.join(" ") + orig_args = ORIG_ARGV.join(" ") + test_opts = "-n#{self.class.name}##{self.name}" + command = "#{Gem.ruby} #{load_paths} #{$0} #{orig_args} #{test_opts}" + + # IO.popen lets us pass env in a cross-platform way + child = IO.popen([env, command]) + + begin + Process.wait(child.pid) + rescue Errno::ECHILD # The child process may exit before we wait + nil + end + + return tmpfile.read.unpack("m")[0] + end + end + end + end + + include forking_env? ? Forking : Subprocess + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/testing/setup_and_teardown.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/testing/setup_and_teardown.rb new file mode 100644 index 0000000..33f2b8d --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/testing/setup_and_teardown.rb @@ -0,0 +1,50 @@ +require 'active_support/concern' +require 'active_support/callbacks' + +module ActiveSupport + module Testing + # Adds support for +setup+ and +teardown+ callbacks. + # These callbacks serve as a replacement to overwriting the + # #setup and #teardown methods of your TestCase. + # + # class ExampleTest < ActiveSupport::TestCase + # setup do + # # ... + # end + # + # teardown do + # # ... + # end + # end + module SetupAndTeardown + extend ActiveSupport::Concern + + included do + include ActiveSupport::Callbacks + define_callbacks :setup, :teardown + end + + module ClassMethods + # Add a callback, which runs before TestCase#setup. + def setup(*args, &block) + set_callback(:setup, :before, *args, &block) + end + + # Add a callback, which runs after TestCase#teardown. + def teardown(*args, &block) + set_callback(:teardown, :after, *args, &block) + end + end + + def before_setup # :nodoc: + super + run_callbacks :setup + end + + def after_teardown # :nodoc: + run_callbacks :teardown + super + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/testing/tagged_logging.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/testing/tagged_logging.rb new file mode 100644 index 0000000..843ce4a --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/testing/tagged_logging.rb @@ -0,0 +1,25 @@ +module ActiveSupport + module Testing + # Logs a "PostsControllerTest: test name" heading before each test to + # make test.log easier to search and follow along with. + module TaggedLogging #:nodoc: + attr_writer :tagged_logger + + def before_setup + if tagged_logger && tagged_logger.info? + heading = "#{self.class}: #{name}" + divider = '-' * heading.size + tagged_logger.info divider + tagged_logger.info heading + tagged_logger.info divider + end + super + end + + private + def tagged_logger + @tagged_logger ||= (defined?(Rails.logger) && Rails.logger) + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/testing/time_helpers.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/testing/time_helpers.rb new file mode 100644 index 0000000..8c63815 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/testing/time_helpers.rb @@ -0,0 +1,131 @@ +module ActiveSupport + module Testing + class SimpleStubs # :nodoc: + Stub = Struct.new(:object, :method_name, :original_method) + + def initialize + @stubs = {} + end + + def stub_object(object, method_name, return_value) + key = [object.object_id, method_name] + + if stub = @stubs[key] + unstub_object(stub) + end + + new_name = "__simple_stub__#{method_name}" + + @stubs[key] = Stub.new(object, method_name, new_name) + + object.singleton_class.send :alias_method, new_name, method_name + object.define_singleton_method(method_name) { return_value } + end + + def unstub_all! + @stubs.each_value do |stub| + unstub_object(stub) + end + @stubs = {} + end + + private + + def unstub_object(stub) + singleton_class = stub.object.singleton_class + singleton_class.send :undef_method, stub.method_name + singleton_class.send :alias_method, stub.method_name, stub.original_method + singleton_class.send :undef_method, stub.original_method + end + end + + # Containing helpers that helps you test passage of time. + module TimeHelpers + # Changes current time to the time in the future or in the past by a given time difference by + # stubbing +Time.now+ and +Date.today+. + # + # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00 + # travel 1.day + # Time.current # => Sun, 10 Nov 2013 15:34:49 EST -05:00 + # Date.current # => Sun, 10 Nov 2013 + # + # This method also accepts a block, which will return the current time back to its original + # state at the end of the block: + # + # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00 + # travel 1.day do + # User.create.created_at # => Sun, 10 Nov 2013 15:34:49 EST -05:00 + # end + # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00 + def travel(duration, &block) + travel_to Time.now + duration, &block + end + + # Changes current time to the given time by stubbing +Time.now+ and + # +Date.today+ to return the time or date passed into this method. + # + # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00 + # travel_to Time.new(2004, 11, 24, 01, 04, 44) + # Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00 + # Date.current # => Wed, 24 Nov 2004 + # + # Dates are taken as their timestamp at the beginning of the day in the + # application time zone. Time.current returns said timestamp, + # and Time.now its equivalent in the system time zone. Similarly, + # Date.current returns a date equal to the argument, and + # Date.today the date according to Time.now, which may + # be different. (Note that you rarely want to deal with Time.now, + # or Date.today, in order to honor the application time zone + # please always use Time.current and Date.current.) + # + # Note that the usec for the time passed will be set to 0 to prevent rounding + # errors with external services, like MySQL (which will round instead of floor, + # leading to off-by-one-second errors). + # + # This method also accepts a block, which will return the current time back to its original + # state at the end of the block: + # + # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00 + # travel_to Time.new(2004, 11, 24, 01, 04, 44) do + # Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00 + # end + # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00 + def travel_to(date_or_time) + if date_or_time.is_a?(Date) && !date_or_time.is_a?(DateTime) + now = date_or_time.midnight.to_time + else + now = date_or_time.to_time.change(usec: 0) + end + + simple_stubs.stub_object(Time, :now, now) + simple_stubs.stub_object(Date, :today, now.to_date) + + if block_given? + begin + yield + ensure + travel_back + end + end + end + + # Returns the current time back to its original state, by removing the stubs added by + # `travel` and `travel_to`. + # + # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00 + # travel_to Time.new(2004, 11, 24, 01, 04, 44) + # Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00 + # travel_back + # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00 + def travel_back + simple_stubs.unstub_all! + end + + private + + def simple_stubs + @simple_stubs ||= SimpleStubs.new + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/time.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/time.rb new file mode 100644 index 0000000..ea2d339 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/time.rb @@ -0,0 +1,18 @@ +module ActiveSupport + autoload :Duration, 'active_support/duration' + autoload :TimeWithZone, 'active_support/time_with_zone' + autoload :TimeZone, 'active_support/values/time_zone' +end + +require 'date' +require 'time' + +require 'active_support/core_ext/time' +require 'active_support/core_ext/date' +require 'active_support/core_ext/date_time' + +require 'active_support/core_ext/integer/time' +require 'active_support/core_ext/numeric/time' + +require 'active_support/core_ext/string/conversions' +require 'active_support/core_ext/string/zones' diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/time_with_zone.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/time_with_zone.rb new file mode 100644 index 0000000..10941ce --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/time_with_zone.rb @@ -0,0 +1,409 @@ +require 'active_support/values/time_zone' +require 'active_support/core_ext/object/acts_like' + +module ActiveSupport + # A Time-like class that can represent a time in any time zone. Necessary + # because standard Ruby Time instances are limited to UTC and the + # system's ENV['TZ'] zone. + # + # You shouldn't ever need to create a TimeWithZone instance directly via +new+. + # Instead use methods +local+, +parse+, +at+ and +now+ on TimeZone instances, + # and +in_time_zone+ on Time and DateTime instances. + # + # Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)' + # Time.zone.local(2007, 2, 10, 15, 30, 45) # => Sat, 10 Feb 2007 15:30:45 EST -05:00 + # Time.zone.parse('2007-02-10 15:30:45') # => Sat, 10 Feb 2007 15:30:45 EST -05:00 + # Time.zone.at(1170361845) # => Sat, 10 Feb 2007 15:30:45 EST -05:00 + # Time.zone.now # => Sun, 18 May 2008 13:07:55 EDT -04:00 + # Time.utc(2007, 2, 10, 20, 30, 45).in_time_zone # => Sat, 10 Feb 2007 15:30:45 EST -05:00 + # + # See Time and TimeZone for further documentation of these methods. + # + # TimeWithZone instances implement the same API as Ruby Time instances, so + # that Time and TimeWithZone instances are interchangeable. + # + # t = Time.zone.now # => Sun, 18 May 2008 13:27:25 EDT -04:00 + # t.hour # => 13 + # t.dst? # => true + # t.utc_offset # => -14400 + # t.zone # => "EDT" + # t.to_s(:rfc822) # => "Sun, 18 May 2008 13:27:25 -0400" + # t + 1.day # => Mon, 19 May 2008 13:27:25 EDT -04:00 + # t.beginning_of_year # => Tue, 01 Jan 2008 00:00:00 EST -05:00 + # t > Time.utc(1999) # => true + # t.is_a?(Time) # => true + # t.is_a?(ActiveSupport::TimeWithZone) # => true + class TimeWithZone + + # Report class name as 'Time' to thwart type checking. + def self.name + 'Time' + end + + include Comparable + attr_reader :time_zone + + def initialize(utc_time, time_zone, local_time = nil, period = nil) + @utc, @time_zone, @time = utc_time, time_zone, local_time + @period = @utc ? period : get_period_and_ensure_valid_local_time(period) + end + + # Returns a Time or DateTime instance that represents the time in +time_zone+. + def time + @time ||= period.to_local(@utc) + end + + # Returns a Time or DateTime instance that represents the time in UTC. + def utc + @utc ||= period.to_utc(@time) + end + alias_method :comparable_time, :utc + alias_method :getgm, :utc + alias_method :getutc, :utc + alias_method :gmtime, :utc + + # Returns the underlying TZInfo::TimezonePeriod. + def period + @period ||= time_zone.period_for_utc(@utc) + end + + # Returns the simultaneous time in Time.zone, or the specified zone. + def in_time_zone(new_zone = ::Time.zone) + return self if time_zone == new_zone + utc.in_time_zone(new_zone) + end + + # Returns a Time.local() instance of the simultaneous time in your + # system's ENV['TZ'] zone. + def localtime(utc_offset = nil) + utc.respond_to?(:getlocal) ? utc.getlocal(utc_offset) : utc.to_time.getlocal(utc_offset) + end + alias_method :getlocal, :localtime + + # Returns true if the current time is within Daylight Savings Time for the + # specified time zone. + # + # Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)' + # Time.zone.parse("2012-5-30").dst? # => true + # Time.zone.parse("2012-11-30").dst? # => false + def dst? + period.dst? + end + alias_method :isdst, :dst? + + # Returns true if the current time zone is set to UTC. + # + # Time.zone = 'UTC' # => 'UTC' + # Time.zone.now.utc? # => true + # Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)' + # Time.zone.now.utc? # => false + def utc? + time_zone.name == 'UTC' + end + alias_method :gmt?, :utc? + + # Returns the offset from current time to UTC time in seconds. + def utc_offset + period.utc_total_offset + end + alias_method :gmt_offset, :utc_offset + alias_method :gmtoff, :utc_offset + + # Returns a formatted string of the offset from UTC, or an alternative + # string if the time zone is already UTC. + # + # Time.zone = 'Eastern Time (US & Canada)' # => "Eastern Time (US & Canada)" + # Time.zone.now.formatted_offset(true) # => "-05:00" + # Time.zone.now.formatted_offset(false) # => "-0500" + # Time.zone = 'UTC' # => "UTC" + # Time.zone.now.formatted_offset(true, "0") # => "0" + def formatted_offset(colon = true, alternate_utc_string = nil) + utc? && alternate_utc_string || TimeZone.seconds_to_utc_offset(utc_offset, colon) + end + + # Time uses +zone+ to display the time zone abbreviation, so we're + # duck-typing it. + def zone + period.zone_identifier.to_s + end + + def inspect + "#{time.strftime('%a, %d %b %Y %H:%M:%S')} #{zone} #{formatted_offset}" + end + + def xmlschema(fraction_digits = 0) + fraction = if fraction_digits.to_i > 0 + (".%06i" % time.usec)[0, fraction_digits.to_i + 1] + end + + "#{time.strftime("%Y-%m-%dT%H:%M:%S")}#{fraction}#{formatted_offset(true, 'Z')}" + end + alias_method :iso8601, :xmlschema + + # Coerces time to a string for JSON encoding. The default format is ISO 8601. + # You can get %Y/%m/%d %H:%M:%S +offset style by setting + # ActiveSupport::JSON::Encoding.use_standard_json_time_format + # to +false+. + # + # # With ActiveSupport::JSON::Encoding.use_standard_json_time_format = true + # Time.utc(2005,2,1,15,15,10).in_time_zone("Hawaii").to_json + # # => "2005-02-01T05:15:10.000-10:00" + # + # # With ActiveSupport::JSON::Encoding.use_standard_json_time_format = false + # Time.utc(2005,2,1,15,15,10).in_time_zone("Hawaii").to_json + # # => "2005/02/01 05:15:10 -1000" + def as_json(options = nil) + if ActiveSupport::JSON::Encoding.use_standard_json_time_format + xmlschema(ActiveSupport::JSON::Encoding.time_precision) + else + %(#{time.strftime("%Y/%m/%d %H:%M:%S")} #{formatted_offset(false)}) + end + end + + def encode_with(coder) + if coder.respond_to?(:represent_object) + coder.represent_object(nil, utc) + else + coder.represent_scalar(nil, utc.strftime("%Y-%m-%d %H:%M:%S.%9NZ")) + end + end + + # Returns a string of the object's date and time in the format used by + # HTTP requests. + # + # Time.zone.now.httpdate # => "Tue, 01 Jan 2013 04:39:43 GMT" + def httpdate + utc.httpdate + end + + # Returns a string of the object's date and time in the RFC 2822 standard + # format. + # + # Time.zone.now.rfc2822 # => "Tue, 01 Jan 2013 04:51:39 +0000" + def rfc2822 + to_s(:rfc822) + end + alias_method :rfc822, :rfc2822 + + # Returns a string of the object's date and time. + # Accepts an optional format: + # * :default - default value, mimics Ruby 1.9 Time#to_s format. + # * :db - format outputs time in UTC :db time. See Time#to_formatted_s(:db). + # * Any key in Time::DATE_FORMATS can be used. See active_support/core_ext/time/conversions.rb. + def to_s(format = :default) + if format == :db + utc.to_s(format) + elsif formatter = ::Time::DATE_FORMATS[format] + formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter) + else + "#{time.strftime("%Y-%m-%d %H:%M:%S")} #{formatted_offset(false, 'UTC')}" # mimicking Ruby 1.9 Time#to_s format + end + end + alias_method :to_formatted_s, :to_s + + # Replaces %Z directive with +zone before passing to Time#strftime, + # so that zone information is correct. + def strftime(format) + format = format.gsub(/((?:\A|[^%])(?:%%)*)%Z/, "\\1#{zone}") + getlocal(utc_offset).strftime(format) + end + + # Use the time in UTC for comparisons. + def <=>(other) + utc <=> other + end + + # Returns true if the current object's time is within the specified + # +min+ and +max+ time. + def between?(min, max) + utc.between?(min, max) + end + + # Returns true if the current object's time is in the past. + def past? + utc.past? + end + + # Returns true if the current object's time falls within + # the current day. + def today? + time.today? + end + + # Returns true if the current object's time is in the future. + def future? + utc.future? + end + + def eql?(other) + other.eql?(utc) + end + + def hash + utc.hash + end + + def +(other) + # If we're adding a Duration of variable length (i.e., years, months, days), move forward from #time, + # otherwise move forward from #utc, for accuracy when moving across DST boundaries + if duration_of_variable_length?(other) + method_missing(:+, other) + else + result = utc.acts_like?(:date) ? utc.since(other) : utc + other rescue utc.since(other) + result.in_time_zone(time_zone) + end + end + + def -(other) + # If we're subtracting a Duration of variable length (i.e., years, months, days), move backwards from #time, + # otherwise move backwards #utc, for accuracy when moving across DST boundaries + if other.acts_like?(:time) + to_time - other.to_time + elsif duration_of_variable_length?(other) + method_missing(:-, other) + else + result = utc.acts_like?(:date) ? utc.ago(other) : utc - other rescue utc.ago(other) + result.in_time_zone(time_zone) + end + end + + def since(other) + # If we're adding a Duration of variable length (i.e., years, months, days), move forward from #time, + # otherwise move forward from #utc, for accuracy when moving across DST boundaries + if duration_of_variable_length?(other) + method_missing(:since, other) + else + utc.since(other).in_time_zone(time_zone) + end + end + + def ago(other) + since(-other) + end + + def advance(options) + # If we're advancing a value of variable length (i.e., years, weeks, months, days), advance from #time, + # otherwise advance from #utc, for accuracy when moving across DST boundaries + if options.values_at(:years, :weeks, :months, :days).any? + method_missing(:advance, options) + else + utc.advance(options).in_time_zone(time_zone) + end + end + + %w(year mon month day mday wday yday hour min sec usec nsec to_date).each do |method_name| + class_eval <<-EOV, __FILE__, __LINE__ + 1 + def #{method_name} # def month + time.#{method_name} # time.month + end # end + EOV + end + + def to_a + [time.sec, time.min, time.hour, time.day, time.mon, time.year, time.wday, time.yday, dst?, zone] + end + + def to_f + utc.to_f + end + + def to_i + utc.to_i + end + alias_method :tv_sec, :to_i + + def to_r + utc.to_r + end + + # Return an instance of Time in the system timezone. + def to_time + utc.to_time + end + + def to_datetime + utc.to_datetime.new_offset(Rational(utc_offset, 86_400)) + end + + # So that +self+ acts_like?(:time). + def acts_like_time? + true + end + + # Say we're a Time to thwart type checking. + def is_a?(klass) + klass == ::Time || super + end + alias_method :kind_of?, :is_a? + + def freeze + period; utc; time # preload instance variables before freezing + super + end + + def marshal_dump + [utc, time_zone.name, time] + end + + def marshal_load(variables) + initialize(variables[0].utc, ::Time.find_zone(variables[1]), variables[2].utc) + end + + # respond_to_missing? is not called in some cases, such as when type conversion is + # performed with Kernel#String + def respond_to?(sym, include_priv = false) + # ensure that we're not going to throw and rescue from NoMethodError in method_missing which is slow + return false if sym.to_sym == :to_str + super + end + + # Ensure proxy class responds to all methods that underlying time instance + # responds to. + def respond_to_missing?(sym, include_priv) + # consistently respond false to acts_like?(:date), regardless of whether #time is a Time or DateTime + return false if sym.to_sym == :acts_like_date? + time.respond_to?(sym, include_priv) + end + + # Send the missing method to +time+ instance, and wrap result in a new + # TimeWithZone with the existing +time_zone+. + def method_missing(sym, *args, &block) + wrap_with_time_zone time.__send__(sym, *args, &block) + rescue NoMethodError => e + raise e, e.message.sub(time.inspect, self.inspect), e.backtrace + end + + private + def get_period_and_ensure_valid_local_time(period) + # we don't want a Time.local instance enforcing its own DST rules as well, + # so transfer time values to a utc constructor if necessary + @time = transfer_time_values_to_utc_constructor(@time) unless @time.utc? + begin + period || @time_zone.period_for_local(@time) + rescue ::TZInfo::PeriodNotFound + # time is in the "spring forward" hour gap, so we're moving the time forward one hour and trying again + @time += 1.hour + retry + end + end + + def transfer_time_values_to_utc_constructor(time) + ::Time.utc(time.year, time.month, time.day, time.hour, time.min, time.sec, Rational(time.nsec, 1000)) + end + + def duration_of_variable_length?(obj) + ActiveSupport::Duration === obj && obj.parts.any? {|p| [:years, :months, :days].include?(p[0]) } + end + + def wrap_with_time_zone(time) + if time.acts_like?(:time) + periods = time_zone.periods_for_local(time) + self.class.new(nil, time_zone, time, periods.include?(period) ? period : nil) + elsif time.is_a?(Range) + wrap_with_time_zone(time.begin)..wrap_with_time_zone(time.end) + else + time + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/values/time_zone.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/values/time_zone.rb new file mode 100644 index 0000000..f7e0c27 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/values/time_zone.rb @@ -0,0 +1,428 @@ +require 'tzinfo' +require 'thread_safe' +require 'active_support/core_ext/object/blank' +require 'active_support/core_ext/object/try' + +module ActiveSupport + # The TimeZone class serves as a wrapper around TZInfo::Timezone instances. + # It allows us to do the following: + # + # * Limit the set of zones provided by TZInfo to a meaningful subset of 146 + # zones. + # * Retrieve and display zones with a friendlier name + # (e.g., "Eastern Time (US & Canada)" instead of "America/New_York"). + # * Lazily load TZInfo::Timezone instances only when they're needed. + # * Create ActiveSupport::TimeWithZone instances via TimeZone's +local+, + # +parse+, +at+ and +now+ methods. + # + # If you set config.time_zone in the Rails Application, you can + # access this TimeZone object via Time.zone: + # + # # application.rb: + # class Application < Rails::Application + # config.time_zone = 'Eastern Time (US & Canada)' + # end + # + # Time.zone # => # + # Time.zone.name # => "Eastern Time (US & Canada)" + # Time.zone.now # => Sun, 18 May 2008 14:30:44 EDT -04:00 + # + # The version of TZInfo bundled with Active Support only includes the + # definitions necessary to support the zones defined by the TimeZone class. + # If you need to use zones that aren't defined by TimeZone, you'll need to + # install the TZInfo gem (if a recent version of the gem is installed locally, + # this will be used instead of the bundled version.) + class TimeZone + # Keys are Rails TimeZone names, values are TZInfo identifiers. + MAPPING = { + "International Date Line West" => "Pacific/Midway", + "Midway Island" => "Pacific/Midway", + "American Samoa" => "Pacific/Pago_Pago", + "Hawaii" => "Pacific/Honolulu", + "Alaska" => "America/Juneau", + "Pacific Time (US & Canada)" => "America/Los_Angeles", + "Tijuana" => "America/Tijuana", + "Mountain Time (US & Canada)" => "America/Denver", + "Arizona" => "America/Phoenix", + "Chihuahua" => "America/Chihuahua", + "Mazatlan" => "America/Mazatlan", + "Central Time (US & Canada)" => "America/Chicago", + "Saskatchewan" => "America/Regina", + "Guadalajara" => "America/Mexico_City", + "Mexico City" => "America/Mexico_City", + "Monterrey" => "America/Monterrey", + "Central America" => "America/Guatemala", + "Eastern Time (US & Canada)" => "America/New_York", + "Indiana (East)" => "America/Indiana/Indianapolis", + "Bogota" => "America/Bogota", + "Lima" => "America/Lima", + "Quito" => "America/Lima", + "Atlantic Time (Canada)" => "America/Halifax", + "Caracas" => "America/Caracas", + "La Paz" => "America/La_Paz", + "Santiago" => "America/Santiago", + "Newfoundland" => "America/St_Johns", + "Brasilia" => "America/Sao_Paulo", + "Buenos Aires" => "America/Argentina/Buenos_Aires", + "Montevideo" => "America/Montevideo", + "Georgetown" => "America/Guyana", + "Greenland" => "America/Godthab", + "Mid-Atlantic" => "Atlantic/South_Georgia", + "Azores" => "Atlantic/Azores", + "Cape Verde Is." => "Atlantic/Cape_Verde", + "Dublin" => "Europe/Dublin", + "Edinburgh" => "Europe/London", + "Lisbon" => "Europe/Lisbon", + "London" => "Europe/London", + "Casablanca" => "Africa/Casablanca", + "Monrovia" => "Africa/Monrovia", + "UTC" => "Etc/UTC", + "Belgrade" => "Europe/Belgrade", + "Bratislava" => "Europe/Bratislava", + "Budapest" => "Europe/Budapest", + "Ljubljana" => "Europe/Ljubljana", + "Prague" => "Europe/Prague", + "Sarajevo" => "Europe/Sarajevo", + "Skopje" => "Europe/Skopje", + "Warsaw" => "Europe/Warsaw", + "Zagreb" => "Europe/Zagreb", + "Brussels" => "Europe/Brussels", + "Copenhagen" => "Europe/Copenhagen", + "Madrid" => "Europe/Madrid", + "Paris" => "Europe/Paris", + "Amsterdam" => "Europe/Amsterdam", + "Berlin" => "Europe/Berlin", + "Bern" => "Europe/Berlin", + "Rome" => "Europe/Rome", + "Stockholm" => "Europe/Stockholm", + "Vienna" => "Europe/Vienna", + "West Central Africa" => "Africa/Algiers", + "Bucharest" => "Europe/Bucharest", + "Cairo" => "Africa/Cairo", + "Helsinki" => "Europe/Helsinki", + "Kyiv" => "Europe/Kiev", + "Riga" => "Europe/Riga", + "Sofia" => "Europe/Sofia", + "Tallinn" => "Europe/Tallinn", + "Vilnius" => "Europe/Vilnius", + "Athens" => "Europe/Athens", + "Istanbul" => "Europe/Istanbul", + "Minsk" => "Europe/Minsk", + "Jerusalem" => "Asia/Jerusalem", + "Harare" => "Africa/Harare", + "Pretoria" => "Africa/Johannesburg", + "Kaliningrad" => "Europe/Kaliningrad", + "Moscow" => "Europe/Moscow", + "St. Petersburg" => "Europe/Moscow", + "Volgograd" => "Europe/Volgograd", + "Samara" => "Europe/Samara", + "Kuwait" => "Asia/Kuwait", + "Riyadh" => "Asia/Riyadh", + "Nairobi" => "Africa/Nairobi", + "Baghdad" => "Asia/Baghdad", + "Tehran" => "Asia/Tehran", + "Abu Dhabi" => "Asia/Muscat", + "Muscat" => "Asia/Muscat", + "Baku" => "Asia/Baku", + "Tbilisi" => "Asia/Tbilisi", + "Yerevan" => "Asia/Yerevan", + "Kabul" => "Asia/Kabul", + "Ekaterinburg" => "Asia/Yekaterinburg", + "Islamabad" => "Asia/Karachi", + "Karachi" => "Asia/Karachi", + "Tashkent" => "Asia/Tashkent", + "Chennai" => "Asia/Kolkata", + "Kolkata" => "Asia/Kolkata", + "Mumbai" => "Asia/Kolkata", + "New Delhi" => "Asia/Kolkata", + "Kathmandu" => "Asia/Kathmandu", + "Astana" => "Asia/Dhaka", + "Dhaka" => "Asia/Dhaka", + "Sri Jayawardenepura" => "Asia/Colombo", + "Almaty" => "Asia/Almaty", + "Novosibirsk" => "Asia/Novosibirsk", + "Rangoon" => "Asia/Rangoon", + "Bangkok" => "Asia/Bangkok", + "Hanoi" => "Asia/Bangkok", + "Jakarta" => "Asia/Jakarta", + "Krasnoyarsk" => "Asia/Krasnoyarsk", + "Beijing" => "Asia/Shanghai", + "Chongqing" => "Asia/Chongqing", + "Hong Kong" => "Asia/Hong_Kong", + "Urumqi" => "Asia/Urumqi", + "Kuala Lumpur" => "Asia/Kuala_Lumpur", + "Singapore" => "Asia/Singapore", + "Taipei" => "Asia/Taipei", + "Perth" => "Australia/Perth", + "Irkutsk" => "Asia/Irkutsk", + "Ulaanbaatar" => "Asia/Ulaanbaatar", + "Seoul" => "Asia/Seoul", + "Osaka" => "Asia/Tokyo", + "Sapporo" => "Asia/Tokyo", + "Tokyo" => "Asia/Tokyo", + "Yakutsk" => "Asia/Yakutsk", + "Darwin" => "Australia/Darwin", + "Adelaide" => "Australia/Adelaide", + "Canberra" => "Australia/Melbourne", + "Melbourne" => "Australia/Melbourne", + "Sydney" => "Australia/Sydney", + "Brisbane" => "Australia/Brisbane", + "Hobart" => "Australia/Hobart", + "Vladivostok" => "Asia/Vladivostok", + "Guam" => "Pacific/Guam", + "Port Moresby" => "Pacific/Port_Moresby", + "Magadan" => "Asia/Magadan", + "Srednekolymsk" => "Asia/Srednekolymsk", + "Solomon Is." => "Pacific/Guadalcanal", + "New Caledonia" => "Pacific/Noumea", + "Fiji" => "Pacific/Fiji", + "Kamchatka" => "Asia/Kamchatka", + "Marshall Is." => "Pacific/Majuro", + "Auckland" => "Pacific/Auckland", + "Wellington" => "Pacific/Auckland", + "Nuku'alofa" => "Pacific/Tongatapu", + "Tokelau Is." => "Pacific/Fakaofo", + "Chatham Is." => "Pacific/Chatham", + "Samoa" => "Pacific/Apia" + } + + UTC_OFFSET_WITH_COLON = '%s%02d:%02d' + UTC_OFFSET_WITHOUT_COLON = UTC_OFFSET_WITH_COLON.tr(':', '') + + @lazy_zones_map = ThreadSafe::Cache.new + + class << self + # Assumes self represents an offset from UTC in seconds (as returned from + # Time#utc_offset) and turns this into an +HH:MM formatted string. + # + # TimeZone.seconds_to_utc_offset(-21_600) # => "-06:00" + def seconds_to_utc_offset(seconds, colon = true) + format = colon ? UTC_OFFSET_WITH_COLON : UTC_OFFSET_WITHOUT_COLON + sign = (seconds < 0 ? '-' : '+') + hours = seconds.abs / 3600 + minutes = (seconds.abs % 3600) / 60 + format % [sign, hours, minutes] + end + + def find_tzinfo(name) + TZInfo::TimezoneProxy.new(MAPPING[name] || name) + end + + alias_method :create, :new + + # Returns a TimeZone instance with the given name, or +nil+ if no + # such TimeZone instance exists. (This exists to support the use of + # this class with the +composed_of+ macro.) + def new(name) + self[name] + end + + # Returns an array of all TimeZone objects. There are multiple + # TimeZone objects per time zone, in many cases, to make it easier + # for users to find their own time zone. + def all + @zones ||= zones_map.values.sort + end + + def zones_map #:nodoc: + @zones_map ||= begin + MAPPING.each_key {|place| self[place]} # load all the zones + @lazy_zones_map + end + end + + # Locate a specific time zone object. If the argument is a string, it + # is interpreted to mean the name of the timezone to locate. If it is a + # numeric value it is either the hour offset, or the second offset, of the + # timezone to find. (The first one with that offset will be returned.) + # Returns +nil+ if no such time zone is known to the system. + def [](arg) + case arg + when String + begin + @lazy_zones_map[arg] ||= create(arg).tap { |tz| tz.utc_offset } + rescue TZInfo::InvalidTimezoneIdentifier + nil + end + when Numeric, ActiveSupport::Duration + arg *= 3600 if arg.abs <= 13 + all.find { |z| z.utc_offset == arg.to_i } + else + raise ArgumentError, "invalid argument to TimeZone[]: #{arg.inspect}" + end + end + + # A convenience method for returning a collection of TimeZone objects + # for time zones in the USA. + def us_zones + @us_zones ||= all.find_all { |z| z.name =~ /US|Arizona|Indiana|Hawaii|Alaska/ } + end + end + + include Comparable + attr_reader :name + attr_reader :tzinfo + + # Create a new TimeZone object with the given name and offset. The + # offset is the number of seconds that this time zone is offset from UTC + # (GMT). Seconds were chosen as the offset unit because that is the unit + # that Ruby uses to represent time zone offsets (see Time#utc_offset). + def initialize(name, utc_offset = nil, tzinfo = nil) + @name = name + @utc_offset = utc_offset + @tzinfo = tzinfo || TimeZone.find_tzinfo(name) + @current_period = nil + end + + # Returns the offset of this time zone from UTC in seconds. + def utc_offset + if @utc_offset + @utc_offset + else + @current_period ||= tzinfo.current_period if tzinfo + @current_period.utc_offset if @current_period + end + end + + # Returns the offset of this time zone as a formatted string, of the + # format "+HH:MM". + def formatted_offset(colon=true, alternate_utc_string = nil) + utc_offset == 0 && alternate_utc_string || self.class.seconds_to_utc_offset(utc_offset, colon) + end + + # Compare this time zone to the parameter. The two are compared first on + # their offsets, and then by name. + def <=>(zone) + return unless zone.respond_to? :utc_offset + result = (utc_offset <=> zone.utc_offset) + result = (name <=> zone.name) if result == 0 + result + end + + # Compare #name and TZInfo identifier to a supplied regexp, returning +true+ + # if a match is found. + def =~(re) + re === name || re === MAPPING[name] + end + + # Returns a textual representation of this time zone. + def to_s + "(GMT#{formatted_offset}) #{name}" + end + + # Method for creating new ActiveSupport::TimeWithZone instance in time zone + # of +self+ from given values. + # + # Time.zone = 'Hawaii' # => "Hawaii" + # Time.zone.local(2007, 2, 1, 15, 30, 45) # => Thu, 01 Feb 2007 15:30:45 HST -10:00 + def local(*args) + time = Time.utc(*args) + ActiveSupport::TimeWithZone.new(nil, self, time) + end + + # Method for creating new ActiveSupport::TimeWithZone instance in time zone + # of +self+ from number of seconds since the Unix epoch. + # + # Time.zone = 'Hawaii' # => "Hawaii" + # Time.utc(2000).to_f # => 946684800.0 + # Time.zone.at(946684800.0) # => Fri, 31 Dec 1999 14:00:00 HST -10:00 + def at(secs) + Time.at(secs).utc.in_time_zone(self) + end + + # Method for creating new ActiveSupport::TimeWithZone instance in time zone + # of +self+ from parsed string. + # + # Time.zone = 'Hawaii' # => "Hawaii" + # Time.zone.parse('1999-12-31 14:00:00') # => Fri, 31 Dec 1999 14:00:00 HST -10:00 + # + # If upper components are missing from the string, they are supplied from + # TimeZone#now: + # + # Time.zone.now # => Fri, 31 Dec 1999 14:00:00 HST -10:00 + # Time.zone.parse('22:30:00') # => Fri, 31 Dec 1999 22:30:00 HST -10:00 + # + # However, if the date component is not provided, but any other upper + # components are supplied, then the day of the month defaults to 1: + # + # Time.zone.parse('Mar 2000') # => Wed, 01 Mar 2000 00:00:00 HST -10:00 + def parse(str, now=now()) + parts = Date._parse(str, false) + return if parts.empty? + + time = Time.new( + parts.fetch(:year, now.year), + parts.fetch(:mon, now.month), + parts.fetch(:mday, parts[:year] || parts[:mon] ? 1 : now.day), + parts.fetch(:hour, 0), + parts.fetch(:min, 0), + parts.fetch(:sec, 0) + parts.fetch(:sec_fraction, 0), + parts.fetch(:offset, 0) + ) + + if parts[:offset] + TimeWithZone.new(time.utc, self) + else + TimeWithZone.new(nil, self, time) + end + end + + # Returns an ActiveSupport::TimeWithZone instance representing the current + # time in the time zone represented by +self+. + # + # Time.zone = 'Hawaii' # => "Hawaii" + # Time.zone.now # => Wed, 23 Jan 2008 20:24:27 HST -10:00 + def now + time_now.utc.in_time_zone(self) + end + + # Return the current date in this time zone. + def today + tzinfo.now.to_date + end + + # Returns the next date in this time zone. + def tomorrow + today + 1 + end + + # Returns the previous date in this time zone. + def yesterday + today - 1 + end + + # Adjust the given time to the simultaneous time in the time zone + # represented by +self+. Returns a Time.utc() instance -- if you want an + # ActiveSupport::TimeWithZone instance, use Time#in_time_zone() instead. + def utc_to_local(time) + tzinfo.utc_to_local(time) + end + + # Adjust the given time to the simultaneous time in UTC. Returns a + # Time.utc() instance. + def local_to_utc(time, dst=true) + tzinfo.local_to_utc(time, dst) + end + + # Available so that TimeZone instances respond like TZInfo::Timezone + # instances. + def period_for_utc(time) + tzinfo.period_for_utc(time) + end + + # Available so that TimeZone instances respond like TZInfo::Timezone + # instances. + def period_for_local(time, dst=true) + tzinfo.period_for_local(time, dst) + end + + def periods_for_local(time) #:nodoc: + tzinfo.periods_for_local(time) + end + + private + def time_now + Time.now + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/values/unicode_tables.dat b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/values/unicode_tables.dat new file mode 100644 index 0000000..760be4c Binary files /dev/null and b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/values/unicode_tables.dat differ diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/version.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/version.rb new file mode 100644 index 0000000..fe03984 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/version.rb @@ -0,0 +1,8 @@ +require_relative 'gem_version' + +module ActiveSupport + # Returns the version of the currently loaded ActiveSupport as a Gem::Version + def self.version + gem_version + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/xml_mini.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/xml_mini.rb new file mode 100644 index 0000000..df7b081 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/xml_mini.rb @@ -0,0 +1,194 @@ +require 'time' +require 'base64' +require 'bigdecimal' +require 'active_support/core_ext/module/delegation' +require 'active_support/core_ext/string/inflections' +require 'active_support/core_ext/date_time/calculations' + +module ActiveSupport + # = XmlMini + # + # To use the much faster libxml parser: + # gem 'libxml-ruby', '=0.9.7' + # XmlMini.backend = 'LibXML' + module XmlMini + extend self + + # This module decorates files deserialized using Hash.from_xml with + # the original_filename and content_type methods. + module FileLike #:nodoc: + attr_writer :original_filename, :content_type + + def original_filename + @original_filename || 'untitled' + end + + def content_type + @content_type || 'application/octet-stream' + end + end + + DEFAULT_ENCODINGS = { + "binary" => "base64" + } unless defined?(DEFAULT_ENCODINGS) + + TYPE_NAMES = { + "Symbol" => "symbol", + "Fixnum" => "integer", + "Bignum" => "integer", + "BigDecimal" => "decimal", + "Float" => "float", + "TrueClass" => "boolean", + "FalseClass" => "boolean", + "Date" => "date", + "DateTime" => "dateTime", + "Time" => "dateTime", + "Array" => "array", + "Hash" => "hash" + } unless defined?(TYPE_NAMES) + + FORMATTING = { + "symbol" => Proc.new { |symbol| symbol.to_s }, + "date" => Proc.new { |date| date.to_s(:db) }, + "dateTime" => Proc.new { |time| time.xmlschema }, + "binary" => Proc.new { |binary| ::Base64.encode64(binary) }, + "yaml" => Proc.new { |yaml| yaml.to_yaml } + } unless defined?(FORMATTING) + + # TODO use regexp instead of Date.parse + unless defined?(PARSING) + PARSING = { + "symbol" => Proc.new { |symbol| symbol.to_s.to_sym }, + "date" => Proc.new { |date| ::Date.parse(date) }, + "datetime" => Proc.new { |time| Time.xmlschema(time).utc rescue ::DateTime.parse(time).utc }, + "integer" => Proc.new { |integer| integer.to_i }, + "float" => Proc.new { |float| float.to_f }, + "decimal" => Proc.new { |number| BigDecimal(number) }, + "boolean" => Proc.new { |boolean| %w(1 true).include?(boolean.to_s.strip) }, + "string" => Proc.new { |string| string.to_s }, + "yaml" => Proc.new { |yaml| YAML::load(yaml) rescue yaml }, + "base64Binary" => Proc.new { |bin| ::Base64.decode64(bin) }, + "binary" => Proc.new { |bin, entity| _parse_binary(bin, entity) }, + "file" => Proc.new { |file, entity| _parse_file(file, entity) } + } + + PARSING.update( + "double" => PARSING["float"], + "dateTime" => PARSING["datetime"] + ) + end + + attr_accessor :depth + self.depth = 100 + + delegate :parse, :to => :backend + + def backend + current_thread_backend || @backend + end + + def backend=(name) + backend = name && cast_backend_name_to_module(name) + self.current_thread_backend = backend if current_thread_backend + @backend = backend + end + + def with_backend(name) + old_backend = current_thread_backend + self.current_thread_backend = name && cast_backend_name_to_module(name) + yield + ensure + self.current_thread_backend = old_backend + end + + def to_tag(key, value, options) + type_name = options.delete(:type) + merged_options = options.merge(:root => key, :skip_instruct => true) + + if value.is_a?(::Method) || value.is_a?(::Proc) + if value.arity == 1 + value.call(merged_options) + else + value.call(merged_options, key.to_s.singularize) + end + elsif value.respond_to?(:to_xml) + value.to_xml(merged_options) + else + type_name ||= TYPE_NAMES[value.class.name] + type_name ||= value.class.name if value && !value.respond_to?(:to_str) + type_name = type_name.to_s if type_name + type_name = "dateTime" if type_name == "datetime" + + key = rename_key(key.to_s, options) + + attributes = options[:skip_types] || type_name.nil? ? { } : { :type => type_name } + attributes[:nil] = true if value.nil? + + encoding = options[:encoding] || DEFAULT_ENCODINGS[type_name] + attributes[:encoding] = encoding if encoding + + formatted_value = FORMATTING[type_name] && !value.nil? ? + FORMATTING[type_name].call(value) : value + + options[:builder].tag!(key, formatted_value, attributes) + end + end + + def rename_key(key, options = {}) + camelize = options[:camelize] + dasherize = !options.has_key?(:dasherize) || options[:dasherize] + if camelize + key = true == camelize ? key.camelize : key.camelize(camelize) + end + key = _dasherize(key) if dasherize + key + end + + protected + + def _dasherize(key) + # $2 must be a non-greedy regex for this to work + left, middle, right = /\A(_*)(.*?)(_*)\Z/.match(key.strip)[1,3] + "#{left}#{middle.tr('_ ', '--')}#{right}" + end + + # TODO: Add support for other encodings + def _parse_binary(bin, entity) #:nodoc: + case entity['encoding'] + when 'base64' + ::Base64.decode64(bin) + else + bin + end + end + + def _parse_file(file, entity) + f = StringIO.new(::Base64.decode64(file)) + f.extend(FileLike) + f.original_filename = entity['name'] + f.content_type = entity['content_type'] + f + end + + private + + def current_thread_backend + Thread.current[:xml_mini_backend] + end + + def current_thread_backend=(name) + Thread.current[:xml_mini_backend] = name && cast_backend_name_to_module(name) + end + + def cast_backend_name_to_module(name) + if name.is_a?(Module) + name + else + require "active_support/xml_mini/#{name.downcase}" + ActiveSupport.const_get("XmlMini_#{name}") + end + end + end + + XmlMini.backend = 'REXML' +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/xml_mini/jdom.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/xml_mini/jdom.rb new file mode 100644 index 0000000..cdc5490 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/xml_mini/jdom.rb @@ -0,0 +1,181 @@ +raise "JRuby is required to use the JDOM backend for XmlMini" unless RUBY_PLATFORM =~ /java/ + +require 'jruby' +include Java + +require 'active_support/core_ext/object/blank' + +java_import javax.xml.parsers.DocumentBuilder unless defined? DocumentBuilder +java_import javax.xml.parsers.DocumentBuilderFactory unless defined? DocumentBuilderFactory +java_import java.io.StringReader unless defined? StringReader +java_import org.xml.sax.InputSource unless defined? InputSource +java_import org.xml.sax.Attributes unless defined? Attributes +java_import org.w3c.dom.Node unless defined? Node + +module ActiveSupport + module XmlMini_JDOM #:nodoc: + extend self + + CONTENT_KEY = '__content__'.freeze + + NODE_TYPE_NAMES = %w{ATTRIBUTE_NODE CDATA_SECTION_NODE COMMENT_NODE DOCUMENT_FRAGMENT_NODE + DOCUMENT_NODE DOCUMENT_TYPE_NODE ELEMENT_NODE ENTITY_NODE ENTITY_REFERENCE_NODE NOTATION_NODE + PROCESSING_INSTRUCTION_NODE TEXT_NODE} + + node_type_map = {} + NODE_TYPE_NAMES.each { |type| node_type_map[Node.send(type)] = type } + + # Parse an XML Document string or IO into a simple hash using Java's jdom. + # data:: + # XML Document string or IO to parse + def parse(data) + if data.respond_to?(:read) + data = data.read + end + + if data.blank? + {} + else + @dbf = DocumentBuilderFactory.new_instance + # secure processing of java xml + # http://www.ibm.com/developerworks/xml/library/x-tipcfsx/index.html + @dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false) + @dbf.setFeature("http://xml.org/sax/features/external-general-entities", false) + @dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false) + @dbf.setFeature(javax.xml.XMLConstants::FEATURE_SECURE_PROCESSING, true) + xml_string_reader = StringReader.new(data) + xml_input_source = InputSource.new(xml_string_reader) + doc = @dbf.new_document_builder.parse(xml_input_source) + merge_element!({CONTENT_KEY => ''}, doc.document_element, XmlMini.depth) + end + end + + private + + # Convert an XML element and merge into the hash + # + # hash:: + # Hash to merge the converted element into. + # element:: + # XML element to merge into hash + def merge_element!(hash, element, depth) + raise 'Document too deep!' if depth == 0 + delete_empty(hash) + merge!(hash, element.tag_name, collapse(element, depth)) + end + + def delete_empty(hash) + hash.delete(CONTENT_KEY) if hash[CONTENT_KEY] == '' + end + + # Actually converts an XML document element into a data structure. + # + # element:: + # The document element to be collapsed. + def collapse(element, depth) + hash = get_attributes(element) + + child_nodes = element.child_nodes + if child_nodes.length > 0 + (0...child_nodes.length).each do |i| + child = child_nodes.item(i) + merge_element!(hash, child, depth - 1) unless child.node_type == Node.TEXT_NODE + end + merge_texts!(hash, element) unless empty_content?(element) + hash + else + merge_texts!(hash, element) + end + end + + # Merge all the texts of an element into the hash + # + # hash:: + # Hash to add the converted element to. + # element:: + # XML element whose texts are to me merged into the hash + def merge_texts!(hash, element) + delete_empty(hash) + text_children = texts(element) + if text_children.join.empty? + hash + else + # must use value to prevent double-escaping + merge!(hash, CONTENT_KEY, text_children.join) + end + end + + # Adds a new key/value pair to an existing Hash. If the key to be added + # already exists and the existing value associated with key is not + # an Array, it will be wrapped in an Array. Then the new value is + # appended to that Array. + # + # hash:: + # Hash to add key/value pair to. + # key:: + # Key to be added. + # value:: + # Value to be associated with key. + def merge!(hash, key, value) + if hash.has_key?(key) + if hash[key].instance_of?(Array) + hash[key] << value + else + hash[key] = [hash[key], value] + end + elsif value.instance_of?(Array) + hash[key] = [value] + else + hash[key] = value + end + hash + end + + # Converts the attributes array of an XML element into a hash. + # Returns an empty Hash if node has no attributes. + # + # element:: + # XML element to extract attributes from. + def get_attributes(element) + attribute_hash = {} + attributes = element.attributes + (0...attributes.length).each do |i| + attribute_hash[CONTENT_KEY] ||= '' + attribute_hash[attributes.item(i).name] = attributes.item(i).value + end + attribute_hash + end + + # Determines if a document element has text content + # + # element:: + # XML element to be checked. + def texts(element) + texts = [] + child_nodes = element.child_nodes + (0...child_nodes.length).each do |i| + item = child_nodes.item(i) + if item.node_type == Node.TEXT_NODE + texts << item.get_data + end + end + texts + end + + # Determines if a document element has text content + # + # element:: + # XML element to be checked. + def empty_content?(element) + text = '' + child_nodes = element.child_nodes + (0...child_nodes.length).each do |i| + item = child_nodes.item(i) + if item.node_type == Node.TEXT_NODE + text << item.get_data.strip + end + end + text.strip.length == 0 + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/xml_mini/libxml.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/xml_mini/libxml.rb new file mode 100644 index 0000000..47a2824 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/xml_mini/libxml.rb @@ -0,0 +1,79 @@ +require 'libxml' +require 'active_support/core_ext/object/blank' +require 'stringio' + +module ActiveSupport + module XmlMini_LibXML #:nodoc: + extend self + + # Parse an XML Document string or IO into a simple hash using libxml. + # data:: + # XML Document string or IO to parse + def parse(data) + if !data.respond_to?(:read) + data = StringIO.new(data || '') + end + + char = data.getc + if char.nil? + {} + else + data.ungetc(char) + LibXML::XML::Parser.io(data).parse.to_hash + end + end + + end +end + +module LibXML #:nodoc: + module Conversions #:nodoc: + module Document #:nodoc: + def to_hash + root.to_hash + end + end + + module Node #:nodoc: + CONTENT_ROOT = '__content__'.freeze + + # Convert XML document to hash. + # + # hash:: + # Hash to merge the converted element into. + def to_hash(hash={}) + node_hash = {} + + # Insert node hash into parent hash correctly. + case hash[name] + when Array then hash[name] << node_hash + when Hash then hash[name] = [hash[name], node_hash] + when nil then hash[name] = node_hash + end + + # Handle child elements + each_child do |c| + if c.element? + c.to_hash(node_hash) + elsif c.text? || c.cdata? + node_hash[CONTENT_ROOT] ||= '' + node_hash[CONTENT_ROOT] << c.content + end + end + + # Remove content node if it is blank + if node_hash.length > 1 && node_hash[CONTENT_ROOT].blank? + node_hash.delete(CONTENT_ROOT) + end + + # Handle attributes + each_attr { |a| node_hash[a.name] = a.value } + + hash + end + end + end +end + +LibXML::XML::Document.send(:include, LibXML::Conversions::Document) +LibXML::XML::Node.send(:include, LibXML::Conversions::Node) diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/xml_mini/libxmlsax.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/xml_mini/libxmlsax.rb new file mode 100644 index 0000000..70a9529 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/xml_mini/libxmlsax.rb @@ -0,0 +1,85 @@ +require 'libxml' +require 'active_support/core_ext/object/blank' +require 'stringio' + +module ActiveSupport + module XmlMini_LibXMLSAX #:nodoc: + extend self + + # Class that will build the hash while the XML document + # is being parsed using SAX events. + class HashBuilder + + include LibXML::XML::SaxParser::Callbacks + + CONTENT_KEY = '__content__'.freeze + HASH_SIZE_KEY = '__hash_size__'.freeze + + attr_reader :hash + + def current_hash + @hash_stack.last + end + + def on_start_document + @hash = { CONTENT_KEY => '' } + @hash_stack = [@hash] + end + + def on_end_document + @hash = @hash_stack.pop + @hash.delete(CONTENT_KEY) + end + + def on_start_element(name, attrs = {}) + new_hash = { CONTENT_KEY => '' }.merge!(attrs) + new_hash[HASH_SIZE_KEY] = new_hash.size + 1 + + case current_hash[name] + when Array then current_hash[name] << new_hash + when Hash then current_hash[name] = [current_hash[name], new_hash] + when nil then current_hash[name] = new_hash + end + + @hash_stack.push(new_hash) + end + + def on_end_element(name) + if current_hash.length > current_hash.delete(HASH_SIZE_KEY) && current_hash[CONTENT_KEY].blank? || current_hash[CONTENT_KEY] == '' + current_hash.delete(CONTENT_KEY) + end + @hash_stack.pop + end + + def on_characters(string) + current_hash[CONTENT_KEY] << string + end + + alias_method :on_cdata_block, :on_characters + end + + attr_accessor :document_class + self.document_class = HashBuilder + + def parse(data) + if !data.respond_to?(:read) + data = StringIO.new(data || '') + end + + char = data.getc + if char.nil? + {} + else + data.ungetc(char) + + LibXML::XML::Error.set_handler(&LibXML::XML::Error::QUIET_HANDLER) + parser = LibXML::XML::SaxParser.io(data) + document = self.document_class.new + + parser.callbacks = document + parser.parse + document.hash + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/xml_mini/nokogiri.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/xml_mini/nokogiri.rb new file mode 100644 index 0000000..7398d4f --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/xml_mini/nokogiri.rb @@ -0,0 +1,83 @@ +begin + require 'nokogiri' +rescue LoadError => e + $stderr.puts "You don't have nokogiri installed in your application. Please add it to your Gemfile and run bundle install" + raise e +end +require 'active_support/core_ext/object/blank' +require 'stringio' + +module ActiveSupport + module XmlMini_Nokogiri #:nodoc: + extend self + + # Parse an XML Document string or IO into a simple hash using libxml / nokogiri. + # data:: + # XML Document string or IO to parse + def parse(data) + if !data.respond_to?(:read) + data = StringIO.new(data || '') + end + + char = data.getc + if char.nil? + {} + else + data.ungetc(char) + doc = Nokogiri::XML(data) + raise doc.errors.first if doc.errors.length > 0 + doc.to_hash + end + end + + module Conversions #:nodoc: + module Document #:nodoc: + def to_hash + root.to_hash + end + end + + module Node #:nodoc: + CONTENT_ROOT = '__content__'.freeze + + # Convert XML document to hash. + # + # hash:: + # Hash to merge the converted element into. + def to_hash(hash={}) + node_hash = {} + + # Insert node hash into parent hash correctly. + case hash[name] + when Array then hash[name] << node_hash + when Hash then hash[name] = [hash[name], node_hash] + when nil then hash[name] = node_hash + end + + # Handle child elements + children.each do |c| + if c.element? + c.to_hash(node_hash) + elsif c.text? || c.cdata? + node_hash[CONTENT_ROOT] ||= '' + node_hash[CONTENT_ROOT] << c.content + end + end + + # Remove content node if it is blank and there are child tags + if node_hash.length > 1 && node_hash[CONTENT_ROOT].blank? + node_hash.delete(CONTENT_ROOT) + end + + # Handle attributes + attribute_nodes.each { |a| node_hash[a.node_name] = a.value } + + hash + end + end + end + + Nokogiri::XML::Document.send(:include, Conversions::Document) + Nokogiri::XML::Node.send(:include, Conversions::Node) + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/xml_mini/nokogirisax.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/xml_mini/nokogirisax.rb new file mode 100644 index 0000000..be2d6a4 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/xml_mini/nokogirisax.rb @@ -0,0 +1,87 @@ +begin + require 'nokogiri' +rescue LoadError => e + $stderr.puts "You don't have nokogiri installed in your application. Please add it to your Gemfile and run bundle install" + raise e +end +require 'active_support/core_ext/object/blank' +require 'stringio' + +module ActiveSupport + module XmlMini_NokogiriSAX #:nodoc: + extend self + + # Class that will build the hash while the XML document + # is being parsed using SAX events. + class HashBuilder < Nokogiri::XML::SAX::Document + + CONTENT_KEY = '__content__'.freeze + HASH_SIZE_KEY = '__hash_size__'.freeze + + attr_reader :hash + + def current_hash + @hash_stack.last + end + + def start_document + @hash = {} + @hash_stack = [@hash] + end + + def end_document + raise "Parse stack not empty!" if @hash_stack.size > 1 + end + + def error(error_message) + raise error_message + end + + def start_element(name, attrs = []) + new_hash = { CONTENT_KEY => '' }.merge!(Hash[attrs]) + new_hash[HASH_SIZE_KEY] = new_hash.size + 1 + + case current_hash[name] + when Array then current_hash[name] << new_hash + when Hash then current_hash[name] = [current_hash[name], new_hash] + when nil then current_hash[name] = new_hash + end + + @hash_stack.push(new_hash) + end + + def end_element(name) + if current_hash.length > current_hash.delete(HASH_SIZE_KEY) && current_hash[CONTENT_KEY].blank? || current_hash[CONTENT_KEY] == '' + current_hash.delete(CONTENT_KEY) + end + @hash_stack.pop + end + + def characters(string) + current_hash[CONTENT_KEY] << string + end + + alias_method :cdata_block, :characters + end + + attr_accessor :document_class + self.document_class = HashBuilder + + def parse(data) + if !data.respond_to?(:read) + data = StringIO.new(data || '') + end + + char = data.getc + if char.nil? + {} + else + data.ungetc(char) + document = self.document_class.new + parser = Nokogiri::XML::SAX::Parser.new(document) + parser.parse(data) + document.hash + end + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/xml_mini/rexml.rb b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/xml_mini/rexml.rb new file mode 100644 index 0000000..924ed72 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.6/lib/active_support/xml_mini/rexml.rb @@ -0,0 +1,130 @@ +require 'active_support/core_ext/kernel/reporting' +require 'active_support/core_ext/object/blank' +require 'stringio' + +module ActiveSupport + module XmlMini_REXML #:nodoc: + extend self + + CONTENT_KEY = '__content__'.freeze + + # Parse an XML Document string or IO into a simple hash. + # + # Same as XmlSimple::xml_in but doesn't shoot itself in the foot, + # and uses the defaults from Active Support. + # + # data:: + # XML Document string or IO to parse + def parse(data) + if !data.respond_to?(:read) + data = StringIO.new(data || '') + end + + char = data.getc + if char.nil? + {} + else + data.ungetc(char) + silence_warnings { require 'rexml/document' } unless defined?(REXML::Document) + doc = REXML::Document.new(data) + + if doc.root + merge_element!({}, doc.root, XmlMini.depth) + else + raise REXML::ParseException, + "The document #{doc.to_s.inspect} does not have a valid root" + end + end + end + + private + # Convert an XML element and merge into the hash + # + # hash:: + # Hash to merge the converted element into. + # element:: + # XML element to merge into hash + def merge_element!(hash, element, depth) + raise REXML::ParseException, "The document is too deep" if depth == 0 + merge!(hash, element.name, collapse(element, depth)) + end + + # Actually converts an XML document element into a data structure. + # + # element:: + # The document element to be collapsed. + def collapse(element, depth) + hash = get_attributes(element) + + if element.has_elements? + element.each_element {|child| merge_element!(hash, child, depth - 1) } + merge_texts!(hash, element) unless empty_content?(element) + hash + else + merge_texts!(hash, element) + end + end + + # Merge all the texts of an element into the hash + # + # hash:: + # Hash to add the converted element to. + # element:: + # XML element whose texts are to me merged into the hash + def merge_texts!(hash, element) + unless element.has_text? + hash + else + # must use value to prevent double-escaping + texts = '' + element.texts.each { |t| texts << t.value } + merge!(hash, CONTENT_KEY, texts) + end + end + + # Adds a new key/value pair to an existing Hash. If the key to be added + # already exists and the existing value associated with key is not + # an Array, it will be wrapped in an Array. Then the new value is + # appended to that Array. + # + # hash:: + # Hash to add key/value pair to. + # key:: + # Key to be added. + # value:: + # Value to be associated with key. + def merge!(hash, key, value) + if hash.has_key?(key) + if hash[key].instance_of?(Array) + hash[key] << value + else + hash[key] = [hash[key], value] + end + elsif value.instance_of?(Array) + hash[key] = [value] + else + hash[key] = value + end + hash + end + + # Converts the attributes array of an XML element into a hash. + # Returns an empty Hash if node has no attributes. + # + # element:: + # XML element to extract attributes from. + def get_attributes(element) + attributes = {} + element.attributes.each { |n,v| attributes[n] = v } + attributes + end + + # Determines if a document element has text content + # + # element:: + # XML element to be checked. + def empty_content?(element) + element.texts.join.blank? + end + end +end diff --git a/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/.index b/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/.index new file mode 100644 index 0000000..53ed8fe --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/.index @@ -0,0 +1,77 @@ +--- +revision: 2013 +type: ruby +sources: +- INDEX.yml +authors: +- name: Thomas Sawyer + email: transfire@gmail.com +- name: Florian Frank +organizations: [] +requirements: +- groups: + - build + development: true + name: mast +- groups: + - build + development: true + name: indexer +- groups: + - build + development: true + name: ergo +- groups: + - test + development: true + name: qed +- groups: + - test + development: true + name: ae +- groups: + - test + development: true + name: lemon +conflicts: [] +alternatives: [] +resources: +- type: home + uri: http://rubyworks.github.com/ansi + label: Homepage +- type: docs + uri: http://rubydoc.info/gems/ansi/frames + label: Documentation +- type: code + uri: http://github.com/rubyworks/ansi + label: Source Code +- type: bugs + uri: http://github.com/rubyworks/ansi/issues + label: Issue Tracker +- type: mail + uri: http://groups.google.com/group/rubyworks-mailinglist + label: Mailing List +repositories: +- name: upstream + scm: git + uri: git://github.com/rubyworks/ansi.git +categories: [] +copyrights: +- holder: Rubyworks + year: '2009' + license: BSD-2-Clause +customs: [] +paths: + lib: + - lib +name: ansi +title: ANSI +version: 1.5.0 +summary: ANSI at your fingertips! +description: The ANSI project is a superlative collection of ANSI escape code related + libraries eabling ANSI colorization and stylization of console output. Byte for + byte ANSI is the best ANSI code library available for the Ruby programming language. +orgranizations: +- Rubyworks +created: '2009-08-01' +date: '2015-01-16' diff --git a/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/.yardopts b/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/.yardopts new file mode 100644 index 0000000..9c435b5 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/.yardopts @@ -0,0 +1,8 @@ +--title ANSI +--protected +--private +lib +- +QED.rdoc +[A-Z]*.* + diff --git a/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/DEMO.md b/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/DEMO.md new file mode 100644 index 0000000..e0166f4 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/DEMO.md @@ -0,0 +1,451 @@ +# ANSI::Code + +Require the library. + + require 'ansi/code' + +ANSI::Code can be used as a functions module. + + str = ANSI::Code.red + "Hello" + ANSI::Code.blue + "World" + str.assert == "\e[31mHello\e[34mWorld" + +If a block is supplied to each method then yielded value will +be wrapped in the ANSI code and clear code. + + str = ANSI::Code.red{ "Hello" } + ANSI::Code.blue{ "World" } + str.assert == "\e[31mHello\e[0m\e[34mWorld\e[0m" + +More conveniently the ANSI::Code module extends ANSI itself. + + str = ANSI.red + "Hello" + ANSI.blue + "World" + str.assert == "\e[31mHello\e[34mWorld" + + str = ANSI.red{ "Hello" } + ANSI.blue{ "World" } + str.assert == "\e[31mHello\e[0m\e[34mWorld\e[0m" + +In the appropriate context the ANSI::Code module can also be +included, making its methods directly accessible. + + include ANSI::Code + + str = red + "Hello" + blue + "World" + str.assert == "\e[31mHello\e[34mWorld" + + str = red{ "Hello" } + blue{ "World" } + str.assert == "\e[31mHello\e[0m\e[34mWorld\e[0m" + +Along with the single font colors, the library include background colors. + + str = on_red + "Hello" + str.assert == "\e[41mHello" + +As well as combined color methods. + + str = white_on_red + "Hello" + str.assert == "\e[37m\e[41mHello" + +The ANSI::Code module supports most standard ANSI codes, though +not all platforms support every code, so YMMV. + + +# String Extensions + +In addition the library offers an extension to String class +called #ansi, which allows some of the ANSI::Code methods +to be called in a more object-oriented fashion. + + require 'ansi/core' + + str = "Hello".ansi(:red) + "World".ansi(:blue) + str.assert == "\e[31mHello\e[0m\e[34mWorld\e[0m" + + +# ANSI::Logger + +Require the ANSI::Logger library. + + require 'ansi/logger' + +Create a new ANSI::Logger + + log = ANSI::Logger.new(STDOUT) + +Info logging appears normal. + + log.info{"Info logs are green.\n"} + +Warn logging appears yellow. + + log.warn{"Warn logs are yellow.\n"} + +Debug logging appears cyan. + + log.debug{"Debug logs are cyan.\n"} + +Error logging appears red. + + log.error{"Error logs are red.\n"} + +Fatal logging appears bright red. + + log.fatal{"Fatal logs are bold red!\n"} + + +# ANSI::Progressbar + +Pretty progress bars are easy to construct. + + require 'ansi/progressbar' + + pbar = ANSI::Progressbar.new("Test Bar", 100) + +Running the bar simply requires calling the #inc method during +a loop and calling #finish when done. + + 100.times do |i| + sleep 0.01 + pbar.inc + end + pbar.finish + +We will use this same rountine in all the examples below, so lets +make a quick macro for it. Notice we have to use #reset first +before reusing the same progress bar. + + def run(pbar) + pbar.reset + 100.times do |i| + sleep 0.01 + pbar.inc + end + pbar.finish + puts + end + +The progress bar can be stylized in almost any way. +The #format setter provides control over the parts +that appear on the line. For example, by default the +format is: + + pbar.format("%-14s %3d%% %s %s", :title, :percentage, :bar, :stat) + +So lets vary it up to demonstrate the case. + + pbar.format("%-14s %3d%% %s %s", :title, :percentage, :stat, :bar) + run(pbar) + +The progress bar has an extra build in format intended for use with +file downloads called #transer_mode. + + pbar.transfer_mode + run(pbar) + +Calling this methods is the same as calling: + + pbar.format("%-14s %3d%% %s %s",:title, :percentage, :bar, :stat_for_file_transfer) + run(pbar) + +The #style setter allows each part of the line be modified with ANSI codes. And the +#bar_mark writer can be used to change the character used to make the bar. + + pbar.standard_mode + pbar.style(:title => [:red], :bar=>[:blue]) + pbar.bar_mark = "=" + run(pbar) + + +# ANSI::Mixin + +The ANSI::Mixin module is design for including into +String-like classes. It will support any class that defines +a #to_s method. + + require 'ansi/mixin' + +In this demonstration we will simply include it in the +core String class. + + class ::String + include ANSI::Mixin + end + +Now all strings will have access to ANSI's style and color +codes via simple method calls. + + "roses".red.assert == "\e[31mroses\e[0m" + + "violets".blue.assert == "\e[34mviolets\e[0m" + + "sugar".italic.assert == "\e[3msugar\e[0m" + +The method can be combined, of course. + + "you".italic.bold.assert == "\e[1m\e[3myou\e[0m\e[0m" + +The mixin also supports background methods. + + "envy".on_green.assert == "\e[42menvy\e[0m" + +And it also supports the combined foreground-on-background +methods. + + "b&w".white_on_black.assert == "\e[37m\e[40mb&w\e[0m" + + +# ANSI::String + +The ANSI::String class is a very sophisticated implementation +of Ruby's standard String class, but one that can handle +ANSI codes seamlessly. + + require 'ansi/string' + + flower1 = ANSI::String.new("Roses") + flower2 = ANSI::String.new("Violets") + +Like any other string. + + flower1.to_s.assert == "Roses" + flower2.to_s.assert == "Violets" + +Bet now we can add color. + + flower1.red! + flower2.blue! + + flower1.to_s.assert == "\e[31mRoses\e[0m" + flower2.to_s.assert == "\e[34mViolets\e[0m" + +Despite that the string representation now contains ANSI codes, +we can still manipulate the string in much the same way that +we manipulate an ordinary string. + + flower1.size.assert == 5 + flower2.size.assert == 7 + +Like ordinary strings we can concatenate the two strings + + flowers = flower1 + ' ' + flower2 + flowers.to_s.assert == "\e[31mRoses\e[0m \e[34mViolets\e[0m" + + flowers.size.assert == 13 + +Standard case conversion such as #upcase and #downcase work. + + flower1.upcase.to_s.assert == "\e[31mROSES\e[0m" + flower1.downcase.to_s.assert == "\e[31mroses\e[0m" + +Some of the most difficult methods to re-implement were the +substitution methods such as #sub and #gsub. They are still +somewhat more limited than the original string methods, but +their primary functionality should work. + + flower1.gsub('s', 'z').to_s.assert == "\e[31mRozez\e[0m" + +There are still a number of methods that need implementation. +ANSI::String is currently a very partial implementation. But +as you can see from the methods it does currently support, +is it already useful. + + +# ANSI::Columns + +The +Columns+ class makes it easy to create nice looking text columns, +sorted from top to bottom, right to left (as opposed to the other way +around). + + require 'ansi/columns' + + list = %w{a b c d e f g h i j k l} + + columns = ANSI::Columns.new(list) + + columns.to_s(4) + +The output will be: + + a d g j + b e h k + c f i l + +Besides an array of elements, Columns.new can take a string in which +the elements are divided by newlines characters. The default column +size can also be given to the initializer. + + list = "a\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl" + + columns = ANSI::Columns.new(list, :columns=>6) + + columns.to_s + +The output will be: + + a c e g i k + b d f h j l + +If the column count is +nil+, then the number of columns will be calculated +as a best fit for the current terminal window. + +## Padding + +Columns can adjust the padding between cells. + + list = %w{a b c d e f g h i j k l} + + columns = ANSI::Columns.new(list, :padding=>2) + + columns.to_s(4) + +The output will be: + + a d g j + b e h k + c f i l + +## Alignment + +Columns can also be aligned either left or right. + + list = %w{xx xx xx yy y yy z zz z} + + columns = ANSI::Columns.new(list, :align=>:right) + + columns.to_s(3) + +The output will be: + + xx yy z + xx y zz + xx yy z + +## Format + +Lastly, columns can be augmented with ANSI codes. This is done through +a formatting block. The block can take up to three parameters, the cell +content, the column and row numbers, or the cell and the column and row +numbers. + + list = %w{a b c d e f g h i j k l} + + columns = ANSI::Columns.new(list){ |c,r| r % 2 == 0 ? :red : :blue } + + out = columns.to_s(4) + + out.assert == ( + "\e[31ma \e[0m\e[31md \e[0m\e[31mg \e[0m\e[31mj \e[0m\n" + + "\e[34mb \e[0m\e[34me \e[0m\e[34mh \e[0m\e[34mk \e[0m\n" + + "\e[31mc \e[0m\e[31mf \e[0m\e[31mi \e[0m\e[31ml \e[0m\n" + ) + + +# ANSI::Table + +The ANSI::Table class can be used to output tabular data with nicely +formated ASCII cell borders. + + require 'ansi/table' + +The constructor takes an 2-dimensional array. + + data = [ + [ 10, 20, 30 ], + [ 20, 10, 20 ], + [ 50, 40, 20 ] + ] + + table = ANSI::Table.new(data) + + table.to_s + +The output will be: + + +----+----+----+ + | 10 | 20 | 30 | + | 20 | 10 | 20 | + | 50 | 40 | 20 | + +----+----+----+ + + + +# ANSI::Diff + + require 'ansi/diff' + + a = 'abcYefg' + b = 'abcXefg' + + diff = ANSI::Diff.new(a,b) + + diff.to_s.assert == "\e[31mabc\e[0m\e[33mYefg\e[0m\n\e[31mabc\e[0mXefg" + +Try another. + + a = 'abc' + b = 'abcdef' + + diff = ANSI::Diff.new(a,b) + + diff.to_s.assert == "\e[31mabc\e[0m\n\e[31mabc\e[0mdef" + +And another. + + a = 'abcXXXghi' + b = 'abcdefghi' + + diff = ANSI::Diff.new(a,b) + + diff.to_s.assert == "\e[31mabc\e[0m\e[33mXXXghi\e[0m\n\e[31mabc\e[0mdefghi" + +And another. + + a = 'abcXXXdefghi' + b = 'abcdefghi' + + diff = ANSI::Diff.new(a,b) + + diff.to_s.assert == "\e[31mabc\e[0m\e[33mXXX\e[0m\e[35mdefghi\e[0m\n\e[31mabc\e[0m\e[35mdefghi\e[0m" + +Comparison that is mostly different. + + a = 'abcpppz123' + b = 'abcxyzzz43' + + diff = ANSI::Diff.new(a,b) + + diff.to_s.assert == "\e[31mabc\e[0m\e[33mpppz123\e[0m\n\e[31mabc\e[0mxyzzz43" + + +# ANSI::BBCode + +The BBCode module provides methods for converting between +BBCodes, basic HTML and ANSI codes. + + require 'ansi/bbcode' + +BBCodes are color and style codes in square brackets, quite +popular with on line forums. + + bbcode = "this is [COLOR=red]red[/COLOR], this is [B]bold[/B]" + +We can convert this to ANSI code simply enough: + + ansi = ANSI::BBCode.bbcode_to_ansi(bbcode) + + ansi.assert == "this is \e[0;31mred\e[0m, this is \e[1mbold\e[0m\n" + +In addition the BBCode module supports conversion to simple HTML. + + html = ANSI::BBCode.bbcode_to_html(bbcode) + + html.assert == "this is red, this is bold
    \n" + + +# ANSI::Terminal + +We should be ables to get the terminal width via the `terminal_width` method. + + width = ANSI::Terminal.terminal_width + + Fixnum.assert === width + + diff --git a/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/HISTORY.md b/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/HISTORY.md new file mode 100644 index 0000000..dfa8838 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/HISTORY.md @@ -0,0 +1,217 @@ +# RELEASE HISTORY + +## 1.5.0 | 2015-01-16 + +ANSI 1.5 introduces one change that is not backward compatiable. The +`:clear_line` code no longer clears to the end of the line. Instead it +clears the entire line. If you have used this in the past you +will need to update your code to use `:clear_eol` or `:clear_right` +instead. In addition this release finally fixes some long time issues +with Windows compatability, and a few other bugs. Yeah! + +Changes: + +* Alias `:right` and `:left` as `:forward` and `:back` respectively. +* Change `:clear_line` to clear whole line, not just to the end of line. +* Add `:cursor_hide` and `:cursor_show` codes. +* Fix and adjust #rgb method to work as one would expect. +* Fix Windows compatability (old code was alwasy using stty). +* Fix duplicated hash key in chart.rb. + + +## 1.4.3 | 2012-06-26 + +This release bring two small changes. The first improves support +for Windows by only rescuing LoadError when 'win32console' fails +to load. The second improves the heuritstics used for determining +the current terminal screen width. + +Changes: + +* Only rescue LoadError on windows require. (#9) [bug] +* Improvements for getting proper screen width. + + +## 1.4.2 | 2012-01-29 + +ANSI chains are a new feature inspired by Kazuyoshi Tlacaelel's Isna project. +It is a fluid notation for the String#ansi method, e.g. `"foo".red.on_white`. +Also, ASNI now supports "smart codes", preventing previously applied codes +from undermining the applicaiton of additional codes --a subtle issue that +most other ANSI libraries overlook. Plus a few other improvements including +that of the API documentation. + +Changes: + +* Add ANSI::Chains, extending String#ansi method. +* Support smart code application. +* Add Diff#to_a and shortcut to it via Diff.diff(). +* Improve #colorize method in ProgressBar. +* Change ProgressBar's default mark to `|` instead of `o`. +* Fix Curses return order of screen cols and rows. +* Support center alignment in Columns. +* Support custom padding for Columns. + + +## 1.4.1 | 2011-11-09 + +This release simply fixes a documentation issue, to make sure +QED.rdoc appears in the YARD docs. And a shout-out to Chad Perrin +for submitting some doc fixes for this project and a few other +Rubyworks projects. + +Changes: + +* Adjust .yardopts file. +* Documentation fixes. + + +## 1.4.0 | 2011-11-05 + +New release adds a HexDump class for colorized byte string dumps +and fixes some minor cell size issues with the Table class. +This release also modernizes the build config and changes the +license to BSD-2-Clause. + +Changes: + +* Add HexDump class. +* Fix cell size of tables when ANSI codes are used. +* Fix extra ansi codes in tables without format. +* Modernize build configuration. +* Switch to BSD-2-Clause license. + + +## 1.3.0 | 2011-06-30 + +This release cleans up the Code module. It adds support for x-term +256 color codes. Also, the Diff class is now awesome, making use of +an LCS algorithm. But the most important difference with this release +is that the String core extensions are in their own file, core.rb. +If you want to use them you will need to require `ansi` or `ansi/core`. + +Changes: + +* Clean-up Code module. +* Utilize common chart for Code methods. +* Constants now have their own module. +* Move core methods to `ansi/core.rb`. +* Add XTerm 256 color code support. +* Improved Diff class with LCS algorithm. + + +## 1.2.5 | 2011-05-03 + +This release introduces a preliminary rendition of a Diff class +for getting colorized comparisons of strings and other objects. +It's not officially supported yet, so this is only a point release. + +Changes: + +* Added Diff class for colorized comparisons. +* Fixed minor issue with Columns format block; col comes before row. + + +## 1.2.4 | 2011-04-29 + +This release improves to the ANSI::Columns class. In particular the +layout is more consistent with intended functionality. + +Changes: + +* Improved ANSI::Columns to give more consistent output. +* ANSI::Columns#to_s can override number of columns. +* ANSI::Columns can take a String or Array list. + + +## 1.2.3 | 2011-04-08 + +Minor release to add #clear method to ProgressBar and provide bug +fix to BBCode.ansi_to_bbcode. Big thanks goes to Junegunn Choi +for this fix. + +Changes: + +* Add ProgressBar#clear method. +* Fixed ANSI::BBCode.ansi_to_bbcode and ansi_to_html from omitting lines +without any ansi code (Junegunn Choi). + +## 1.2.2 | 2010-06-12 + +This release removes warnings about string arguments for certain +ANSI::Code methods. While the string form is considered deprecated, +for a few methods there is no use for any argument, so the string +form can remain. In addition, String#unansi has been added to +compliment String#ansi. Lastly, this release also adds the #display +method to ANSI::Mixin. + +Changes: + +* Remove string argument warnings. +* Add String#unansi and String#unansi! +* Add ANSI::Mixin#display. + + +## 1.2.1 | 2010-05-10 + +This release was simply a quick fix to remove the incorrect embedded +version number, until it gets fixed. + + +## 1.2.0 | 2010-05-10 + +This release entails numerous improvements. First and foremost +the Code module is transitioning to a block interface only +and phasing out the string argument interface. Admittedly this +is mildly unconventional, but it allows the arguments to be used +as options with common defaults more elegantly. + +Another important change is that ANSI::Code no longer provides +String extension methods when included. For this use the new +ANSI::Mixin. + +Other improvements include a String extension, #ansi, added to +code.rb, which makes it even easier to apply ANSI codes to strings. +Also, the ANSI::String class has been fixed (a few bugs crept +it with the last release) and continues to improve. On top of all +this testing has substantially improved thanks to QED. + +Changes: + +* Support string argument for now but with warning +* Bug fixes for ANSI::String +* Add mixin.rb for alternate mixin. +* Many new tests and QED documents. + + +## 1.1.0 | 2009-10-04 + +This release is the first toward making the ANSI library +more widely usable. + +Changes: + +* Add bbcode.rb for conversion between BBCode/ANSI/HTML. +* ProgressBar and Progressbar are the same. +* Other minor underthehood improvements. + + +## 1.0.1 | 2009-08-15 + +The release fixes a single bug that should allow Ruby 1.9 +to use the ANSI library. + +Changes: + +* Renamed PLATFORM to RUBY_PLATFORM + + +## 1.0.0 | 2009-08-15 + +This is the initial stand-alone release of ANSI, a collection +of ANSI based classes spun-off from Ruby Facets. + +Changes: + +* Happy Birthday! + diff --git a/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/LICENSE.txt b/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/LICENSE.txt new file mode 100644 index 0000000..314131a --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/LICENSE.txt @@ -0,0 +1,23 @@ +BSD-2-Clause License (http://spdx.org/licenses/BSD-2-Clause) + +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + diff --git a/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/NOTICE.md b/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/NOTICE.md new file mode 100644 index 0000000..7667164 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/NOTICE.md @@ -0,0 +1,170 @@ +# COPYRIGHT NOTICES + +## ANSI + +Copyright © 2009 [Rubyworks](http://rubyworks.github.com) · +License [BSD-2-Clause](http://spdx.org/licenses/BSD-2-Clause) · +Website http://rubyworks.github.com/ansi + + Copyright 2009 Rubyworks. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are + permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + (https://raw.github.com/rubyworks/ansi/master/LICENSE.txt) + + +## ProgressBar + +Copyright © 2001 *Satoru Takabayashi* · +License [Ruby](http://spdx.org/licenses/Ruby) · +Website http://0xcc.net/ruby-progressbar + +ProgressBar class is based on the original ProgressBar by Satoru Takabayashi. + + Ruby/ProgressBar - a text progress bar library + + Copyright (C) 2001-2005 Satoru Takabayashi + All rights reserved. + This is free software with ABSOLUTELY NO WARRANTY. + + You can redistribute it and/or modify it under the terms + of Ruby's license. + + +## HighLine (Terminal Extensions) + +Copyright © 2006 *Gray Productions* · +License [Ruby](http://spdx.org/licenses/Ruby) · +Website http://highline.rubyforge.org + +The terminal extensions are based on HighLine's SystemExtensions +by James Edward Gray II. + + Copyright 2006 Gray Productions + + Distributed under the user's choice of the {GPL Version 2}[http://www.gnu.org/licenses/old-licenses/gpl-2.0.html] + (see GPL-2.0.txt for details) or the {Ruby software license}[http://www.ruby-lang.org/en/LICENSE.txt] + by James Edward Gray II and Greg Brown. + + Please email James[mailto:james@grayproductions.net] with any questions. + + (https://github.com/JEG2/highline/blob/master/LICENSE) + + +## BBCode + +Copyright © 2002 *Thomas-Ivo Heinen* · +License [Ruby](http://spdx.org/licenses/Ruby) + +BBCode module is a derivative of BBCode by Thomas-Ivo Heinen. + + Copyright (c) 2002 Thomas-Ivo Heinen + + This module is free software. You may use, modify, and/or redistribute this + software under the same terms as Ruby. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. + + +## Rainbow (XTerm Color Support) + +Copyright © *Marcin Kulik* · +License [MIT](http://spdx.org/licenses/MIT) · +Website http://github.com/sickill/rainbow + +Rainbox provided the bases for building the XTerm 256 color code +support into the ANSI::Code module. + + Copyright (c) Marcin Kulik + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + (https://raw.github.com/sickill/rainbow/master/LICENSE) + + +## Paint (ANSI Code Names) + +Copyright © 2011 *Jan Lelis* · +License [MIT](http://spdx.org/licenses/MIT) · +Website https://github.com/janlelis/paint + +Some of the latest ANSI code names, and inspiration to check out Rainbow +and include XTerm 256 color codes, came from Paint. + + Copyright (c) 2011 Jan Lelis + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + (https://raw.github.com/janlelis/paint/master/LICENSE.txt) + + +## ANSIColor + +_Acknowlegement_ + +Copyright © 2002 *Florian Frank* · +Website http://flori.github.com/term-ansicolor + +Albeit the code no long bares much, if any, resemblance to it, the ANSI Code +module (and subsequently the Constants module) originated with the +ANSIColor library by Florian Frank. + + Copyright (c) 2002 Florian Frank + + diff --git a/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/README.md b/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/README.md new file mode 100644 index 0000000..7ec7c6c --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/README.md @@ -0,0 +1,91 @@ +# ANSI + +[HOME](http://rubyworks.github.com/ansi) · +[API](http://rubydoc.info/gems/ansi/frames) · +[MAIL](http://googlegroups.com/group/rubyworks-mailinglist) · +[ISSUES](http://github.com/rubyworks/ansi/issues) · +[SOURCE](http://github.com/rubyworks/ansi) + +[![Build Status](https://secure.travis-ci.org/rubyworks/ansi.png)](http://travis-ci.org/rubyworks/ansi) + +
    + +The ANSI project is a collection of ANSI escape code related libraries +enabling ANSI code based colorization and stylization of output. +It is very nice for beautifying shell output. + +This collection is based on a set of scripts spun-off from +Ruby Facets. Included are Code (used to be ANSICode), Logger, +ProgressBar and String. In addition the library includes +Terminal which provides information about the current output +device. + + +## Features + +* ANSI::Code provides ANSI codes as module functions. +* String#ansi makes common usage very easy and elegant. +* ANSI::Mixin provides an alternative mixin (like +colored+ gem). +* Very Good coverage of standard ANSI codes. +* Additional clases for colorized columns, tables, loggers and more. + + +## Synopsis + +There are a number of modules and classes provided by the ANSI +package. To get a good understanding of them it is best to pursue +the [QED documents](http://github.com/rubyworks/ansi/tree/master/qed/) +or the [API documentation](http://rubyworks.github.com/ansi/api/index.html). + +At the heart of all the provided libraries lies the ANSI::Code module +which defines ANSI codes as constants and methods. For example: + + require 'ansi/code' + + ANSI.red + "Hello" + ANSI.blue + "World" + => "\e[31mHello\e[34mWorld" + +Or in block form. + + ANSI.red{ "Hello" } + ANSI.blue{ "World" } + => "\e[31mHello\e[0m\e[34mWorld\e[0m" + +The methods defined by this module are used throughout the rest of +the system. + + +## Installation + +### RubyGems + +To install with RubyGems simply open a console and type: + + $ sudo gem install ansi + +### Setup.rb (not recommended) + +Local installation requires Setup.rb (gem install setup), +then [download](http://github.com/rubyworks/ansi/download) the tarball package and type: + + $ tar -xvzf ansi-1.0.0.tgz + $ cd ansi-1.0.0 + $ sudo setup.rb all + +Windows users use 'ruby setup.rb all'. + + +## Release Notes + +Please see HISTORY.md file. + + +## License & Copyrights + +Copyright (c) 2009 Rubyworks + +This program is redistributable under the terms of the *FreeBSD* license. + +Some pieces of the code are copyrighted by others. + +See LICENSE.txt and NOTICE.md files for details. + diff --git a/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/demo/01_ansicode.md b/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/demo/01_ansicode.md new file mode 100644 index 0000000..6620383 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/demo/01_ansicode.md @@ -0,0 +1,65 @@ +# ANSI::Code + +Require the library. + + require 'ansi/code' + +ANSI::Code can be used as a functions module. + + str = ANSI::Code.red + "Hello" + ANSI::Code.blue + "World" + str.assert == "\e[31mHello\e[34mWorld" + +If a block is supplied to each method then yielded value will +be wrapped in the ANSI code and clear code. + + str = ANSI::Code.red{ "Hello" } + ANSI::Code.blue{ "World" } + str.assert == "\e[31mHello\e[0m\e[34mWorld\e[0m" + +More conveniently the ANSI::Code module extends ANSI itself. + + str = ANSI.red + "Hello" + ANSI.blue + "World" + str.assert == "\e[31mHello\e[34mWorld" + + str = ANSI.red{ "Hello" } + ANSI.blue{ "World" } + str.assert == "\e[31mHello\e[0m\e[34mWorld\e[0m" + +ANSI also supports XTerm 256 color mode using red, blue and green values +with the `#rgb` method. + + str = ANSI::Code.rgb(0, 255, 0) + str.assert == "\e[38;5;46m" + +Or using CSS style hex codes as well. + + str = ANSI::Code.rgb("#00FF00") + str.assert == "\e[38;5;46m" + +Both of these methods can take blocks to wrap text in the color and clear codes. + + str = ANSI::Code.rgb("#00FF00"){ "Hello" } + str.assert == "\e[38;5;46mHello\e[0m" + +In the appropriate context the ANSI::Code module can also be +included, making its methods directly accessible. + + include ANSI::Code + + str = red + "Hello" + blue + "World" + str.assert == "\e[31mHello\e[34mWorld" + + str = red{ "Hello" } + blue{ "World" } + str.assert == "\e[31mHello\e[0m\e[34mWorld\e[0m" + +Along with the single font colors, the library include background colors. + + str = on_red + "Hello" + str.assert == "\e[41mHello" + +As well as combined color methods. + + str = white_on_red + "Hello" + str.assert == "\e[37m\e[41mHello" + +The ANSI::Code module supports most standard ANSI codes, though +not all platforms support every code, so YMMV. + diff --git a/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/demo/02_core.md b/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/demo/02_core.md new file mode 100644 index 0000000..caee21b --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/demo/02_core.md @@ -0,0 +1,11 @@ +# String Extensions + +In addition the library offers an extension to String class +called #ansi, which allows some of the ANSI::Code methods +to be called in a more object-oriented fashion. + + require 'ansi/core' + + str = "Hello".ansi(:red) + "World".ansi(:blue) + str.assert == "\e[31mHello\e[0m\e[34mWorld\e[0m" + diff --git a/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/demo/03_logger.md b/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/demo/03_logger.md new file mode 100644 index 0000000..6e2aa6d --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/demo/03_logger.md @@ -0,0 +1,30 @@ +# ANSI::Logger + +Require the ANSI::Logger library. + + require 'ansi/logger' + +Create a new ANSI::Logger + + log = ANSI::Logger.new(STDOUT) + +Info logging appears normal. + + log.info{"Info logs are green.\n"} + +Warn logging appears yellow. + + log.warn{"Warn logs are yellow.\n"} + +Debug logging appears cyan. + + log.debug{"Debug logs are cyan.\n"} + +Error logging appears red. + + log.error{"Error logs are red.\n"} + +Fatal logging appears bright red. + + log.fatal{"Fatal logs are bold red!\n"} + diff --git a/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/demo/04_progressbar.md b/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/demo/04_progressbar.md new file mode 100644 index 0000000..13fa150 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/demo/04_progressbar.md @@ -0,0 +1,62 @@ +# ANSI::Progressbar + +Pretty progress bars are easy to construct. + + require 'ansi/progressbar' + + pbar = ANSI::Progressbar.new("Test Bar", 100) + +Running the bar simply requires calling the #inc method during +a loop and calling `#finish` when done. + + 100.times do |i| + sleep 0.01 + pbar.inc + end + pbar.finish + +We will use this same rountine in all the examples below, so lets +make a quick macro for it. Notice we have to use `#reset` first +before reusing the same progress bar. + + def run(pbar) + pbar.reset + 100.times do |i| + sleep 0.01 + pbar.inc + end + pbar.finish + puts + end + +The progress bar can be stylized in almost any way. +The `#format` setter provides control over the parts +that appear on the line. For example, by default the +format is: + + pbar.format("%-14s %3d%% %s %s", :title, :percentage, :bar, :stat) + +So lets vary it up to demonstrate the case. + + pbar.format("%-14s %3d%% %s %s", :title, :percentage, :stat, :bar) + run(pbar) + +The progress bar has an extra build in format intended for use with +file downloads called `#transer_mode`. + + pbar.transfer_mode + run(pbar) + +Calling this methods is the same as calling: + + pbar.format("%-14s %3d%% %s %s",:title, :percentage, :bar, :stat_for_file_transfer) + run(pbar) + +The `#style` setter allows each part of the line be modified with ANSI codes. And the +`#bar_mark` writer can be used to change the character used to make the bar. + + pbar.standard_mode + pbar.style(:title => [:red], :bar=>[:blue]) + pbar.bar_mark = "=" + run(pbar) + diff --git a/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/demo/05_mixin.md b/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/demo/05_mixin.md new file mode 100644 index 0000000..ca2897d --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/demo/05_mixin.md @@ -0,0 +1,37 @@ +# ANSI::Mixin + +The ANSI::Mixin module is design for including into +String-like classes. It will support any class that defines +a #to_s method. + + require 'ansi/mixin' + +In this demonstration we will simply include it in the +core String class. + + class ::String + include ANSI::Mixin + end + +Now all strings will have access to ANSI's style and color +codes via simple method calls. + + "roses".red.assert == "\e[31mroses\e[0m" + + "violets".blue.assert == "\e[34mviolets\e[0m" + + "sugar".italic.assert == "\e[3msugar\e[0m" + +The method can be combined, of course. + + "you".italic.bold.assert == "\e[1m\e[3myou\e[0m\e[0m" + +The mixin also supports background methods. + + "envy".on_green.assert == "\e[42menvy\e[0m" + +And it also supports the combined foreground-on-background +methods. + + "b&w".white_on_black.assert == "\e[37m\e[40mb&w\e[0m" + diff --git a/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/demo/06_string.md b/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/demo/06_string.md new file mode 100644 index 0000000..03e96c6 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/demo/06_string.md @@ -0,0 +1,56 @@ +# ANSI::String + +The ANSI::String class is a very sophisticated implementation +of Ruby's standard String class, but one that can handle +ANSI codes seamlessly. + + require 'ansi/string' + + flower1 = ANSI::String.new("Roses") + flower2 = ANSI::String.new("Violets") + +Like any other string. + + flower1.to_s.assert == "Roses" + flower2.to_s.assert == "Violets" + +Bet now we can add color. + + flower1.red! + flower2.blue! + + flower1.to_s.assert == "\e[31mRoses\e[0m" + flower2.to_s.assert == "\e[34mViolets\e[0m" + +Despite that the string representation now contains ANSI codes, +we can still manipulate the string in much the same way that +we manipulate an ordinary string. + + flower1.size.assert == 5 + flower2.size.assert == 7 + +Like ordinary strings we can concatenate the two strings + + flowers = flower1 + ' ' + flower2 + flowers.to_s.assert == "\e[31mRoses\e[0m \e[34mViolets\e[0m" + + flowers.size.assert == 13 + +Standard case conversion such as #upcase and #downcase work. + + flower1.upcase.to_s.assert == "\e[31mROSES\e[0m" + flower1.downcase.to_s.assert == "\e[31mroses\e[0m" + +Some of the most difficult methods to re-implement were the +substitution methods such as #sub and #gsub. They are still +somewhat more limited than the original string methods, but +their primary functionality should work. + + flower1.gsub('s', 'z').to_s.assert == "\e[31mRozez\e[0m" + +There are still a number of methods that need implementation. +ANSI::String is currently a very partial implementation. But +as you can see from the methods it does currently support, +is it already useful. + + diff --git a/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/demo/07_columns.md b/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/demo/07_columns.md new file mode 100644 index 0000000..4b47e3c --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/demo/07_columns.md @@ -0,0 +1,89 @@ +# ANSI::Columns + +The +Columns+ class makes it easy to create nice looking text columns, +sorted from top to bottom, right to left (as opposed to the other way +around). + + require 'ansi/columns' + + list = %w{a b c d e f g h i j k l} + + columns = ANSI::Columns.new(list) + + columns.to_s(4) + +The output will be: + + a d g j + b e h k + c f i l + +Besides an array of elements, Columns.new can take a string in which +the elements are divided by newlines characters. The default column +size can also be given to the initializer. + + list = "a\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl" + + columns = ANSI::Columns.new(list, :columns=>6) + + columns.to_s + +The output will be: + + a c e g i k + b d f h j l + +If the column count is +nil+, then the number of columns will be calculated +as a best fit for the current terminal window. + +## Padding + +Columns can adjust the padding between cells. + + list = %w{a b c d e f g h i j k l} + + columns = ANSI::Columns.new(list, :padding=>2) + + columns.to_s(4) + +The output will be: + + a d g j + b e h k + c f i l + +## Alignment + +Columns can also be aligned either left or right. + + list = %w{xx xx xx yy y yy z zz z} + + columns = ANSI::Columns.new(list, :align=>:right) + + columns.to_s(3) + +The output will be: + + xx yy z + xx y zz + xx yy z + +## Format + +Lastly, columns can be augmented with ANSI codes. This is done through +a formatting block. The block can take up to three parameters, the cell +content, the column and row numbers, or the cell and the column and row +numbers. + + list = %w{a b c d e f g h i j k l} + + columns = ANSI::Columns.new(list){ |c,r| r % 2 == 0 ? :red : :blue } + + out = columns.to_s(4) + + out.assert == ( + "\e[31ma \e[0m\e[31md \e[0m\e[31mg \e[0m\e[31mj \e[0m\n" + + "\e[34mb \e[0m\e[34me \e[0m\e[34mh \e[0m\e[34mk \e[0m\n" + + "\e[31mc \e[0m\e[31mf \e[0m\e[31mi \e[0m\e[31ml \e[0m\n" + ) + diff --git a/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/demo/08_table.md b/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/demo/08_table.md new file mode 100644 index 0000000..198a7d9 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/demo/08_table.md @@ -0,0 +1,28 @@ +# ANSI::Table + +The ANSI::Table class can be used to output tabular data with nicely +formated ASCII cell borders. + + require 'ansi/table' + +The constructor takes an 2-dimensional array. + + data = [ + [ 10, 20, 30 ], + [ 20, 10, 20 ], + [ 50, 40, 20 ] + ] + + table = ANSI::Table.new(data) + + table.to_s + +The output will be: + + +----+----+----+ + | 10 | 20 | 30 | + | 20 | 10 | 20 | + | 50 | 40 | 20 | + +----+----+----+ + + diff --git a/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/demo/09_diff.md b/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/demo/09_diff.md new file mode 100644 index 0000000..204a13e --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/demo/09_diff.md @@ -0,0 +1,47 @@ +# ANSI::Diff + + require 'ansi/diff' + + a = 'abcYefg' + b = 'abcXefg' + + diff = ANSI::Diff.new(a,b) + + diff.to_s.assert == "\e[31mabc\e[0m\e[33mYefg\e[0m\n\e[31mabc\e[0mXefg" + +Try another. + + a = 'abc' + b = 'abcdef' + + diff = ANSI::Diff.new(a,b) + + diff.to_s.assert == "\e[31mabc\e[0m\n\e[31mabc\e[0mdef" + +And another. + + a = 'abcXXXghi' + b = 'abcdefghi' + + diff = ANSI::Diff.new(a,b) + + diff.to_s.assert == "\e[31mabc\e[0m\e[33mXXXghi\e[0m\n\e[31mabc\e[0mdefghi" + +And another. + + a = 'abcXXXdefghi' + b = 'abcdefghi' + + diff = ANSI::Diff.new(a,b) + + diff.to_s.assert == "\e[31mabc\e[0m\e[33mXXX\e[0m\e[35mdefghi\e[0m\n\e[31mabc\e[0m\e[35mdefghi\e[0m" + +Comparison that is mostly different. + + a = 'abcpppz123' + b = 'abcxyzzz43' + + diff = ANSI::Diff.new(a,b) + + diff.to_s.assert == "\e[31mabc\e[0m\e[33mpppz123\e[0m\n\e[31mabc\e[0mxyzzz43" + diff --git a/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/demo/10_bbcode.md b/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/demo/10_bbcode.md new file mode 100644 index 0000000..59423a4 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/demo/10_bbcode.md @@ -0,0 +1,24 @@ +# ANSI::BBCode + +The BBCode module provides methods for converting between +BBCodes, basic HTML and ANSI codes. + + require 'ansi/bbcode' + +BBCodes are color and style codes in square brackets, quite +popular with on line forums. + + bbcode = "this is [COLOR=red]red[/COLOR], this is [B]bold[/B]" + +We can convert this to ANSI code simply enough: + + ansi = ANSI::BBCode.bbcode_to_ansi(bbcode) + + ansi.assert == "this is \e[0;31mred\e[0m, this is \e[1mbold\e[0m\n" + +In addition the BBCode module supports conversion to simple HTML. + + html = ANSI::BBCode.bbcode_to_html(bbcode) + + html.assert == "this is red, this is bold
    \n" + diff --git a/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/demo/11_terminal.md b/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/demo/11_terminal.md new file mode 100644 index 0000000..a0bd4f0 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/demo/11_terminal.md @@ -0,0 +1,8 @@ +# ANSI::Terminal + +We should be ables to get the terminal width via the `terminal_width` method. + + width = ANSI::Terminal.terminal_width + + Fixnum.assert === width + diff --git a/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/demo/applique/ae.rb b/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/demo/applique/ae.rb new file mode 100644 index 0000000..84ae3d2 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/demo/applique/ae.rb @@ -0,0 +1 @@ +require 'ae' diff --git a/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/demo/applique/output.rb b/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/demo/applique/output.rb new file mode 100644 index 0000000..39c3251 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/demo/applique/output.rb @@ -0,0 +1,5 @@ +When "output will be" do |text| + # how to get result of last block? + @_.strip.assert == text.strip +end + diff --git a/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/lib/ansi.rb b/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/lib/ansi.rb new file mode 100644 index 0000000..428b237 --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/lib/ansi.rb @@ -0,0 +1,22 @@ +# ANSI namespace module contains all the ANSI related classes. +module ANSI +end + +require 'ansi/version' +require 'ansi/core' +require 'ansi/code' +require 'ansi/bbcode' +require 'ansi/columns' +require 'ansi/diff' +require 'ansi/logger' +require 'ansi/mixin' +require 'ansi/progressbar' +require 'ansi/string' +require 'ansi/table' +require 'ansi/terminal' + +# Kernel method +def ansi(string, *codes) + ANSI::Code.ansi(string, *codes) +end + diff --git a/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/lib/ansi.yml b/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/lib/ansi.yml new file mode 100644 index 0000000..53ed8fe --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/lib/ansi.yml @@ -0,0 +1,77 @@ +--- +revision: 2013 +type: ruby +sources: +- INDEX.yml +authors: +- name: Thomas Sawyer + email: transfire@gmail.com +- name: Florian Frank +organizations: [] +requirements: +- groups: + - build + development: true + name: mast +- groups: + - build + development: true + name: indexer +- groups: + - build + development: true + name: ergo +- groups: + - test + development: true + name: qed +- groups: + - test + development: true + name: ae +- groups: + - test + development: true + name: lemon +conflicts: [] +alternatives: [] +resources: +- type: home + uri: http://rubyworks.github.com/ansi + label: Homepage +- type: docs + uri: http://rubydoc.info/gems/ansi/frames + label: Documentation +- type: code + uri: http://github.com/rubyworks/ansi + label: Source Code +- type: bugs + uri: http://github.com/rubyworks/ansi/issues + label: Issue Tracker +- type: mail + uri: http://groups.google.com/group/rubyworks-mailinglist + label: Mailing List +repositories: +- name: upstream + scm: git + uri: git://github.com/rubyworks/ansi.git +categories: [] +copyrights: +- holder: Rubyworks + year: '2009' + license: BSD-2-Clause +customs: [] +paths: + lib: + - lib +name: ansi +title: ANSI +version: 1.5.0 +summary: ANSI at your fingertips! +description: The ANSI project is a superlative collection of ANSI escape code related + libraries eabling ANSI colorization and stylization of console output. Byte for + byte ANSI is the best ANSI code library available for the Ruby programming language. +orgranizations: +- Rubyworks +created: '2009-08-01' +date: '2015-01-16' diff --git a/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/lib/ansi/bbcode.rb b/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/lib/ansi/bbcode.rb new file mode 100644 index 0000000..2d7124c --- /dev/null +++ b/vendor/bundle/ruby/2.2.0/gems/ansi-1.5.0/lib/ansi/bbcode.rb @@ -0,0 +1,334 @@ +# BBCode +# +# Copyright (c) 2002 Thomas-Ivo Heinen +# +# This module is free software. You may use, modify, and/or redistribute this +# software under the same terms as Ruby. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. + +# +module ANSI + + # TODO: Integrate BBCode with Code module. + + # The BBCode module helps ease the separation of core and frontend with the + # core (or submodules) being still able to say, what colors shall be used + # in it's responses. This is achieved by encoding formatting information + # using the BBCode tokens. This enables you to "pipe" layout information + # such as colors, style, font, size and alignment through the core to + # the frontend. + # + # Additionally it converts markups/codes between ANSI, HTML and BBCode + # almost freely ;) + # + # # Converting a bbcode string to ANSI and XHTML + # str = "this is [COLOR=red]red[/COLOR], this is [B]bold[/B]" + # print( BBCode.bbcode_to_ansi(str) ) + # print( BBCode.bbcode_to_html(str) ) + # + module BBCode + + ## ANSIname => ANSIcode LUT + ANSINAME2CODE= { "reset" => "\e[0m", "bold" => "\e[1m", + "underline" => "\e[4m", "blink" => "\e[5m", + "reverse" => "\e[7m", "invisible" => "\e[8m", + "black" => "\e[0;30m", "darkgrey" => "\e[1;30m", + "red" => "\e[0;31m", "lightred" => "\e[1;31m", + "green" => "\e[0;32m", "lightgreen" => "\e[1;32m", + "brown" => "\e[0;33m", "yellow" => "\e[1;33m", + "blue" => "\e[0;34m", "lightblue" => "\e[1;34m", + "purple" => "\e[0;35m", "magenta" => "\e[1;35m", + "cyan" => "\e[1;36m", "lightcyan" => "\e[1;36m", + "grey" => "\e[0;37m", "white" => "\e[1;37m", + "bgblack" => "\e[40m", "bgred" => "\e[41m", + "bggreen" => "\e[42m", "bgyellow" => "\e[43m", + "bgblue" => "\e[44m", "bgmagenta" => "\e[45m", + "bgcyan" => "\e[46m", "bgwhite" => "\e[47m" + } + + ## BBColor => ANSIname LUT + BBCOLOR2ANSI = { "skyblue" => "blue", "royalblue" => "blue", + "blue" => "blue", "darkblue" => "blue", + "orange" => "red", "orangered" => "red", + "crimson" => "red", "red" => "lightred", + "firebrick" => "red", "darkred" => "red", + "green" => "green", "limegreen" => "green", + "seagreen" => "green", "darkgreen" => "green", + "deeppink" => "magenta", "tomato" => "red", + "coral" => "cyan", "purple" => "purple", + "indigo" => "blue", "burlywood" => "red", + "sandybrown"=> "red", "sierra" => "sierra", + "chocolate" => "brown", "teal" => "teal", + "silver" => "white", + "black" => "black", "yellow" => "yellow", + "magenta" => "magenta", "cyan" => "cyan", + "white" => "white" + } + + ## ANSInames => BBCode LUT + ANSINAME2BBCODE = { "bold" => "B", "underline" => "U", "reverse" => "I", + + "red" => "COLOR=red", "blue" => "COLOR=blue", + "green" => "COLOR=green", "cyan" => "COLOR=cyan", + "magenta"=> "COLOR=deeppink", "purple" => "COLOR=purple", + "black" => "COLOR=black", "white" => "COLOR=white", + "yellow" => "COLOR=yellow", "brown" => "COLOR=chocolate" + } + + ## Needed for alignments + @@width = 80 + + + # --------------------------- + + # Returns the ANSI sequence for given color, if existant + def BBCode.ansi(colorname) + colorname.strip! + return ANSINAME2CODE[ colorname.downcase ] + end + + # --- strip_bbcode( string ) + # Will strip any BBCode tags from the given string. + def BBCode.strip_bbcode(string) + string.strip! + return string.gsub(/\[[A-Za-z0-9\/=]+\]/, "") + end + + # Returns the string with all ansi escape sequences converted to BBCodes + def BBCode.ansi_to_bbcode(string) + return "" if string.nil? || string.to_s.strip.empty? + result = "" + tagstack = [] + + ## Iterate over input lines + string.split("\n").each do |line| + ## Iterate over found ansi sequences + line.scan(/\e\[[0-9;]+m/).each do |seq| + ansiname = ANSINAME2CODE.invert["#{seq}"] + + ## Pop last tag and form closing tag + if ansiname == "reset" + lasttag = tagstack.pop + bbname = "/" + String.new( lasttag.split("=")[0] ) + + ## Get corresponding BBCode tag + Push to stack + else + bbname = ANSINAME2BBCODE[ansiname] + tagstack.push(bbname) + end + + ## Replace ansi sequence by BBCode tag + replace = sprintf("[%s]", bbname) + line.sub!(seq, replace) + end + + ## Append converted line + result << sprintf("%s\n", line) + end + + + ## Some tags are unclosed + while !tagstack.empty? + result << sprintf("[/%s]", String.new(tagstack.pop.split("=")[0]) ) + end + + return result + end + + # Converts a BBCode string to one with ANSI sequences. + # Returns the string with all formatting instructions in BBCodes converted + # to ANSI code sequences / aligned with spaces to specified width. + def BBCode.bbcode_to_ansi(string, usecolors = true) + return "" if string.nil? || string.to_s.strip.empty? + result = "" + + return BBCode.strip_bbcode(string) if !usecolors + + ## Iterate over lines + string.split("\n").each do |line| + + ## TODO: stacking? other styles! + ANSINAME2BBCODE.each do |key,val| + line.gsub!(/\[#{val}\]/, ANSINAME2CODE[key]) + line.gsub!(/\[\/#{val}\]/, ANSINAME2CODE["reset"]) + end + + ## Fonttypes and sizes not available + line.gsub!(/\[SIZE=\d\]/, "") + line.gsub!(/\[\/SIZE\]/, "") + line.gsub!(/\[FONT=[^\]]*\]/, "") + line.gsub!(/\[\/FONT\]/, "") + + ## Color-mapping + colors = line.scan(/\[COLOR=(.*?)\]/i) + colors = colors.collect{|s| s[0].to_s} if !colors.nil? + colors.each do |col| + name = BBCOLOR2ANSI[col.downcase] + name = BBCOLOR2ANSI["white"] if name.nil? + code = ANSINAME2CODE[name] + + line.gsub!(/\[COLOR=#{col}\]/i, code) + end + line.gsub!(/\[\/COLOR\]/, ANSINAME2CODE["reset"]) + + ## TODO: Alignment + ## TODO: IMGs + ## TODO: EMAILs + ## TODO: URLs + ## TODO: QUOTEs + ## TODO: LISTs + + result << sprintf("%s\n", line) + end + + return result + end + + # Converts a HTML string into one with BBCode markup (TODO) + # Returns the (X)HTML markup string as BBCode + def BBCode.html_to_bbcode(string) + return "" if string.nil? || string.to_s.strip.empty? + result = "" + + ## Iterate over lines + string.split(/
    /i).each do |line| + styles = { "strong" => "b", "b" => "b", + "em" => "i", "i" => "i", + "u" => "u" } + + ## preserve B, I, U + styles.each do |html,code| + line.gsub!(/<#{html}>/i, "[#{code.upcase}]") + line.gsub!(/<\/#{html}>/i, "[/#{code.upcase}]") + end + + ## TODO: COLORs + ## TODO: SIZEs + ## TODO: FONTs + + ## EMAIL + line.gsub!(/.*?<\/a>/i, "[EMAIL]\\1[/EMAIL]") + + ## URL + line.gsub!(/(.*?)<\/a>/i, "[URL=\\1]\\2[/URL]") + + ## Other refs + closing tags => throw away + line.gsub!(//i, "") + line.gsub!(/<\/a>/i, "") + + ## IMG + #line.gsub!(//i, "[IMG=\\1]") + line.gsub!(//i, "[IMG]\\1[/IMG]") + + ## CENTER (right/left??) + line.gsub!(/
    /i, "[ALIGN=center]") + line.gsub!(/<\/center>/i, "[/ALIGN]") + + ## QUOTE + line.gsub!(/<(?:xmp|pre)>/i, "[QUOTE]") + line.gsub!(/<\/(?:xmp|pre)>/i, "[/QUOTE]") + + ## LIST + line.gsub!(/