[Cheyenne] [pgsql] bug do-sql/flat
Laurent2-May-2011/15:53:24+2:00
J'ai pu constater que dans Cheyenne le refinement /flat de do-sql est sans effet (même après le redémarrage de ma machine ). Je suis sous Linux Ubuntu et j'utilise le driver pgsql de Dockimbel.

On peut voir ce que /flat est censé faire à http://cheyenne-server.org/docs/rsp-api.html#def-32.


On peut pallier ce bug facilement avec par exemple:

do-sql-flat: func [db [word!] query [string! block! word!] /local out] [
	out: copy []
	foreach row (do-sql db query) [
		foreach item row [append out item]
	] 
	out
]


Mais un petit correctif serait fortement apprécié.
DocKimbel2-May-2011/16:16:02+2:00
J'ai fait une version expérimentale il y a quelques semaines qui ajoute le support de /flat, SEND-SQL et NAME-FIELD (identique au driver MySQL: http://softinnov.org/rebol/mysql-usage.html#sect11.)

La version est disponible ici: http://softinnov.org/tmp/pgsql-protocol-091.r
Laurent2-May-2011/16:56:46+2:00
GENIAL! C'est exactement ce qui me manquait, je vais tester ça le plus vite possible.

MERCI DocKimbel !
Laurent14-May-2011/23:36:22+2:00
En effet cette version du protocole ajoute /flat, c'est cool.
Par contre malgré bien des essais je ne suis pas arrivé à faire marcher name-field, même en passant par la syntaxe "open etc" et en prenant bien soin de ne renvoyer qu'un élément.
J'ai des erreurs du genre:

Error Code   300
Description   Script Error : insert* has no value
Near   [insert* tail out to word!]
Where   name-fields

Mais de toute façon name-field ne résoud pas le problème des enregistrements multiples en retour, et n'est utilisable qu'avec des requètes simplissimes.

Modestement je vous propose la solution que j'ai trouvée qui utilise les alias SQL pour définir les "variables" Rebol qui recevront les valeurs.
Ainsi même avec des clés étrangères et compagnie on récupère N lignes hyper simplement de la façon suivante :

(par exemple pour une table "book" qui utilise une clé étrangère dans une table "author")

<%
books: do-sql-as 'db {SELECT "title" as "title", "author"."name" as "name-or-something-else" 
FROM "book" LEFT JOIN "author" ON "book"."author_id" = "author"."author_id"}

foreach book books [
	print [book/title "by" book/name-or-something-else <br/>]
]
%>



Difficile de faire plus simple et en plus j'utilise do-sql dans do-sql-as ce qui permet de ne ne pas se soucier du type de la base et d'utiliser les fonctionalités de mise en cache etc.

Ma fonction do-sql-as est la suivante:

do-sql-as: func [database [word! path!] query [string! block! word!] /local result str aliases alias fields out out-row][
	
	result: do-sql database query
	
	str: copy/deep query
	if block? str [str: first str]
	parse trim/lines trim/with str {"} [thru "select" copy fields to "from"]	
	aliases: copy[]
	foreach field (parse/all fields ",") [
		alias: none
		parse field [thru " as " copy alias to end ]
		if alias [alias: to-word trim/all alias]
		append aliases alias
	]
	
	out: copy[]
	foreach row result [
		out-row: copy[]
		foreach alias aliases [
			if alias [ repend out-row [alias (first row)] ]
			row: next row
		]
		append/only out out-row
	]
	out
]


En gros j'utilise la série aliases de "couples mot - valeur" (je ne sais pas si un nom existe pour ça en rebol) pour stocker les valeurs de chaque enregristrement retourné.
Ma fonction peut certainement être optimisée mais j'èspère qu'elle en aidera certains pour traiter les requêtes avec beaucoup de champs et beaucoup de lignes.
Vos remarques sont les bienvenues.
Laurent25-May-2011/21:54:47+2:00
PS: pour pouvoir utiliser les requêtes mises en cache par Cheyenne il suffit d'ajouter en dessous de l'appel à do-sql:

if word? query [query: second select (db-cache/get-cache database) query] 

Login required to Post.


Powered by RebelBB and REBOL 2.7.8.4.2