To je neobratně řečeno. Jejich argument je, že když by zavedli jen běžnou interpolaci, tak by se to těžko ošetřovalo. Proto umožňili tvorbu vlastních procesorů, do kterých si vývojář může napsat jakoukoli kontrolu, escapování atd. a tedy ošetřit konkrétní nasazení třeba pro sestavení SQL query apod.
O tomto mluvi Ink:
cursor.execute("insert into some_table (id, created_at, last_name) values (%s, %s, %s);", (10, datetime.date(2020, 11, 18), "O'Reilly"))
Dle meho si jen nerozumite. Ten samotný dotaz bez dat si naopak umim predstavit, ze nejaka knihovna "poslepuje" ze stringu, napr. interpoluje nazev tabulky atd.
23. 3. 2024, 13:12 editováno autorem komentáře
Len pre uplnost by som doplnil, ze dalsim pristupom (okrem vseobecne znameho ORM, JPA/hibernate) je aj jooq ci querydsl:
create.select(AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME, count())
.from(AUTHOR)
.join(BOOK).on(AUTHOR.ID.equal(BOOK.AUTHOR_ID))
.where(BOOK.LANGUAGE.eq("DE"))
.and(BOOK.PUBLISHED.gt(date("2008-01-01")))
.groupBy(AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME)
.having(count().gt(5))
.orderBy(AUTHOR.LAST_NAME.asc().nullsFirst())
.limit(2)
.offset(1)
Je to typesafe na urovni aplikacneho kodu a nasledne sa clovek spolieha na kvalitu kniznice, ktora psoklada parametricku query pre jdbc, alebo R2DBC driver pre db.
JEP má príklad pre Query Builder.
PreparedStatement ps = DB."SELECT * FROM Person p WHERE p.last_name = \{name}"; ResultSet rs = ps.executeQuery();
Je to riešené tak šalamúnsky. V tom DB procesore to hodia do metódy prepareStatement
. Nerobia vlastnú kontrolu, len ide o sprehľadnenie a zjednodušenie syntaxe.
Tá kontrola má stovky riadkov kódu, pričom sú odlišnosti pre MySQL a pre Postgres. Takže určite žiadna vlastná kontrola na strane klienta.
23. 3. 2024, 11:00 editováno autorem komentáře
Řešením je vlastní procesor, který bezpečně sestaví objekt `PreparedStatement`. Elegantní řešení je naznačeno tady:
https://openjdk.org/jeps/459#Safely-composing-and-executing-database-queries
26. 3. 2024, 15:15 editováno autorem komentáře