2011-07-27 9 views
8

Mam następujące oświadczenie w Rails 3 przy użyciu bazy danych SQLite3:Jak włączyć REGEXP w SQLite3 i Rails 3.1?

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

Jednak kiedy to działa pod SQLite3, ciśgle:

SQLite3 :: SQLException: brak takiej funkcji: REGEXP

Przeczytałem w dokumentacji SQLite3, że rzeczywiście obsługuje funkcję REGEXP. W moim gemfile mam linia

gem 'sqlite3' 

A mój plik konfiguracyjny bazy danych wygląda następująco:

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

Wszelkie pomysły, co się dzieje?

UCHWAŁA: skończyło się znalezieniem this solution. Niestety, nie działa dla Rails 3. Tak więc, aby używać wyrażeń regularnych, zakończyłem przełączanie na MYSQL zamiast SQLite3.

Odpowiedz

13

Wpadłem na ten sam problem. Wziąłem kod użyty w rozdzielczości, przeportowałem go do pracy z Railsami 3+ i zrobiłem klejnot dla łatwiejszego użycia. Mam nadzieję, że to pomoże.

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

+0

I za to otrzymujesz punktowe punkty (a twoja odpowiedź jest oznaczona jako poprawna). Dziekuję Dziekuję Dziękuję! –

7

Z fine manual:

Operator REGEXP jest szczególnym składni tego wyrażenia() Działanie użytkownika. Żadna funkcja użytkownika regexp() nie jest zdefiniowana domyślnie, więc użycie operatora REGEXP spowoduje zwykle pojawienie się komunikatu o błędzie. Jeśli w czasie wykonywania zostanie dodana funkcja SQL zdefiniowana przez aplikację o nazwie "regexp", funkcja ta zostanie wywołana w celu implementacji operatora REGEXP.

Gramatyka obsługuje REGEXP, ale domyślna biblioteka SQLite nie zapewnia jej implementacji. Będziesz musiał podłączyć własną implementację poprzez niektóre spory C, jeśli chcesz lub potrzebujesz czegoś takiego.

Prawdopodobnie ludzie z SQLite chcą, aby SQLite był tak mały i ciasny, jak to tylko możliwe, ale włączając w to całą bibliotekę regularnych wyrażeń, dodawałby wagi, której większość ludzi nie chce. Ponadto będą musieli wybrać bibliotekę wyrażeń regularnych i dołączyć ją do źródła SQLite, inaczej będą musieli znosić różnice w wyrażeniach regularnych wyrażenia regularnego w bibliotece libc. Nie jestem jednym z programistów SQLite, więc jest to czysta spekulacja.

Zgaduję, że prawdopodobnie będziesz musiał zrobić z LIKE and GLOB. Korzystanie z LIKE zapewni bardziej przenośne rozwiązanie.

+0

naprawdę nie jest wystarczająco precyzyjny, aby rozwiązać mój problem, ale to jest prawidłowa odpowiedź na moje pytanie. Zobacz edycję mojego pytania o nazwie "ROZSTRZYGANIE". –

+1

@yuval: To dość dobre znalezisko, szkoda, że ​​już nie działa. –

2

miałem podobne pytanie i znalazł Gem nazwie wherex że jest dobrze udokumentowany i pracował po wyjęciu z pudełka.

wyrażenia z góry

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

będzie tam

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

działa jak czar dla mnie :-)

2

może być intested w pakiecie sqlite3-pcre, który realizuje REGEXP dla SQLite.

Zobacz podobną sprawę pod numerem this comment.

0

od źródła projektu sqlite3_ar_regexp, wyodrębnić to:

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