quiver 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +14 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +3 -0
  5. data/Gemfile +6 -0
  6. data/README.md +22 -0
  7. data/Rakefile +17 -0
  8. data/bin/quiver +9 -0
  9. data/lib/quiver.rb +46 -0
  10. data/lib/quiver/abstract_action.rb +31 -0
  11. data/lib/quiver/action.rb +208 -0
  12. data/lib/quiver/action/filter_error.rb +33 -0
  13. data/lib/quiver/action/filter_value.rb +152 -0
  14. data/lib/quiver/action/invalid_request_body_error.rb +30 -0
  15. data/lib/quiver/action/pagination_link_builder.rb +67 -0
  16. data/lib/quiver/adapter.rb +51 -0
  17. data/lib/quiver/adapter/active_record_adapter_filter.rb +102 -0
  18. data/lib/quiver/adapter/active_record_helpers.rb +258 -0
  19. data/lib/quiver/adapter/arec_low_level_creator.rb +82 -0
  20. data/lib/quiver/adapter/arec_low_level_deleter.rb +74 -0
  21. data/lib/quiver/adapter/arec_low_level_updater.rb +105 -0
  22. data/lib/quiver/adapter/filter_helpers.rb +58 -0
  23. data/lib/quiver/adapter/helpers_helpers.rb +53 -0
  24. data/lib/quiver/adapter/memory_adapter_filter.rb +71 -0
  25. data/lib/quiver/adapter/memory_adapter_store.rb +34 -0
  26. data/lib/quiver/adapter/memory_helpers.rb +182 -0
  27. data/lib/quiver/adapter/memory_uuid_primary_key.rb +25 -0
  28. data/lib/quiver/application.rb +128 -0
  29. data/lib/quiver/cli/app.rb +25 -0
  30. data/lib/quiver/cli/generators/endpoint.rb +17 -0
  31. data/lib/quiver/cli/generators/new_application.rb +166 -0
  32. data/lib/quiver/cli/generators/new_application_cli.rb +25 -0
  33. data/lib/quiver/cli/server.rb +37 -0
  34. data/lib/quiver/cli/templates/Gemfile.tt +8 -0
  35. data/lib/quiver/cli/templates/Rakefile.tt +12 -0
  36. data/lib/quiver/cli/templates/config.tt +3 -0
  37. data/lib/quiver/cli/templates/config/database.tt +21 -0
  38. data/lib/quiver/cli/templates/gemspec.tt +33 -0
  39. data/lib/quiver/cli/templates/gitignore.tt +10 -0
  40. data/lib/quiver/cli/templates/lib/application.tt +14 -0
  41. data/lib/quiver/cli/templates/lib/application/config/router.tt +11 -0
  42. data/lib/quiver/cli/templates/lib/application/version.tt +3 -0
  43. data/lib/quiver/cli/templates/spec/spec_helper.tt +19 -0
  44. data/lib/quiver/duty.rb +34 -0
  45. data/lib/quiver/duty_master.rb +23 -0
  46. data/lib/quiver/duty_master/delayed_job_adapter.rb +15 -0
  47. data/lib/quiver/duty_master/memory_adapter.rb +18 -0
  48. data/lib/quiver/duty_test_helper.rb +23 -0
  49. data/lib/quiver/duty_test_helper/delayed_job_helper.rb +9 -0
  50. data/lib/quiver/duty_test_helper/memory_helper.rb +15 -0
  51. data/lib/quiver/error.rb +24 -0
  52. data/lib/quiver/error_collection.rb +60 -0
  53. data/lib/quiver/json_parser.rb +17 -0
  54. data/lib/quiver/logger.rb +26 -0
  55. data/lib/quiver/mapper.rb +311 -0
  56. data/lib/quiver/mapper/hook.rb +21 -0
  57. data/lib/quiver/mapper/mapper_result.rb +7 -0
  58. data/lib/quiver/mapper/not_found_error.rb +27 -0
  59. data/lib/quiver/mapper/simple_query_builder.rb +70 -0
  60. data/lib/quiver/mapper/soft_delete.rb +15 -0
  61. data/lib/quiver/mappers.rb +75 -0
  62. data/lib/quiver/middleware_stack.rb +35 -0
  63. data/lib/quiver/model.rb +63 -0
  64. data/lib/quiver/model/soft_delete.rb +14 -0
  65. data/lib/quiver/model/validation_error.rb +27 -0
  66. data/lib/quiver/model/validations.rb +45 -0
  67. data/lib/quiver/patcher.rb +94 -0
  68. data/lib/quiver/result.rb +44 -0
  69. data/lib/quiver/route_helper.rb +16 -0
  70. data/lib/quiver/router.rb +37 -0
  71. data/lib/quiver/serialization.rb +6 -0
  72. data/lib/quiver/serialization/json_api.rb +7 -0
  73. data/lib/quiver/serialization/json_api/item_type_handler.rb +96 -0
  74. data/lib/quiver/serialization/json_api/serializer.rb +77 -0
  75. data/lib/quiver/tasks.rb +31 -0
  76. data/lib/quiver/validator.rb +83 -0
  77. data/lib/quiver/validators/base.rb +21 -0
  78. data/lib/quiver/validators/presence.rb +34 -0
  79. data/lib/quiver/validators/unique.rb +33 -0
  80. data/lib/quiver/version.rb +3 -0
  81. data/quiver.gemspec +42 -0
  82. metadata +393 -0
@@ -0,0 +1,25 @@
1
+ module Quiver
2
+ module CLI
3
+ class NewApplicationCli < Thor::Group
4
+ include Thor::Actions
5
+
6
+ argument :name
7
+ class_option :active_record, type: :boolean, desc: "use ActiveRecord"
8
+ class_option :rspec, type: :boolean, default: true, desc: "use RSpec"
9
+ class_option :ext, type: :string, desc: "use the specified extension"
10
+
11
+ def create_base_app
12
+ klass = if options[:ext]
13
+ require "#{options[:ext]}/quiver_ext"
14
+ options[:ext].classify.constantize::QuiverExt::NewApplication
15
+ else
16
+ NewApplication
17
+ end
18
+
19
+ instance = klass.new(name, options)
20
+ instance.destination_root = destination_root
21
+ instance.generate!
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,37 @@
1
+ require 'rack'
2
+
3
+ module Quiver
4
+ module CLI
5
+ class Server < ::Rack::Server
6
+ DEFAULT_OPTIONS = {
7
+ config: 'config.ru',
8
+ Port: '3000',
9
+ Host: '127.0.0.1',
10
+ AccessLog: []
11
+ }
12
+
13
+ def initialize(options = {})
14
+ @quiver_opts = options
15
+ @options = DEFAULT_OPTIONS.merge(rack_options)
16
+
17
+ if reloading_code?
18
+ require 'shotgun'
19
+ @app = Shotgun::Loader.new(@options[:config])
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def reloading_code?
26
+ @quiver_opts[:reloading_code] || false
27
+ end
28
+
29
+ def rack_options
30
+ {}.tap do |h|
31
+ h[:Host] = @quiver_opts[:host] if @quiver_opts[:host]
32
+ h[:Port] = @quiver_opts[:port] if @quiver_opts[:port]
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ <%- if options[:active_record] -%>
4
+ gem 'activerecord', '~> 4.2.0'
5
+ gem 'sqlite3'
6
+ <%- end -%>
7
+
8
+ gemspec
@@ -0,0 +1,12 @@
1
+ require 'rake'
2
+ begin
3
+ require 'rspec/core/rake_task'
4
+ rescue LoadError
5
+ # Do nothing
6
+ end
7
+
8
+ require_relative './lib/<%= underscored_name %>'
9
+ <%= camelized_name %>::Tasks.load_tasks
10
+
11
+ task :environment do
12
+ end
@@ -0,0 +1,3 @@
1
+ require './lib/<%= underscored_name %>'
2
+
3
+ run <%= camelized_name %>::Application.new
@@ -0,0 +1,21 @@
1
+ development:
2
+ adapter: sqlite
3
+ database: <%= underscored_name %>_development
4
+ min_messages: warning
5
+ pool: 5
6
+
7
+ test:
8
+ adapter: sqlite
9
+ database: <%= underscored_name %>_test
10
+ min_messages: warning
11
+ pool: 5
12
+
13
+ staging: &staging
14
+ adapter: sqlite
15
+ database: <%= underscored_name %>_staging
16
+ pool: 5
17
+
18
+ production:
19
+ adapter: sqlite
20
+ database: <%= underscored_name %>_production
21
+ pool: 5
@@ -0,0 +1,33 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require '<%= underscored_name %>/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "<%= underscored_name %>"
8
+ spec.version = <%= camelized_name %>::VERSION
9
+ spec.authors = ["TODO: Set Author"]
10
+ spec.email = ["TODO: Set Email"]
11
+
12
+ spec.summary = %q{TODO: Set Summary}
13
+ spec.description = %q{TODO: Set Description}
14
+
15
+ # Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
16
+ # delete this section to allow pushing this gem to any host.
17
+ if spec.respond_to?(:metadata)
18
+ spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
19
+ else
20
+ raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
21
+ end
22
+
23
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
24
+ spec.bindir = "bin"
25
+ spec.require_paths = ["lib"]
26
+
27
+ spec.add_dependency "quiver", "<%= Quiver::VERSION %>"
28
+
29
+ <%- if options[:rspec] -%>
30
+ spec.add_development_dependency "rspec"
31
+ spec.add_development_dependency "rack-test"
32
+ <%- end -%>
33
+ end
@@ -0,0 +1,10 @@
1
+ .DS_Store
2
+ /.bundle
3
+ /.ruby-version
4
+ /.rvmrc
5
+ /config/database.yml
6
+ /db/*.sqlite3
7
+ /db/*.sqlite3-journal
8
+ /log/*
9
+ /tmp/*
10
+ /vendor/bundle
@@ -0,0 +1,14 @@
1
+ require 'bundler/setup'
2
+ require 'quiver'
3
+
4
+ module <%= camelized_name %>
5
+ class Application
6
+ include Quiver::Application
7
+
8
+ <%- if options[:active_record] -%>
9
+ use_active_record!
10
+ <%- end -%>
11
+
12
+ load_everything!
13
+ end
14
+ end
@@ -0,0 +1,11 @@
1
+ module <%= camelized_name %>
2
+ module Config
3
+ class Router
4
+ include Quiver::Router
5
+
6
+ routes do
7
+ # get '/hello_world', to: 'hello_world#index'
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ module <%= camelized_name %>
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,19 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+ ENV['RACK_ENV'] = 'test'
3
+
4
+ require 'rack/test'
5
+ require '<%= underscored_name %>'
6
+
7
+ Dir[File.join('spec', 'support', '**', '*.rb')].each { |f| require File.expand_path(f) }
8
+
9
+ RSpec.configure do |config|
10
+ config.include Rack::Test::Methods
11
+
12
+ def app
13
+ <%= camelized_name %>::Application.new
14
+ end
15
+
16
+ config.before(:each) do
17
+ <%= camelized_name %>::Application.memory_adapter_store.clean!
18
+ end
19
+ end
@@ -0,0 +1,34 @@
1
+ module Quiver
2
+ module Duty
3
+ attr_reader :arguments
4
+
5
+ def self.included(host)
6
+ host.send(:prepend, PrependMethods)
7
+ end
8
+
9
+ def initialize(*args)
10
+ self.arguments = args
11
+ end
12
+
13
+ def perform(*args)
14
+ raise NotImplementedError, 'Duties must implement #perform'
15
+ end
16
+
17
+ module PrependMethods
18
+ def perform(*args)
19
+ super
20
+ rescue => e
21
+ handle_error(e) if respond_to?(:handle_error, true)
22
+ raise
23
+ ensure
24
+ if self.class.parents[-2]::Application.using_active_record
25
+ ActiveRecord::Base.clear_active_connections!
26
+ end
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ attr_writer :arguments
33
+ end
34
+ end
@@ -0,0 +1,23 @@
1
+ module Quiver
2
+ class DutyMaster
3
+ def initialize
4
+ self.adapter = adapter_class.new
5
+ end
6
+
7
+ def queue(duty)
8
+ adapter.queue(duty.class, duty.arguments)
9
+ end
10
+
11
+ private
12
+
13
+ attr_accessor :adapter
14
+
15
+ def adapter_class
16
+ adapter_type = self.class.parents[-2]::Application.default_duty_queue_backend
17
+ self.class.const_get(adapter_type.to_s.camelize + 'Adapter')
18
+ end
19
+ end
20
+ end
21
+
22
+ require 'quiver/duty_master/memory_adapter'
23
+ require 'quiver/duty_master/delayed_job_adapter'
@@ -0,0 +1,15 @@
1
+ module Quiver
2
+ class DutyMaster
3
+ class DelayedJobAdapter
4
+ WrapperClass = Struct.new(:duty_class, :arguments) do
5
+ def perform
6
+ duty_class.new(*arguments).perform
7
+ end
8
+ end
9
+
10
+ def queue(duty_class, arguments)
11
+ Delayed::Job.enqueue WrapperClass.new(duty_class, arguments)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,18 @@
1
+ module Quiver
2
+ class DutyMaster
3
+ class MemoryAdapter
4
+ class << self
5
+ def queue_array
6
+ @queue_array ||= []
7
+ end
8
+ end
9
+
10
+ def queue(duty_class, arguments)
11
+ self.class.queue_array << {
12
+ duty_class: duty_class,
13
+ arguments: arguments
14
+ }
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,23 @@
1
+ module Quiver
2
+ class DutyTestHelper
3
+ def initialize
4
+ self.adapter = helper_class.new
5
+ end
6
+
7
+ def carry_out(count)
8
+ adapter.carry_out(count)
9
+ end
10
+
11
+ private
12
+
13
+ attr_accessor :adapter
14
+
15
+ def helper_class
16
+ adapter_type = self.class.parents[-2]::Application.default_duty_queue_backend
17
+ self.class.const_get(adapter_type.to_s.camelize + 'Helper')
18
+ end
19
+ end
20
+ end
21
+
22
+ require 'quiver/duty_test_helper/memory_helper'
23
+ require 'quiver/duty_test_helper/delayed_job_helper'
@@ -0,0 +1,9 @@
1
+ module Quiver
2
+ class DutyTestHelper
3
+ class DelayedJobHelper
4
+ def carry_out(count)
5
+ Delayed::Worker.new.work_off(count)
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,15 @@
1
+ module Quiver
2
+ class DutyTestHelper
3
+ class MemoryHelper
4
+ def carry_out(count)
5
+ count.times do
6
+ duty_data = Quiver::DutyMaster::MemoryAdapter.queue_array.shift
7
+ next unless duty_data
8
+
9
+ duty = duty_data[:duty_class].new(*duty_data[:arguments])
10
+ duty.perform
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,24 @@
1
+ module Quiver
2
+ class Error
3
+ attr_reader :type, :subject
4
+
5
+ def initialize(subject, type)
6
+ if type.is_a?(Symbol)
7
+ @type = type
8
+ else
9
+ @type = type.dup.freeze if type
10
+ end
11
+
12
+ if subject.is_a?(Symbol)
13
+ @subject = subject
14
+ else
15
+ @subject = subject.dup.freeze if subject
16
+ end
17
+ end
18
+
19
+ def ==(other)
20
+ type == other.type &&
21
+ subject == other.subject
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,60 @@
1
+ module Quiver
2
+ class ErrorCollection
3
+ include Enumerable
4
+
5
+ def initialize(initial=nil)
6
+ self.collection = []
7
+
8
+ if initial
9
+ initial.each do |e|
10
+ raise ArgumentError, 'initial must be an array of Quiver::Errors' unless e.is_a?(Quiver::Error)
11
+ collection << e
12
+ end
13
+ end
14
+ end
15
+
16
+ def errors
17
+ collection.dup
18
+ end
19
+
20
+ def each
21
+ collection.each do |e|
22
+ yield e
23
+ end
24
+ end
25
+
26
+ def <<(val)
27
+ if val.is_a?(Quiver::Error)
28
+ collection << val
29
+ else
30
+ raise ArgumentError, 'arg must be a Quiver::Error'
31
+ end
32
+ end
33
+
34
+ def add(val)
35
+ if val.is_a?(Quiver::ErrorCollection)
36
+ collection.push(*val.errors)
37
+ else
38
+ raise ArgumentError, 'arg must be a Quiver::ErrorCollection'
39
+ end
40
+ end
41
+
42
+ def +(val)
43
+ raise ArgumentError, 'rval must be a Quiver::ErrorCollection' unless val.is_a?(Quiver::ErrorCollection)
44
+
45
+ Quiver::ErrorCollection.new(collection + val.errors)
46
+ end
47
+
48
+ def success?
49
+ !collection.any?
50
+ end
51
+
52
+ def ==(other)
53
+ collection == other.send(:collection)
54
+ end
55
+
56
+ private
57
+
58
+ attr_accessor :collection
59
+ end
60
+ end