Vous n'êtes pas identifié(e).
Pages : 1
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
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.
Julien.
https://rjuju.github.io/
Hors ligne
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
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
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
Beaucoup de modules contrib ont ce type de fonctions (adminpack, pg_stat_statements, etc).
Guillaume.
Hors ligne
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
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
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
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
Julien.
https://rjuju.github.io/
Hors ligne
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
Pages : 1