From 168429d5977592e8e5aaa8f740191711b1cbe054 Mon Sep 17 00:00:00 2001 From: Adrian Holovaty Date: Sat, 3 Jun 2006 23:28:24 +0000 Subject: [PATCH] Fixed #593 -- Added 'search' DB-API lookup type, which does full-text index searches in MySQL git-svn-id: http://code.djangoproject.com/svn/django/trunk@3073 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/db/backends/ado_mssql/base.py | 3 +++ django/db/backends/dummy/base.py | 1 + django/db/backends/mysql/base.py | 3 +++ django/db/backends/oracle/base.py | 3 +++ django/db/backends/postgresql/base.py | 3 +++ django/db/backends/postgresql_psycopg2/base.py | 3 +++ django/db/backends/sqlite3/base.py | 3 +++ django/db/models/fields/__init__.py | 2 +- django/db/models/query.py | 2 ++ docs/db-api.txt | 9 +++++++++ 10 files changed, 31 insertions(+), 1 deletion(-) diff --git a/django/db/backends/ado_mssql/base.py b/django/db/backends/ado_mssql/base.py index c5a3b2cc33..b645b053bf 100644 --- a/django/db/backends/ado_mssql/base.py +++ b/django/db/backends/ado_mssql/base.py @@ -125,6 +125,9 @@ def get_limit_offset_sql(limit, offset=None): def get_random_function_sql(): return "RAND()" +def get_fulltext_search_sql(field_name): + raise NotImplementedError + def get_drop_foreignkey_sql(): return "DROP CONSTRAINT" diff --git a/django/db/backends/dummy/base.py b/django/db/backends/dummy/base.py index 89fec00c1d..985fe96469 100644 --- a/django/db/backends/dummy/base.py +++ b/django/db/backends/dummy/base.py @@ -33,5 +33,6 @@ get_date_extract_sql = complain get_date_trunc_sql = complain get_limit_offset_sql = complain get_random_function_sql = complain +get_fulltext_search_sql = complain get_drop_foreignkey_sql = complain OPERATOR_MAPPING = {} diff --git a/django/db/backends/mysql/base.py b/django/db/backends/mysql/base.py index 6a53956cad..4a13450c67 100644 --- a/django/db/backends/mysql/base.py +++ b/django/db/backends/mysql/base.py @@ -152,6 +152,9 @@ def get_limit_offset_sql(limit, offset=None): def get_random_function_sql(): return "RAND()" +def get_fulltext_search_sql(field_name): + return 'MATCH (%s) AGAINST (%%s IN BOOLEAN MODE)' % field_name + def get_drop_foreignkey_sql(): return "DROP FOREIGN KEY" diff --git a/django/db/backends/oracle/base.py b/django/db/backends/oracle/base.py index 2af80ef099..e981805108 100644 --- a/django/db/backends/oracle/base.py +++ b/django/db/backends/oracle/base.py @@ -108,6 +108,9 @@ def get_limit_offset_sql(limit, offset=None): def get_random_function_sql(): return "DBMS_RANDOM.RANDOM" +def get_fulltext_search_sql(field_name): + raise NotImplementedError + def get_drop_foreignkey_sql(): return "DROP FOREIGN KEY" diff --git a/django/db/backends/postgresql/base.py b/django/db/backends/postgresql/base.py index a365434318..decb160ee9 100644 --- a/django/db/backends/postgresql/base.py +++ b/django/db/backends/postgresql/base.py @@ -102,6 +102,9 @@ def get_limit_offset_sql(limit, offset=None): def get_random_function_sql(): return "RANDOM()" +def get_fulltext_search_sql(field_name): + raise NotImplementedError + def get_drop_foreignkey_sql(): return "DROP CONSTRAINT" diff --git a/django/db/backends/postgresql_psycopg2/base.py b/django/db/backends/postgresql_psycopg2/base.py index 13e7be7a98..697a33bb76 100644 --- a/django/db/backends/postgresql_psycopg2/base.py +++ b/django/db/backends/postgresql_psycopg2/base.py @@ -108,6 +108,9 @@ def get_limit_offset_sql(limit, offset=None): def get_random_function_sql(): return "RANDOM()" +def get_fulltext_search_sql(field_name): + raise NotImplementedError + def get_drop_foreignkey_sql(): return "DROP CONSTRAINT" diff --git a/django/db/backends/sqlite3/base.py b/django/db/backends/sqlite3/base.py index 7c3018aed9..7b51967416 100644 --- a/django/db/backends/sqlite3/base.py +++ b/django/db/backends/sqlite3/base.py @@ -124,6 +124,9 @@ def get_limit_offset_sql(limit, offset=None): def get_random_function_sql(): return "RANDOM()" +def get_fulltext_search_sql(field_name): + raise NotImplementedError + def get_drop_foreignkey_sql(): return "" diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py index b5245d6624..2f8a8651a1 100644 --- a/django/db/models/fields/__init__.py +++ b/django/db/models/fields/__init__.py @@ -162,7 +162,7 @@ class Field(object): def get_db_prep_lookup(self, lookup_type, value): "Returns field's value prepared for database lookup." - if lookup_type in ('exact', 'gt', 'gte', 'lt', 'lte', 'ne', 'year', 'month', 'day'): + if lookup_type in ('exact', 'gt', 'gte', 'lt', 'lte', 'ne', 'year', 'month', 'day', 'search'): return [value] elif lookup_type in ('range', 'in'): return value diff --git a/django/db/models/query.py b/django/db/models/query.py index 3517d6bed5..4bd9b3b9fe 100644 --- a/django/db/models/query.py +++ b/django/db/models/query.py @@ -615,6 +615,8 @@ def get_where_clause(lookup_type, table_prefix, field_name, value): return "%s = %%s" % backend.get_date_extract_sql(lookup_type, table_prefix + field_name) elif lookup_type == 'isnull': return "%s%s IS %sNULL" % (table_prefix, field_name, (not value and 'NOT ' or '')) + elif lookup_type == 'search': + return backend.get_fulltext_search_sql(table_prefix + field_name) raise TypeError, "Got invalid lookup_type: %s" % repr(lookup_type) def get_cached_row(klass, row, index_start): diff --git a/docs/db-api.txt b/docs/db-api.txt index 0f1064efb5..3624620609 100644 --- a/docs/db-api.txt +++ b/docs/db-api.txt @@ -1035,6 +1035,15 @@ SQL equivalent:: SELECT ... WHERE pub_date IS NULL; +search +~~~~~~ + +A boolean full-text search, taking advantage of full-text indexing. This is +like ``contains`` but is significantly faster due to full-text indexing. + +Note this is only available in MySQL and requires direct manipulation of the +database to add the full-text index. + Default lookups are exact ~~~~~~~~~~~~~~~~~~~~~~~~~