PostgreSQL La base de donnees la plus sophistiquee au monde.

Forums PostgreSQL.fr

Le forum officiel de la communauté francophone de PostgreSQL

Vous n'êtes pas identifié(e).

#1 Re : Général » Notification Asynchrone » 09/08/2010 14:26:00

Ce que je veux dire c'est comment activer des notifications sur le serveur ?

#2 Re : Général » Notification Asynchrone » 09/08/2010 11:45:33

J'aurais une derniere question, comment rajouter des regles de notifications pour ma base de données ? en commande SQL ou sur PGAdmin (n'importe) car j'aimerais tester ce que j'ai codé.

#4 Général » Notification Asynchrone » 03/08/2010 14:39:28

Fooshi
Réponses : 7

Bonjour,
Je developpe actuellement un client PostgreSQL sans bibliotheque, je souhaite maintenant ajouter les notifications asynchrones a mon client (LISTEN, UNLISTEN, NOTIFY).
Doit t'on definir des regles de notifications sur le serveur ? La syntaxe 'LISTEN test_sqlclient;' si ma base de donnée test_sqlclient est elle bonne ? le nom que l'on appelle apres la fonction LISTEN fais t'elle reference a une table ou a une regle de notification que l'on a defini sur le serveur ?
Merci d'avance.

#5 Re : C et C++ » Message d'erreur Bind » 23/07/2010 15:16:06

Oui mais ici ma fonction COPY prend en compte 1 parametre ($1) donc il veut mieux que je passe par PQprepare puis PQExecPrepared non ?

#6 C et C++ » Message d'erreur Bind » 23/07/2010 14:50:06

Fooshi
Réponses : 3

Bonjour,
je developpe acutellement un client postgreSQL il est parfaitement operationel pour les commandes SELECT, j'essaie d'inclure la commande COPY.

Ma commande
const char * sql_query = "SELECT intval, floatval, strval FROM test_sqlclient WHERE name=$1;";

se transforme en :

const char * sql_query = "COPY ( SELECT intval, floatval, strval FROM test_sqlclient WHERE name=$1 ) TO STDOUT;";

Lors de l'envoie d'une commande j'envoie un message 'Parse' , 'Bind', 'Describe', 'Execute' puis 'Sync'

si joins ma fonction qui crée le message Bind  :

/* Construct the 'Bind' message        */
    msg_len = 0;
    msg[msg_len++] = 0;                // An empty string selects the non-portal named.
    msg[msg_len++] = 0;                // An empty string selects the non-prepared statement named.
    if (count > 0 && formats)        // Send parameter formats.
    {
        sql_put_int(sizeof(int16), count, msg + msg_len);            // Number format codes following parameters.
        msg_len  += sizeof(int16);
        for (i = 0; i < count; ++i)
        {
            sql_put_int(sizeof(int16), formats[i], msg + msg_len);    // Format codes parameters. All must be zero (text) or one (binary).
            msg_len  += sizeof(int16);
        }           
    }
    else
    {
        sql_put_int(sizeof(int16), 0, msg + msg_len);    // Number format codes following parameters = 0
        msg_len  += sizeof(int16);
    }
    sql_put_int(sizeof(int16), count, msg + msg_len);    // Number of parameter values.
    msg_len  += sizeof(int16);
    /* Send parameters    */
    for (i = 0; i < count; ++i)
    {
        if (values && values[i])
        {
            int nbytes;
            if (formats && formats[i] != 0)
            {
                nbytes = lengths[i];        // Binary parameter
            }
            else
            {
                nbytes = strlen(values[i]);    // Text parameter, do not use lengths.
            }               
            sql_put_int(sizeof(int32), nbytes, msg + msg_len);    // Size parameter (this number does not include the length itself). Can be zero.
            msg_len  += sizeof(int32);
            memcpy(msg + msg_len, values[i], nbytes);            // Parameter value.
            msg_len += nbytes;
        }
        else
        {
            sql_put_int(sizeof(int32), -1, msg + msg_len);        // -1 indicates a NULL parameter value. No byte value does not follow the NULL case.
            msg_len  += sizeof(int32);
        }
    }
    sql_put_int(sizeof(int16), 1, msg + msg_len);                // Number format codes result columns following.
    msg_len  += sizeof(int16);
    sql_put_int(sizeof(int16), result_format, msg + msg_len);    // Format codes result columns.
    msg_len  += sizeof(int16);   
    msg[msg_len] = '\0';
    sql_add_start_msg(sql_conn, 'B', msg_len);
    block_list_write_buffer(&sql_conn->send, msg, msg_len);   

Cette fonction apelle toujours un nom d'instruction vide.

le serveur me renvoie une erreur :

bind message supplies 1 parameters , but prepared statement "" requires 0

Dois je passer par une fonction PQprepare puis PQExedPrepared puis passer en parametre de ma foncton le nom de l'instruction préparée ?

Merci d'avance pour vos reponses !

#7 Re : C et C++ » Probleme de message Parse » 24/06/2010 15:01:18

Faut 'il que j'encode tout le message en UTF-8 ou juste la requete passée en parametre ?
Faut 'il que rajoute juste un BOM (Marque d'ordre des octets) ou que je passe par une fonction d'encodage de caractere ?

Merci en tout cas de m'aider, ca fais plaisir !

#8 Re : C et C++ » Probleme de message Parse » 24/06/2010 14:33:03

@Marc cousin : Effectivement je force une chaine vide mais pas '\0', le 2 eme memcpy fonctionne tres bien d'ailleurs. Ce code vient de moi mais je m'inspire des fonctions de la libpq pour construire les messages et oui je comprend trés bien comment il fonctionne.

@gleu : Car mon chef de projet et moi avons développé des fonctions de requetes TCP et de gestion memoire (Double liste chainée de block pool notament) plus efficace que la libpq selon mon chef de projet et que je rajoute en ce moment la couche de communication du client PostgreSQL.

Apres avoir modifié mon code comme ceci :


do
    {
        msg_len = 0;
        if (msg)        memcpy(msg + msg_len, "", 1);                // An empty string selects the non-prepared statement named.
        msg_len += 1;
        if (msg)        memcpy(msg + msg_len, query, strlen(query));// Query string to analyse.
        msg_len += strlen(query) + 1;
        if (count > 0 && paramtypes)
        {
            if (msg)    sql_put_int(sizeof(int16), count, msg + msg_len);       
            msg_len += sizeof(int16);
            for (i=0; i<count; i++)
            {
                if (msg)sql_put_int(sizeof(int32), paramtypes[i], msg + msg_len);// Object ID of the data type of the parameter.
                msg_len += sizeof(int32);
            }
        }
        else
        {
            if (msg)    sql_put_int(sizeof(int16), 0, msg + msg_len);            // Many types of data specified parameter.
            msg_len += sizeof(int16);
        }
        msg_len ++;
        if (msg) break;   
        msg = (char *) malloc(msg_len);       
    }
    while (msg);
    sql_send_msg(sql_conn, 'P', msg_len, msg);

Le serveur me renvoie : Invalid byte sequence for encoding 'UTF8', This error can also happen if the byte sequence does not match the encoding exceped by the server, wich is controlled by 'clients_encoding'
Faut t'il que j'encode ma requete en UTF8 ?

#9 C et C++ » Probleme de message Parse » 24/06/2010 12:03:09

Fooshi
Réponses : 7

Bonjour,
En C j'essaye d'envoyer une commande 'Parse' a un serveur PostgreSQL .

Dans mon cas à moi, je selectionne une instruction préparée non nommée (chaine vide donc), nombre de types de donnée de paramètres spécifiés = 0 codé sur 16 bits donc.

j'ai donc codé une fonction pour réaliser cette commande Parse, qui m'enregistre dans un buffer la chaine suivante :

'P00073 SELECT intval, floatval, strval FROM test_sqlclient WHERE name=$1;00 '

P = Marqueur de commande 'Parse'
00073 = 4 octets qui indiquent la taille
00 = Nombre de types de données de paramètre spécifiés (a la fin aprés le point virgule)

Je vous donne ma fonction en C :

/* Construct the 'Parse' message    */
    do
    {
        msg_len = 0;
        IF (msg)        memcpy(msg + msg_len, "", 1);                // An empty string selects the non-prepared statement named.
        msg_len += 1;
        IF (msg)        memcpy(msg + msg_len, query, strlen(query));// Query string TO analyse.
        msg_len += strlen(query);
        IF (count > 0 && paramtypes)
        {
            IF (msg)    sql_put_int(sizeof(int16), count, msg + msg_len);       
            msg_len += sizeof(int16);
            FOR (i=0; i<count; i++)
            {
                IF (msg)sql_put_int(sizeof(int32), paramtypes[i], msg + msg_len);// Object ID of the DATA type of the parameter.
                msg_len += sizeof(int32);
            }
        }
        else
        {
            IF (msg)    sql_put_int(sizeof(int16), 0, msg + msg_len);            // Many types of DATA specified parameter.
            msg_len += sizeof(int16);
        }
        IF (msg) break;   
        msg = (char *) malloc(msg_len);
    }
    while(msg);

    FOR (i=0; i<msg_len; i++)
    fprintf(stdout,"%c",msg[i]);
   
    sql_send_msg(sql_conn, 'P', msg_len, msg);

La fonction sql_send_msg ajoute le message type 'P' , puis la taille calculée (taille du message + taille elle meme"), puis le message.

C'est un probleme un peu special que j'ai l'a (developper un client postgrsql sans lib) mais je bloque pas mal et je vois pas ou est le probleme (j'ai presque fais un copier coller de la libpq bibliotheque de postgresql)

Merci d'avance en tout ca

Pied de page des forums

Propulsé par FluxBB