A `Composable` object made of a sequence of `!Composable`. The object is usually created using `!Composable` operators and methods (such as the `SQL.format()` method). `!Composed` objects can be passed directly to `~psycopg.Cursor.execute()`, `~psycopg.Cursor.executemany()`, `~
| 106 | |
| 107 | |
| 108 | class Composed(Composable): |
| 109 | """ |
| 110 | A `Composable` object made of a sequence of `!Composable`. |
| 111 | |
| 112 | The object is usually created using `!Composable` operators and methods |
| 113 | (such as the `SQL.format()` method). `!Composed` objects can be passed |
| 114 | directly to `~psycopg.Cursor.execute()`, `~psycopg.Cursor.executemany()`, |
| 115 | `~psycopg.Cursor.copy()` in place of the query string. |
| 116 | |
| 117 | It is also possible to create a `!Composed` directly specifying a sequence |
| 118 | of objects as arguments: if they are not `!Composable` they will be wrapped |
| 119 | in a `Literal`. |
| 120 | |
| 121 | Example:: |
| 122 | |
| 123 | >>> comp = sql.Composed( |
| 124 | ... [sql.SQL("INSERT INTO "), sql.Identifier("table")]) |
| 125 | >>> print(comp.as_string(conn)) |
| 126 | INSERT INTO "table" |
| 127 | |
| 128 | `!Composed` objects are iterable (so they can be used in `SQL.join` for |
| 129 | instance). |
| 130 | """ |
| 131 | |
| 132 | _obj: list[Composable] |
| 133 | |
| 134 | def __init__(self, seq: Sequence[Any]): |
| 135 | seq = [obj if isinstance(obj, Composable) else Literal(obj) for obj in seq] |
| 136 | super().__init__(seq) |
| 137 | |
| 138 | def as_bytes(self, context: AdaptContext | None = None) -> bytes: |
| 139 | return b"".join(obj.as_bytes(context) for obj in self._obj) |
| 140 | |
| 141 | def __iter__(self) -> Iterator[Composable]: |
| 142 | return iter(self._obj) |
| 143 | |
| 144 | def __add__(self, other: Composable) -> Composed: |
| 145 | if isinstance(other, Composed): |
| 146 | return Composed(self._obj + other._obj) |
| 147 | if isinstance(other, Composable): |
| 148 | return Composed(self._obj + [other]) |
| 149 | else: |
| 150 | return NotImplemented |
| 151 | |
| 152 | def join(self, joiner: SQL | LiteralString) -> Composed: |
| 153 | """ |
| 154 | Return a new `!Composed` interposing the `!joiner` with the `!Composed` items. |
| 155 | |
| 156 | The `!joiner` must be a `SQL` or a string which will be interpreted as |
| 157 | an `SQL`. |
| 158 | |
| 159 | Example:: |
| 160 | |
| 161 | >>> fields = sql.Identifier('foo') + sql.Identifier('bar') # a Composed |
| 162 | >>> print(fields.join(', ').as_string(conn)) |
| 163 | "foo", "bar" |
| 164 | |
| 165 | """ |