<commit_before>require 'caruby/util/log'
require 'caruby/util/pretty_print'
require 'caruby/util/inflector'
require 'caruby/util/collection'
require 'caruby/util/validation'

module CaRuby
  # The Persistable mixin adds persistance capability. Every instance which includes Persistable
  # must respond to an overrided {#database} method.
  module Persistable
    # @return [{Symbol => Object}] the content value hash at the point of the last {#take_snapshot}
    #   call
    attr_reader :snapshot
      
    # @param [Resource, <Resource>, nil] obj the object(s) to check
    # @return [Boolean] whether the given object(s) have an identifier, or the object is nil or empty
    def self.saved?(obj)
      if obj.collection? then
        obj.all? { |ref| saved?(ref) }
      else
        obj.nil? or obj.identifier
      end
    end
    
    # @param [Resource, <Resource>, nil] obj the object(s) to check
    # @return [Boolean] whether at least one of the given object(s) does not have an identifier
    def self.unsaved?(obj)
      not saved?(obj)
    end
    
    # Returns the data access mediator for this domain object, if any. The default implementation
    # returns nil. Application #{Resource} modules can override this method.
    #
    # @return [Database, nil] the data access mediator for this Persistable, if any
    def database
      nil
    end
    
    # @return [PersistenceService, nil] the database application service for this Persistable, if any
    def persistence_service
      database.persistence_service(self.class) if database
    end

    # Fetches the domain objects which match this template from the {#database}.
    #
    # @param path (see Reader#query)
    # @return (see Reader#query)
    # @raise (see #database)
    # @raise (see Reader#query)
    # @see Reader#query
    def query(*path)
      path.empty? ? database.query(self) : database.query(self, *path)
    end

    # Fetches this domain object from the {#database}.
    #
    # @param opts (see Reader#find)
    # @option (see Reader#find)
    # @return (see Reader#find)
    # @raise (see #database)
    # @raise (see Reader#find)
    # @see Reader#find
    def find(opts=nil)
      database.find(self, opts)
    end

    # Creates this domain object in the {#database}.
    #
    # @return (see Writer#create)
    # @raise (see #database)
    # @raise (see Writer#create)
    # @see Writer#create
    def create
      database.create(self)
    end

    # Saves this domain object in the {#database}.
    #
    # @return (see Writer#save)
    # @raise (see #database)
    # @raise (see Writer#save)
    # @see Writer#save
    def save
      database.save(self)
    end

    alias :store :save

    # Updates this domain object in the {#database}.
    #
    # @return (see Writer#update)
    # @raise (see #database)
    # @raise (see Writer#update)
    # @see Writer#update
    def update
      database.update(self)
    end

    # Deletes this domain object from the {#database}.
    #
    # @return (see Writer#delete)
    # @raise (see #database)
    # @raise (see Writer#delete)
    # @see Writer#delete
    def delete
      database.delete(self)
    end

    alias :== :equal?

    alias :eql? :==
    
    # Captures the Persistable's updatable attribute base values.
    # The snapshot is subsequently accessible using the {#snapshot} method.
    #
    # @return [{Symbol => Object}] the snapshot value hash
    def take_snapshot<commit_msg>Subclass database implementation is required.<commit_after>require 'caruby/util/log'
require 'caruby/util/pretty_print'
require 'caruby/util/inflector'
require 'caruby/util/collection'
require 'caruby/util/validation'

module CaRuby
  # The Persistable mixin adds persistance capability. Every instance which includes Persistable
  # must respond to an overrided {#database} method.
  module Persistable
    # @return [{Symbol => Object}] the content value hash at the point of the last {#take_snapshot}
    #   call
    attr_reader :snapshot
      
    # @param [Resource, <Resource>, nil] obj the object(s) to check
    # @return [Boolean] whether the given object(s) have an identifier, or the object is nil or empty
    def self.saved?(obj)
      if obj.collection? then
        obj.all? { |ref| saved?(ref) }
      else
        obj.nil? or obj.identifier
      end
    end
    
    # @param [Resource, <Resource>, nil] obj the object(s) to check
    # @return [Boolean] whether at least one of the given object(s) does not have an identifier
    def self.unsaved?(obj)
      not saved?(obj)
    end
    
    # Returns the data access mediator for this domain object.
    # Application #{Resource} modules are required to override this method.
    #
    # @return [Database] the data access mediator for this Persistable, if any
    # @raise [DatabaseError] if the subclass does not override this method
    def database
      raise DatabaseError.new("#{self} database is missing")
    end
    
    # @return [PersistenceService] the database application service for this Persistable
    def persistence_service
      database.persistence_service(self.class)
    end

    # Fetches the domain objects which match this template from the {#database}.
    #
    # @param path (see Reader#query)
    # @return (see Reader#query)
    # @raise (see #database)
    # @raise (see Reader#query)
    # @see Reader#query
    def query(*path)
      path.empty? ? database.query(self) : database.query(self, *path)
    end

    # Fetches this domain object from the {#database}.
    #
    # @param opts (see Reader#find)
    # @option (see Reader#find)
    # @return (see Reader#find)
    # @raise (see #database)
    # @raise (see Reader#find)
    # @see Reader#find
    def find(opts=nil)
      database.find(self, opts)
    end

    # Creates this domain object in the {#database}.
    #
    # @return (see Writer#create)
    # @raise (see #database)
    # @raise (see Writer#create)
    # @see Writer#create
    def create
      database.create(self)
    end

    # Saves this domain object in the {#database}.
    #
    # @return (see Writer#save)
    # @raise (see #database)
    # @raise (see Writer#save)
    # @see Writer#save
    def save
      database.save(self)
    end

    alias :store :save

    # Updates this domain object in the {#database}.
    #
    # @return (see Writer#update)
    # @raise (see #database)
    # @raise (see Writer#update)
    # @see Writer#update
    def update
      database.update(self)
    end

    # Deletes this domain object from the {#database}.
    #
    # @return (see Writer#delete)
    # @raise (see #database)
    # @raise (see Writer#delete)
    # @see Writer#delete
    def delete
      database.delete(self)
    end

    alias :== :equal?

    alias :eql? :==

    # Captures the Persistable's updatable attribute base values.
    # The snapshot is subsequently accessible using the {#snapshot} method.
    #
    # @return [{Symbol => Object}] the snapshot value hash
    def take_snapshot
{'fraction_non_alphanumeric': 0.10105926137990266, 'fraction_numerical': 0.0, 'mean_word_length': 2.8263964950711937, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5811993', 'n_tokens_mistral': 2107, 'n_tokens_neox': 2050, 'n_words': 720}