2011-07-27 8 views
8

Tengo el siguiente comunicado en Rails 3 utilizando una base de datos SQLite3:Cómo activar REGEXP en SQLite3 y Rails 3.1?

word = 'Hello' 
word_entry = Word.where("name REGEXP :word", {:word => "[[:<:]]#{word}[[:>:]]"}) 

Sin embargo, cuando se ejecuta este bajo SQLite3, me siguen dando:

SQLite3 :: excepción de SQL: no hay tal función: REGEXP

Leí en la documentación de SQLite3 que sí es compatible con la función REGEXP. En mi Gemfile, tengo la línea

gem 'sqlite3' 

Y mi archivo de configuración de base de datos se ve así:

development: 
    adapter: sqlite3 
    database: db/development.sqlite3 
    pool: 5 
    timeout: 5000 

¿Alguna idea de lo que pasa?

RESOLUCIÓN: que terminó encontrando this solution. Desafortunadamente, no funciona para Rails 3. Entonces, para usar expresiones regulares, terminé cambiando a MYSQL en lugar de SQLite3.

Respuesta

13

Me encontré con el mismo problema. Tomé el código utilizado en la resolución, lo porté para trabajar con Rails 3+ e hice una gema para facilitar su uso. Espero que esto ayude.

https://github.com/sei-mi/sqlite3_ar_regexp

+0

Y para eso, obtienes puntos de brownie (y tu respuesta está marcada como la correcta). ¡Gracias, gracias, gracias! –

7

Desde el fine manual:

El operador REGEXP es una sintaxis especial para la función de usuario expresión regular(). Ninguna función de usuario regexp() se define de manera predeterminada, por lo que el uso del operador REGEXP normalmente generará un mensaje de error. Si se agrega una función SQL definida por la aplicación llamada "regexp" en el tiempo de ejecución, se invocará esa función para implementar el operador REGEXP.

De modo que la gramática admite REGEXP pero la biblioteca SQLite predeterminada no proporciona una implementación para ella. Tendrás que conectar tu propia implementación a través de C discusiones si quieres o necesitas algo así.

Presumiblemente, la razón es que las personas SQLite quieren mantener SQLite lo más pequeño y ajustado posible, pero incluir toda una biblioteca de expresiones regulares agregará un peso que la mayoría de la gente no quiere. Además, tendrían que elegir una biblioteca de expresiones regulares e incluirla con la fuente de SQLite o tendrían que aguantar los caprichos del soporte de expresiones regulares de todos en libc. No soy uno de los desarrolladores de SQLite, así que esto es pura especulación.

Supongo que probablemente tendrá que conformarse con LIKE and GLOB. Usar LIKE proporcionará una solución más portátil.

+0

en realidad no es lo suficientemente específico para resolver mi problema, pero esa es la respuesta correcta a la pregunta. Ver la edición en mi pregunta titulada 'RESOLUCIÓN'. –

+1

@yuval: Es un hallazgo bastante bueno, lástima que ya no funciona. –

2

que tenía una pregunta similar y encontramos una joya nombrado wherex que está bien documentado y trabajó fuera de la caja.

Su expresión desde arriba

Word.where("name REGEXP :word", {:word => "[[:<:]]#{word}[[:>:]]"}) 

¿habría

Word.where(:name => Regexp.new("[[:<:]]#{word}[[:>:]]")) 

funciona como un encanto para mí :-)

2

Es posible que se intested en el paquete sqlite3-pcre, que implementa REGEXP para SQLite.

Ver this comment en un problema similar.

0

De fuente de proyecto sqlite3_ar_regexp, extraigo la siguiente:

db = SQLite3::Database.open(database_name) 
db.create_function('regexp', 2) do |func, pattern, expression| 
    func.result = expression.to_s.match(
     Regexp.new(pattern.to_s, Regexp::IGNORECASE)) ? 1 : 0 
end