PostgreSQL: Utiliser le principe du type “varlena”

PostgreSQL utilise depuis Postgres le type varlena, qui signifie variable length array en anglais, soit tableau à taille variable en français. Ce type permet de stocker des données à taille variable dans la base de données. Le principe est très simple: stocker en mémoire une ou plusieurs données de façon contiguë. De plus, il ne doit pas y avoir de pointeur dans le type.

La structure “de base” de varlena est définie dans le fichier src/include/c.h, line 401 pour PostgreSQL 8.4 par:

struct varlena
{
	char	vl_len_[4];
	char	vl_dat[1];
};

Note: le premier tableau de 4 caractères peu très bien est remplacé par un int32, ça revient au même: 4 octets.

Ce type représente le principe: un champ vl_dat, qui contiendra la donnée et d’autres champs qui ne doivent pas être des pointeurs, mais des entiers le plus souvent (ici un tableau de 4 caractères), qui contiennent des informations sur cette donnée. Cela permet à PostgreSQL de pouvoir stocker sur le disque et en mémoire toutes les données en une fois, pouvant ainsi les déplacer comme bon lui semble.

Attention: la propriété qui contient les données doit être la dernière propriété de la structure.

Tout type de donnée un peu complexe doit utiliser ce principe lorsqu’il stocke des données de taille variable en base afin d’assurer une intégrité aux données stockées. Nous allons voir, à l’aide de la librairie parse_url pour PostgreSQL, comment créer un type de données stockant de nombreuses données de taille variable dans une seule et même donnée, dans le but d’être utilisé comme type de colonne dans une table par exemple.

Continue reading

I2C (IP-to-Country): Gestion des comptes utilisateurs

La récupération des données depuis I2C vient de changer. En effet, dorénavant il vous faudra vous authentifier à l’aide d’un compte client D-Sites avant la récupération du pays d’une adresse IP.

La page du projet i2c à été mise à jour.

Pourquoi ?

Ce système à été mis en place pour lutter contre les utilisations abusives (plusieurs centaines de milliers de requêtes par mois) de I2C.

Qu’est-ce que ça change ?

Pas grand chose, le code de récupération change un peu, rien de bien méchant. Seulement, maintenant, le nombre maximal de requêtes est de 50 000 requêtes par mois. Si vous souhaitez en faire plus, c’est tout à fait possible en payant un peu (quelques euros): 100 000 requêtes (1€), 500 000 requêtes (4€) et 1 000 000 requêtes (7€). Pour plus de requêtes contactez-moi.

Comment ?

Pour créer un compte client D-Sites vous devez vous inscrire sur le site puis aller dans l’administration, où vous trouverez un menu “Compte D-Sites”. Ce menu concerne le compte client D-Sites qui vous permettra de vous identifier au près de tous les services de D-Sites. Une fois créé, activez-le pour i2c dans le sous-menu correspondant. C’est bon, vous pouvez vous connecter avec les identifiants choisis.

Concrètement, le code à mettre en place change pour HTTP et SOAP:

Pour HTTP

Vous devez ajouter les paramètres URL u et p décrivant respectivement le nom d’utilisateur et le mot de passe.

Pour SOAP

Si vous utilisez SOAP, vous avez deux options: soit vous utilisez la fonction login qui prend comme paramètres le nom d’utilisateur et le mot de passe avant getCountry, soit vous utilisez la fonction getCountryLogin qui prend dans l’ordre l’adresse IP, le nom d’utilisateur et le mot de passe.

En espérant améliorer la qualité du service.
Cordialement, Samuel ROZE.

La source de PHP dans un projet avec Eclipse CDT

Si vous souhaitez écrire de nouvelles fonctionnalités, créer des patchs, corriger quelques bugs ou tout simplement aider la communauté PHP sur le code source, il vous faut l’avoir dans un éditeur de code. Eclipse est mon favori, il permet de gérer presque tous les types de codes, bref, il est génial ! Seulement, j’ai un peu de mal à mettre en place le code source (du tronc ou d’une branche, peu importe) en tant que projet C dans Eclipse CDT.

Continue reading

Pl/PgSQL: Parcourir un tableau

Pour PostgreSQL >= 9.1

Depuis PostgreSQL 9.1, nous pouvons utiliser l’opérateur FOREACH, comme ceci:

FOREACH v_row IN ARRAY v_monarray
LOOP
        -- La variable "v_row" contient le row de votre tableau.
END LOOP;

Pour PostgreSQL > 8.3 et <= 9.0

Pour parcourir un tableau de données, ça pourrait être très simple en utilisant FOR ... IN ... mais cette synthaxe utilise uniquement des données de type RECORD pour fonctionner. C’est pourquoi, depuis PostgreSQL 8.4, il y a une fonction unnest qui permet de transformer un tableau (array) en un RECORD. Avant, nous allons créer cette fonction.

Dans votre bloc Pl/PgSQL, faites comme ceci:

FOR v_array_data IN SELECT unnest(v_monarray) LOOP
 
        -- Vos instructions...
 
END LOOP;

Données:

  • v_monarray est un tableau de données (exemple: integer[] )
  • v_array_data est une variable contenant la valeur de la donnée du tableau du tour (exemple: integer)
    Note: Doit être du même type que la donnée du tableau

Pour PostgreSQL <= 8.3

Pour ces versions, nous allons créer la fonction unnset (voir article sur le wiki de PostgreSQL) comme ceci:

CREATE OR REPLACE FUNCTION unnest(anyarray)
  RETURNS SETOF anyelement AS
$BODY$
SELECT $1[i] FROM
    generate_series(array_lower($1,1),
                    array_upper($1,1)) i;
$BODY$
  LANGUAGE 'sql' IMMUTABLE

Ainsi, vous pouvez appliquer l’exemple pour PostgreSQL 8.4.

Sinon, vous pouvez aussi utiliser WHILE comme ceci:

WHILE v_loop_i <= v_array_count LOOP
 
        -- Vos instructions...
        v_array_data := v_monarray[v_loop_i];
 
        v_loop_i := v_loop_i + 1;
    END LOOP;

Avec:

  • v_array_count la taille du tableau
  • v_loop_i une variable de type integer initialisée à 1

Pl/PgSQL: Noms de variables dynamiques

Si dans un trigger vous voulez récupérer un champ qui change à chaque fois (nom dynamique), ou plus généralement si vous voulez récupérer la valeur d’un champ xxxxxx d’un RECORD, il faut utiliser EXECUTE. Soient:

  • NEW, la nouvelle ligne (automatiquement créé avec les triggers sur INSERT et UPDATE)
    Note: C’est une variable de type RECORD. Ainsi, vous pouvez la remplacer par n’importe quel autre RECORD.
  • v_critere, le nom du champ à récupérer
  • v_value, la variable dans laquelle on veut mettre la valeur
  • monschema.matable, le nom de la table qui correspond au RECORD.
EXECUTE 'SELECT (' || quote_literal(NEW) || '::monschema.matable).' || v_critere INTO v_value;

Ainsi, si v_critere = id_somethink, alors la valeur du champ “id_somethink” du RECORD sera placée dans la variable v_value. “Tout simplement” :-)

Merci beaucoup à Dimitri et Guillaume de la liste PostgreSQL pour m’avoir aider à trouver cette solution qui n’est pas implantée malgré le patch proposé.

Bien gérer les tâches avec Redmine depuis Eclipse

Redmine est un Bug Tracker (on peut même l’appeller un Gestionnaire de projet tellement il est complet) très innovant qui contient toutes les optionnalités necessaires à un bon développement. Après avoir installer Ruby On Rails, puis Redmine lui-même, cet outil est très performant. Pour encore plus de facilitée, Redmine peut être interfacé à Mylyn (plug-in de gestion approfondie des tâches) grâce à Redmine-Mylyn Connector.
Continue reading

Créer une documentation à partir de fichiers bien commentés

Dans n’importe quel projet, la documentation est presque indispensable dans la mesure où l’on passe plus de temps à relire et à maintenir du code qu’a en écrire… Commenter le code source est tout aussi important et permet d’intervenir beaucoup plus rapidement sur le code, même après quelques mois voir années. Il permet aussi à quelqu’un qui reprend le projet de mieux comprendre comment il fonctionne.

Seulement, une fois que l’on a commenter, on doit à nouveau s’occuper d’écrire la documentation, chose très ennuyante. Afin d’aider au maximum les développeurs, il existe de nombreux outils pour créer des documentations à partir du code source comme PHPDocumentor.

Continue reading