module Mongo # @api private module Lint def validate_underscore_read_preference(read_pref) return unless enabled? return if read_pref.nil? unless read_pref.is_a?(Hash) raise Error::LintError, "Read preference is not a hash: #{read_pref}" end validate_underscore_read_preference_mode(read_pref[:mode] || read_pref['mode']) end module_function :validate_underscore_read_preference def validate_underscore_read_preference_mode(mode) return unless enabled? if mode unless %w(primary primary_preferred secondary secondary_preferred nearest).include?(mode.to_s) raise Error::LintError, "Invalid read preference mode: #{mode}" end end end module_function :validate_underscore_read_preference_mode def validate_camel_case_read_preference(read_pref) return unless enabled? return if read_pref.nil? unless read_pref.is_a?(Hash) raise Error::LintError, "Read preference is not a hash: #{read_pref}" end validate_camel_case_read_preference_mode(read_pref[:mode] || read_pref['mode']) end module_function :validate_camel_case_read_preference def validate_camel_case_read_preference_mode(mode) return unless enabled? if mode unless %w(primary primaryPreferred secondary secondaryPreferred nearest).include?(mode.to_s) raise Error::LintError, "Invalid read preference mode: #{mode}" end end end module_function :validate_camel_case_read_preference_mode # Validates the provided hash as a read concern object, per the # read/write concern specification # (https://github.com/mongodb/specifications/blob/master/source/read-write-concern/read-write-concern.rst#read-concern). # # This method also accepts nil as input for convenience. # # The read concern document as sent to the server may include # additional fields, for example afterClusterTime. These fields # are generated internally by the driver and cannot be specified by # the user (and would potentially lead to incorrect behavior if they # were specified by the user), hence this method prohibits them. # # @param [ Hash ] read_concern The read concern options hash, # with the following optional keys: # - *:level* -- the read preference level as a symbol; valid values # are *:local*, *:majority*, and *:snapshot* # # @raise [ Error::LintError ] If the validation failed. def validate_read_concern_option(read_concern) return unless enabled? return if read_concern.nil? unless read_concern.is_a?(Hash) raise Error::LintError, "Read concern is not a hash: #{read_concern}" end return if read_concern.empty? keys = read_concern.keys if read_concern.is_a?(BSON::Document) # Permits indifferent access allowed_keys = ['level'] else # Does not permit indifferent access allowed_keys = [:level] end if keys != allowed_keys raise Error::LintError, "Read concern has invalid keys: #{keys.inspect}" end level = read_concern[:level] return if [:local, :available, :majority, :linearizable, :snapshot].include?(level) raise Error::LintError, "Read concern level is invalid: value must be a symbol: #{level.inspect}" end module_function :validate_read_concern_option def enabled? ENV['MONGO_RUBY_DRIVER_LINT'] && %w(1 yes true on).include?(ENV['MONGO_RUBY_DRIVER_LINT'].downcase) end module_function :enabled? end end