Apache Adobe Flex TutorialTutoriaux Adobe Flex & AIR en Français

26jan/110

AIR SQLite – Création de tables SQLite et types de données

Dans le tutorial précédent, on a vu comment créer une base de données SQLite de manière synchrone ou asynchrone. Maintenant que l'on a établi notre connexion à la base, il va falloir l'utiliser et la peupler. Mais avant de pouvoir peupler notre base, il va nous falloir créer des tables pour stocker nos informations.

La création de tables SQLite se fait par simple exécution de requête SQL. Pour créer une table, il faut utiliser une instruction "CREATE TABLE" qui inclut les définitions des colonnes et des contraintes de la table. Dans cette requête, vous devrez aussi définir les types de données de chaque colonnes.

Si vous ne connaissez pas la syntaxe pour la création d'une table en SQL, cet article devrait vous aider:

http://www.commentcamarche.net/contents/sql/sqlcreate.php3

La syntaxe est assez simple:

CREATE TABLE Nom_de_la_table (Nom_de_colonne1 Type_de_donnée,
				  Nom_de_colonne2 Type_de_donnée,
				  ...);

Dans les exemples suivants, vous verrez souvent l'instruction CREATE TABLE IF NOT EXISTS. Cela permet d'exécuter la requête de création de table uniquement si celle-ci n'existe pas encore. Si elle existe déjà, aucune opération ne sera effectuée. Comme cela, vous aurez le même code qui sera exécuté pour vous assurer que votre table soit bien là par la suite.

Un petit mot sur les types de données

Contrairement à la plupart des bases de données, une base SQLite embarquée dans AIR ne requiert pas un type de colonne et ne force pas de type arbitraire. Pour contrôler les types de données, le runtime AIR utilise deux concepts: "Storage Classes" et "Column Affinity".

Ceci est un sujet assez avancé, je vous conseille de lire la documentation (difficile à trouver!) si cela vous intéresse:

Data type support

Le plus important est la partie "Column affinity". Quand on définit le type d'une colonne dans Adobe AIR, on définit en fait une recommandation de type de donnée qui sera stocké dans la colonne. Quand une valeur est enregistrée dans une colonne (par un INSERT ou un UPDATE), AIR va essayer de convertir la donnée vers la "Column affinity" qui a été donnée à la colonne.

Par exemple, si vous insérer un objet Date ActionScript dans une colonne que vous avez défini comme TEXT, l'objet Date sera d'abord converti en sa représentation String, en appelant la méthode toString() par défaut. Si la valeur ne peut pas être convertie, une erreur sera lancée et l'opération sera abandonnée.

Lorsqu'une valeur est récupérée d'une BDD en utilisant un SELECT, elle est retournée en une instance de classe correspondant à la "Column affinity". Notre objet Date reviendrait donc sous forme de String.

Voici les grands types de colonne (les "Column affinities"):

  • TEXT (or String)
  • NUMERIC
  • INTEGER (or int)
  • REAL (or Number)
  • Boolean
  • Date
  • XML
  • XMLLIST
  • Object
  • NONE

La différence entre NUMERIC et REAL se fait au niveau du type des valeurs qui vous seront renvoyées. Une colonne de type NUMERIC va vous renvoyer une valeur du type le plus approprié. Par exemple, 40 sera renvoyé en uint, -8 sera renvoyé comme int et 10.05 sera renvoyé comme Number. Une colonne de type REAL va elle toujours renvoyé une valeur de type Number, quel que soit son type.

Une colonne de type DATE va enregistrer des objets ActionScript de type Date. Si on essaie de stocker une String, AIR va tenter de convertir cette String en objet Date pour la stocker (sûrement avec la méthode Date.parse(str)).

Une colonne de type OBJECT peut contenir un objet ActionScript sérialisé comme un Array ou une classe perso que vous avez crée. Votre objet sera sérialisé en AMF3 et enregistré dans un BLOB. Quand vous allez récupérer la valeur, une dé-serialisation sera effectuée et vous obtiendrez une instance d'objet. Pour pouvoir stocker une classe à vous dans la base, vous devrez enregistrer un alias pour la classe en utilisant la méthode flash.net.registerClassAlias() ou en ajoutant le tag [RemoteObject] juste au dessus de la définition de classe. Avant de récupérer la donnée, vous devrez aussi enregistrer l'alias de la classe. Un tutorial sera consacré à cette pratique par la suite.

La définition de ces types de données est très importante car elle va vous permettre d'assurer l'intégrité des données entrées / récupérées. Ainsi, les tris (SORT / ORDER BY) et les GROUP BY ne se comporteront pas de la même manière si vous définissez mal votre type de donnée.

Création de table en mode synchrone

Dans cet exemple, on crée une table "employees" avec deux champs texte pour nom/prénom et un champ NUMERIC pour le salaire. Un champ d'identifiant AUTOINCREMENT et aussi créé pour assurer l'unicité de chaque ligne:

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml"
                        applicationComplete="onAppComplete();">
  <mx:Script>
    <![CDATA[
      import flash.data.SQLConnection;
      import flash.events.SQLErrorEvent;
      import flash.events.SQLEvent;
      import flash.filesystem.File;

      private var _sqlConnection:SQLConnection = null;

      private function onAppComplete():void {
        _sqlConnection = new SQLConnection();
        var dbFile:File = File.applicationStorageDirectory.resolvePath("DBSample.db");
        try {
          _sqlConnection.open(dbFile);
          trace("the database was created successfully");
        } catch (error:SQLError) {
          trace("Error message:", error.message);
          trace("Details:", error.details);
        }
        // votre BDD est accessible ici
        var createStmt:SQLStatement = new SQLStatement();
        createStmt.sqlConnection = _sqlConnection;

        var sql:String = "CREATE TABLE IF NOT EXISTS employees (" + "    empId INTEGER PRIMARY KEY AUTOINCREMENT, " +
          "    firstName TEXT, " + "    lastName TEXT, " + "    salary NUMERIC" + ")";
        createStmt.text = sql;

        try {
          createStmt.execute();
          trace("Table created");
        } catch (error:SQLError) {
          trace("Error message:", error.message);
          trace("Details:", error.details);
        }

      }
    ]]>
  </mx:Script>
</mx:WindowedApplication>

Création de table en mode asynchrone

Même code mais cette fois-ci en mode asynchrone:

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml"
                        applicationComplete="onAppComplete();">
  <mx:Script>
    <![CDATA[
      import flash.data.SQLConnection;
      import flash.events.SQLErrorEvent;
      import flash.events.SQLEvent;
      import flash.filesystem.File;

      private var _sqlConnection:SQLConnection = null;

      private function onAppComplete():void {
        _sqlConnection = new SQLConnection();
        _sqlConnection.addEventListener(SQLEvent.OPEN, openHandler);
        _sqlConnection.addEventListener(SQLErrorEvent.ERROR, errorHandler);

        var dbFile:File = File.applicationStorageDirectory.resolvePath("DBSample.db");

        _sqlConnection.openAsync(dbFile);
      }

      private function openHandler(event:SQLEvent):void {
        trace("the database was created successfully");
        var createStmt:SQLStatement = new SQLStatement();
        createStmt.sqlConnection = _sqlConnection;

        var sql:String = "CREATE TABLE IF NOT EXISTS employees (" + "    empId INTEGER PRIMARY KEY AUTOINCREMENT, " +
          "    firstName TEXT, " + "    lastName TEXT, " + "    salary NUMERIC" +
          ")";
        createStmt.text = sql;

        createStmt.addEventListener(SQLEvent.RESULT, createResult);
        createStmt.addEventListener(SQLErrorEvent.ERROR, createError);

        createStmt.execute();

      }

      private function errorHandler(event:SQLErrorEvent):void {
        trace("Error message:", event.error.message);
        trace("Details:", event.error.details);
      }

      private function createResult(event:SQLEvent):void {
        trace("Table created");
      }

      private function createError(event:SQLErrorEvent):void {
        trace("Error message:", event.error.message);
        trace("Details:", event.error.details);
      }
    ]]>
  </mx:Script>
</mx:WindowedApplication>

Articles similaires