sql >> Database >  >> RDS >> PostgreSQL

Problemen met oneindig tijdbereik in Rails

Je kunt Infinity niet opslaan als onderdeel van een tijdbereik in Rails. Ik geloof dat dit komt omdat Infinity zal worden ingevoegd als een tekenreekswaarde en geïnterpreteerd wordt als een float wanneer deze uit de native PSQL oid wordt gehaald. Dus elk datumbereik van Datum -> Zweven zal niet haalbaar zijn. Maar u kunt uw eigen bereik maken met pseudo-datums (1 miljoen jaar vanaf nu) of u kunt gewoon twee afzonderlijke datumvelden gebruiken en deze op de juiste manier interpreteren in het model. Begindatum, einddatum.

In Rails 4.2+ kun je een Float::INFINITY-waarde opslaan in je datetime-type. Voorbeeld.

User.first.update(begin_date: DateTime.now, end_date: 'infinity')
User.first.end_date # => Infinity

Echter, end_date zal geen geldige datum zijn. Je slaat gewoon de string op in de database en je haalt een float . tevoorschijn wanneer je het noemt.

Hier is de daadwerkelijke (Rails 4.2) code die dat afhandelt:

module ActiveRecord
  module ConnectionAdapters
    module PostgreSQL
      module OID # :nodoc:
        class DateTime < Type::DateTime # :nodoc:
          include Infinity

          def type_cast_for_database(value)
            if has_precision? && value.acts_like?(:time) && value.year <= 0
              bce_year = format("%04d", -value.year + 1)
              super.sub(/^-?\d+/, bce_year) + " BC"
            else
              super
            end
          end

          def cast_value(value)
            if value.is_a?(::String)
              case value
              when 'infinity' then ::Float::INFINITY
              when '-infinity' then -::Float::INFINITY
              when / BC$/
                astronomical_year = format("%04d", -value[/^\d+/].to_i + 1)
                super(value.sub(/ BC$/, "").sub(/^\d+/, astronomical_year))
              else
                super
              end
            else
              value
            end
          end
        end
      end
    end
  end
end

Nogmaals, u zult niet in staat zijn om datum-tijdvergelijkingen te doen met een float. Maar het is waarschijnlijk eenvoudig genoeg om een ​​speciaal geval voor deze twee waarden te hebben -::Float::INFINITY en ::Float::INFINITY




  1. PLS-00386:type-mismatch gevonden tussen FETCH-cursor en INTO-variabelen

  2. ListArray Zelfde records opslaan

  3. Hoe u handmatig een waarde in de identiteitskolom in de SQL Server-tabel kunt invoegen - SQL Server / T-SQL-zelfstudie, deel 41

  4. mysql opgeslagen procedurefout (1172, 'Resultaat bestond uit meer dan één rij')