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.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/.rspec +2 -0
- data/.travis.yml +3 -0
- data/Gemfile +6 -0
- data/README.md +22 -0
- data/Rakefile +17 -0
- data/bin/quiver +9 -0
- data/lib/quiver.rb +46 -0
- data/lib/quiver/abstract_action.rb +31 -0
- data/lib/quiver/action.rb +208 -0
- data/lib/quiver/action/filter_error.rb +33 -0
- data/lib/quiver/action/filter_value.rb +152 -0
- data/lib/quiver/action/invalid_request_body_error.rb +30 -0
- data/lib/quiver/action/pagination_link_builder.rb +67 -0
- data/lib/quiver/adapter.rb +51 -0
- data/lib/quiver/adapter/active_record_adapter_filter.rb +102 -0
- data/lib/quiver/adapter/active_record_helpers.rb +258 -0
- data/lib/quiver/adapter/arec_low_level_creator.rb +82 -0
- data/lib/quiver/adapter/arec_low_level_deleter.rb +74 -0
- data/lib/quiver/adapter/arec_low_level_updater.rb +105 -0
- data/lib/quiver/adapter/filter_helpers.rb +58 -0
- data/lib/quiver/adapter/helpers_helpers.rb +53 -0
- data/lib/quiver/adapter/memory_adapter_filter.rb +71 -0
- data/lib/quiver/adapter/memory_adapter_store.rb +34 -0
- data/lib/quiver/adapter/memory_helpers.rb +182 -0
- data/lib/quiver/adapter/memory_uuid_primary_key.rb +25 -0
- data/lib/quiver/application.rb +128 -0
- data/lib/quiver/cli/app.rb +25 -0
- data/lib/quiver/cli/generators/endpoint.rb +17 -0
- data/lib/quiver/cli/generators/new_application.rb +166 -0
- data/lib/quiver/cli/generators/new_application_cli.rb +25 -0
- data/lib/quiver/cli/server.rb +37 -0
- data/lib/quiver/cli/templates/Gemfile.tt +8 -0
- data/lib/quiver/cli/templates/Rakefile.tt +12 -0
- data/lib/quiver/cli/templates/config.tt +3 -0
- data/lib/quiver/cli/templates/config/database.tt +21 -0
- data/lib/quiver/cli/templates/gemspec.tt +33 -0
- data/lib/quiver/cli/templates/gitignore.tt +10 -0
- data/lib/quiver/cli/templates/lib/application.tt +14 -0
- data/lib/quiver/cli/templates/lib/application/config/router.tt +11 -0
- data/lib/quiver/cli/templates/lib/application/version.tt +3 -0
- data/lib/quiver/cli/templates/spec/spec_helper.tt +19 -0
- data/lib/quiver/duty.rb +34 -0
- data/lib/quiver/duty_master.rb +23 -0
- data/lib/quiver/duty_master/delayed_job_adapter.rb +15 -0
- data/lib/quiver/duty_master/memory_adapter.rb +18 -0
- data/lib/quiver/duty_test_helper.rb +23 -0
- data/lib/quiver/duty_test_helper/delayed_job_helper.rb +9 -0
- data/lib/quiver/duty_test_helper/memory_helper.rb +15 -0
- data/lib/quiver/error.rb +24 -0
- data/lib/quiver/error_collection.rb +60 -0
- data/lib/quiver/json_parser.rb +17 -0
- data/lib/quiver/logger.rb +26 -0
- data/lib/quiver/mapper.rb +311 -0
- data/lib/quiver/mapper/hook.rb +21 -0
- data/lib/quiver/mapper/mapper_result.rb +7 -0
- data/lib/quiver/mapper/not_found_error.rb +27 -0
- data/lib/quiver/mapper/simple_query_builder.rb +70 -0
- data/lib/quiver/mapper/soft_delete.rb +15 -0
- data/lib/quiver/mappers.rb +75 -0
- data/lib/quiver/middleware_stack.rb +35 -0
- data/lib/quiver/model.rb +63 -0
- data/lib/quiver/model/soft_delete.rb +14 -0
- data/lib/quiver/model/validation_error.rb +27 -0
- data/lib/quiver/model/validations.rb +45 -0
- data/lib/quiver/patcher.rb +94 -0
- data/lib/quiver/result.rb +44 -0
- data/lib/quiver/route_helper.rb +16 -0
- data/lib/quiver/router.rb +37 -0
- data/lib/quiver/serialization.rb +6 -0
- data/lib/quiver/serialization/json_api.rb +7 -0
- data/lib/quiver/serialization/json_api/item_type_handler.rb +96 -0
- data/lib/quiver/serialization/json_api/serializer.rb +77 -0
- data/lib/quiver/tasks.rb +31 -0
- data/lib/quiver/validator.rb +83 -0
- data/lib/quiver/validators/base.rb +21 -0
- data/lib/quiver/validators/presence.rb +34 -0
- data/lib/quiver/validators/unique.rb +33 -0
- data/lib/quiver/version.rb +3 -0
- data/quiver.gemspec +42 -0
- 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,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,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
|
data/lib/quiver/duty.rb
ADDED
@@ -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,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
|
data/lib/quiver/error.rb
ADDED
@@ -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
|