Ik heb een zelfgemaakte database-class die de queries die mijn appje nodig heeft genereert met MySQLi.
Nu wil ik die class ombuigen van MySQLi naar PostgreSQL. PHP heeft daarvoor een keuze voor twee opties, pgsql en PDO. Beiden heb ik nog niet eerder gebruikt. Ik beschik dus ook over de meest recente PostgreSQL 9.4.5.

Op het eerste gezicht ben ik wel gecharmeerd van PDO, maar nu loop ik tegen het volgende aan:
Om queries veilig te kunnen genereren dingen moeten schema-, tabel- en kolomnaam kunnen worden ge-escape-d, en dat gaat met PostgreSQL net anders dan met literals. Dientengevolge zijn er in pgsql verschillende functies voor:
- pg_escape_string(), pg_escape_literal() en pg_escape_bytea() voor literals en binaire data
- pg_escape_identifier() voor escapen van identifiers (schema-, tabel- en kolomnaam)

Echter, als ik die functionaliteit in PDO zoek dan lijkt die niet te bestaan?
Uiteraard ben ik niet de eerste met die vraag, en hij is al eerder beantwoord op deze plek:
http://stackoverflow.com/questions/13448274/escaping-column-name-with-pdo

Mijn vraag voor PHP-hulp: wie gebruikt PDO met PostgreSQL en heeft hier dus ervaring mee? Ben ik inderdaad aangewezen op pgsql? (geen ramp verder) of is het toch gewoon met PDO op te lossen?

[size=xsmall]Toevoeging op 02/11/2015 12:09:03:[/size]

Kleine toevoeging: de reden waarom ik niet zit te springen op de whitelisting-oplossing op StackOverflow is dat ik hem vrij omslachtig vind, daarnaast check ik ook van te voren of een tabel bestaat* en het zou omslachtig worden om voorafgaand aan elke query een whitelist te bouwen om daarop te checken.

* http://stackoverflow.com/questions/20582500/how-to-check-if-a-table-exists-in-a-given-schema (gelukkig kan ik al van 9.4 gebruik maken)
Dat is niet eigenaardig, dat is hoe prepared statements werken

Hm, en ik maar hopen dat het ook voor DDL geschikt zou zijn. Het ziet er naar uit dat je daarin gelijk hebt, als ik bv. kijk naar het PREPARE statement in PostgreSQL (http://www.postgresql.org/docs/9.4/static/sql-prepare.html) dan mag een statement alleen zijn: "Any SELECT, INSERT, UPDATE, DELETE, or VALUES statement."

Ik blijf het vreemd vinden dat een functie als pg_prepare() dat niet aangeeft:
$rResultaat = pg_prepare($rPgsql, "myquery", 'SET SCHEMA $1');

Werkt prima, totdat de query voorbereid moet worden door PostgreSQL:
pg_prepare(): Query failed: ERROR: syntax error at or near "$1"

Kan ik hem gelukkig toch nog toeschrijven aan de pgsql-extentie voor het niet tijdig afvangen van statements anders dan "SELECT, INSERT, UPDATE, DELETE, or VALUES". Want je raad het al, zonder parameters doet het prepared statement het wel... (?)
$rResultaat = pg_prepare($rPgsql, "myquery", "SET SCHEMA 'mijnschema'"); 

Is dat dan een bug? Gooit pg_prepare() het zomaar over de schutting bij PostgreSQL?

Ik denk dat ik maar aan moet wennen dat ook prepared statements hun limitaties kennen. Maar zo is het leven van een eenvoudige ontwikkelaar.


An tje op 02/11/2015 16:59:40

Soms is de data belangrijk genoeg, ook al weet je van te voren nog niet precies hoe het is georganiseerd. Dat is een lang proces dat ikzelf niet hoef te doen gelukkig, ik wil alleen maar de tooling maken.


Het klinkt alsof je meer hebt aan een NoSQL oplossing, daarin maakt de structuur van de data niet uit en heb je al het gedoe met kolomnamen niet meer.
PostgreSQL kan dat ook, via HSTORE en BSON; dan sla je elke rij gewoon op 'as is' en als iemand laeter denkt te hebben achterhaald waar de data voor is dan kan hij de data herstructureren.
Bedankt voor het meedenken. Qua datakwaliteit zit ik vooral te denken aan oudere technieken op basis van een RDBMS waarbij kolomgegevens (naamgeving, datatype, soort gegevens) via profiling worden geanalyseerd en gematched met dat van de andere gegevens, om zo een voorzetje te geven voor een ERD. Op die manier kan je ook relatief goed ongerelateerde databases koppelen, als je de gegevens (NAW, etc.) standaardiseert. Dat is wat de app in de 'enterprise'-setting moet gaan doen. Eerder was het MySQL en enkel beperkt tot een handjevol afdelingen, nu wordt het groter en wil ik gegevens die aangeleverd worden van buiten de organisatie snel kunnen matchen. Dan voel ik me nog wat minder thuis met HSTORE, maar ik zal me inlezen.
PostgreSQL kan ook gewooon met JSON werken, dat is nog een stapje makkelijker, dan kun je complete documente tegelijk in één veld proppen. XML kan ook, dan kun je met xpath data ophalen en verzamelen.

Dit klinkt ook als een geval waar je met tekst-klassificatie aan de gang moet; onbekende data vergelijken met bekende data om te zien hoeveel daarvan overeenkomt qua inhoud en formaat. Huisummers zitten altijd tussen de 1 en 2000, postcodes hebben altijd 4 cijfers en eventueel twee letters als het een Nederlandse postcode is, en straatnamen zijn er maar een stuk of 20.000 dus daarvan moet een hele bups overeenkomen, met als bij steden.

Iets vergelijbaars moet ook wel te doen zijn voor andere datasoorten waarvan je een bekende set hebt.

Reageren