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 02/03/2015 15:33:38

créer une vue en langage C

Salut
J'ai un projet dans lequel je voudrais masquer certaines de mais vues dans des procédures en langage C.
En effet, ma base est sur PostgreSQL et l'interface est en ACCESS. Quand j'installe la base sur le serveur du client, l'administrateur du serveur a accès aux codes source de ma base sur PostgreSQL.
L'objectif est alors de créer quelques unes des mes vues dans des procédures en langage C.
Jusqu'à présent j'ai réussi à faire uniquement des fonctions qui retournent des types simples en langage C. J'ai tenter de comprendre le mécanisme mais il est trop compliqué (trop de pointeurs et de structures compliquées); et les exemples de la doc utilisent des lignes créées et non des lignes de tables.
Si vous avez un exemple?
Merci d'avance.
@+

Hors ligne

#2 02/03/2015 21:49:31

rjuju
Administrateur

Re : créer une vue en langage C

Bonjour,

Tout d'abord il n'est pas possible de créer de vue en C, uniquement des fonctions. Ensuite, je vous déconseillerai très fortement de partir sur une obfuscation du code via des fonctions en C, tout d'abord parce que les requêtes effectuées seront récupérables d'une manière ou d'une autre, et ensuite car cela complexifierait énormément toute votre application : beaucoup de bug, difficulté de livraison, nécessité compiler le code et de redémarrer l'instance pour mettre à jour une fonction.

Hors ligne

#3 04/03/2015 21:33:40

Re : créer une vue en langage C

Salut et grand merci de la réponse (qui m'apprend plus PostgreSQL).
Pour la création de vues, il s'agit de créer une fonction en C qui retourne une table puis je crée une vue par "CREATE VIEW NOMVUE AS SELECT * FROM MAFONCTION(...)".
Par ailleurs, il s'agit des codes de quelques uns de mes objets que je trouve être le cœur de mon œuvre.
Par votre réponse, doit-on comprendre qu'il est impossible de protéger un code source dans une base PostgreSQL?
Merci d'avance

Hors ligne

#4 05/03/2015 12:52:26

gleu
Administrateur

Re : créer une vue en langage C

Le seul moyen est de faire une procédure stockée en C. En dehors de ça, ce n'est pas possible. La raison est déjà donné par Julien, pas besoin de revenir dessus. Juste dire que je suis entièrement d'accord avec lui.


Guillaume.

Hors ligne

#5 05/03/2015 17:40:46

Re : créer une vue en langage C

Salut
Merci du temps perdu à m'aider.
Je reformule ma question...
Avez-vous un exemple de fonction (procédure stockée) en C qui exécute un select sur des tables et retourne le résultat sous forme de table? (le code du select étant intégré dans la fonction en C).
Merci d'avance.

Hors ligne

#6 05/03/2015 21:03:26

gleu
Administrateur

Re : créer une vue en langage C

Beaucoup de modules contrib ont ce type de fonctions (adminpack, pg_stat_statements, etc).


Guillaume.

Hors ligne

#7 05/03/2015 22:32:42

Re : créer une vue en langage C

Salut et encore merci
J'ai juste besoin D'UN POINT de départ. Ce n'est pas la volonté de chercher qui manque (plus de 90% de ma connaissance est le résultat d'une autoformation!!!).
Je trouve que c'est vraiment pas trop demandé de me coller UN PETIT EXEMPLE comme point de départ.
Merci d'avance.

Hors ligne

#8 05/03/2015 23:00:39

gleu
Administrateur

Re : créer une vue en langage C

Pardon ? je viens de vous le donner, votre exemple. Allez dans le code source du module adminpack, tout y est. Allez, jour de bonté (vraiment de bonté vu le ton que vous employez), le lien vers le source http://git.postgresql.org/gitweb/?p=pos … cb;hb=HEAD


Guillaume.

Hors ligne

#9 08/03/2015 22:56:59

Re : créer une vue en langage C

Salut
Grand merci à vous gleu, mais l'exemple donné ne m'a pas été très utile.
J'ai trouvé un code (sur une page en russe! avec les mots clé "postgresql srf function language C") que j'ai travaillé un peut...
La fonction en C

#include "postgres.h"
#include "fmgr.h"
#include "executor/spi.h"
#include "funcapi.h" // to return set of rows and cope with tuples
#include <string.h>
#include <stdio.h>
#include <stdlib.h> 
PG_MODULE_MAGIC; 
PG_FUNCTION_INFO_V1(get_level1_c);
PGDLLEXPORT 
        Datum
        get_level1_c(PG_FUNCTION_ARGS)
        {
            int spi_ret;
            char sql[100]; 
            char *id;
            FuncCallContext *funcctx;
            MemoryContext oldcontext;
            Datum result;

            if (SRF_IS_FIRSTCALL()) {
                funcctx = SRF_FIRSTCALL_INIT();
                oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);


                SPI_connect(); 
                snprintf(sql, sizeof(sql), "SELECT id, prenom, lenom  FROM personne;");

                    spi_ret = SPI_execute(sql, true, 0);

                    funcctx->max_calls = SPI_processed;

                MemoryContextSwitchTo(oldcontext);
            }

            funcctx = SRF_PERCALL_SETUP();

            if (funcctx->call_cntr < funcctx->max_calls) {
				HeapTuple tuple = SPI_tuptable->vals[funcctx->call_cntr];// ligne que j'ai ajouté	
                    //id = SPI_getvalue(SPI_tuptable->vals[funcctx->call_cntr], SPI_tuptable->tupdesc, 1);

                //result = Int32GetDatum(atoi(id));
				
				result=HeapTupleGetDatum(tuple);// ligne que j'ai ajouté	
                SRF_RETURN_NEXT(funcctx, result);
            } else {
                SPI_finish();
                SRF_RETURN_DONE(funcctx);
            }
        }

La fonction correspondante dans postgresql...

CREATE OR REPLACE  FUNCTION get_level1_c(IN integer)
  RETURNS table(id integer, prenom character varying(30),  lenom character varying(20)) AS
'fnpgsqlsrf.dll', 'get_level1_c'
  LANGUAGE C

Sans les lignes ajoutées j'obtiens une seule colonne. J'ai essayé d'avoir plusieurs colonnes mais j'ai l'erreur...

ERREUR: cache lookup failed for type 0
État SQL :XX000

J’ai espoir que quelqu'un m'aidera à compléter cette fonction.
Merci d'avance.

Dernière modification par alassanediakite (08/03/2015 22:57:49)

Hors ligne

#10 09/03/2015 22:10:48

rjuju
Administrateur

Re : créer une vue en langage C

Vous ne pouvez pas utiliser ces fonctions comme ça. Je vous conseille de regarder des exemples d'appels à tuplestore_begin_heap(), tuplestore_putvalues() et tuplestore_donestoring(). N'importe quelle extension officielle avec des SRF fera l'affaire, comme pg_stat_statements par exemple : https://github.com/postgres/postgres/bl … ts.c#L1299

Hors ligne

#11 15/03/2015 23:39:54

Re : créer une vue en langage C

Salut
J'ai finalement trouvé une solution par SPI_returntuple dans la doc. Grand merci à vous.
Le code en C

#include "postgres.h"
#include "fmgr.h"
#include "executor/spi.h"
#include "funcapi.h" 
#include <string.h>
#include <stdio.h>
#include <stdlib.h> 
PG_MODULE_MAGIC; 
PG_FUNCTION_INFO_V1(vpersonne);
PGDLLEXPORT 
        Datum
        vpersonne(PG_FUNCTION_ARGS)
        {
	int spi_ret;
            char sql[100];            
            FuncCallContext *funcctx;
            MemoryContext oldcontext;
            Datum result;

            if (SRF_IS_FIRSTCALL()) {
                funcctx = SRF_FIRSTCALL_INIT();
                oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);

                SPI_connect(); 
                snprintf(sql, sizeof(sql), "SELECT id, prenom, lenom  FROM personne;");

                    spi_ret = SPI_execute(sql, true, 0);

                    funcctx->max_calls = SPI_processed;

                MemoryContextSwitchTo(oldcontext);
            }

            funcctx = SRF_PERCALL_SETUP();

            if (funcctx->call_cntr < funcctx->max_calls) {
				result=PointerGetDatum(SPI_returntuple(SPI_tuptable->vals[funcctx->call_cntr],SPI_tuptable->tupdesc));
				SRF_RETURN_NEXT(funcctx, result);
            } else {
                SPI_finish();
                SRF_RETURN_DONE(funcctx);
            }
        }

La fonction dans PostgreSQL

CREATE OR REPLACE FUNCTION vpersonne(integer)
  RETURNS SETOF record AS
'fnpgsqlsrf.dll', 'vpersonne'
  LANGUAGE c

Le test de la fonction

SELECT * from  vpersonne(null) as (id int, prenom varchar, nom varchar);

@+

Hors ligne

Pied de page des forums