On Tuesday, June 08, 2010 02:33:27 pm Juan Manuel Barreneche wrote:
> Buenas!
>
> 2010/6/8 Luciano Ruete <[email protected]>
>
> > Hola lista,
> >
> > Estoy trabajando con una clase que en parte cuenta bits, esos bits me
> > sirven
> > para luego alimentar una round robin data base[1].
> >
> > El contador es incrementado periodicamente y llega un punto que supera la
> > capacidad de almacenamiento en la base de datos, en mi caso estoy usando
> > 'integer unsigned' en la migración y MySQL detrás.
> >
> > No quiero usar numeros más grandes(:limit => xx) ya que no me hace falta,
> > no
> > tengo problemas en, una vez que se llene el entero, resetear el
> > "contador".
> >
> > Mi problema particular es que cuando paso el límite y hago un save, rails
> > no
> > me avisa del overflow, y simplemente guarda el valor más grande posible
> > para
> > esa variable que en un unsigned int es 4294967295.
> >
> > Puedo hacer el chequeo a mano(if x > 4294967295) , pero me gustaría que
> > sea algo más prolijo si fuera posible. Buscar en google no me ayudo
> > mucho así que
> > por eso paso por aquí.
>
> Hice la prueba con Rails 2.3.5 y Rails inserta el valor correcto (Al menos
> intenta).
> En el Log se ve lo siguiente:
> INSERT INTO `bws` (`valor`, `created_at`, `updated_at`, `deleted_at`)
> VALUES(2147483648, '2010-06-08 17:24:55', '2010-06-08 17:24:55', NULL)
>
> Esto en MySql le da un Warning, MySQL graba exitosamente pero trunca. No
> encontré una manera limpia desde Rails de consultar los warnings . Pero si
> encontré lo siguiente:
> ruby-1.9.1-p378 > b = Bw.create :valor => 2147483648
> => #<Bw id: 20, valor: *2147483648*, created_at: "2010-06-08 17:21:52",
> updated_at: "2010-06-08 17:21:52", deleted_at: nil>
> ruby-1.9.1-p378 > *conn = b.connection.instance_variable_get '@connection'*
> => #<Mysql:0x8e20ac8>
> ruby-1.9.1-p378 > *res = conn.query('SHOW WARNINGS').fetch_hash*
> => {"Level"=>"Warning", "Code"=>"1264", "Message"=>"Out of range value for
> column 'valor' at row 1"}
> ruby-1.9.1-p378 > b.reload
> => #<Bw id: 20, valor: *2147483647*, created_at: "2010-06-08 17:21:52",
> updated_at: "2010-06-08 17:21:52", deleted_at: nil>
>
> También la raw connection a MySQL (@connection dentro del mySQL Adapter)
> tiene un #warning_count, pero por la manera en que el adapter usa la
> conexión, si consultás ese valor te va a dar cero.
>
> Personalmente optaría por verificar el límite antes de salvar... y que ese
> límite se pueda configurar en algún YML o algo así...
Fui por ese lado nomás, hice un módulo en /lib para poder sharear el código
entre las 3 clases que necesitan el check y luego un before_save
check_integer_overflow que hace el trabajo.
En mi caso es muy básico ya que los atributos que necesitan el check son
omónimos en todas las clases.
Dejo el código para archivo
en lib/overflow_check.rb:
module OverflowCheck
INT_OVERFLOW=4294967295
def check_integer_overflow
self.attribute_to_check -= INT_OVERFLOW if self.attribute_to_check >
INT_OVERFLOW
end
end
Y en el model:
class NeedOverflowCheck < ActiveRecord::Base
include OverflowCheck
before_save :check_integer_overflow
end
Gracias por la ayuda! :)
--
Luciano Ruete
_______________________________________________
Ruby mailing list
[email protected]
http://lista.rubyargentina.com.ar/listinfo.cgi/ruby-rubyargentina.com.ar