When we're composing complex queries, we're combining QueryStrings, rather than concatenating strings directly. The reason for this is QueryStrings keep the parameters separate, so we can pass parameterised queries to the engine - which helps prevent SQL Injection attacks.
| 56 | |
| 57 | |
| 58 | class QueryString(Selectable): |
| 59 | """ |
| 60 | When we're composing complex queries, we're combining QueryStrings, rather |
| 61 | than concatenating strings directly. The reason for this is QueryStrings |
| 62 | keep the parameters separate, so we can pass parameterised queries to the |
| 63 | engine - which helps prevent SQL Injection attacks. |
| 64 | """ |
| 65 | |
| 66 | __slots__ = ( |
| 67 | "template", |
| 68 | "args", |
| 69 | "query_type", |
| 70 | "table", |
| 71 | "_frozen_compiled_strings", |
| 72 | "columns", |
| 73 | ) |
| 74 | |
| 75 | def __init__( |
| 76 | self, |
| 77 | template: str, |
| 78 | *args: Any, |
| 79 | query_type: str = "generic", |
| 80 | table: Optional[type[Table]] = None, |
| 81 | alias: Optional[str] = None, |
| 82 | ) -> None: |
| 83 | """ |
| 84 | :param template: |
| 85 | The SQL query, with curly brackets as placeholders for any values:: |
| 86 | |
| 87 | "WHERE {} = {}" |
| 88 | |
| 89 | :param args: |
| 90 | The values to insert (one value is needed for each set of curly |
| 91 | braces in the template). |
| 92 | :param query_type: |
| 93 | The query type is sometimes used by the engine to modify how the |
| 94 | query is run. For example, INSERT queries on old SQLite versions. |
| 95 | :param table: |
| 96 | Sometimes the ``piccolo.engine.base.Engine`` needs access to the |
| 97 | table that the query is being run on. |
| 98 | |
| 99 | """ |
| 100 | self.template = template |
| 101 | self.query_type = query_type |
| 102 | self.table = table |
| 103 | self._frozen_compiled_strings: Optional[tuple[str, list[Any]]] = None |
| 104 | self._alias = alias |
| 105 | self.args, self.columns = self.process_args(args) |
| 106 | |
| 107 | def process_args( |
| 108 | self, args: Sequence[Any] |
| 109 | ) -> tuple[Sequence[Any], Sequence[Column]]: |
| 110 | """ |
| 111 | If a Column is passed in, we convert it to the name of the column |
| 112 | (including joins). |
| 113 | """ |
| 114 | from piccolo.columns import Column |
| 115 |
no outgoing calls