sp-duh 2.0.6
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/LICENSE +661 -0
 - data/README.md +2 -0
 - data/Rakefile +32 -0
 - data/config/i18n/i18n.xlsx +0 -0
 - data/config/initializers/active_record/connection_adapters_postgre_sql_adapter.rb +165 -0
 - data/config/initializers/active_record/migration_without_transaction.rb +4 -0
 - data/config/initializers/active_record/migrator.rb +34 -0
 - data/config/initializers/rails/generators.rb +13 -0
 - data/config/jsonapi/settings.yml +14 -0
 - data/config/locales/pt.yml +15 -0
 - data/lib/generators/accounting_migration/accounting_migration_generator.rb +10 -0
 - data/lib/generators/accounting_migration/templates/migration.rb +42 -0
 - data/lib/generators/accounting_payroll_migration/accounting_payroll_migration_generator.rb +10 -0
 - data/lib/generators/accounting_payroll_migration/templates/migration.rb +73 -0
 - data/lib/generators/sharded_migration/sharded_migration_generator.rb +10 -0
 - data/lib/generators/sharded_migration/templates/migration.rb +45 -0
 - data/lib/sp-duh.rb +32 -0
 - data/lib/sp/duh.rb +180 -0
 - data/lib/sp/duh/adapters/pg/text_decoder/json.rb +15 -0
 - data/lib/sp/duh/adapters/pg/text_encoder/json.rb +15 -0
 - data/lib/sp/duh/db/transfer/backup.rb +71 -0
 - data/lib/sp/duh/db/transfer/restore.rb +89 -0
 - data/lib/sp/duh/engine.rb +35 -0
 - data/lib/sp/duh/exceptions.rb +70 -0
 - data/lib/sp/duh/i18n/excel_loader.rb +26 -0
 - data/lib/sp/duh/jsonapi/adapters/base.rb +168 -0
 - data/lib/sp/duh/jsonapi/adapters/db.rb +36 -0
 - data/lib/sp/duh/jsonapi/adapters/raw_db.rb +77 -0
 - data/lib/sp/duh/jsonapi/configuration.rb +167 -0
 - data/lib/sp/duh/jsonapi/doc/apidoc_documentation_format_generator.rb +286 -0
 - data/lib/sp/duh/jsonapi/doc/generator.rb +32 -0
 - data/lib/sp/duh/jsonapi/doc/schema_catalog_helper.rb +97 -0
 - data/lib/sp/duh/jsonapi/doc/victor_pinus_metadata_format_parser.rb +374 -0
 - data/lib/sp/duh/jsonapi/exceptions.rb +56 -0
 - data/lib/sp/duh/jsonapi/model/base.rb +25 -0
 - data/lib/sp/duh/jsonapi/model/concerns/attributes.rb +94 -0
 - data/lib/sp/duh/jsonapi/model/concerns/model.rb +42 -0
 - data/lib/sp/duh/jsonapi/model/concerns/persistence.rb +221 -0
 - data/lib/sp/duh/jsonapi/model/concerns/serialization.rb +59 -0
 - data/lib/sp/duh/jsonapi/parameters.rb +44 -0
 - data/lib/sp/duh/jsonapi/resource_publisher.rb +28 -0
 - data/lib/sp/duh/jsonapi/service.rb +110 -0
 - data/lib/sp/duh/migrations.rb +47 -0
 - data/lib/sp/duh/migrations/migrator.rb +41 -0
 - data/lib/sp/duh/repl.rb +193 -0
 - data/lib/sp/duh/version.rb +25 -0
 - data/lib/tasks/db_utils.rake +98 -0
 - data/lib/tasks/doc.rake +27 -0
 - data/lib/tasks/i18n.rake +23 -0
 - data/lib/tasks/oauth.rake +29 -0
 - data/lib/tasks/transfer.rake +48 -0
 - data/lib/tasks/xls2jrxml.rake +15 -0
 - data/test/jsonapi/server.rb +67 -0
 - data/test/tasks/test.rake +10 -0
 - metadata +170 -0
 
| 
         @@ -0,0 +1,56 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module SP
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Duh
         
     | 
| 
      
 3 
     | 
    
         
            +
                module JSONAPI
         
     | 
| 
      
 4 
     | 
    
         
            +
                  module Exceptions
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                    # JSONAPI service and configuration errors
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                    class ServiceSetupError < SP::Duh::Exceptions::GenericError ; ; end
         
     | 
| 
      
 9 
     | 
    
         
            +
                    class ServiceProtocolError < SP::Duh::Exceptions::GenericDetailedError ; ; end
         
     | 
| 
      
 10 
     | 
    
         
            +
                    class InvalidResourceConfigurationError < SP::Duh::Exceptions::GenericDetailedError ; ; end
         
     | 
| 
      
 11 
     | 
    
         
            +
                    class InvalidResourcePublisherError < SP::Duh::Exceptions::GenericDetailedError ; ; end
         
     | 
| 
      
 12 
     | 
    
         
            +
                    class DuplicateResourceError < SP::Duh::Exceptions::GenericDetailedError ; ; end
         
     | 
| 
      
 13 
     | 
    
         
            +
                    class SaveConfigurationError < SP::Duh::Exceptions::GenericError ; ; end
         
     | 
| 
      
 14 
     | 
    
         
            +
                    class InvalidJSONAPIKeyError < SP::Duh::Exceptions::GenericDetailedError ; ; end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                    # JSONAPI model querying errors
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                    class GenericModelError < SP::Duh::Exceptions::GenericError
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                      attr_reader :id
         
     | 
| 
      
 21 
     | 
    
         
            +
                      attr_reader :status
         
     | 
| 
      
 22 
     | 
    
         
            +
                      attr_reader :result
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                      def initialize(result, nested = $!)
         
     | 
| 
      
 25 
     | 
    
         
            +
                        @result = result
         
     | 
| 
      
 26 
     | 
    
         
            +
                        errors = get_result_errors()
         
     | 
| 
      
 27 
     | 
    
         
            +
                        @status = (errors.map { |error| error[:status].to_i }.max) || 403
         
     | 
| 
      
 28 
     | 
    
         
            +
                        message = errors.first[:detail]
         
     | 
| 
      
 29 
     | 
    
         
            +
                        super(message, nested)
         
     | 
| 
      
 30 
     | 
    
         
            +
                      end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                      def internal_error
         
     | 
| 
      
 33 
     | 
    
         
            +
                        errors = get_result_errors()
         
     | 
| 
      
 34 
     | 
    
         
            +
                        if errors.length != 1
         
     | 
| 
      
 35 
     | 
    
         
            +
                          @result.to_json
         
     | 
| 
      
 36 
     | 
    
         
            +
                        else
         
     | 
| 
      
 37 
     | 
    
         
            +
                          errors.first[:meta]['internal-error'] if errors.first[:meta]
         
     | 
| 
      
 38 
     | 
    
         
            +
                        end
         
     | 
| 
      
 39 
     | 
    
         
            +
                      end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                      def inspect()
         
     | 
| 
      
 42 
     | 
    
         
            +
                        description = super()
         
     | 
| 
      
 43 
     | 
    
         
            +
                        description = description + " (#{internal_error})" if internal_error
         
     | 
| 
      
 44 
     | 
    
         
            +
                        description
         
     | 
| 
      
 45 
     | 
    
         
            +
                      end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                      private
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                        def get_result_errors() ; (result.is_a?(Hash) ? result : HashWithIndifferentAccess.new(JSON.parse(result)))[:errors] ; end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                    end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                  end
         
     | 
| 
      
 54 
     | 
    
         
            +
                end
         
     | 
| 
      
 55 
     | 
    
         
            +
              end
         
     | 
| 
      
 56 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,25 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'sp/duh/jsonapi/model/concerns/model'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module SP
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Duh
         
     | 
| 
      
 5 
     | 
    
         
            +
                module JSONAPI
         
     | 
| 
      
 6 
     | 
    
         
            +
                  module Model
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                    class Base
         
     | 
| 
      
 9 
     | 
    
         
            +
                      include ::ActiveRecord::Validations
         
     | 
| 
      
 10 
     | 
    
         
            +
                      include Concerns::Model
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                      def self.inherited(child)
         
     | 
| 
      
 13 
     | 
    
         
            +
                        child.resource_name = child.name.demodulize.underscore.pluralize
         
     | 
| 
      
 14 
     | 
    
         
            +
                        child.autogenerated_id = true
         
     | 
| 
      
 15 
     | 
    
         
            +
                      end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                      def self.i18n_scope
         
     | 
| 
      
 18 
     | 
    
         
            +
                        :activerecord
         
     | 
| 
      
 19 
     | 
    
         
            +
                      end
         
     | 
| 
      
 20 
     | 
    
         
            +
                    end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                  end
         
     | 
| 
      
 23 
     | 
    
         
            +
                end
         
     | 
| 
      
 24 
     | 
    
         
            +
              end
         
     | 
| 
      
 25 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,94 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module SP
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Duh
         
     | 
| 
      
 3 
     | 
    
         
            +
                module JSONAPI
         
     | 
| 
      
 4 
     | 
    
         
            +
                  module Model
         
     | 
| 
      
 5 
     | 
    
         
            +
                    module Concerns
         
     | 
| 
      
 6 
     | 
    
         
            +
                      module Attributes
         
     | 
| 
      
 7 
     | 
    
         
            +
                        extend ::ActiveSupport::Concern
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                        included do
         
     | 
| 
      
 10 
     | 
    
         
            +
                        end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                        module ClassMethods
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                          def attributes
         
     | 
| 
      
 15 
     | 
    
         
            +
                            if !@attributes && superclass.respond_to?(:attributes)
         
     | 
| 
      
 16 
     | 
    
         
            +
                              @attributes = []
         
     | 
| 
      
 17 
     | 
    
         
            +
                              @attributes += superclass.attributes
         
     | 
| 
      
 18 
     | 
    
         
            +
                            end
         
     | 
| 
      
 19 
     | 
    
         
            +
                            @attributes = [] if !@attributes
         
     | 
| 
      
 20 
     | 
    
         
            +
                            @attributes
         
     | 
| 
      
 21 
     | 
    
         
            +
                          end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                          def attr_accessible(name)
         
     | 
| 
      
 24 
     | 
    
         
            +
                            attributes << name if !attributes.include?(name)
         
     | 
| 
      
 25 
     | 
    
         
            +
                            attr_accessor name
         
     | 
| 
      
 26 
     | 
    
         
            +
                          end
         
     | 
| 
      
 27 
     | 
    
         
            +
                        end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                        def initialize(new_attributes = nil)
         
     | 
| 
      
 30 
     | 
    
         
            +
                          assign_attributes(new_attributes) if new_attributes
         
     | 
| 
      
 31 
     | 
    
         
            +
                          yield self if block_given?
         
     | 
| 
      
 32 
     | 
    
         
            +
                        end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                        def attributes=(new_attributes)
         
     | 
| 
      
 35 
     | 
    
         
            +
                          return unless new_attributes.is_a?(Hash)
         
     | 
| 
      
 36 
     | 
    
         
            +
                          assign_attributes(new_attributes)
         
     | 
| 
      
 37 
     | 
    
         
            +
                        end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                        private
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                          def assign_attributes(new_attributes)
         
     | 
| 
      
 42 
     | 
    
         
            +
                            return if new_attributes.blank?
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                            new_attributes = new_attributes.stringify_keys
         
     | 
| 
      
 45 
     | 
    
         
            +
                            nested_parameter_attributes = []
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                            new_attributes.each do |k, v|
         
     | 
| 
      
 48 
     | 
    
         
            +
                              if respond_to?("#{k}=")
         
     | 
| 
      
 49 
     | 
    
         
            +
                                if v.is_a?(Hash)
         
     | 
| 
      
 50 
     | 
    
         
            +
                                  nested_parameter_attributes << [ k, v ]
         
     | 
| 
      
 51 
     | 
    
         
            +
                                else
         
     | 
| 
      
 52 
     | 
    
         
            +
                                  send("#{k}=", v)
         
     | 
| 
      
 53 
     | 
    
         
            +
                                end
         
     | 
| 
      
 54 
     | 
    
         
            +
                              # else
         
     | 
| 
      
 55 
     | 
    
         
            +
                              #   raise(ActiveRecord::UnknownAttributeError, "unknown attribute: #{k}")
         
     | 
| 
      
 56 
     | 
    
         
            +
                              end
         
     | 
| 
      
 57 
     | 
    
         
            +
                            end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                            # Assign any deferred nested attributes after the base attributes have been set
         
     | 
| 
      
 60 
     | 
    
         
            +
                            nested_parameter_attributes.each do |k,v|
         
     | 
| 
      
 61 
     | 
    
         
            +
                              send("#{k}=", v)
         
     | 
| 
      
 62 
     | 
    
         
            +
                            end
         
     | 
| 
      
 63 
     | 
    
         
            +
                          end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                          # Returns an <tt>#inspect</tt>-like string for the value of the
         
     | 
| 
      
 66 
     | 
    
         
            +
                          # attribute +attr_name+. String attributes are truncated upto 50
         
     | 
| 
      
 67 
     | 
    
         
            +
                          # characters, and Date and Time attributes are returned in the
         
     | 
| 
      
 68 
     | 
    
         
            +
                          # <tt>:db</tt> format. Other attributes return the value of
         
     | 
| 
      
 69 
     | 
    
         
            +
                          # <tt>#inspect</tt> without modification.
         
     | 
| 
      
 70 
     | 
    
         
            +
                          #
         
     | 
| 
      
 71 
     | 
    
         
            +
                          #   person = Person.create!(:name => "David Heinemeier Hansson " * 3)
         
     | 
| 
      
 72 
     | 
    
         
            +
                          #
         
     | 
| 
      
 73 
     | 
    
         
            +
                          #   person.attribute_for_inspect(:name)
         
     | 
| 
      
 74 
     | 
    
         
            +
                          #   # => '"David Heinemeier Hansson David Heinemeier Hansson D..."'
         
     | 
| 
      
 75 
     | 
    
         
            +
                          #
         
     | 
| 
      
 76 
     | 
    
         
            +
                          #   person.attribute_for_inspect(:created_at)
         
     | 
| 
      
 77 
     | 
    
         
            +
                          #   # => '"2009-01-12 04:48:57"'
         
     | 
| 
      
 78 
     | 
    
         
            +
                          def attribute_for_inspect(name)
         
     | 
| 
      
 79 
     | 
    
         
            +
                            value = self.send(name)
         
     | 
| 
      
 80 
     | 
    
         
            +
                            if value.is_a?(String) && value.length > 50
         
     | 
| 
      
 81 
     | 
    
         
            +
                              "#{value[0..50]}...".inspect
         
     | 
| 
      
 82 
     | 
    
         
            +
                            elsif value.is_a?(Date) || value.is_a?(Time)
         
     | 
| 
      
 83 
     | 
    
         
            +
                              %("#{value.to_s(:db)}")
         
     | 
| 
      
 84 
     | 
    
         
            +
                            else
         
     | 
| 
      
 85 
     | 
    
         
            +
                              value.inspect
         
     | 
| 
      
 86 
     | 
    
         
            +
                            end
         
     | 
| 
      
 87 
     | 
    
         
            +
                          end
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
                      end
         
     | 
| 
      
 90 
     | 
    
         
            +
                    end
         
     | 
| 
      
 91 
     | 
    
         
            +
                  end
         
     | 
| 
      
 92 
     | 
    
         
            +
                end
         
     | 
| 
      
 93 
     | 
    
         
            +
              end
         
     | 
| 
      
 94 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,42 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'active_support'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'active_record'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            require 'sp/duh/jsonapi/model/concerns/attributes'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'sp/duh/jsonapi/model/concerns/serialization'
         
     | 
| 
      
 6 
     | 
    
         
            +
            require 'sp/duh/jsonapi/model/concerns/persistence'
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            module SP
         
     | 
| 
      
 9 
     | 
    
         
            +
              module Duh
         
     | 
| 
      
 10 
     | 
    
         
            +
                module JSONAPI
         
     | 
| 
      
 11 
     | 
    
         
            +
                  module Model
         
     | 
| 
      
 12 
     | 
    
         
            +
                    module Concerns
         
     | 
| 
      
 13 
     | 
    
         
            +
                      module Model
         
     | 
| 
      
 14 
     | 
    
         
            +
                        extend ::ActiveSupport::Concern
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                        include Attributes
         
     | 
| 
      
 17 
     | 
    
         
            +
                        include Serialization
         
     | 
| 
      
 18 
     | 
    
         
            +
                        include Persistence
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                        included do
         
     | 
| 
      
 21 
     | 
    
         
            +
                        end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                        module ClassMethods
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                          def inspect
         
     | 
| 
      
 26 
     | 
    
         
            +
                            "#{super}(#{self.attributes.join(', ')})"
         
     | 
| 
      
 27 
     | 
    
         
            +
                          end
         
     | 
| 
      
 28 
     | 
    
         
            +
                        end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                        # Returns the contents of the record as a nicely formatted string.
         
     | 
| 
      
 31 
     | 
    
         
            +
                        def inspect
         
     | 
| 
      
 32 
     | 
    
         
            +
                          # attrs = self.class.attributes
         
     | 
| 
      
 33 
     | 
    
         
            +
                          inspection = self.class.attributes.collect { |name| "#{name}: #{attribute_for_inspect(name)}" }.compact.join(", ")
         
     | 
| 
      
 34 
     | 
    
         
            +
                          "#<#{self.class} #{inspection}>"
         
     | 
| 
      
 35 
     | 
    
         
            +
                        end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                      end
         
     | 
| 
      
 38 
     | 
    
         
            +
                    end
         
     | 
| 
      
 39 
     | 
    
         
            +
                  end
         
     | 
| 
      
 40 
     | 
    
         
            +
                end
         
     | 
| 
      
 41 
     | 
    
         
            +
              end
         
     | 
| 
      
 42 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,221 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module SP
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Duh
         
     | 
| 
      
 3 
     | 
    
         
            +
                module JSONAPI
         
     | 
| 
      
 4 
     | 
    
         
            +
                  module Model
         
     | 
| 
      
 5 
     | 
    
         
            +
                    module Concerns
         
     | 
| 
      
 6 
     | 
    
         
            +
                      module Persistence
         
     | 
| 
      
 7 
     | 
    
         
            +
                        extend ::ActiveSupport::Concern
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                        included do
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                          # Idem for data adapter configuration...
         
     | 
| 
      
 12 
     | 
    
         
            +
                          # In a similar way to ActiveRecord::Base.connection, the adapter should be defined at the base level and is inherited by all subclasses
         
     | 
| 
      
 13 
     | 
    
         
            +
                          class_attribute :adapter, instance_reader: false, instance_writer: false
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                          self.autogenerated_id = true
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                          attr_accessible :id
         
     | 
| 
      
 18 
     | 
    
         
            +
                        end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                        module ClassMethods
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                          # Define resource configuration accessors at the class (and subclass) level (static).
         
     | 
| 
      
 23 
     | 
    
         
            +
                          # These attribute values are NOT inherited by subclasses, each subclass MUST define their own.
         
     | 
| 
      
 24 
     | 
    
         
            +
                          # Instances can access these attributes at the class level only.
         
     | 
| 
      
 25 
     | 
    
         
            +
                          attr_accessor :resource_name
         
     | 
| 
      
 26 
     | 
    
         
            +
                          attr_accessor :autogenerated_id
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                          def find!(id, conditions = nil) ; get(id, conditions) ; end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                          def find_explicit!(exp_accounting_schema, exp_accounting_prefix, id, conditions = nil)
         
     | 
| 
      
 31 
     | 
    
         
            +
                            get_explicit(exp_accounting_schema, exp_accounting_prefix, id, conditions)
         
     | 
| 
      
 32 
     | 
    
         
            +
                          end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                          def find(id, conditions = nil)
         
     | 
| 
      
 35 
     | 
    
         
            +
                            begin
         
     | 
| 
      
 36 
     | 
    
         
            +
                              get(id, conditions)
         
     | 
| 
      
 37 
     | 
    
         
            +
                            rescue Exception => e
         
     | 
| 
      
 38 
     | 
    
         
            +
                              return nil
         
     | 
| 
      
 39 
     | 
    
         
            +
                            end
         
     | 
| 
      
 40 
     | 
    
         
            +
                          end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                          def query!(condition) ; get_all(condition) ; end
         
     | 
| 
      
 43 
     | 
    
         
            +
                          def query_explicit!(exp_accounting_schema, exp_accounting_prefix, condition) ; get_all_explicit(exp_accounting_schema, exp_accounting_prefix, condition) ; end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                          def query(condition)
         
     | 
| 
      
 46 
     | 
    
         
            +
                            begin
         
     | 
| 
      
 47 
     | 
    
         
            +
                              get_all(condition)
         
     | 
| 
      
 48 
     | 
    
         
            +
                            rescue Exception => e
         
     | 
| 
      
 49 
     | 
    
         
            +
                              nil
         
     | 
| 
      
 50 
     | 
    
         
            +
                            end
         
     | 
| 
      
 51 
     | 
    
         
            +
                          end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                          def first!(condition = "")
         
     | 
| 
      
 54 
     | 
    
         
            +
                            condition += (condition.blank? ? "" : "&") + "page[size]=1"
         
     | 
| 
      
 55 
     | 
    
         
            +
                            get_all(condition).first
         
     | 
| 
      
 56 
     | 
    
         
            +
                          end
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                          def first(condition = "")
         
     | 
| 
      
 59 
     | 
    
         
            +
                            begin
         
     | 
| 
      
 60 
     | 
    
         
            +
                              condition += (condition.blank? ? "" : "&") + "page[size]=1"
         
     | 
| 
      
 61 
     | 
    
         
            +
                              get_all(condition).first
         
     | 
| 
      
 62 
     | 
    
         
            +
                            rescue Exception => e
         
     | 
| 
      
 63 
     | 
    
         
            +
                              nil
         
     | 
| 
      
 64 
     | 
    
         
            +
                            end
         
     | 
| 
      
 65 
     | 
    
         
            +
                          end
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
                          def all! ; get_all("") ; end
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                          def all
         
     | 
| 
      
 70 
     | 
    
         
            +
                            begin
         
     | 
| 
      
 71 
     | 
    
         
            +
                              get_all("")
         
     | 
| 
      
 72 
     | 
    
         
            +
                            rescue Exception => e
         
     | 
| 
      
 73 
     | 
    
         
            +
                              nil
         
     | 
| 
      
 74 
     | 
    
         
            +
                            end
         
     | 
| 
      
 75 
     | 
    
         
            +
                          end
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                          private
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                            def get_explicit(exp_accounting_schema, exp_accounting_prefix, id, conditions = nil)
         
     | 
| 
      
 80 
     | 
    
         
            +
                              result = self.adapter.get_explicit!(exp_accounting_schema, exp_accounting_prefix, "#{self.resource_name}/#{id.to_s}", conditions)
         
     | 
| 
      
 81 
     | 
    
         
            +
                              jsonapi_result_to_instance(result[:data], result)
         
     | 
| 
      
 82 
     | 
    
         
            +
                            end
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                            def get(id, conditions = nil)
         
     | 
| 
      
 85 
     | 
    
         
            +
                              result = self.adapter.get("#{self.resource_name}/#{id.to_s}", conditions)
         
     | 
| 
      
 86 
     | 
    
         
            +
                              jsonapi_result_to_instance(result[:data], result)
         
     | 
| 
      
 87 
     | 
    
         
            +
                            end
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
                            def get_all(condition)
         
     | 
| 
      
 90 
     | 
    
         
            +
                              got = []
         
     | 
| 
      
 91 
     | 
    
         
            +
                              result = self.adapter.get(self.resource_name, condition)
         
     | 
| 
      
 92 
     | 
    
         
            +
                              if result
         
     | 
| 
      
 93 
     | 
    
         
            +
                                got = result[:data].map do |item|
         
     | 
| 
      
 94 
     | 
    
         
            +
                                  data = { data: item }
         
     | 
| 
      
 95 
     | 
    
         
            +
                                  data.merge(included: result[:included]) if result[:included]
         
     | 
| 
      
 96 
     | 
    
         
            +
                                  jsonapi_result_to_instance(item, data)
         
     | 
| 
      
 97 
     | 
    
         
            +
                                end
         
     | 
| 
      
 98 
     | 
    
         
            +
                              end
         
     | 
| 
      
 99 
     | 
    
         
            +
                              got
         
     | 
| 
      
 100 
     | 
    
         
            +
                            end
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
                            def get_all_explicit(exp_accounting_schema, exp_accounting_prefix, condition)
         
     | 
| 
      
 103 
     | 
    
         
            +
                              got = []
         
     | 
| 
      
 104 
     | 
    
         
            +
                              result = self.adapter.get_explicit!(exp_accounting_schema, exp_accounting_prefix, self.resource_name, condition)
         
     | 
| 
      
 105 
     | 
    
         
            +
                              if result
         
     | 
| 
      
 106 
     | 
    
         
            +
                                got = result[:data].map do |item|
         
     | 
| 
      
 107 
     | 
    
         
            +
                                  data = { data: item }
         
     | 
| 
      
 108 
     | 
    
         
            +
                                  data.merge(included: result[:included]) if result[:included]
         
     | 
| 
      
 109 
     | 
    
         
            +
                                  jsonapi_result_to_instance(item, data)
         
     | 
| 
      
 110 
     | 
    
         
            +
                                end
         
     | 
| 
      
 111 
     | 
    
         
            +
                              end
         
     | 
| 
      
 112 
     | 
    
         
            +
                              got
         
     | 
| 
      
 113 
     | 
    
         
            +
                            end
         
     | 
| 
      
 114 
     | 
    
         
            +
             
     | 
| 
      
 115 
     | 
    
         
            +
                            def jsonapi_result_to_instance(result, data)
         
     | 
| 
      
 116 
     | 
    
         
            +
                              if result
         
     | 
| 
      
 117 
     | 
    
         
            +
                                instance = self.new(result.merge(result[:attributes]).except(:attributes))
         
     | 
| 
      
 118 
     | 
    
         
            +
                                instance.send :_data=, data
         
     | 
| 
      
 119 
     | 
    
         
            +
                              end
         
     | 
| 
      
 120 
     | 
    
         
            +
                              instance
         
     | 
| 
      
 121 
     | 
    
         
            +
                            end
         
     | 
| 
      
 122 
     | 
    
         
            +
                        end
         
     | 
| 
      
 123 
     | 
    
         
            +
             
     | 
| 
      
 124 
     | 
    
         
            +
                        # Instance methods
         
     | 
| 
      
 125 
     | 
    
         
            +
             
     | 
| 
      
 126 
     | 
    
         
            +
                        def new_record?
         
     | 
| 
      
 127 
     | 
    
         
            +
                          if self.class.autogenerated_id || self.id.nil?
         
     | 
| 
      
 128 
     | 
    
         
            +
                            self.id.nil?
         
     | 
| 
      
 129 
     | 
    
         
            +
                          else
         
     | 
| 
      
 130 
     | 
    
         
            +
                            self.class.find(self.id).nil?
         
     | 
| 
      
 131 
     | 
    
         
            +
                          end
         
     | 
| 
      
 132 
     | 
    
         
            +
                        end
         
     | 
| 
      
 133 
     | 
    
         
            +
             
     | 
| 
      
 134 
     | 
    
         
            +
                        def save!
         
     | 
| 
      
 135 
     | 
    
         
            +
                          if new_record?
         
     | 
| 
      
 136 
     | 
    
         
            +
                            create!
         
     | 
| 
      
 137 
     | 
    
         
            +
                          else
         
     | 
| 
      
 138 
     | 
    
         
            +
                            update!
         
     | 
| 
      
 139 
     | 
    
         
            +
                          end
         
     | 
| 
      
 140 
     | 
    
         
            +
                        end
         
     | 
| 
      
 141 
     | 
    
         
            +
             
     | 
| 
      
 142 
     | 
    
         
            +
                        def save_explicit!(exp_accounting_schema, exp_accounting_prefix)
         
     | 
| 
      
 143 
     | 
    
         
            +
                          if new_record?
         
     | 
| 
      
 144 
     | 
    
         
            +
                            create!(exp_accounting_schema, exp_accounting_prefix)
         
     | 
| 
      
 145 
     | 
    
         
            +
                          else
         
     | 
| 
      
 146 
     | 
    
         
            +
                            update!(exp_accounting_schema, exp_accounting_prefix)
         
     | 
| 
      
 147 
     | 
    
         
            +
                          end
         
     | 
| 
      
 148 
     | 
    
         
            +
                        end
         
     | 
| 
      
 149 
     | 
    
         
            +
             
     | 
| 
      
 150 
     | 
    
         
            +
                        def destroy!
         
     | 
| 
      
 151 
     | 
    
         
            +
                          if !new_record?
         
     | 
| 
      
 152 
     | 
    
         
            +
                            self.class.adapter.delete(path_for_id)
         
     | 
| 
      
 153 
     | 
    
         
            +
                          end
         
     | 
| 
      
 154 
     | 
    
         
            +
                        end
         
     | 
| 
      
 155 
     | 
    
         
            +
             
     | 
| 
      
 156 
     | 
    
         
            +
                        def destroy_explicit!(exp_accounting_schema, exp_accounting_prefix)
         
     | 
| 
      
 157 
     | 
    
         
            +
                          if !new_record?
         
     | 
| 
      
 158 
     | 
    
         
            +
                            self.class.adapter.delete_explicit!(exp_accounting_schema, exp_accounting_prefix, path_for_id)
         
     | 
| 
      
 159 
     | 
    
         
            +
                          end
         
     | 
| 
      
 160 
     | 
    
         
            +
                        end
         
     | 
| 
      
 161 
     | 
    
         
            +
             
     | 
| 
      
 162 
     | 
    
         
            +
                        alias :delete! :destroy!
         
     | 
| 
      
 163 
     | 
    
         
            +
             
     | 
| 
      
 164 
     | 
    
         
            +
                        def create!(exp_accounting_schema = nil, exp_accounting_prefix = nil)
         
     | 
| 
      
 165 
     | 
    
         
            +
                          if self.class.autogenerated_id
         
     | 
| 
      
 166 
     | 
    
         
            +
                            params = {
         
     | 
| 
      
 167 
     | 
    
         
            +
                              data: {
         
     | 
| 
      
 168 
     | 
    
         
            +
                                type: self.class.resource_name,
         
     | 
| 
      
 169 
     | 
    
         
            +
                                attributes: get_persistent_json.reject { |k,v| k == :id || v.nil? }
         
     | 
| 
      
 170 
     | 
    
         
            +
                              }
         
     | 
| 
      
 171 
     | 
    
         
            +
                            }
         
     | 
| 
      
 172 
     | 
    
         
            +
                          else
         
     | 
| 
      
 173 
     | 
    
         
            +
                            params = {
         
     | 
| 
      
 174 
     | 
    
         
            +
                              data: {
         
     | 
| 
      
 175 
     | 
    
         
            +
                                type: self.class.resource_name,
         
     | 
| 
      
 176 
     | 
    
         
            +
                                attributes: get_persistent_json.reject { |k,v| v.nil? }
         
     | 
| 
      
 177 
     | 
    
         
            +
                              }
         
     | 
| 
      
 178 
     | 
    
         
            +
                            }
         
     | 
| 
      
 179 
     | 
    
         
            +
                          end
         
     | 
| 
      
 180 
     | 
    
         
            +
                          result = if !exp_accounting_schema.blank? || !exp_accounting_prefix.blank?
         
     | 
| 
      
 181 
     | 
    
         
            +
                            self.class.adapter.post_explicit!(exp_accounting_schema, exp_accounting_prefix, self.class.resource_name, params)
         
     | 
| 
      
 182 
     | 
    
         
            +
                          else
         
     | 
| 
      
 183 
     | 
    
         
            +
                            self.class.adapter.post(self.class.resource_name, params)
         
     | 
| 
      
 184 
     | 
    
         
            +
                          end
         
     | 
| 
      
 185 
     | 
    
         
            +
                          # Set the id to the newly created id
         
     | 
| 
      
 186 
     | 
    
         
            +
                          self.id = result[:data][:id]
         
     | 
| 
      
 187 
     | 
    
         
            +
                        end
         
     | 
| 
      
 188 
     | 
    
         
            +
             
     | 
| 
      
 189 
     | 
    
         
            +
                        def update!(exp_accounting_schema = nil, exp_accounting_prefix = nil)
         
     | 
| 
      
 190 
     | 
    
         
            +
                          params = {
         
     | 
| 
      
 191 
     | 
    
         
            +
                            data: {
         
     | 
| 
      
 192 
     | 
    
         
            +
                              type: self.class.resource_name,
         
     | 
| 
      
 193 
     | 
    
         
            +
                              id: self.id.to_s,
         
     | 
| 
      
 194 
     | 
    
         
            +
                              attributes: get_persistent_json.reject { |k,v| k == :id }
         
     | 
| 
      
 195 
     | 
    
         
            +
                            }
         
     | 
| 
      
 196 
     | 
    
         
            +
                          }
         
     | 
| 
      
 197 
     | 
    
         
            +
                          result = if !exp_accounting_schema.blank? || !exp_accounting_prefix.blank?
         
     | 
| 
      
 198 
     | 
    
         
            +
                            self.class.adapter.patch_explicit!(exp_accounting_schema, exp_accounting_prefix, path_for_id, params)
         
     | 
| 
      
 199 
     | 
    
         
            +
                          else
         
     | 
| 
      
 200 
     | 
    
         
            +
                            self.class.adapter.patch(path_for_id, params)
         
     | 
| 
      
 201 
     | 
    
         
            +
                          end
         
     | 
| 
      
 202 
     | 
    
         
            +
                        end
         
     | 
| 
      
 203 
     | 
    
         
            +
             
     | 
| 
      
 204 
     | 
    
         
            +
                        def get_persistent_json
         
     | 
| 
      
 205 
     | 
    
         
            +
                          as_json.reject { |k| !k.in?(self.class.attributes) }
         
     | 
| 
      
 206 
     | 
    
         
            +
                        end
         
     | 
| 
      
 207 
     | 
    
         
            +
             
     | 
| 
      
 208 
     | 
    
         
            +
                        protected
         
     | 
| 
      
 209 
     | 
    
         
            +
             
     | 
| 
      
 210 
     | 
    
         
            +
                          attr_accessor :_data
         
     | 
| 
      
 211 
     | 
    
         
            +
             
     | 
| 
      
 212 
     | 
    
         
            +
                        private
         
     | 
| 
      
 213 
     | 
    
         
            +
             
     | 
| 
      
 214 
     | 
    
         
            +
                          def path_for_id ; "#{self.class.resource_name}/#{self.id.to_s}" ; end
         
     | 
| 
      
 215 
     | 
    
         
            +
             
     | 
| 
      
 216 
     | 
    
         
            +
                      end
         
     | 
| 
      
 217 
     | 
    
         
            +
                    end
         
     | 
| 
      
 218 
     | 
    
         
            +
                  end
         
     | 
| 
      
 219 
     | 
    
         
            +
                end
         
     | 
| 
      
 220 
     | 
    
         
            +
              end
         
     | 
| 
      
 221 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,59 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module SP
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Duh
         
     | 
| 
      
 3 
     | 
    
         
            +
                module JSONAPI
         
     | 
| 
      
 4 
     | 
    
         
            +
                  module Model
         
     | 
| 
      
 5 
     | 
    
         
            +
                    module Concerns
         
     | 
| 
      
 6 
     | 
    
         
            +
                      module Serialization
         
     | 
| 
      
 7 
     | 
    
         
            +
                        extend ::ActiveSupport::Concern
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                        included do
         
     | 
| 
      
 10 
     | 
    
         
            +
                        end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                        def as_json(options = {})
         
     | 
| 
      
 13 
     | 
    
         
            +
                          root = ActiveRecord::Base.include_root_in_json
         
     | 
| 
      
 14 
     | 
    
         
            +
                          root = options[:root] if options.try(:key?, :root)
         
     | 
| 
      
 15 
     | 
    
         
            +
                          if root
         
     | 
| 
      
 16 
     | 
    
         
            +
                            root = self.class.name.underscore.gsub('/','_').to_sym
         
     | 
| 
      
 17 
     | 
    
         
            +
                            { root => serializable_hash(options) }
         
     | 
| 
      
 18 
     | 
    
         
            +
                          else
         
     | 
| 
      
 19 
     | 
    
         
            +
                            serializable_hash(options)
         
     | 
| 
      
 20 
     | 
    
         
            +
                          end
         
     | 
| 
      
 21 
     | 
    
         
            +
                        end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                        def from_json(json)
         
     | 
| 
      
 24 
     | 
    
         
            +
                          root = ActiveRecord::Base.include_root_in_json
         
     | 
| 
      
 25 
     | 
    
         
            +
                          hash = ActiveSupport::JSON.decode(json)
         
     | 
| 
      
 26 
     | 
    
         
            +
                          hash = hash.values.first if root
         
     | 
| 
      
 27 
     | 
    
         
            +
                          self.attributes = hash
         
     | 
| 
      
 28 
     | 
    
         
            +
                          self
         
     | 
| 
      
 29 
     | 
    
         
            +
                        end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                        private
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                          alias :read_attribute_for_serialization :send
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                          def serializable_hash(options = {})
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                            attribute_names = self.class.attributes.sort
         
     | 
| 
      
 38 
     | 
    
         
            +
                            if only = options[:only]
         
     | 
| 
      
 39 
     | 
    
         
            +
                              attribute_names &= Array.wrap(only).map(&:to_s)
         
     | 
| 
      
 40 
     | 
    
         
            +
                            elsif except = options[:except]
         
     | 
| 
      
 41 
     | 
    
         
            +
                              attribute_names -= Array.wrap(except).map(&:to_s)
         
     | 
| 
      
 42 
     | 
    
         
            +
                            end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                            hash = {}
         
     | 
| 
      
 45 
     | 
    
         
            +
                            attribute_names.each { |n| hash[n] = read_attribute_for_serialization(n) }
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                            method_names = Array.wrap(options[:methods]).select { |n| respond_to?(n) }
         
     | 
| 
      
 48 
     | 
    
         
            +
                            method_names.each { |n| hash[n] = send(n) }
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                            hash
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                          end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                      end
         
     | 
| 
      
 55 
     | 
    
         
            +
                    end
         
     | 
| 
      
 56 
     | 
    
         
            +
                  end
         
     | 
| 
      
 57 
     | 
    
         
            +
                end
         
     | 
| 
      
 58 
     | 
    
         
            +
              end
         
     | 
| 
      
 59 
     | 
    
         
            +
            end
         
     |