]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Fix docs + add match function tests
authorAnton Kovalevich <kai3341@gmail.com>
Fri, 2 Apr 2021 12:41:03 +0000 (15:41 +0300)
committerAnton Kovalevich <kai3341@gmail.com>
Fri, 2 Apr 2021 12:41:03 +0000 (15:41 +0300)
lib/sqlalchemy/dialects/mysql/__init__.py
lib/sqlalchemy/dialects/mysql/expression.py
test/dialect/mysql/test_compiler.py
test/dialect/mysql/test_match_expression.py [new file with mode: 0644]

index 20dd68d8f0bfebd38cc11dc8fe9a10c818f91f08..4db05984c25257da90088427cc526f8fd2e758b7 100644 (file)
@@ -49,6 +49,7 @@ from .base import VARCHAR
 from .base import YEAR
 from .dml import Insert
 from .dml import insert
+from .expression import match
 from ...util import compat
 
 if compat.py3k:
@@ -99,4 +100,5 @@ __all__ = (
     "dialect",
     "insert",
     "Insert",
+    "match",
 )
index 49cdc43fd254ee7f2dbcd66ceaaea9be0e7e0df9..6af57baaed59e4097772ff7a7c22cbee5d7286e4 100644 (file)
@@ -1,5 +1,6 @@
 from functools import wraps
 
+from sqlalchemy import exc
 from sqlalchemy.ext.compiler import compiles
 from sqlalchemy.sql.elements import (
     ColumnElement,
@@ -58,9 +59,38 @@ class match(ColumnElement):
     All positional arguments passed to :func:`.match`, typically should be a
      :class:`_expression.ColumnElement` instances
 
-    :param against: typically scalar expression to be coerced into a ``str``
+    :param: against typically scalar expression to be coerced into a ``str``
 
-    :param flags: optional ``dict``
+    :param: flags optional ``dict``. Use properties ``in_boolean_mode``,
+     ``in_natural_language_mode`` and ``with_query_expansion`` to control it:
+
+        match_expr = match(
+            users_table.c.firstname,
+            users_table.c.lastname,
+            against="John Connor",
+        )
+
+        print(match_expr)
+
+        # MATCH(firstname, lastname) AGAINST (:param_1)
+
+        print(match_expr.in_boolean_mode)
+
+        # MATCH(firstname, lastname) AGAINST (:param_1 IN BOOLEAN MODE)
+
+        print(match_expr.in_natural_language_mode.with_query_expansion)
+
+        # MATCH(firstname, lastname) AGAINST
+        # (:param_1 IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION)
+
+    :property: ``in_boolean_mode`` returns new ``match`` object with
+     set to ``True`` the ``mysql_boolean_mode`` flag
+
+    :property: ``in_natural_language_mode`` returns new ``match`` object with
+     set to ``True`` the ``mysql_natural_language`` flag
+
+    :property: ``with_query_expansion`` returns new ``match`` object with
+     set to ``True`` the ``mysql_query_expansion`` flag
 
      .. versionadded:: 1.4.4
 
@@ -77,7 +107,10 @@ class match(ColumnElement):
     }
 
     def __init__(self, *clauselist, against, flags=None):
-        if len(clauselist) == 1:
+        clauselist_len = len(clauselist)
+        if clauselist_len == 0:
+            raise exc.CompileError("Can not match with no columns")
+        elif clauselist_len == 1:
             self.clause = clauselist[0]
         else:
             self.clause = ClauseElementBatch(*clauselist, group=False)
index a21f191ed9a0724f369aaa24943082ece3672341..75f7e4c5de940930e1de44b5ffd2e6eec5d67d20 100644 (file)
@@ -433,12 +433,11 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
     def test_match_compile_modifiers(self):
         matchtable = table("matchtable", column("title", String))
         title = matchtable.c.title
-        dialect = mysql.dialect()
 
         self.assert_compile(
             title.match("somstr", mysql_boolean_mode=False),
             "MATCH (matchtable.title) AGAINST (%s)",
-            dialect=dialect,
+            dialect=self.__dialect__,
         )
 
         self.assert_compile(
@@ -448,7 +447,7 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
                 mysql_natural_language=True,
             ),
             "MATCH (matchtable.title) AGAINST (%s IN NATURAL LANGUAGE MODE)",
-            dialect=dialect,
+            dialect=self.__dialect__,
         )
 
         self.assert_compile(
@@ -458,7 +457,7 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
                 mysql_query_expansion=True,
             ),
             "MATCH (matchtable.title) AGAINST (%s WITH QUERY EXPANSION)",
-            dialect=dialect,
+            dialect=self.__dialect__,
         )
 
         self.assert_compile(
@@ -470,13 +469,12 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
             ),
             "MATCH (matchtable.title) AGAINST "
             "(%s IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION)",
-            dialect=dialect,
+            dialect=self.__dialect__,
         )
 
     def test_match_compile_modifiers_fail(self):
         matchtable = table("matchtable", column("title", String))
         title = matchtable.c.title
-        dialect = mysql.dialect()
 
         msg = "Flag combination does not make sence: " \
             "mysql_boolean_mode=%s, " \
@@ -491,7 +489,7 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
                 mysql_natural_language=True,
                 mysql_query_expansion=True,
             ).compile,
-            dialect=dialect,
+            dialect=self.__dialect__,
         )
 
         assert_raises_message(
@@ -501,7 +499,7 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
                 "somstr",
                 mysql_query_expansion=True,
             ).compile,
-            dialect=dialect,
+            dialect=self.__dialect__,
         )
 
         assert_raises_message(
@@ -511,7 +509,7 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
                 "somstr",
                 mysql_natural_language=True,
             ).compile,
-            dialect=dialect,
+            dialect=self.__dialect__,
         )
 
     def test_concat_compile_kw(self):
diff --git a/test/dialect/mysql/test_match_expression.py b/test/dialect/mysql/test_match_expression.py
new file mode 100644 (file)
index 0000000..97023f7
--- /dev/null
@@ -0,0 +1,103 @@
+from sqlalchemy import exc
+from sqlalchemy import String
+from sqlalchemy.dialects.mysql import base as mysql
+from sqlalchemy.dialects.mysql import match
+from sqlalchemy.sql import column
+from sqlalchemy.sql import table
+# from sqlalchemy.sql.expression import literal_column
+from sqlalchemy.testing import assert_raises_message
+from sqlalchemy.testing import AssertsCompiledSQL
+from sqlalchemy.testing import fixtures
+
+
+class MatchExpressionTest(fixtures.TestBase, AssertsCompiledSQL):
+
+    __dialect__ = mysql.dialect()
+
+    matcheble = table(
+        "user",
+        column("firstname", String),
+        column("lastname", String),
+    )
+
+    def test_match_expression(self):
+        firstname = self.matcheble.c.firstname
+        lastname = self.matcheble.c.lastname
+
+        expr = match(firstname, lastname, against="John Connor")
+
+        self.assert_compile(
+            expr,
+            "MATCH (user.firstname, user.lastname) AGAINST (%s)",
+            dialect=self.__dialect__,
+        )
+
+        self.assert_compile(
+            expr.in_boolean_mode,
+            "MATCH (user.firstname, user.lastname) AGAINST "
+            "(%s IN BOOLEAN MODE)",
+            dialect=self.__dialect__,
+        )
+
+        self.assert_compile(
+            expr.in_natural_language_mode,
+            "MATCH (user.firstname, user.lastname) AGAINST "
+            "(%s IN NATURAL LANGUAGE MODE)",
+            dialect=self.__dialect__,
+        )
+
+        self.assert_compile(
+            expr.with_query_expansion,
+            "MATCH (user.firstname, user.lastname) AGAINST "
+            "(%s WITH QUERY EXPANSION)",
+            dialect=self.__dialect__,
+        )
+
+        self.assert_compile(
+            expr.in_natural_language_mode.with_query_expansion,
+            "MATCH (user.firstname, user.lastname) AGAINST "
+            "(%s IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION)",
+            dialect=self.__dialect__,
+        )
+
+    def test_match_expression_fails(self):
+        firstname = self.matcheble.c.firstname
+        lastname = self.matcheble.c.lastname
+
+        assert_raises_message(
+            exc.CompileError,
+            "Can not match with no columns",
+            match,
+            against="John Connor",
+        )
+
+        expr = match(firstname, lastname, against="John Connor")
+
+        msg = "Flag combination does not make sence: " \
+            "mysql_boolean_mode=%s, " \
+            "mysql_natural_language=%s, " \
+            "mysql_query_expansion=%s"
+
+        assert_raises_message(
+            exc.CompileError,
+            msg % (True, False, True),
+            expr.in_boolean_mode.with_query_expansion
+            .compile,
+            dialect=self.__dialect__,
+        )
+
+        assert_raises_message(
+            exc.CompileError,
+            msg % (True, True, False),
+            expr.in_boolean_mode.in_natural_language_mode
+            .compile,
+            dialect=self.__dialect__,
+        )
+
+        assert_raises_message(
+            exc.CompileError,
+            msg % (True, True, True),
+            expr.in_boolean_mode.in_natural_language_mode.with_query_expansion
+            .compile,
+            dialect=self.__dialect__,
+        )