quiver 0.21.0

Sign up to get free protection for your applications and to get access to all the features.
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