diff options
author | Florian Merz <me@fiji-flo.de> | 2021-02-11 12:36:08 +0100 |
---|---|---|
committer | Florian Merz <me@fiji-flo.de> | 2021-02-11 12:36:08 +0100 |
commit | 39f2114f9797eb51994966c6bb8ff1814c9a4da8 (patch) | |
tree | 66dbd9c921f56e440f8816ed29ac23682a1ac4ef /files/fr/web/api/indexeddb_api | |
parent | 8260a606c143e6b55a467edf017a56bdcd6cba7e (diff) | |
download | translated-content-39f2114f9797eb51994966c6bb8ff1814c9a4da8.tar.gz translated-content-39f2114f9797eb51994966c6bb8ff1814c9a4da8.tar.bz2 translated-content-39f2114f9797eb51994966c6bb8ff1814c9a4da8.zip |
unslug fr: move
Diffstat (limited to 'files/fr/web/api/indexeddb_api')
4 files changed, 2007 insertions, 0 deletions
diff --git a/files/fr/web/api/indexeddb_api/basic_concepts_behind_indexeddb/index.html b/files/fr/web/api/indexeddb_api/basic_concepts_behind_indexeddb/index.html new file mode 100644 index 0000000000..cb05bef3fe --- /dev/null +++ b/files/fr/web/api/indexeddb_api/basic_concepts_behind_indexeddb/index.html @@ -0,0 +1,209 @@ +--- +title: Les concepts basiques d'IndexedDB +slug: Web/API/API_IndexedDB/Basic_Concepts_Behind_IndexedDB +tags: + - Avancé + - IndexedDB + - concepts +translation_of: Web/API/IndexedDB_API/Basic_Concepts_Behind_IndexedDB +--- +<p>{{DefaultAPISidebar("IndexedDB")}}</p> + +<p class="summary"><strong>IndexedDB</strong> est un moyen pour permettre le stockage de données dans le navigateur d'un utilisateur, de manière persistante. Ses fonctions de recherche avancées permettent de créer des applications qui fonctionnent tant connectées que déconnectées. IndexedDB est utile pour créer des applications qui stockent une grande quantité de données (par exemple : un catalogue de DVDs dans une bibliothèque) et des applications qui n'ont pas forcément besoin d'une connectivité Internet continue (par exemple : des clients de messagerie électronique, des listes de tâches, des bloc-notes).</p> + +<h2 id="À_propos_de_ce_document">À propos de ce document</h2> + +<p>Ce document introduit les concepts et les termes essentiels d'IndexedDB. Vous aurez une vue d'ensemble et vous comprendrez les concepts-clés.</p> + +<p>Vous pourrez trouver ici :</p> + +<ul> + <li>Pour en savoir plus sur les termes d'IndexedDB, voyez la section <a href="#definitions">Définitions</a>.</li> + <li>Pour avoir un tutoriel sur l'utilisation de l'API, voyez <a href="https://developer.mozilla.org/fr/docs/Web/API/API_IndexedDB/Using_IndexedDB" title="en/IndexedDB/IndexedDB primer">Utiliser IndexedDB</a>.</li> + <li>Pour la documentation de référence sur l'API IndexedDB, voyez l'article <a href="https://developer.mozilla.org/fr/docs/Web/API/API_IndexedDB" title="https://developer.mozilla.org/en/IndexedDB">IndexedDB</a> et ses sous-parties, qui documentent les types d'objets utilisés par IndexedDB.</li> + <li>Pour plus d'informations sur la manière dont le navigateur gère vos données en arrière-plan, lisez <a href="https://developer.mozilla.org/fr/docs/Web/API/API_IndexedDB/Browser_storage_limits_and_eviction_criteria">Limites de stockage du navigateur et critères d'éviction</a><a href="https://developer.mozilla.org/fr/docs/Web/API/API_IndexedDB/Browser_storage_limits_and_eviction_criteria">.</a></li> +</ul> + +<h2 id="Vue_densemble_dIndexedDB">Vue d'ensemble d'IndexedDB</h2> + +<p>IndexedDB vous permet de stocker et récupérer des objets qui sont indexés avec une "clé". Tous les changements que vous faites dans la base de données sont forcément transactionnels. Comme la plupart des solutions de stockage du web, IndexedDB respecte la politique de sécurité utilisant l'origne (<a class="external" href="http://www.w3.org/Security/wiki/Same_Origin_Policy" title="http://www.w3.org/Security/wiki/Same_Origin_Policy">same-origin policy</a>). Ainsi, vous pouvez accéder aux données stockées d'un domaine, alors que vous ne pouvez pas accéder aux données de domaines différents.</p> + +<p>IndexedDB est une API <a href="https://developer.mozilla.org/fr/docs/Web/API/API_IndexedDB#Asynchronous_API" title="/en/IndexedDB#Asynchronous_API">asynchrone</a> qui peut être utilisée dans la plupart des contextes, <a href="https://developer.mozilla.org/fr/docs/Utilisation_des_web_workers" title="/fr/docs/DOM/Using_web_workers">Web Workers</a> inclus. Elle comportait également une version <a href="https://developer.mozilla.org/fr/docs/Web/API/API_IndexedDB#Synchronous_API" title="/en/IndexedDB#Synchronous_API">synchrone</a> prévue pour être utilisée dans des <a href="https://developer.mozilla.org/fr/docs/Utilisation_des_web_workers" title="/fr/docs/DOM/Using_web_workers">Web Workers</a>. mais cette option a été retirée de la spécification en raison du manque d'intérêt de la communauté Web.</p> + +<p>IndexedDB est une alternative à l'API WebSQL Database, qui a été dépréciée par le W3C le 18 novembre 2010. Alors que ces APIs sont toutes deux des solutions de stockage, elles n'offrent pas les mêmes fonctionnalités. WebSQL Database est un système d'accès à une base de données relationnelle alors qu'IndexedDB est un système de table indexée. </p> + +<h2 id="concepts" name="concepts">Les grands concepts</h2> + +<p>Si vous avez l'habitude de travailler avec d'autres types de bases de données, vous pourrez être désorienté par l'utlisation d'IndexedDB. Mais il suffit de garder les concepts importants suivants en tête :</p> + +<ul> + <li><strong>Les bases de données IndexedDB stockent des paires clé-valeur.</strong> Les valeurs peuvent êtres des objets structurés, et les clés peuvent être des propriétés de ces objets. Vous pouvez créer des index à partir de n'importe quelle propriété des objets, pour faciliter la recherche et l'énumération triée. Les clés peuvent être des objets binaires.</li> + <li><strong>IndexedDB est construit autour d'un modèle de base de données transactionnelle.</strong> Tout ce que vous faites avec IndexedDB se passe dans le contexte d'une <a href="#gloss_transaction">transaction</a>. L'API IndexedDB fournit beaucoup d'objets qui représentent des index, des tables, des curseurs, etc, mais chacun de ces objets est forcément relié à une transaction donnée. Il n'est pas possible d'exécuter de commandes ou d'ouvrir des curseurs en dehors d'une transaction. Les transactions ont une durée de vie bien définie, donc essayez d'utiliser une transaction après avoir terminé le traitement des exceptions. De plus, les transactions s'engagent automatiquement, elles ne peuvent être lancées manuellement.<br> + Ce modèle basé sur des transactions est vraiment utile : rendez-vous compte qu'un utilisateur peut ouvrir deux instances de la même application web dans deux onglets différents en même temps. Si on n'utilisait pas d'opérations transactionnelles, une instance pourrait écraser les modifications de l'autre, et vice versa. Si vous n'êtes pas à l'aise avec la notion de transaction dans une base de données, vous pouvez consulter l'<a href="http://fr.wikipedia.org/wiki/Transaction_%28base_de_donn%C3%A9es%29" title="http://fr.wikipedia.org/wiki/Transaction_%28base_de_donn%C3%A9es%29">article Wikipedia sur les transactions</a>. Vous pouvez aussi voir plus loin la partie <a href="#gloss_transaction">transaction</a> dans la section des définitions.</li> + <li><strong>L'API IndexedDB est principalement asynchrone.</strong> L'API ne vous donne pas les données en retournant des valeurs. Au contraire, vous devez utiliser une fonction de rappel ("callback"). Vous ne stockez pas une valeur dans la base de données, ou vous ne récupérez pas une valeur de la base de manière synchrone, mais vous demandez qu'une opération de base de données soit exécutée. Un événement DOM est envoyé lorsque l'opération est terminée, et le type d'événement vous permet de savoir si l'opération a réussi ou échoué. Cela peut sembler un peu compliqué au premier abord, mais après tout, ce n'est pas si différent du fonctionnement de <a href="/fr/docs/XMLHttpRequest" title="/fr/docs/XMLHttpRequest">XMLHttpRequest</a>.</li> + <li><strong>IndexedDB utilise de nombreuses requêtes. </strong>Les requêtes sont des objets qui reçoivent les événements DOM de succès ou d'échec mentionnés précédemment. Elles ont des propriétés <code>onsuccess</code> et <code>onerror</code>, et vous pouvez appeler <code>addEventListener()</code> et <code>removeEventListener()</code> sur ces objets. Elles ont aussi les propriétés <code>readyState</code>, <code>result</code>, et <code>errorCode</code> qui vous donnent l'état d'une requête. La propriété <code>result</code> est plutôt magique car elle peut correspondre à beaucoup de choses différentes, en fonction de la manière dont la requête a été créée (par exemple, une instance de <code>IDBCursor</code>, ou la clé de la valeur que vous venez d'insérer dans la base de données.)</li> + <li><strong>IndexedDB utilise les évènements DOM pour vous informer quand les résultats sont disponibles.</strong> Les évènements DOM ont toujours une propriété de <code style="font-size: 14px;">type</code> (dans IndexedDB, sont préférables <code>"success" <em>(succès)</em></code> ou <code>"error" <em>(erreur)</em></code>). Les évènements DOM ont aussi une propriété <code>target</code> <em>(cible) </em>qui dit vers où l'évènement est dirigé. Dans la plupart des cas, la <code>target</code> d'un évènement est l'objet <code>IDBRequest</code> <span id="result_box" lang="fr"><span>qui a été généré à la suite d'une opération de base de données</span></span> . <span id="result_box" lang="fr"><span>Les événements "success" ne se propagent pas et ne peuvent être annulés</span></span> . Les évènements "Error", se propagent et peuvent être annulés. C'est très important, <span id="result_box" lang="fr"><span>lors d'un événement d'erreur, les transactions annulent au fur et à mesure </span></span><span lang="fr"><span> qu'elles s'exécutent, à moins qu'il ne soit annulé</span></span> .</li> + <li><strong>IndexedDB est orienté objet.</strong> IndexedDB n'est pas une base de données relationnelle, avec des tables, des colonnes et des lignes. Cette différence importante et fondamentale change votre manière de concevoir et construire vos applications.<br> + Dans un espace de stockage de données relationel habituel, on aurait un tableau qui permet de stocker un ensemble de lignes de données, et de colonnes de types nommés de donnée. Avec IndexedDB, au contraire, vous créez un objet de stockage pour un type de données, et les objets JavaScript persistent simplement dans cet espace. Chaque objet de stockage peut utiliser un ensemble d'index qui rendent efficaces la recherche et l'itération. Si les systèmes de base de données orientée objet ne vous sont pas familiers, vous pouvez aller lire l'<a href="http://fr.wikipedia.org/wiki/Base_de_donn%C3%A9es_orient%C3%A9e_objet" title="http://fr.wikipedia.org/wiki/Base_de_donn%C3%A9es_orient%C3%A9e_objet">article Wikipedia sur les bases de données orientées objet</a>.</li> + <li><strong>IndexedDB n'utilise pas le langage </strong> <strong>Structured Query Language</strong> (<strong>SQL).</strong> Il utilise des requêtes sur un index pour obtenir un curseur, que l'on utilise ensuite pour parcourir l'ensemble des résultats. Si vous ne connaissez pas bien les systèmes NoSQL, vous pouvez consulter l'<a href="http://fr.wikipedia.org/wiki/NoSQL" title="http://fr.wikipedia.org/wiki/NoSQL">article Wikipedia sur NoSQL</a>.</li> + <li><a name="origin"><strong>IndexedDB adhère au principe de same-origin policy <em>(politique de même origine)</em></strong></a>. <span id="result_box" lang="fr"><span>Une origine est le domaine, le protocole d'application et le port URL du document où le script est exécuté.</span></span> Chaque origine <span id="result_box" lang="fr"><span>a son propre ensemble de bases de données associées</span></span> . Chaque base de données a un nom qui l'identifie dans une origine.<br> + La limite de sécurité d'IndexedDB empêche les applications d'accèder à des données d'origine différente. Par exemple, alors qu'une application ou une page <a class="external" href="http://www.example.com/app/" rel="freelink">http://www.example.com/app/</a> peut récupérer des données de <a class="external" href="http://www.example.com/dir/" rel="freelink">http://www.example.com/dir/</a>, parce qu'elles ont la même origine, elle ne peut pas récupérer les données de <a class="external" href="http://www.example.com:8080/dir/" rel="freelink">http://www.example.com:8080/dir/</a> (port différent) ni de <a class="link-https" href="https://www.example.com/dir/" rel="freelink">https://www.example.com/dir/</a> (protocole différent), parce que leurs origines sont différentes.</li> +</ul> + +<h2 id="definitions" name="definitions">Définitions</h2> + +<p>Cette section définit et explique les termes utilisés dans l'API IndexedDB.</p> + +<h3 id="database" name="database">Database <em>(base de données)</em></h3> + +<dl> + <dt><a name="gloss_database">database<em> (base de données)</em></a></dt> + <dd><span id="result_box" lang="fr"><span>Un référentiel d'informations, comprenant généralement un ou plusieurs objets de stockage.</span> <span>Chaque base de données doit avoir les éléments suivants</span></span> : + <ul> + <li>Name . <em>(nom)</em> Il identifie la base de données <span id="result_box" lang="fr"><span>dans une origine spécifique et reste constant tout au long de la durée de sa vie.</span> <span>Le nom peut être n'importe quelle valeur de chaîne de caractères (y compris une chaîne vide).</span></span></li> + <li>Current <a href="#gloss_version"><em>version</em></a> <em>(version actuelle)</em>. Lors de la création de la base de données, sa version est le nombre entier <code>1</code>. <span id="result_box" lang="fr"><span>Chaque base de données ne peut avoir qu'une seule version à un moment donné</span></span> .</li> + </ul> + </dd> + <dt><a name="durable">durable</a></dt> + <dd><span id="result_box" lang="fr"><span>Dans Firefox, IndexedDB était durable, ce qui signifie que dans une transaction readwrite <em>(lecture/écriture)</em> {{domxref ("IDBTransaction.on complet")}} était déclenché uniquement lorsque toutes les données étaient garanties, avant d'être écrites sur le disque.</span></span></dd> + <dd><span lang="fr"><span>À partir de Firefox 40, les transactions IndexedDB ont des garanties de durabilité relachées pour augmenter les performances (voir {{Bug ("1112702")}}) ; comportement identique à celui des autres navigateurs qui mettent en oeuvre IndexedDB. Dans ce cas, l'événement {{Event ("complete")}} est déclenché après la réception par le système d'exploitation de la commande d'écriture, mais potentiellement avant l'écriture effective de ces données sur le disque. L'événement peut donc être livré plus rapidement qu'avant, mais il existe un petit risque que la transaction entière soit perdue si le système d'exploitation l'écrase ou s'il y a une perte de puissance du système avant l'écriture sur le disque. Étant donné que ces événements catastrophiques sont rares, la plupart des consommateurs ne devraient pas nécessairement s'en préoccuper davantage.</span></span></dd> +</dl> + +<div class="note"> +<p><span lang="fr"><span>Note : Dans Firefox, si vous souhaitez être sûr de la durabilité pour une raison ou une autre (par exemple, vous stockez des données critiques qui ne peuvent pas être recalculées plus tard), vous pouvez forcer une transaction d'écriture sur le disque avant la délivrance de l'évènement </span></span> <code>complete</code> par la création d'une transaction utilisant le mode expérimental (non standard) <code>readwriteflush</code> (voir {{domxref("IDBDatabase.transaction")}}). Ceci est actuellement expérimental et ne peut être utilisé que si la préférence <code>dom.indexedDB.experimental</code> est renseignée avec " <code>true</code> " <em>(vrai)</em> dans <code>about:config</code>.</p> +</div> + +<dl> + <dt></dt> + <dt><a name="gloss_object_store">object store <em>(objet de stockage)</em></a></dt> + <dd> + <p><span id="result_box" lang="fr"><span>Le mécanisme avec lequel les données sont stockées dans la base de données</span></span>. L'objet de stockage maintient constamment ses enregistrements, lesquels sont des paires "key-value" <em>(clé-valeur)</em>. Les enregistrements dans l'objet de stockage sont triés dans l'ordre ascendant des "<em><a href="#gloss_key">keys"</a></em> <em>(clés)</em>.</p> + + <p>Chaque objet de stockage doit avoir un nom qui est unique dans la base de données. Il peut éventuellement avoir un <em><a href="#gloss_keygenerator">key generator</a></em> (générateur de clé) et un <em><a href="#gloss_keypath">key path</a></em> <em>(chemin de clé)</em>. S'il a un "key path", il utilise <em><a href="#gloss_inline_key">in-line keys</a></em> <em>(clés en ligne)</em> ; sinon, il utilise <em><a href="#gloss_outofline_key">out-of-line keys</a></em> <em>(clé hors ligne)</em>.</p> + + <p>Pour la documentation de référence sur les objets de stockage, voir <a href="https://developer.mozilla.org/fr/docs/Web/API/IDBObjectStore" rel="internal">IDBObjectStore</a> ou <a href="https://developer.mozilla.org/fr/docs/Web/API/IDBObjectStoreSync" rel="internal">IDBObjectStoreSync</a>.</p> + </dd> + <dt><a name="gloss_version">version</a></dt> + <dd>À la première création de la base de données, sa version est le nombre entier <code>1</code>. <span id="result_box" lang="fr"><span>Chaque base de données possède une seule version à un moment donné ;</span> <span>il ne peut pas exister plusieurs versions dans le même temps.</span></span> La seule façon de changer la version est de l'ouvrir avec une version plus haute. Ceci démarre une <em>transaction</em> <code>VERSION_CHANGE</code> et lance un évènement <code>upgradeneeded</code>. <span id="result_box" lang="fr"><span>Le seul endroit où le schéma de la base de données peut être mis à jour est à l'intérieur du gestionnaire de cet événement</span></span>.</dd> + <dd>Note : Cette définition décrit les <a class="external external-icon" href="http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html">spécifications les plus récentes</a>, <span id="result_box" lang="fr"><span>qui ne sont implémentées que dans des navigateurs à jour.</span></span> <span id="result_box" lang="fr"><span>Les anciens navigateurs ont implémenté la méthode </span></span> <a href="https://developer.mozilla.org/en-US/docs/IndexedDB/IDBDatabase#setVersion()" title="/en-US/docs/IndexedDB/IDBDatabase#setVersion()"><code>IDBDatabase.setVersion()</code></a> <span id="result_box" lang="fr"><span>maintenant obsolète et supprimée</span></span>.</dd> + <dt><a name="gloss_database_connection">database connection<em> (connexion de la base de données)</em></a></dt> + <dd>Une opération créée en ouvrant une <em><a href="#gloss_database">database</a></em> <em>(base de données)</em>. <span id="result_box" lang="fr"><span>Une base de données peut avoir plusieurs connexions en même temps.</span></span></dd> + <dt><a name="gloss_transaction">transaction</a></dt> + <dd> + <p><span id="result_box" lang="fr"><span>Un ensemble atomique d'accès aux données et d'opérations de modification des données sur une base de données particulière.</span> <span>C'est la façon dont vous interagissez avec les données dans une base.</span> <span>En fait, toute lecture ou changement dans la base de données doit se produire dans une transaction.</span></span></p> + + <p><span id="result_box" lang="fr"><span>Une connexion à la base de données peut avoir plusieurs transactions actives associées à la fois, pourvu que les transactions d'écriture n'aient pas de chevauchement</span></span> <a href="#gloss_scope"><em>scopes</em></a>. <span id="result_box" lang="fr"><span>La portée (scope) des transactions, qui est définie lors de la création, détermine l'objet avec lequel la transaction peut interagir, et reste constante pour la durée de vie de la transaction.</span></span> <span id="result_box" lang="fr"><span>Ainsi, par exemple, si une connexion à la base de données a déjà une transaction d'écriture avec une portée qui couvre simplement l'objet de stockage </span></span> <code>flyingMonkey</code> <span lang="fr"><span>, vous pouvez commencer une seconde transaction avec une portée sur les objets de stockage unicornCentaur et unicornPegasus.</span> <span>En ce qui concerne les transactions de lecture, vous pouvez en avoir plusieurs - même avec chevauchements.</span></span></p> + + <p><span id="result_box" lang="fr"><span>Les transactions doivent être de courte durée, pour que le navigateur puisse mettre fin à une transaction trop longue, afin de libérer des ressources de stockage verrouillées par cette dernière.</span> <span>Vous pouvez annuler la transaction, ce qui modifie les changements apportés à la base de données dans la transaction.</span> <span>Et vous n'avez même pas à attendre que la transaction commence ou soit active pour l'annuler.</span></span></p> + + <p>Les trois modes de transaction sont : " <code>readwrite</code> " <em>(lecture/écriture)</em>, " <code>readonly</code> " <em>(lecture seule)</em>, et " <code>versionchange</code> " <em>(changement de version)</em>. La seule manière de créer et supprimer les objets de stockage et les index est d'utiliser une transaction <a href="https://developer.mozilla.org/en-US/docs/Web/Reference/Events/versionchange_indexedDB"><code>versionchange</code></a> . Pour en apprendre plus sur les types de transactions, voir l'article de référence pour <a href="https://developer.mozilla.org/fr/docs/Web/API/API_IndexedDB" title="https://developer.mozilla.org/en/IndexedDB">IndexedDB</a>.</p> + + <p><span id="result_box" lang="fr"><span>Parce que tout se passe au sein d'une transaction, c'est un concept très important dans IndexedDB.</span> <span>Pour en savoir plus sur les transactions, en particulier sur la façon dont elles se rapportent aux versions, voir</span></span> <a href="https://developer.mozilla.org/fr/docs/Web/API/IDBTransaction"> IDBTransaction</a>, <span class="short_text" id="result_box" lang="fr"><span>qui a également une documentation de référence</span></span> . Pour la documentation sur l'API synchrone, voir <a href="https://developer.mozilla.org/fr/docs/Web/API/IDBTransactionSync" rel="internal">IDBTransactionSync</a>.</p> + </dd> + <dt><a name="gloss_request">request <em>(requêtes)</em></a></dt> + <dd><span id="result_box" lang="fr"><span>L'opération par laquelle la lecture et l'écriture sur une base de données est effectuée.</span> <span>Chaque requête représente une opération de lecture ou d'écriture.</span></span></dd> + <dt><a name="gloss_index">index</a></dt> + <dd> + <p><span id="result_box" lang="fr"><span>Un index est un objet de stockage spécialisé pour rechercher des enregistrements dans un autre objet de stockage appelé "</span></span> <em>referenced object store"</em> <em>(objet de stockage référencé)</em><span lang="fr"><span>.</span> <span>L'index est un stockage persistant de key-value <em>(clé-valeur)</em> dans lequel la partie "value" des enregistrements contient la partie "key" d'un enregistrement de l'objet de stockage référencé.</span> <span>Les enregistrements dans un index sont automatiquement remplis chaque fois que ceux de l'objet référencé sont insérés, mis à jour ou supprimés.</span> <span>Chaque enregistrement d'un index ne peut indiquer qu'un seul enregistrement dans son objet référencé, mais plusieurs index peuvent référencer le même objet.</span> <span>Lorsque l'objet référencé change, tous les index qui s'y réfèrent sont mis à jour automatiquement.</span></span></p> + + <p><span id="result_box" lang="fr"><span>Vous pouvez également rechercher des enregistrements dans un objet de stockage en utilisant la</span></span> <a href="#gloss_key">clé</a><em>.</em></p> + + <p>Pour en apprendre plus sur l'utilisation des index, voir <a href="/en/IndexedDB/Using_IndexedDB#Using_an_index" title="en/IndexedDB/Using_IndexedDB#Using_an_index">Using IndexedDB</a>. Pour la documentation de référence sur l'index, voir <a href="../../../../en/IndexedDB/IDBKeyRange" rel="internal">IDBKeyRange</a>.</p> + </dd> +</dl> + +<h3 id="key" name="key">Key and value <em>(clé et valeur)</em></h3> + +<dl> + <dt><a name="gloss_key">key <em>(clé)</em></a></dt> + <dd> + <p><span id="result_box" lang="fr"><span>Une valeur de données par laquelle les valeurs stockées sont organisées et récupérées dans l'objet de stockage .</span> <span>Celui-ci peut obtenir la clé de l'une des trois sources : un générateur de clés, un chemin de clé et une valeur explicitement spécifiée.</span> <span>La clé doit être d'un type de données qui a un nombre supérieur au précédent.</span> <span>Chaque enregistrement doit avoir une clé unique dans l'objet de stockage, de sorte que celui-ci ne peut comporter plusieurs enregistrements avec la même clé.</span></span></p> + + <p><span class="short_text" id="result_box" lang="fr"><span>Une clé peut être de l'un des types suivants</span></span> : <a href="https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/String" title="https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String">string</a> <em>(chaîne de caractères)</em>, <a href="https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Date" title="en/JavaScript/Reference/Global Objects/Date">date</a>, float <em>(flottante)</em>, binary blob <em>(blob binaire)</em> et <a href="https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Array" title="en/JavaScript/Reference/Global Objects/Array">array</a> <em>(tableau)</em>. Pour les tableaux, <span class="short_text" id="result_box" lang="fr"><span>la valeur de la clé peut être comprise entre vide et l'infini</span></span>. Et vous pouvez inclure un tableau dans un tableau.</p> + + <p>Vous pouvez également rechercher des enregistrements dans un objet de stockage en utilisant l'<em><a href="#gloss_index">index</a>.</em></p> + </dd> + <dt><a name="gloss_keygenerator">key generator<em> (générateur de clé)</em></a></dt> + <dd>Un mécanisme pour produire de nouvelles clés dans une séquence ordonnée. Si un objet de stockage n'a pas de générateur de clé, l'application doit fournir les clés des enregistrements stockés. Les générateurs ne sont pas partagés entre les objets de stockage. <span id="result_box" lang="fr"><span>Il s'agit d'un détail concernant les navigateurs, car dans le développement web, vous ne créez pas réellement ou ne gérez pas les accès aux générateurs de clés.</span></span></dd> + <dt><a name="gloss_inline_key">in-line key <em>(clé en ligne)</em></a></dt> + <dd>Une clé qui est stockée comme partie d'une valeur de stockage. Elle est trouvée en utilisant "<em>key path" (chemin de clé)</em>. Une clé en ligne peut être créée par un générateur. Une fois la clé générée, elle peut être stockée dans la valeur utilisant le "key path" ou être utilisée comme clé.</dd> + <dt><a name="gloss_outofline_key">out-of-line key <em>(clé hors ligne)</em></a></dt> + <dd>Une clé stockée séparément de la valeur stockée.</dd> + <dt><a name="gloss_keypath">key path <em>(chemin de clé)</em></a></dt> + <dd><span id="result_box" lang="fr"><span>Définit où le navigateur doit extraire la clé d'une valeur dans l'objet de stockage ou l'index.</span> <span>Un chemin de clé valide peut inclure l'un des éléments suivants : une chaîne vide, un identifiant JavaScript ou plusieurs identifiants JavaScript séparés par des périodes, ou un tableau contenant ces éléments.</span> <span>Il ne peut pas inclure d'espaces.</span></span></dd> + <dt><a name="gloss_value">value <em>(valeur)</em></a></dt> + <dd> + <p><span id="result_box" lang="fr"><span>Chaque enregistrement a une valeur, qui peut inclure tout ce qui peut être exprimé en JavaScript, y compris</span></span> : <a href="https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Boolean" rel="internal" title="en/JavaScript/Reference/Global_Objects/Boolean">boolean</a> <em>(bouléen)</em>, <a href="https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Number" rel="internal" title="en/JavaScript/Reference/Global_Objects/Number">number</a><em> (nombre)</em>, <a href="https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/String" title="https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String">string</a> <em>(chaîne de caractères)</em>, <a href="https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Date" title="en/JavaScript/Reference/Global Objects/Date">date</a>, <a href="https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Object" title="en/JavaScript/Reference/Global Objects/Object">object</a> <em>(objet)</em>, <a href="https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Array" title="en/JavaScript/Reference/Global Objects/Array">array</a> <em>(tableau)</em>, <a href="https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/RegExp" rel="internal" title="en/JavaScript/Reference/Global_Objects/RegExp">regexp</a>, <a href="https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/undefined" title="en/JavaScript/Reference/Global_Objects/undefined">undefined</a> <em>(indéfini)</em>, and null <em>(nul)</em>.</p> + + <p>Quand un objet ou un tableau est stocké, les propriétés et valeurs dans cet objet ou ce tableau peuvent aussi être toute valeur valide.</p> + + <p><a href="https://developer.mozilla.org/fr/docs/Web/API/Blob" title="en/DOM/Blob">Blobs</a> et fichiers peuvent être stockés, voir <a class="external external-icon" href="http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html">specification</a> {{ fx_minversion_inline("11") }}.</p> + </dd> +</dl> + +<h3 id="range" name="range">Intervalle et portée</h3> + +<dl> + <dt><a name="gloss_scope">scope (<em>portée ou étendue</em>)</a></dt> + <dd><span id="result_box" lang="fr"><span>L'ensemble des objets de stockage et index auxquels s'applique une transaction.</span> <span>Les portées des transactions en lecture seule peuvent se chevaucher et s'exécuter en même temps.</span> <span>Par contre, les portées des transactions d'écriture ne peuvent pas se chevaucher.</span> <span>Vous pouvez toujours démarrer plusieurs transactions avec la même portée en même temps, mais elles entrent dans une file d'attente et s'exécutent l'une après l'autre.</span></span></dd> + <dt><a name="gloss_cursor">cursor <em>(curseur)</em></a></dt> + <dd>Un mécanisme <span id="result_box" lang="fr"><span>pour l'itération de plusieurs enregistrements avec une </span></span> <em>"key range"</em> <span lang="fr"><span><em>(intervalle de clés</em>).</span> <span>Le curseur possède une source qui indique quel index ou objet stocké est itéré.</span> <span>Il a une position dans l'intervalle et se déplace dans une direction qui augmente ou diminue dans l'ordre des clés d'enregistrement.</span> <span>Pour la documentation de référence sur les curseurs, voir</span></span> <a href="https://developer.mozilla.org/fr/docs/Web/API/IDBCursor" rel="internal">IDBCursor</a> ou <a href="https://developer.mozilla.org/fr/docs/Web/API/IDBCursorSync" rel="internal">IDBCursorSync</a>.</dd> + <dt><a name="gloss_key_range">key range <em>(intervalle de clés)</em></a></dt> + <dd> + <p><span id="result_box" lang="fr"><span>Un intervalle continu sur un type de données utilisé pour les clés.</span> <span>Les enregistrements peuvent être récupérés à partir des objets de stockage et des index à l'aide de touches ou d'un intervalle de clés.</span> <span>Vous pouvez limiter ou filtrer l'intervalle en utilisant les limites inférieures et supérieures.</span> <span>Par exemple, vous pouvez itérer sur toutes les valeurs d'une clé entre x et y.</span></span></p> + + <p>Pour la documentation de référence sur "key range", voir <a href="https://developer.mozilla.org/fr/docs/Web/API/IDBKeyRange" rel="internal">IDBKeyRange</a>.</p> + </dd> +</dl> + +<h2 id="limitations" name="limitations">Limitations</h2> + +<p>IndexedDB <span id="result_box" lang="fr"><span>est conçu pour couvrir la plupart des cas qui nécessitent un stockage côté client.</span> <span>Cependant, il n'est pas adapté pour quelques cas comme les suivants :</span></span></p> + +<ul> + <li><span id="result_box" lang="fr"><span>Tri par classement international .</span> <span>Toutes les langues ne trient pas les chaînes de la même manière, de sorte que le classement ne peut être internationalisé.</span> <span>Bien que la base de données ne puisse pas stocker des données dans un ordre spécifiquement international, vous pouvez trier les données que vous avez déjà lues sur votre base de données.</span> <span>Notez, cependant, que le </span></span><a href="https://developer.mozilla.org/fr/docs/Web/API/API_IndexedDB/Using_IndexedDB#Locale-aware_sorting">locale-aware sorting</a> <span lang="fr"><span> a été autorisée avec un indicateur expérimental activé (actuellement pour Firefox uniquement) depuis Firefox 43.</span></span></li> + <li><span id="result_box" lang="fr"><span>Synchronisation .</span> <span>L'API n'est pas conçue pour prendre en charge la synchronisation avec une base de données côté serveur.</span> <span>Vous devez écrire un code qui synchronise une base de données indexedDB côté client avec une base de données côté serveur.</span></span></li> + <li><span id="result_box" lang="fr"><span>Recherche de texte intégral .</span> <span>L'API n'a pas d'équivalent à l'opérateur </span></span> <span style="direction: ltr;"><code>LIKE</code></span> <span lang="fr"><span> en SQL.</span></span></li> +</ul> + +<p><span id="result_box" lang="fr"><span>En outre, sachez que les navigateurs peuvent effacer la base de données, comme dans les conditions suivantes</span></span> :</p> + +<ul> + <li><span id="result_box" lang="fr"><span>L'utilisateur demande un effacement.</span> <span>De nombreux navigateurs ont des paramètres qui permettent aux utilisateurs d'effacer toutes les données stockées pour un site Web donné, y compris les cookies, les signets, les mots de passe stockés et les données IndexedDB.</span></span></li> + <li><span id="result_box" lang="fr"><span>Le navigateur est en mode de navigation privée.</span> <span>Certains navigateurs ont des modes "navigation privée" (Firefox) ou "incognito" (Chrome).</span> <span>À la fin de la session, le navigateur efface la base de données.</span></span></li> + <li><span class="short_text" id="result_box" lang="fr"><span>La limite de disque ou de quota a été atteinte.</span></span></li> + <li>Les données sont corrompues.</li> + <li><span id="result_box" lang="fr"><span>Un changement incompatible est apporté à la fonctionnalité.</span></span></li> +</ul> + +<p><span id="result_box" lang="fr"><span>Les circonstances exactes et les capacités du navigateur changent au fil du temps, mais la philosophie générale des fournisseurs de navigateurs est de faire les efforts nécessaires pour conserver les données lorsque c'est possible.</span></span></p> + +<h2 id="next" name="next">Étape suivante</h2> + +<p><span id="result_box" lang="fr"><span>Avec ces grands concepts dans nos poches, nous pouvons obtenir des choses plus concrètes.</span> <span>Pour un tutoriel sur l'utilisation de l'API, voir</span></span> <a href="https://developer.mozilla.org/fr/docs/Web/API/API_IndexedDB/Using_IndexedDB"> Using IndexedDB</a>.</p> + +<h2 id="Voir_aussi">Voir aussi</h2> + +<p>Spécification</p> + +<ul> + <li><a href="http://www.w3.org/TR/IndexedDB/" title="http://www.w3.org/TR/IndexedDB/"><span style="direction: ltr;">Indexed Database API Specification</span></a></li> +</ul> + +<p>Référence</p> + +<ul> + <li><a href="https://developer.mozilla.org/fr/docs/Web/API/API_IndexedDB" title="https://developer.mozilla.org/en/IndexedDB">IndexedDB API Reference</a></li> +</ul> + +<p>Tutoriels</p> + +<ul> + <li><a href="https://developer.mozilla.org/fr/docs/Web/API/API_IndexedDB/Using_IndexedDB">Using IndexedDB</a></li> +</ul> + +<p>Article connexe</p> + +<ul> + <li><a class="external" href="http://msdn.microsoft.com/en-us/scriptjunkie/gg679063.aspx" title="http://msdn.microsoft.com/en-us/scriptjunkie/gg679063.aspx">IndexedDB — The Store in Your Browser</a></li> +</ul> diff --git a/files/fr/web/api/indexeddb_api/browser_storage_limits_and_eviction_criteria/index.html b/files/fr/web/api/indexeddb_api/browser_storage_limits_and_eviction_criteria/index.html new file mode 100644 index 0000000000..bfa95657cc --- /dev/null +++ b/files/fr/web/api/indexeddb_api/browser_storage_limits_and_eviction_criteria/index.html @@ -0,0 +1,139 @@ +--- +title: Limites de stockage du navigateur et critères d'éviction +slug: Web/API/API_IndexedDB/Browser_storage_limits_and_eviction_criteria +tags: + - Base de données + - IndexedDB + - LRU + - Limites + - Stockage + - eviction +translation_of: Web/API/IndexedDB_API/Browser_storage_limits_and_eviction_criteria +--- +<div>{{DefaultAPISidebar("IndexedDB")}}</div> + +<div class="note"> +<p>Il existe un certain nombre de technologies Web qui stockent des données d'un type ou d'un autre du côté client (c'est-à-dire sur le disque local). Le processus par lequel le navigateur calcule l'espace alloué au stockage de données Web et les données à supprimer quand la limite est atteinte n'est pas simple et diffère d'un navigateur à l'autre. Cet article tente d'expliquer comment tout cela fonctionne.</p> +</div> + +<div class="note"> +<p><strong>Note </strong>: Les informations ci-dessous devraient être assez précises pour la plupart des navigateurs modernes, mais les spécificités du navigateur sont évoquées quand elles sont connues. Opera et Chrome devraient se comporter de la même manière dans tous les cas. Mais <a href="http://www.opera.com/mobile/mini">Opera Mini</a> (encore basé sur presto du côté serveur) ne stocke aucune donnée sur le client.</p> +</div> + +<h2 id="Les_différents_types_de_stockage_des_données">Les différents types de stockage des données</h2> + +<p>Même dans le même navigateur, en utilisant la même méthode de stockage, il existe différentes classes de stockage de données à comprendre. Cette section traite des différents types que vous pouvez trouver dans différents navigateurs.</p> + +<p>Généralement, les deux principaux types de stockage sont les suivants :</p> + +<ul> + <li>Persistant : ce sont des données qui doivent être conservées pendant une longue période. Elles ne seront évincéés que si l'utilisateur le choisit (par exemple, dans Firefox, il existe un bouton "nettoyer stockage" dans la boîte de dialogue d'informations sur la page pour chaque page).</li> + <li>Temporaire : il s'agit de données qui n'ont pas besoin de persister très longtemps. Elles seront évacuées en-dessous d'un minimum d'utilisation ({{anch("LRU policy")}}) lorsque les limites de stockage sont atteintes.</li> +</ul> + +<p>Par défaut, le stockage temporaire sera utilisé dans la plupart des contextes d'utilisation (par exemple, des applications Web standard) et le persistant pour les applications installées (par exemple, les applications Firefox installées sur le système d'exploitation Firefox OS / Firefox de bureau, les applications Chrome).</p> + +<h3 id="Spécificités_de_Firefox">Spécificités de Firefox</h3> + +<p>Dans Firefox, vous pouvez choisir le type de stockage que vous souhaitez utiliser en incluant une option propriétaire — <code>storage</code> — lorsque vous créez une base de données IndexedDB en utilisant {{domxref ("IDBFactory.open ()", "open ()")}} :</p> + +<ul> + <li> + <pre class="brush: js"><code>var request = indexedDB.open("myDatabase", { version: 1, storage: "persistent" });</code></pre> + </li> + <li> + <pre class="brush: js"><code>var request = indexedDB.open("myDatabase", { version: 1, storage: "temporary" });</code></pre> + </li> +</ul> + +<p>Dans Firefox, quand le stockage persistant est choisi, l'utilisateur reçoit une fenêtre de dialogue d'interface utilisateur pour l'avertir que ces données persisteront et lui demander s'il en est satisfait.</p> + +<p>Les données de stockage temporaire ne provoquent aucune fenêtre de dialogue vers l'utilisateur, mais il y a des {{anch("Limites de stockage")}}.</p> + +<h3 id="Default_storage_dans_Firefox_(stockage_par_défaut)">"Default storage" dans Firefox <em>(stockage par défaut)</em></h3> + +<p>C'est le troisième type de stockage à envisager dans Firefox — "Default storage" <em>(stockage par défaut)</em>. C'est une option par défaut, utilisée quand vous ne spécifiez pas le paramètre <code>storage</code> vu ci-dessus. Les données du stockage par défaut se comportent différemment selon les circonstances : assimilées aux données d'un stockage persistant pour les applications installées de Firefox OS, ou d'un stockage temporaire pour tout autre type d'utilisation.</p> + +<h2 id="Où_sont_stockées_les_données">Où sont stockées les données ?</h2> + +<p>Chaque type de stockage représente un référentiel distinct, voici la cartographie réelle des répertoires sous le profil Firefox d'un utilisateur (d'autres navigateurs peuvent différer légèrement) :</p> + +<ul> + <li><code><profile>/storage</code> — le principal, le plus haut niveau de répertoire pour le stockage maintenu par le " quota manager " <em>(manager de quotas)</em> (voir ci-dessous).</li> + <li><code><profile>/storage/permanent</code> — répertoire de stockage des données persistantes.</li> + <li><code><profile>/storage/temporary</code> — répertoire de stockage des données temporaires.</li> + <li><code><profile>/storage/default</code> — répertoire de stockage des données par défaut.</li> +</ul> + +<div class="note"> +<p><strong>Note :</strong> Depuis l'introduction de l' <a href="https://developer.mozilla.org/en-US/docs/Web/API/Storage_API">API Storage</a> , le dossier "permanent" peut être considéré comme obsolète, il n'est plus utilisé que pour les bases de données de type persistant IndexedDB. Peu importe le mode, "best-effort"<em> (meilleur effort)</em> ou "persistant", les données sont stockées sous <code><profile>/storage/default</code>.</p> +</div> + +<div class="note"> +<p><strong>Note</strong>: Dans Firefox, vous pouvez trouver votre dossier profil en entrant : <code>support</code> dans la barre d'URL et en appuyant sur le bouton <em>Show in..</em>. <em>(</em><em>Afficher dans ...)</em> (par exemple, <em>"Show in Finder"</em> sur Mac OS X) à côté du titre <em>"Profile Folder" (</em><em>dossier de profil)</em> .</p> +</div> + +<div class="note"> +<p><strong>Note</strong>: Si vous regardez dans votre profil les répertoires de données stockées, vous pouvez voir un quatrième dossier : <code>persistent</code> . À la base, le dossier <code>persistent</code> a été renommé <code>permanent,</code> il y a quelques temps, pour faciliter les mises à niveau / migrations.</p> +</div> + +<div class="note"> +<p><strong>Note</strong>: Les utilisateurs ne doivent pas ajouter leurs propres répertoires ou fichiers sous <code><profile>/storage</code> . Cela entraînerait l'échec de l'initialisation du stockage ; par exemple {{domxref ("IDBFactory.open ()", "open ()")}} déclencherait un événement d'erreur.</p> +</div> + +<h2 id="Limites_de_stockage">Limites de stockage</h2> + +<p>L'espace de stockage maximal du navigateur est dynamique — il est basé sur la taille de votre disque dur. La limite globale est calculée sur la base de 50% de l'espace disque libre. Dans Firefox, un outil interne du navigateur appelé " Quota Manager " <em>(gestionnaire de quotas)</em> surveille la quantité d'espace disque utilisée par chaque origine et supprime les données si nécessaire.</p> + +<p>Donc, si votre disque dur est de 500 Go, le stockage total d'un navigateur est de 250 Go. S'il est dépassé, une procédure appelée <strong>"origin eviction"</strong> <em>(</em><em>éviction d'origine)</em> entre en jeu, en supprimant la valeur totale de l'origine jusqu'à ramener le niveau de stockage en-dessous de la limite. La suppression d'une base de données d'origine peut entraîner des problèmes d'incohérence.</p> + +<p>Il y a aussi une autre limite appelée <strong>group limit</strong> — ceci est défini comme 20% de la limite globale. Chaque origine fait partie d'un groupe (groupe d'origines). Il existe un groupe pour chaque domaine eTLD + 1.</p> + +<p>Par exemple :</p> + +<ul> + <li><code>mozilla.org</code> — groupe1, origine1</li> + <li><code>www.mozilla.org</code> — groupe1, origine2</li> + <li><code>joe.blogs.mozilla.org</code> — groupe1, origine3</li> + <li><code>firefox.com</code> — groupe2, origine4</li> +</ul> + +<p>Ces groupes, <code>mozilla.org</code>, <code>www.mozilla.org</code>, et <code>joe.blogs.mozilla.org</code> peuvent utiliser globalement un maximum de 20% de la limite globale. <code>firefox.com</code> a un maximum distinct de 20%.</p> + +<p>Les deux limites reagissent différemment quand la limite est atteinte :</p> + +<ul> + <li>La limite de groupe est également appelée «limite dure»: elle ne déclenche pas l'éviction d'origine.</li> + <li>La limite globale est une «limite douce» car il est possible que certains espaces soient libérés et que l'opération puisse se poursuivre.</li> +</ul> + +<div class="note"> +<p><strong>Note</strong>: Si la limite de groupe est dépassée, ou si l'éviction d'origine ne crée pas assez d'espace libre, le navigateur lance <code>QuotaExceededError</code>.</p> +</div> + +<h2 id="Politique_LRU">Politique LRU</h2> + +<p>Lorsque l'espace disque disponible est rempli, le gestionnaire de quotas commence à effacer les données sur la base de la politique LRU — l'origine la moins utilisée sera d'abord supprimée, puis la suivante, jusqu'à ce que le navigateur ne dépasse plus la limite.</p> + +<p>Nous traçons le "dernier temps d'accès" pour chaque origine utilisant le stockage temporaire. Une fois que la limite globale du stockage temporaire est atteinte, nous essayons de trouver toutes les origines actuellement inutilisées (c'est-à-dire, sans onglets ou applications ouverts qui conservent des bases de données ouvertes). Celles-ci sont ensuite triées sur le dernier accès. Les origines les moins récemment utilisées sont ensuite supprimées jusqu'à ce qu'il y ait suffisamment d'espace pour répondre à la demande qui a déclenché cette éviction d'origine.</p> + +<h2 id="Quelles_technologies_utilisent_le_stockage_de_données_du_navigateur">Quelles technologies utilisent le stockage de données du navigateur ?</h2> + +<p>Dans Firefox, les technologies suivantes utilisent le stockage de données du navigateur pour stocker des données au besoin. Nous les qualifions de "quota clients" dans ce contexte :</p> + +<ul> + <li><a href="https://developer.mozilla.org/fr/docs/Web/API/API_IndexedDB">IndexedDB</a></li> + <li><a href="http://asmjs.org/">asm.js</a> caching</li> + <li><a href="/fr/docs/Web/API/Cache">Cache API</a></li> +</ul> + +<p>Le «dernier temps d'accès» des origines est mis à jour lorsque l'un de ces éléments est activé / désactivé. L'éviction d'origine supprimera les données pour tous ces "quota clients".</p> + +<p>Dans Chrome / Opera, l'API " Quota Management" gère les quotas pour <a href="/en-US/docs/Web/HTML/Using_the_application_cache">AppCache</a>, <a href="/en-US/docs/Web/API/IndexedDB_API">IndexedDB</a>, WebSQL et <a href="/en-US/docs/Web/API/File_System_API">File System API</a>.</p> + +<h2 id="Voir_aussi">Voir aussi</h2> + +<ul> + <li><a href="http://www.html5rocks.com/en/tutorials/offline/quota-research/">Working with quota on mobile browsers</a>, de<a href="http://blog.agektmr.com" title="Eiji Kitamura"> Eiji Kitamura.</a> Une analyse détaillée du stockage côté client sur les navigateurs mobiles.</li> + <li><a href="https://developers.google.com/web/updates/2011/11/Quota-Management-API-Fast-Facts">Quota Management API : Fast Facts</a>, de<a href="http://blog.agektmr.com" title="Eiji Kitamura"> Eiji Kitamura.</a> Un regard sur l'API Quota Management dans Chrome / Blink (qui devrait également inclure Opera aussi.)</li> +</ul> diff --git a/files/fr/web/api/indexeddb_api/index.html b/files/fr/web/api/indexeddb_api/index.html new file mode 100644 index 0000000000..682043df0e --- /dev/null +++ b/files/fr/web/api/indexeddb_api/index.html @@ -0,0 +1,322 @@ +--- +title: IndexedDB +slug: Web/API/API_IndexedDB +tags: + - API + - Avancé + - Bases de données + - IndexedDB + - Stockage +translation_of: Web/API/IndexedDB_API +--- +<p>{{DefaultAPISidebar("IndexedDB")}}</p> + +<p>IndexedDB est une API de bas niveau qui permet le stockage côté client de quantités importantes de données structurées, incluant des fichiers/blobs. Cette API utilise des index afin de permettre des recherches performantes sur ces données. Alors que <a href="/fr/docs/Web/API/Web_Storage_API">Web Storage</a> est utile pour stocker de petites quantités de données, il est moins utile pour stocker de grandes quantités de données structurées. IndexedDB fournit une solution. Cette page est le point d'entrée pour tout ce qui concerne IndexedDB sur MDN - vous y trouverez les liens vers la référence complète de l'API et les guides d'utilisation, le support par les navigateurs, et quelques explications des concepts clés.</p> + +<p>{{AvailableInWorkers}}</p> + +<div class="note"> +<p><strong>Note</strong>: l'API IndexedDB est puissante, mais elle peut sembler trop compliquée dans les cas simples. Si vous préferez une API plus simple, essayez des librairies comme <a href="https://localforage.github.io/localForage/">localForage</a>, <a href="http://www.dexie.org/">dexie.js</a>, <a href="https://github.com/erikolson186/zangodb">ZangoDB</a>, <a href="https://pouchdb.com/">PouchDB</a>, <a href="https://www.npmjs.com/package/idb">idb</a>, <a href="https://www.npmjs.com/package/idb-keyval">idb-keyval</a>, <a href="http://jsstore.net/">JsStore</a> et <a href="https://github.com/google/lovefield">lovefield</a> qui offrent de nombreux avantages aux développeurs de IndexedDB.</p> +</div> + +<h2 id="Concepts_clés_et_utilisation">Concepts clés et utilisation</h2> + +<p>IndexedDB est un système de gestion de base de données transactionnel, similaire à un SGBD relationnel basé sur SQL. Cependant contrairement aux SGBD relationnels, qui utilisent des tables avec des colonnes fixes, IndexedDB est une base de données orientée objet basée sur JavaScript. <span style="line-height: 1.5;">IndexedDB vous permet de stocker et de récupérer des objets qui sont indexés avec une </span><strong style="line-height: 1.5;">clef</strong><span style="line-height: 1.5;">; tout objet supporté par </span><a href="https://developer.mozilla.org/fr/docs/Web/API/Web_Workers_API/algorithme_clonage_structure">l'algorithme de clônage structuré</a><span style="line-height: 1.5;"> peut être stocké. </span><span style="line-height: 1.5;">Vous devez spécifier le schéma de la base de données, ouvrir une connexion à votre base de données, puis récupérer et mettre à jour des données dans une série de </span><strong style="line-height: 1.5;">transactions</strong><span style="line-height: 1.5;">.</span></p> + +<ul> + <li><span style="line-height: 1.5;">Plus d'informations sur les <a href="/fr/docs/IndexedDB/Basic_Concepts_Behind_IndexedDB">concepts derrière IndexedDB</a>.</span></li> + <li><span style="line-height: 1.5;">Apprenez à utiliser IndexedDB de manière asynchrone à partir des principes fondamentaux grâce à notre guide <a href="/fr/docs/IndexedDB/Using_IndexedDB">Utiliser IndexedDB</a>.</span></li> + <li><span style="line-height: 1.5;">Combinez IndexedDB pour le stockage des données en mode déconnecté avec les Service Workers pour stocker des assets en mode déconnecté, comme précisé dans <a href="/fr/docs/Web/Progressive_web_apps/Offline_Service_workers">Faire fonctionner les PWAs en mode déconnecté grâce aux Service workers</a></span><span style="line-height: 1.5;">.</span></li> +</ul> + +<div class="note"> +<p><strong>Note</strong>: Comme la plupart des solutions de stockage en ligne, IndexedDB suit la politique <a class="external" href="http://www.w3.org/Security/wiki/Same_Origin_Policy">same-origin policy</a>. Alors même que vous pouvez accèder à des données stockées au sein d'un domaine, vous ne pouvez pas accéder à des données sur plusieurs domaines.</p> +</div> + +<h3 id="Synchrone_et_asynchrone">Synchrone et asynchrone</h3> + +<p>Les opérations effectuées par IndexedDB sont réalisées de manière asynchrone, afin de ne pas bloquer l'application. IndexedDB comprend à la fois une API asynchrone et une API synchrone. L'API synchrone était à l'origine uniquement destinée pour un usage avec les <a href="/fr/docs/Utilisation_des_web_workers">Web workers</a>, mais elle a été retirée de la spécification parce qu'il était difficile de savoir si elle était nécessaire. Cependant l'API synchrone pourrait être ré-integrée si il y a une demande suffisante de la part des développeurs web.</p> + +<h3 id="Limites_de_stockage_et_critères_déviction">Limites de stockage et critères d'éviction</h3> + +<p>Il y a un certain nombre de technologies web pour stocker différents types de données côté client (par exemple sur votre disque local). IndexedDB est la plus couramment citée. Le processus par lequel le navigateur calcule combien d'espace il doit allouer aux données web, et ce qu'il doit supprimer quand la limite est atteinte, n'est pas simple et varie entre les différents navigateurs.<a href="/fr/docs/IndexedDB/Browser_storage_limits_and_eviction_criteria"> L'article "limites de stockage des navigateurs et critères d'éviction"</a> tente d'expliquer ce fonctionnement, au moins pour le cas de Firefox.</p> + +<h2 id="Interfaces">Interfaces</h2> + +<p>Pour accèder à une base de données, il faut apeller <a href="/fr/docs/Web/API/IDBFactory.open"><code>open()</code></a> sur l'attribut <a href="/fr/docs/Web/API/IDBEnvironment.indexedDB"><code>indexedDB</code></a> d'un objet <a href="/fr/docs/DOM/window">window</a>. Cette méthode retourne un objet {{domxref("IDBRequest")}}; Les opérations asynchrones communiquent avec l'application appelante en déclenchant des évènements sur les objets {{domxref("IDBRequest")}}.</p> + +<h3 id="Se_connecter_à_la_base_de_données">Se connecter à la base de données</h3> + +<dl> + <dt>{{domxref("IDBEnvironment")}}</dt> + <dd>Fournit un accès aux fonctionnalités d'IndexedDB. Implémenté par les objets {{domxref("window")}} et {{domxref("worker")}}.</dd> + <dt>{{domxref("IDBFactory")}}</dt> + <dd>Fournit un accès à la base de données.C'est l'interface implémentée par l'objet global <a href="/fr/docs/Web/API/IDBEnvironment.indexedDB"><code>indexedDB</code></a> et c'est donc le point d'entrée de l'API.</dd> + <dt>{{domxref("IDBOpenDBRequest")}}</dt> + <dd>Représente une requête d'ouverture de la base de données.</dd> + <dt>{{domxref("IDBDatabase")}}</dt> + <dd>Représente une connexion à la base de données. C'est le seul moyen d'obtenir une transaction sur la base de données.</dd> + <dt> + <h3 id="Récupérer_et_modifier_les_données">Récupérer et modifier les données</h3> + </dt> +</dl> + +<dl> + <dt>{{domxref("IDBTransaction")}}</dt> + <dd>Représente une transaction. Vous créez une transaction sur la base de données, spécifiez la portée (comme à quel magasin d'objets vous souhaitez accèder), et déterminez le type d'accès désiré (lecture seule ou lecture et écriture).</dd> + <dt>{{domxref("IDBRequest")}}</dt> + <dd>Interface générique qui récupère les requêtes à la base de données et fournit un accès aux résultats.</dd> + <dt>{{domxref("IDBObjectStore")}}</dt> + <dd>Représente un magasin d'objets qui permet l'accès à un ensemble de données d'une base de données IndexedDB, recherché par clé primaire.</dd> + <dt>{{domxref("IDBIndex")}}</dt> + <dd>Permet aussi d'accèder à un sous-ensemble de données d'une base IndexedDB mais utilise un index pour récupérer les enregistrements, au lieu d'une clé primaire. C'est parfois plus rapide qu'un usage de {{domxref("IDBObjectStore")}}.</dd> + <dt>{{domxref("IDBCursor")}}</dt> + <dd>Itérateur sur les magasins d'objets et les index.</dd> + <dt>{{domxref("IDBCursorWithValue")}}</dt> + <dd>Itérateur sur les magasins d'objets et les index et retourne la valeur courante du curseur.</dd> + <dt>{{domxref("IDBKeyRange")}}</dt> + <dd>Définit une portée de valeurs qui peut être utilisée pour récupérer des données de la base de données dans une certaine portée.</dd> + <dt>{{domxref("IDBLocaleAwareKeyRange")}} {{Non-standard_inline}}</dt> + <dd>Définit une portée de valeurs qui peut être utilisée pour récupérer des données de la base de données dans une certaine portée, triées en fonction des règles de la localisation spécifiée pour un certain index (voir <a href="/fr/docs/Web/API/IDBObjectStore/createIndex#Parameters"><code>createIndex()</code>'s optionalParameters</a>).</dd> +</dl> + +<h3 id="Interfaces_dévénements_personnalisés">Interfaces d'événements personnalisés</h3> + +<p>Cette spécification provoque des évènements avec les interfaces personnalisées suivantes:</p> + +<dl> + <dt>{{domxref("IDBVersionChangeEvent")}}</dt> + <dd><code>L'interface IDBVersionChangeEvent</code> indique que la version de la base de données à changé, résultat de la fonction de saisie d'un évènement {{domxref("IDBOpenDBRequest.onupgradeneeded")}}.</dd> +</dl> + +<h3 id="Interfaces_obsolètes">Interfaces obsolètes</h3> + +<p>Une précedente version des spécifications a défini ces interfaces, désormais supprimées. Elles sont toujours documentées dans le cas où vous avez besoin de mettre à jour du code déja écrit :</p> + +<dl> + <dt>{{domxref("IDBVersionChangeRequest")}} {{obsolete_inline}}</dt> + <dd>Représente une requête de changement de version de la base de données. Le moyen pour changer de version de la base de données a désormais changé (avec un appel de {{domxref("IDBFactory.open")}} sans aussi appeler {{domxref("IDBDatabase.setVersion")}}), et l'interface {{domxref("IDBOpenDBRequest")}} a désormais la fonction de l'ancienne (supprimée) {{domxref("IDBVersionChangeRequest")}}.</dd> + <dt>{{domxref("IDBDatabaseException")}} {{obsolete_inline}}</dt> + <dd>Représente une exception (erreur) qui peut survenir durant les opérations sur la base de données.</dd> + <dt>{{domxref("IDBTransactionSync")}} {{obsolete_inline}}</dt> + <dd>Version synchrone de {{domxref("IDBTransaction")}}.</dd> + <dt>{{domxref("IDBObjectStoreSync")}} {{obsolete_inline}}</dt> + <dd>Version synchrone de {{domxref("IDBObjectStore")}}.</dd> + <dt>{{domxref("IDBIndexSync")}} {{obsolete_inline}}</dt> + <dd>Version synchrone de {{domxref("IDBIndex")}}.</dd> + <dt>{{domxref("IDBFactorySync")}} {{obsolete_inline}}</dt> + <dd>Version synchrone de {{domxref("IDBFactory")}}.</dd> + <dt>{{domxref("IDBEnvironmentSync")}} {{obsolete_inline}}</dt> + <dd>Version synchrone de {{domxref("IDBEnvironment")}}.</dd> + <dt>{{domxref("IDBDatabaseSync")}} {{obsolete_inline}}</dt> + <dd>Version synchrone de {{domxref("IDBDatabase")}}.</dd> + <dt>{{domxref("IDBCursorSync")}} {{obsolete_inline}}</dt> + <dd>Version synchrone de {{domxref("IDBCursor")}}.</dd> +</dl> + +<h2 id="Example" name="Example">Exemples</h2> + +<ul> + <li><a class="external external-icon" href="http://marco-c.github.io/eLibri/">eLibri:</a> Une application puissante de bibliothèque et de lecteur de livres électroniques, écrit par Marco Castelluccio, gagnant du <em>DevDerby IndexedDB</em> de Mozilla.</li> + <li><a class="external external-icon" href="https://github.com/chrisdavidmills/to-do-notifications/tree/gh-pages">To-do Notifications</a> (<a class="external external-icon" href="http://mdn.github.io/to-do-notifications/">voir la démonstration en ligne</a>): L'application de référence pour les exemples de la documentation.</li> + <li><a class="external external-icon" href="http://hacks.mozilla.org/2012/02/storing-images-and-files-in-indexeddb/">Stocker des images et des fichiers dans IndexedDB</a></li> +</ul> + +<h2 id="Browser_compatibility" name="Browser_compatibility">Spécifications</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Spécification</th> + <th scope="col">Statut</th> + <th scope="col">Commentaire</th> + </tr> + <tr> + <td>{{SpecName('IndexedDB')}}</td> + <td>{{Spec2('IndexedDB')}}</td> + <td>Définition initiale</td> + </tr> + <tr> + <td>{{SpecName("IndexedDB 2")}}</td> + <td>{{Spec2("IndexedDB 2")}}</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility" name="Browser_compatibility">Compatibilité des navigateurs</h2> + +<p>{{CompatibilityTable}}</p> + +<div id="compat-desktop"> +<div id="compat-desktop"> +<div id="compat-desktop"> +<table class="compat-table"> + <tbody> + <tr> + <th>Fonctionnalité</th> + <th>Chrome</th> + <th>Edge</th> + <th>Firefox (Gecko)</th> + <th>Internet Explorer</th> + <th>Opera</th> + <th>Safari (WebKit)</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{CompatChrome(23)}}{{property_prefix("webkit")}}<br> + {{CompatChrome(24)}} (unprefixed)<br> + {{CompatChrome(38)}} (prefixes deprecated)<br> + {{CompatChrome(57)}} (prefixes removed)</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatGeckoDesktop("10.0")}} {{property_prefix("moz")}}<br> + {{CompatGeckoDesktop("16.0")}}</td> + <td>10</td> + <td>15</td> + <td> + <p>7.1, partial<br> + 10</p> + </td> + </tr> + <tr> + <td>Available in workers</td> + <td>{{CompatVersionUnknown}} (unprefixed)<br> + {{CompatChrome(38)}} (prefixes deprecated)<br> + {{CompatChrome(57)}} (prefixes removed)</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatGeckoDesktop("37.0")}}<sup>[1]</sup></td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>10</td> + </tr> + <tr> + <td>Available in privacy mode<sup>[3]</sup></td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + </tr> + <tr> + <td><code>IDBLocaleAwareKeyRange</code></td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatGeckoDesktop("43.0")}}<sup>[2]</sup></td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + </tr> + <tr> + <td>Indexed Database 2.0</td> + <td>{{CompatChrome(58)}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatOpera(45)}}</td> + <td>{{CompatUnknown}}</td> + </tr> + </tbody> +</table> +</div> + +<div id="compat-mobile"> +<table class="compat-table"> + <tbody> + <tr> + <th>Fonctionnalité</th> + <th>Android Webview</th> + <th>Chrome for Android</th> + <th>Edge</th> + <th>Firefox Mobile (Gecko)</th> + <th>Firefox OS</th> + <th>IE/Edge Phone</th> + <th>Opera Mobile</th> + <th>Safari Mobile</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{CompatVersionUnknown}} (unprefixed)<br> + {{CompatChrome(38)}} (prefixes deprecated)<br> + {{CompatChrome(57)}} (prefixes removed)</td> + <td>{{CompatVersionUnknown}} (unprefixed)<br> + {{CompatChrome(38)}} (prefixes deprecated)<br> + {{CompatChrome(57)}} (prefixes removed)</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatGeckoMobile("22.0")}}</td> + <td>1.0.1</td> + <td>10</td> + <td>{{CompatOpera(22)}}</td> + <td>8, partial<br> + 10</td> + </tr> + <tr> + <td>Available in workers</td> + <td>{{CompatVersionUnknown}} (unprefixed)<br> + {{CompatChrome(38)}} (prefixes deprecated)<br> + {{CompatChrome(57)}} (prefixes removed)</td> + <td>{{CompatVersionUnknown}} (unprefixed)<br> + {{CompatChrome(38)}} (prefixes deprecated)<br> + {{CompatChrome(57)}} (prefixes removed)</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatGeckoMobile("37.0")}}<sup>[1]</sup></td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>10</td> + </tr> + <tr> + <td>Available in privacy mode<sup>[3]</sup></td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>IDBLocaleAwareKeyRange</code></td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatGeckoMobile("43.0")}}<sup>[2]</sup></td> + <td>2.5<sup>[2]</sup></td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + </tr> + <tr> + <td>Indexed Database 2.0</td> + <td>{{CompatChrome(58)}}</td> + <td>{{CompatChrome(58)}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatOpera(45)}}</td> + <td>{{CompatUnknown}}</td> + </tr> + </tbody> +</table> +</div> +</div> +</div> + +<ul> + <li>[1] {{domxref("IDBCursorWithValue")}} n'est pas disponible dans les workers jusqu'à Gecko 42.0 {{geckoRelease("42.0")}}.</li> + <li>[2] Cette fonctions est actuellement cachée — pour l'activer et l'experimenter, aller dans about:config et activer dom.indexedDB.experimental.</li> + <li>[3] AKA "Private Browsing Mode" (Firefox) et "Incognito" (Chrome).</li> +</ul> + +<h2 id="Voir_aussi">Voir aussi</h2> + +<ul> + <li><a class="external" href="https://localforage.github.io/localForage/">localForage</a>: Un <em>Polyfill</em> fournissant une syntaxe clé-valeurs simple pour un stockage côté client; il utilise IndexedDB en arrière plan, mais se retourne d'abord sur WebSQL puis sur localStorage pour les navigateurs qui ne supportent pas IndexedDB.</li> + <li><a class="external" href="http://www.dexie.org/">dexie.js</a> : Un <em>wrapper </em>pour IndexedDB qui permet un développement plus rapide avec une syntaxe simple.</li> + <li><a class="external" href="https://github.com/erikolson186/zangodb">ZangoDB </a>: Une interface MongoDB-like pour indexedDB qui <span id="result_box" lang="fr"><span>prend en charge la plupart des fonctionnalités familières de filtrage, projection, tri, mise à jour et agrégation de MongoDB.</span></span></li> + <li><a class="external" href="http://jsstore.net/">JsStore </a>: Un contenu indexedDB avec SQL comme syntaxe.</li> + <li><a class="external" href="https://github.com/mWater/minimongo">MiniMongo</a></li> + <li><a class="external" href="https://pouchdb.com">PouchDB</a></li> +</ul> diff --git a/files/fr/web/api/indexeddb_api/using_indexeddb/index.html b/files/fr/web/api/indexeddb_api/using_indexeddb/index.html new file mode 100644 index 0000000000..a8df123888 --- /dev/null +++ b/files/fr/web/api/indexeddb_api/using_indexeddb/index.html @@ -0,0 +1,1337 @@ +--- +title: Utiliser IndexedDB +slug: Web/API/API_IndexedDB/Using_IndexedDB +tags: + - Avancé + - Base de données + - Guide + - IndexedDB + - Stockage + - Tutoriel +translation_of: Web/API/IndexedDB_API/Using_IndexedDB +--- +<p class="summary">IndexedDB est un moyen de stocker des données de manière persistante dans un navigateur. Cela vous laisse créer des applications web avec de riches possibilités de requêtes indépendamment de la disponibilité du réseau puisque vos applications peuvent fonctionner en ligne ou hors-ligne. </p> + +<h2 id="À_propos_de_ce_document">À propos de ce document</h2> + +<p>Ce tutoriel vous guide à travers l'utilisation de l'API asynchrone de IndexedDB. Si vous n'êtes pas familier avec le principe de IndexedDB, vous devriez d'abord lire <a href="/en/IndexedDB/Basic_Concepts_Behind_IndexedDB" title="en/IndexedDB/Basic Concepts Behind IndexedDB">les concepts basiques d'IndexedDB</a>.</p> + +<p>Pour la documentation de référence sur l'API d'IndexedDB, voyez l'article <a href="/en/IndexedDB" title="https://developer.mozilla.org/en/IndexedDB">IndexedDB</a> et ses sous-parties, qui détaille les types d'objets utilisés par IndexedDB, ainsi que les méthodes sur l'API asynchrone (l'API synchrone a été retirée de la spécification).</p> + +<h2 id="pattern" name="pattern">Modèle de base</h2> + +<p>Le modèle de base qu'IndexedDB utilise est le suivant :</p> + +<ol> + <li>Ouvrir une base de données.</li> + <li>Créer un objet de stockage dans la base de données. </li> + <li>Démarrer une transaction, et faire des requêtes pour faire quelques opérations sur des bases de données, comme ajouter, ou récupérer des données.</li> + <li> + <div>Attendre que l'exécution soit terminée, en écoutant le bon type d'événement DOM.</div> + </li> + <li> + <div>Faire quelque chose avec les résultats (qui peuvent être trouvés dans l'objet de la requête).</div> + </li> +</ol> + +<p>Maintenant que nous avons ces grands concepts en poche, nous pouvons voir des choses plus concrètes.</p> + +<h2 id="open" name="open">Créer et structurer l'objet de stockage</h2> + +<p><span id="result_box" lang="fr"><span>Étant donné que la spécification évolue encore, les implémentations actuelles de IndexedDB se cachent sous les préfixes du navigateur.</span> <span>Les fournisseurs de navigateurs peuvent avoir des implémentations différentes de l'API IndexedDB standard jusqu'à ce que la spécification se soit solidifiée.</span> <span>Mais une fois qu'un consensus est atteint sur la norme, les fournisseurs l'implémentent sans les balises de préfixe.</span> <span>Actuellement, certaines implémentations ont supprimé le préfixe : Internet Explorer 10, Firefox 16, Chrome 24. Lorsqu'ils utilisent un préfixe, les navigateurs basés sur Gecko utilisent le préfixe </span></span> <code>moz</code><span lang="fr"><span>, tandis que les navigateurs WebKit utilisent le préfixe </span></span> <code>webkit</code><span lang="fr"><span>.</span></span></p> + +<h3 id="Utiliser_une_version_expérimentale_dIndexedDB">Utiliser une version expérimentale d'IndexedDB</h3> + +<p>Au cas où vous souhaiteriez tester votre code dans des navigateurs qui utilisent toujours un préfixe, vous pouvez utiliser le code suivant : </p> + +<pre class="brush: js">// Sur la ligne suivante, vous devez inclure les préfixes des implémentations que vous souhaitez tester. +window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB; +// N'UTILISEZ PAS "var indexedDB = ..." si vous n'êtes pas dans une fonction. +// De plus, vous pourriez avoir besoin de réferences à des objets window.IDB*: +window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction; +window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange +// (Mozilla n'a jamais préfixé ces objets, donc nous n'avons pas besoin de window.mozIDB*)</pre> + +<p>Faites attention aux implémentations qui utilisent un préfixe ; elles peuvent être boguées, incomplètes, voire suivre une ancienne version de la spécification. Il n'est donc pas recommandé d'utiliser en production. Il serait préférable de ne pas supporter ces navigateurs :</p> + +<pre class="brush: js">if (!window.indexedDB) { + window.alert("Votre navigateur ne supporte pas une version stable d'IndexedDB. Quelques fonctionnalités ne seront pas disponibles.") +} +</pre> + +<h3 id="Ouvrir_une_base_de_données">Ouvrir une base de données</h3> + +<p>On commence l'ensemble du processus comme ceci :</p> + +<pre class="brush: js">// Ouvrons notre première base +var request = window.indexedDB.open("MyTestDatabase", 3); +</pre> + +<p>Vous avez vu ? Ouvrir une base de données est comme n'importe quelle autre opération — vous avez juste à le "demander".</p> + +<p>La requête "open" n'ouvre pas la base de données ni ne démarre une transaction aussitôt. L'appel de la fonction <code>open()</code> retourne un objet <a href="/en-US/docs/IndexedDB/IDBOpenDBRequest" title="/en-US/docs/IndexedDB/IDBOpenDBRequest"><code>IDBOpenDBRequest</code></a> avec un résultat (success) ou une valeur d'erreur qui permet de la gérer comme un évènement. La plupart des autres fonctions asynchrones dans IndexedDB fonctionnent de la même façon ; Elles retournent un objet <a href="/en-US/docs/IndexedDB/IDBRequest" title="/en-US/docs/IndexedDB/IDBRequest"><code style="font-size: 14px; color: rgb(51, 51, 51);">IDBRequest</code></a> avec le résultat ou une erreur. Le résultat de la fonction "open" est une instance de <code style="font-size: 14px; color: rgb(51, 51, 51);"><a href="/en-US/docs/IndexedDB/IDBDatabase" title="/en-US/docs/IndexedDB/IDBDatabase">IDBDatabase</a></code>.</p> + +<p>Le second paramètre de la méthode open est la version de la base de données. La version de la base détermine le schéma de celle-ci — Les objets stockés dans la base de données et leur structure. Si la base de données n'existe pas déjà, elle est créée via l'opération <code>open()</code>, puis, un événement <code>onupgradeneeded</code> est déclenché et vous créez le schéma de la base dans le gestionnaire pour cet événement. Si la base de données existe, mais que vous spécifiez un numéro de version plus élevé, un événement <code>onupgradeneeded</code> est déclenché immédiatement, vous permettant de mettre à jour le schéma dans son gestionnaire – plus d'informations dans <a href="#Updating_the_version_of_the_database">Updating the version of the database</a> plus bas et la page référence {{ domxref("IDBFactory.open") }}.</p> + +<div class="warning"> +<p><strong>Important</strong>: Le numéro de version est un nombre "<code>unsigned long long</code>" <span id="result_box" lang="fr"><span>ce qui signifie qu'il peut s'agir d'un entier très grand</span></span>. Cela veut également dire que vous ne pouvez pas utiliser de réél, sinon, il sera converti au nombre entier le plus proche (inférieur) et la transaction peut ne pas démarrer ou ne pas déclencher l'événement <code>upgradeneeded</code>. Par exemple, n'utilisez pas 2.4 comme un numéro de version :<br> + <code>var request = indexedDB.open("MyTestDatabase", 2.4); // Ne faites pas ça, même si la version sera arrondie à 2</code></p> +</div> + +<h4 id="Générer_des_gestionnaires">Générer des gestionnaires</h4> + +<p>La première chose que vous ferez avec la plupart des requêtes que vous générerez sera d'ajouter des gestionnaires de succès ou d'erreurs :</p> + +<pre class="brush: js">request.onerror = function(event) { + // Faire quelque chose avec request.errorCode ! +}; +request.onsuccess = function(event) { + // Faire quelque chose avec request.result ! +};</pre> + +<p>Laquelle de ces deux fonctions, <code>onsuccess()</code> or <code>onerror()</code>, sera appelée ? Si tout se passe bien, un évènement success (qui est un évènement DOM dont la propriété <code>type</code> est à <code>"success"</code>) est déclenché avec <code>request</code> comme cible. Une fois déclenché, la fonction <code>onsuccess()</code> de <code>request</code> est lancée avec l'évènement success comme argument. S’il y avait un quelconque problème, un évènement erreur (qui est un évènement DOM dont la propriété <code>type</code> est définie à <code>"error"</code>) est lancée dans <code>request</code>. Cela déclenche la fonction <code><code>onerror()</code></code> avec l'évènement d'erreur comme argument.</p> + +<p>L'API IndexedDB est conçue pour minimiser le recours à la gestion des erreurs, donc vous ne serez pas amené à voir beaucoup d'évènements erreurs (du moins, pas tant que vous utilisez l'API !). Cependant, dans le cas d'une ouverture de base de données, il y a quelques conditions qui génèrent des évènements d'erreurs. Le problème le plus courant est que l'utilisateur a décidé d'interdire l'accès à la création de base de données. Un des principaux objectifs d’IndexedDB est de permettre un stockage important de données pour l'utilisation hors-ligne. (Pour en savoir plus sur la capacité de stockage de chaque navigateur, voyez <a href="/en/IndexedDB#Storage_limits" title="https://developer.mozilla.org/en/IndexedDB#Storage_limits">Storage limits</a>).</p> + +<p>Évidemment, les navigateurs ne peuvent permettre qu'une publicité en ligne ou un site malicieux pollue votre ordinateur, donc ils informent l’utilisateur la première fois qu'une application web tente d'ouvrir un espace de stockage IndexedDB. L'utilisateur peut choisir de permettre ou refuser l'accès. En ce qui concerne l’utilisation d’IndexedDB en mode privé, les données restent en mémoire jusqu’à ce que la session privée soit close (Navigation privée pour Firefox et mode Incognito pour Chrome, mais dans Firefox, cela <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=781982">n'est pas encore implémenté</a> depuis novembre 2015, aussi vous ne pouvez pas utiliser IndexedDB dans le mode privé de Firefo du tout).</p> + +<p>Maintenant, en admettant qu’un utilisateur ait accepté la création d'une base, et que vous receviez un évènement "success" qui déclenche le callback <em>(rappel)</em> "success" ; que se passe-il après ? La requête a génèré un appel à <code>indexedDB.open()</code>, donc <code>request.result</code> est une instance de <code>IDBDatabase</code>, et vous voulez garder en mémoire cela pour plus tard. Votre code devrait ressembler à ceci :</p> + +<pre class="brush: js">var db; +var request = indexedDB.open("MyTestDatabase"); +request.onerror = function(event) { + alert("Pourquoi ne permettez-vous pas à ma web app d'utiliser IndexedDB?!"); +}; +request.onsuccess = function(event) { + db = event.target.result; +}; +</pre> + +<h4 id="Gérer_les_erreurs">Gérer les erreurs</h4> + +<p>Comme mentionné ci-dessus, les évènements d’erreur génèrent des info-bulles. Ils sont rattachés à la requête qui a généré l’erreur, puis la bulle de l'évènement est transmis à la transaction, et enfin à l'objet de la base de données. Si vous souhaitez éviter d'ajouter un gestionnaire d'erreurs à chaque requête, vous pouvez en ajouter un unique à l'objet de la base de donnée, de cette manière :</p> + +<pre class="brush: js">db.onerror = function(event) { + // Gestionnaire d'erreur générique pour toutes les erreurs de requêtes de cette base + alert("Database error: " + event.target.errorCode); +}; +</pre> + +<p>Une des erreurs courantes possibles lorsqu'on ouvre une base de données, c'est <code>VER_ERR</code>. Celle-ci indique que la version de la base de données stockée sur le disque est <em>supérieure </em>à la version que vous êtes en train d'essayer d'ouvrir. C'est un cas qui doit toujours être pris en considération par le gestionnaire d'erreurs.</p> + +<h3 id="Créer_ou_mettre_à_jour_une_version_de_base_de_données">Créer ou mettre à jour une version de base de données</h3> + +<p>Lorsque vous créez une nouvelle base de données, ou que vous augmentez le numéro de version d'une base existante (en spécifiant un numéro de version supérieur à celui que vous aviez auparavant, lors de {{ anch("Ouvrir une base de données") }}), l'évènement <code style="font-size: 14px; color: rgb(51, 51, 51);">onupgradeneeded</code><span style="line-height: 21px;"> sera déclenché et un objet </span><code><span style="line-height: 1.5;">IDBVersionChangeEvent</span></code> sera passé à un évènement <code>onversionchange</code> dans <code>request.result</code> (la variable <code>db</code> dans l'exemple). Dans le gestionnaire d’évènement <code>upgradeneeded</code>, vous devez créer les objets de stockage requis pour cette version de base :</p> + +<pre class="brush:js; language-js"><code class="language-js"><span class="comment token">// Cet évènement est seulement implémenté dans des navigateurs récents +</span>request<span class="punctuation token">.</span>onupgradeneeded <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span>event<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> db <span class="operator token">=</span> event<span class="punctuation token">.</span>target<span class="punctuation token">.</span>result<span class="punctuation token">;</span> + + <span class="comment token"> // Crée un </span></code>objet de stockage<code class="language-js"><span class="comment token"> pour cette base de données +</span> <span class="keyword token">var</span> objectStore <span class="operator token">=</span> db<span class="punctuation token">.</span><span class="function token">createObjectStore<span class="punctuation token">(</span></span><span class="string token">"name"</span><span class="punctuation token">,</span> <span class="punctuation token">{</span> keyPath<span class="punctuation token">:</span> <span class="string token">"myKey"</span> <span class="punctuation token">}</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="punctuation token">}</span><span class="punctuation token">;</span></code></pre> + +<p>Dans ce cas, la base de données disposera aussitôt des objets de stockage de la version précédente de la base, donc vous n’aurez pas à créer de nouveau ces objets de stockage. Vous aurez seulement besoin de créer de nouveaux objets de stockage, ou d'en supprimer de la version précédente si vous n'en avez plus besoin. Si vous avez besoin de changer un objet de stockage existant (par exemple, pour changer la <code>keyPath</code>), alors vous devez supprimer l’ancien objet de stockage et le créer à nouveau avec les nouveaux paramètres. Notez que ceci supprimera les informations dans l'objet de stockage ! Si vous avez besoin de sauvegarder ces informations, vous devez les lire et les sauvegarder quelque part avant de mettre à jour la base de données.</p> + +<p>Essayer de créer un objet de stockage avec un nom déjà existant (ou essayer de supprimer un objet de stockage avec un nom qui n'existe pas encore) renverra une erreur. </p> + +<p>Si l'évènement <code>onupgradeneeded</code> quitte avec succès, le gestionnaire <code>onsuccess</code> de la requête d'ouverture de la base de données sera déclenché. </p> + +<p>Blink/Webkit supporte la version courante de la spécification, telle que livrée dans Chrome 23+ et Opera 17+ ; IE10+ également. Les autres implémentations plus anciennes ne prennent pas en charge <code>indexedDB.open(name, version).onupgradeneeded</code>. Pour plus d'informations sur la mise à jour de version de base de données sur les anciens Webkit/Blink, référez vous à <a href="https://developer.mozilla.org/en/IndexedDB/IDBDatabase#setVersion%28%29_.0A.0ADeprecated" title="https://developer.mozilla.org/en/IndexedDB/IDBDatabase#setVersion()_.0A.0ADeprecated">IDBDatabase reference article</a>.</p> + +<h3 id="Structurer_la_base_de_données">Structurer la base de données</h3> + +<p>Maintenant, structurons la base de données. IndexedDB utilise des objets de stockage plutôt que des tableaux, et une seule base de données peut contenir un nombre quelconque d'objets de stockage. Chaque fois qu'une valeur est stockée dans un objet de stockage, elle est associée à une clé. Il y a différentes manières pour une clé d'être définie, selon que l'objet de stockage utilise un <a href="/en/IndexedDB#gloss_key_path" title="https://developer.mozilla.org/en/IndexedDB#gloss_key_path">key path</a> <em>(chemin de clé)</em> ou un <a href="/en/IndexedDB#gloss_key_generator" title="en/IndexedDB#gloss key generator">key generator</a> <em>(générateur de clé)</em>.</p> + +<p>Le tableau suivant montre les différentes manières d'attribuer des clés.</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Key Path <em>chemin de clé </em>(<code>keyPath</code>)</th> + <th scope="col">Key Generator <em>générateur de clé </em>(<code>autoIncrement</code>)</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td>Non</td> + <td>Non</td> + <td>L'objet de stockage peut contenir n'importe quel type de valeur, même des valeurs primitives comme des nombres ou des chaînes de caractères. Vous devez fournir un argument clé séparé chaque fois que vous souhaitez ajouter une nouvelle valeur.</td> + </tr> + <tr> + <td>Oui</td> + <td>Non</td> + <td>L'objet de stockage peut contenir des objets JavaScript. Les objets doivent avoir une propriété qui a le même nom que le key path.</td> + </tr> + <tr> + <td>Non</td> + <td>Oui</td> + <td>L'objet de stockage peut contenir n'importe quel type de valeur. La clé est générée pour vous automatiquement, ou vous pouvez fournir un argument clé séparé si vous voulez utiliser une clé spécifique.</td> + </tr> + <tr> + <td>Oui</td> + <td>Oui</td> + <td>L'objet de stockage peut contenir des objets JavaScript. Normalement, une clé est générée, et sa valeur est stockée dans l'objet dans une propriété avec le même nom que le key path. Cependant, si une telle propriété existe, sa valeur est utilisée en tant que clé, plutôt que la génération d'une nouvelle clé.</td> + </tr> + </tbody> +</table> + +<p>Vous pouvez aussi créer des index sur un objet de stockage, à condition que l'objet de stockage contienne des objets, et non des primitives. Un index vous permet de consulter les valeurs stockées dans un objet de stockage en utilisant la valeur d'une propriété de l'objet stocké, plutôt que la clé de l'objet.</p> + +<p>En outre, les index ont la capacité d'appliquer des contraintes simples sur les données stockées. En paramétrant l'option <code>unique</code> lorsque l'on crée un index, ce dernier fait que deux objets ne peuvent être enregistrés en ayant la même valeur pour le chemin de clé de l'index. Par exemple, si vous avez un objet de stockage qui contient un ensemble de personnes, et que vous voulez vous assurer que deux personnes n’aient pas la même adresse de courriel, vous pouvez utiliser un index avec le paramètre <code>unique</code> à <code>true</code>.</p> + +<p>Cela peut sembler confus, mais ce simple exemple devrait illustrer ces concepts. D'abord, nous définissons quelques données client à utiliser dans notre exemple :</p> + +<pre class="brush: js language-js"><code class="language-js"><span class="comment token">// Voici à quoi ressemblent nos données client. +</span><span class="keyword token">const</span> customerData <span class="operator token">=</span> <span class="punctuation token">[</span> + <span class="punctuation token">{</span> ssn<span class="punctuation token">:</span> <span class="string token">"444-44-4444"</span><span class="punctuation token">,</span> name<span class="punctuation token">:</span> <span class="string token">"Bill"</span><span class="punctuation token">,</span> age<span class="punctuation token">:</span> <span class="number token">35</span><span class="punctuation token">,</span> email<span class="punctuation token">:</span> <span class="string token">"bill@company.com"</span> <span class="punctuation token">}</span><span class="punctuation token">,</span> + <span class="punctuation token">{</span> ssn<span class="punctuation token">:</span> <span class="string token">"555-55-5555"</span><span class="punctuation token">,</span> name<span class="punctuation token">:</span> <span class="string token">"Donna"</span><span class="punctuation token">,</span> age<span class="punctuation token">:</span> <span class="number token">32</span><span class="punctuation token">,</span> email<span class="punctuation token">:</span> <span class="string token">"donna@home.org"</span> <span class="punctuation token">}</span> +<span class="punctuation token">]</span><span class="punctuation token">;</span></code></pre> + +<p>Bien sûr, vous n'utiliseriez pas le numéro de sécurité sociale comme clé primaire dans une table clients parce que tout le monde n'a pas de numéro de sécurité sociale, et vous pourriez stocker leur date de naissance au lieu de leur âge, mais laissons ces choix non pertinents pour des raisons de commodité et continuons.</p> + +<p>Maintenant, voyons la création d'une base de données pour stocker ces données :</p> + +<pre class="brush: js language-js"><code class="language-js"><span class="keyword token">const</span> dbName <span class="operator token">=</span> <span class="string token">"the_name"</span><span class="punctuation token">;</span> + +<span class="keyword token">var</span> request <span class="operator token">=</span> indexedDB<span class="punctuation token">.</span><span class="function token">open<span class="punctuation token">(</span></span>dbName<span class="punctuation token">,</span> <span class="number token">2</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + +request<span class="punctuation token">.</span>onerror <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span>event<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="comment token"> // Gestion des erreurs. +</span><span class="punctuation token">}</span><span class="punctuation token">;</span> +request<span class="punctuation token">.</span>onupgradeneeded <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span>event<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> db <span class="operator token">=</span> event<span class="punctuation token">.</span>target<span class="punctuation token">.</span>result<span class="punctuation token">;</span> + + <span class="comment token"> // Créer un objet de stockage qui contient les informations de nos clients. +</span> <span class="comment token"> // Nous allons utiliser "ssn" en tant que clé parce qu'il est garanti d'être +</span> <span class="comment token"> // unique - du moins, c'est ce qu'on en disait au lancement. +</span> <span class="keyword token">var</span> objectStore <span class="operator token">=</span> db<span class="punctuation token">.</span><span class="function token">createObjectStore<span class="punctuation token">(</span></span><span class="string token">"customers"</span><span class="punctuation token">,</span> <span class="punctuation token">{</span> keyPath<span class="punctuation token">:</span> <span class="string token">"ssn"</span> <span class="punctuation token">}</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="comment token"> // Créer un index pour rechercher les clients par leur nom. Nous pourrions +</span> <span class="comment token"> // avoir des doublons (homonymes), alors on n'utilise pas d'index unique. +</span> objectStore<span class="punctuation token">.</span><span class="function token">createIndex<span class="punctuation token">(</span></span><span class="string token">"name"</span><span class="punctuation token">,</span> <span class="string token">"name"</span><span class="punctuation token">,</span> <span class="punctuation token">{</span> unique<span class="punctuation token">:</span> <span class="keyword token">false</span> <span class="punctuation token">}</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="comment token"> // Créer un index pour rechercher les clients par leur adresse courriel. Nous voulons nous +</span> <span class="comment token"> // assurer que deux clients n'auront pas la même, donc nous utilisons un index unique. +</span> objectStore<span class="punctuation token">.</span><span class="function token">createIndex<span class="punctuation token">(</span></span><span class="string token">"email"</span><span class="punctuation token">,</span> <span class="string token">"email"</span><span class="punctuation token">,</span> <span class="punctuation token">{</span> unique<span class="punctuation token">:</span> <span class="keyword token">true</span> <span class="punctuation token">}</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="comment token"> // Utiliser la transaction "oncomplete" pour être sûr que la création de l'objet de stockage +</span> <span class="comment token"> // est terminée avant d'ajouter des données dedans. +</span> objectStore<span class="punctuation token">.</span>transaction<span class="punctuation token">.</span>oncomplete <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span>event<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="comment token"> // Stocker les valeurs dans le nouvel objet de stockage. +</span> <span class="keyword token">var</span> customerObjectStore <span class="operator token">=</span> db<span class="punctuation token">.</span><span class="function token">transaction<span class="punctuation token">(</span></span><span class="string token">"customers"</span><span class="punctuation token">,</span> <span class="string token">"readwrite"</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">objectStore<span class="punctuation token">(</span></span><span class="string token">"customers"</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">for</span> <span class="punctuation token">(</span><span class="keyword token">var</span> i <span class="keyword token">in</span> customerData<span class="punctuation token">)</span> <span class="punctuation token">{</span> + customerObjectStore<span class="punctuation token">.</span><span class="function token">add<span class="punctuation token">(</span></span>customerData<span class="punctuation token">[</span>i<span class="punctuation token">]</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> + <span class="punctuation token">}</span> +<span class="punctuation token">}</span><span class="punctuation token">;</span></code></pre> + +<div>Comme indiqué précédemment, <code>onupgradeneeded</code> est le seul endroit où vous pouvez modifier la structure de la base de données. Dans cette méthode, vous pouvez créer et supprimer des objets de stockage, construire et supprimer des index.</div> + +<div></div> + +<p>Les objets de stockage sont créés avec un simple appel à <code>createObjectStore()</code>. La méthode prend le nom du stockage et un paramètre de type objet. Même si les paramètres sont optionnels, ils vous laissent définir d'importantes propriétés et redéfinir le type d'un objet de stockage que vous voulez créer. Dans notre cas, nous avons demandé un objet de stockage nommé "customers" et défini un <code>keyPath</code>, qui est la propriété rendant unique un objet individuel dans le stockage. Cette propriété dans l'exemple est "ssn" puisqu'un numéro de sécurité sociale est garanti unique. "ssn" doit être présent sur chaque objet stocké dans <code>objectStore</code>.</p> + +<p>Nous avons aussi demandé un index nommé "name" qui examine la propriété <code>name</code> dans les objets stockés. Comme avec<code> createObjectStore()</code>, <code>createIndex()</code> prend un paramètre de type objet facultatif (<code>options</code>) qui définit le type d’index à créer. Ajouter des objets qui n’auront pas de propriété <code>name</code> fonctionnera, mais ces objets n'apparaîtront pas dans l'index "name".</p> + +<p>Nous pouvons récupérer les objets client stockés, en utilisant directement leur <code>ssn</code> dans l'objet de stockage, ou en utilisant leur nom via l’index <code>name</code>. Pour en savoir plus sur ce fonctionnement, se référer à la section <a href="https://developer.mozilla.org/en/IndexedDB/Using_IndexedDB#Using_an_index" title="Using IndexedDB#Using an index">utiliser un index</a>.</p> + +<h3 id="Utiliser_le_générateur_de_clés">Utiliser le générateur de clés</h3> + +<p>Paramétrer un marqueur <code>autoIncrement</code> lorsque l'on crée un objet de stockage activera le générateur de clés pour cet objet de stockage. Par défault, ce marqueur n'est pas défini.</p> + +<p>Avec la générateur de clés, une clé sera générée automatiquement lorsque vous ajoutez une valeur dans un objet de stockage. Le compteur initial pour la génération de clés est toujours défini à 1 lorsque l'objet de stockage est créé pour la première fois. Fondamentalement, une nouvelle clé auto-générée sera incrémentée de 1 par rapport à la précédente. Le nombre courant d'un générateur de clé ne décroit jamais, à moins qu'un résultat d'opération sur la base soit annulé, par exemple, l'abandon d'une transaction sur la base. En conséquence, supprimer un enregistrement, voire l'ensemble des enregistrements d'un objet de stockage n'affecte jamais le générateur de clés d'un objet de stockage.</p> + +<p>Nous pouvons créer un autre objet de stockage avec un générateur de clés comme ci-dessous :</p> + +<pre class="brush: js language-js"><code class="language-js"><span class="comment token">// Ouverture d'indexedDB. +</span><span class="keyword token">var</span> request <span class="operator token">=</span> indexedDB<span class="punctuation token">.</span><span class="function token">open<span class="punctuation token">(</span></span>dbName<span class="punctuation token">,</span> <span class="number token">3</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + +request<span class="punctuation token">.</span>onupgradeneeded <span class="operator token">=</span> <span class="keyword token">function</span> <span class="punctuation token">(</span>event<span class="punctuation token">)</span> <span class="punctuation token">{</span> + + <span class="keyword token">var</span> db <span class="operator token">=</span> event<span class="punctuation token">.</span>target<span class="punctuation token">.</span>result<span class="punctuation token">;</span> + + <span class="comment token"> // Création d'un autre objet appelé "names" avec l'option autoIncrement définie à true. +</span> <span class="keyword token">var</span> objStore <span class="operator token">=</span> db<span class="punctuation token">.</span><span class="function token">createObjectStore<span class="punctuation token">(</span></span><span class="string token">"names"</span><span class="punctuation token">,</span> <span class="punctuation token">{</span> autoIncrement <span class="punctuation token">:</span> <span class="keyword token">true</span> <span class="punctuation token">}</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="comment token"> // Puisque l'objet "names" a un générateur de clés, la clé pour la valeur name est générée automatiquement. +</span> <span class="comment token"> // Les enregistrements ajoutés ressembleront à ceci : +</span> <span class="comment token"> // key : 1 => value : "Bill" +</span> <span class="comment token"> // key : 2 => value : "Donna" +</span> <span class="keyword token">for</span> <span class="punctuation token">(</span><span class="keyword token">var</span> i <span class="keyword token">in</span> customerData<span class="punctuation token">)</span> <span class="punctuation token">{</span> + objStore<span class="punctuation token">.</span><span class="function token">add<span class="punctuation token">(</span></span>customerData<span class="punctuation token">[</span>i<span class="punctuation token">]</span><span class="punctuation token">.</span>name<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> +<span class="punctuation token">}</span></code></pre> + +<p>Pour plus de détails sur le générateur de clés, voyez <a href="http://www.w3.org/TR/IndexedDB/#key-generator-concept">"W3C Key Generators"</a>.</p> + +<h2 id="Ajouter_récupérer_et_supprimer_des_données">Ajouter, récupérer et supprimer des données</h2> + +<p>Avant de faire quoi que ce soit avec votre nouvelle base de données, vous aurez besoin de démarrer une transaction. Les transactions viennent de l'objet base de données, et vous devez spécifier sur quel objet vous souhaitez faire pointer la transaction. Une fois dans la transaction, vous pouvez accéder à l'objet de stockage qui contient vos données et faire vos requêtes. Puis, vous devez décider si vous allez appliquer des changements à la base de données, ou si vous avez juste besoin de la lire. Les transactions disposent de trois modes disponibles: <code>readonly</code> <em>(lecture seule)</em>, <code>readwrite</code> <em>(lecture/écriture)</em>, et <code>versionchange</code> <em>(changement de version)</em>.</p> + +<p>Pour changer le "schéma" ou la structure de la base de données — qui implique de créer ou supprimer des objets de stockage ou des index — la transaction doit être en mode <code>versionchange</code>. Cette transaction est ouverte en appelant la méthode {{domxref("IDBFactory.open")}} avec une <code>version</code> spécifiée. (Dans les navigateurs WebKit, qui n'ont pas implémenté la dernière spécification, la méthode {{domxref("IDBFactory.open")}} prend seulement un paramètre, le <code>nom</code> de la base de données ; Vous devez donc appeler {{domxref("IDBVersionChangeRequest.setVersion")}} pour établir la transaction <code>versionchange</code>.)</p> + +<p>Pour lire les enregistrements d'un objet de stockage existant, la transaction peut être en mode <code>readonly</code>ou <code>readwrite</code>. Pour appliquer des changements à un objet de stockage existant, la transaction doit être en mode <code>readwrite</code>. Vous démarrez ces transactions avec {{domxref("IDBDatabase.transaction")}}. La méthode accepte deux paramètres : les <code>storeNames</code> (la portée, définie comme un tableau des objets de stockage auxquels vous souhaitez accéder) et le <code>mode</code> (<code>readonly</code> ou <code>readwrite</code>) pour la transaction. La méthode retourne un objet de transaction contenant la méthode {{domxref("IDBIndex.objectStore")}}, que vous utilisez pour accéder à votre objet de stockage. Par défaut, lorsqu'aucun mode n'est spécifié, les transactions démarrent en mode <code>readonly</code>.</p> + +<div class="note"> +<p><strong>Note</strong>: À partir de Firefox 40, les transactions IndexedDB ont des garanties de durabilité relachées afin d'augmenter les performances (voir {{Bug("1112702")}}.) Auparavant, lors d'une transaction <code>readwrite</code> {{domxref("IDBTransaction.oncomplete")}} était déclenché seulement lorsque les données étaient garanties pour une écriture sur le disque. Dans Firefox 40+ l'évènement <code>complete</code> est déclenché une fois que l'OS a autorisé l'écriture de données, mais potentiellement avant que les données soient réellement écrites sur le disque. L'évènement <code>complete</code> peut ainsi être livré plus vite qu'avant, cependant, il existe un petit risque que l'ensemble de la transaction soit perdu si l'OS s'effondre ou si un problème électrique survient avant que les données soient écrites. Comme de tels évènements catastrophiques sont rares, la plupart des utilisateurs n'ont pas à s'en soucier. Si vous devez vous assurer de la durabilité pour quelconque raison que ce soit (par exemple, vous stockez des données critiques qui ne peuvent être recalculées plus tard) vous pouvez forcer une transaction à écrire sur le disque avant que l'évènement <code>complete</code> ne soit délivré en créant une transaction utilisant un mode expérimental (non-standard) <code>readwriteflush</code> (se référer à {{domxref("IDBDatabase.transaction")}}.</p> +</div> + +<p>Vous pouvez accélérer l'accès à vos données en utilisant le bon mode et la bonne portée dans la transaction. Voici deux astuces :</p> + +<ul> + <li>Lorsque vous définissez la portée, spécifiez uniquement les objets de stockage dont vous avez besoin. De cette manière, vous pouvez exécuter plusieurs transactions simultanément sans qu'elles se chevauchent.</li> + <li>Spécifier le mode <code>readwrite</code> pour une transaction seulement lorsque c'est nécessaire. Vous pouvez exécuter simulaténement plusieurs transactions <code>readonly</code> avec chevauchements, mais vous ne pouvez avoir qu'une seule transaction <code>readwrite</code> dans un objet de stockage. Pour en savoir plus, regardez la définition des <dfn><a href="https://developer.mozilla.org/en-US/docs/IndexedDB/Basic_Concepts_Behind_IndexedDB#Database">transactions</a></dfn> dans l'article des <a href="https://developer.mozilla.org/en-US/docs/IndexedDB/Basic_Concepts_Behind_IndexedDB">concepts de base</a>.</li> +</ul> + +<h3 id="Ajouter_des_données_dans_la_base_de_données">Ajouter des données dans la base de données</h3> + +<p>Si vous venez juste de créer une base de données, alors vous souhaitez probablement écrire dedans. Voici comment ça se passe :</p> + +<pre class="brush:js; language-js"><code class="language-js"><span class="keyword token">var</span> transaction <span class="operator token">=</span> db<span class="punctuation token">.</span><span class="function token">transaction<span class="punctuation token">(</span></span><span class="punctuation token">[</span><span class="string token">"customers"</span><span class="punctuation token">]</span><span class="punctuation token">,</span> <span class="string token">"readwrite"</span><span class="punctuation token">)</span><span class="punctuation token">;</span><span class="comment token"> +// Note: Les anciennes implémentations utilisent la constante dépréciée IDBTransaction.READ_WRITE au lieu de "readwrite". +</span><span class="comment token">// Au cas où vous souhaitiez mettre en oeuvre ces implémentations, vous pouvez écrire : +</span><span class="comment token">// var transaction = db.transaction(["customers"], IDBTransaction.READ_WRITE);</span></code></pre> + +<p>La fonction <code>transaction()</code> prend deux arguments (bien que l'un d'eux soit facultatif) et retourne un objet transaction. Le premier argument est une liste d'objets de stockage que la transaction va traiter. Vous pouvez passer un tableau vide si vous voulez que la transaction traite l'ensemble des objets de stockage, mais ne le faites pas, parce que la spécification indique qu'un tableau vide devrait générer une InvalidAccessError. Si vous ne spécifiez rien pour le deuxième argument, vous démarrerez une transaction "read-only" <em>(lecture seule)</em> . Si vous souhaitez aussi écrire, vous devrez passer l'option <code>"readwrite"</code> <em>(lecture/écriture)</em>.</p> + +<p>Maintenant que vous avez une transaction, vous devez comprendre sa durée de vie. Les transactions sont étroitement liées à la boucle de l'évènement. Si vous établissez une transaction et si vous sortez de la boucle d'évènements sans l'utiliser, alors la transaction deviendra inactive. La seule manière de garder la transaction active est d'y insérer une requête. Lorsque la requête est terminée, vous obtenez un évènement DOM, et en supposant que la requête ait réussi, vous avez une autre opportunité d'étendre la transaction durant ce "callback" <em>(rappel)</em>. Si vous sortez de la boucle d'évènements sans étendre la transaction, alors elle devient inactive, etc… Tant qu'il reste des demandes en attente, la transaction reste active. La durée de vie des transactions est vraiment très simple, mais cela peut prendre un peu de temps de la maîtriser. Quelques exemples supplémentaires aideront. Si vous commencez à voir des codes d'erreur <code>TRANSACTION_INACTIVE_ERR</code>, alors vous avez raté quelque chose.</p> + +<p>Les transactions peuvent recevoir des évènements DOM de trois types : <code>error</code> <em>(erreur)</em>, <code>abort</code> <em>(abandonnée)</em> et <code>complete</code> <em>(terminée)</em>. Nous avons déjà parlé du fait que les <code>error</code> créent des bulles, ainsi une transaction peut recevoir des évènements d'erreur venant de n'importe quelle requête l'ayant généré. Un point plus subtil ici, c'est que le comportement par défaut d'une erreur est d'abandonner la transaction là où elle a eu lieu. A moins que vous gériez l’erreur en appelant d'abord <code>stopPropagation()</code> sur l’évènement erreur, puis que vous fassiez quelque chose d'autre, la transaction complète sera annulée. Cette conception vous oblige à réfléchir et gérer les erreurs, mais vous pouvez toujours ajouter un gestionnaire d'erreurs "fourre-tout" à la base de données si la gestion d'erreurs fines est trop lourde. Si vous ne gérez pas un évènement d'erreur, ou si vous appelez <code>abort()</code> sur la transaction, alors la transaction est annulée et un évènement <code>abort</code> est lancé sur la transaction. Sinon, une fois que toutes les demandes en instance sont terminées, vous recevez un évènement <code>complete</code>. Si vous faites beaucoup d'opérations sur les bases de données, alors suivre la transaction plutôt que les requêtes individuelles, peut certainement vous aider.</p> + +<p>Maintenant que vous avons une transaction, nous avons besoin de récupérer l'objet de stockage de celle-ci. Les transactions vous permettent seulement d'avoir l'objet de stockage que vous avez spécifié lors de la création de la transaction. Puis, vous pouvez ajouter toutes les données dont vous avez besoin.</p> + +<pre class="brush: js language-js"><code class="language-js"><span class="comment token">// Faire quelque chose lorsque toutes les données sont ajoutées à la base de données. +</span>transaction<span class="punctuation token">.</span>oncomplete <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span>event<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="function token">alert<span class="punctuation token">(</span></span><span class="string token">"All done!"</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="punctuation token">}</span><span class="punctuation token">;</span> + +transaction<span class="punctuation token">.</span>onerror <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span>event<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="comment token"> // N'oubliez pas de gérer les erreurs ! +</span><span class="punctuation token">}</span><span class="punctuation token">;</span> + +<span class="keyword token">var</span> objectStore <span class="operator token">=</span> transaction<span class="punctuation token">.</span><span class="function token">objectStore<span class="punctuation token">(</span></span><span class="string token">"customers"</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="keyword token">for</span> <span class="punctuation token">(</span><span class="keyword token">var</span> i <span class="keyword token">in</span> customerData<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> request <span class="operator token">=</span> objectStore<span class="punctuation token">.</span><span class="function token">add<span class="punctuation token">(</span></span>customerData<span class="punctuation token">[</span>i<span class="punctuation token">]</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + request<span class="punctuation token">.</span>onsuccess <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span>event<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="comment token"> // event.target.result == customerData[i].ssn; +</span> <span class="punctuation token">}</span><span class="punctuation token">;</span> +<span class="punctuation token">}</span></code></pre> + +<div>La méthode <code>result</code> d’une requête venant d'un appel à <code>add()</code> est la clé de la valeur qui vient d'être ajoutée. Dans ce cas, ce devrait être équivalent à la propriété <code>ssn</code> de l'objet qui vient d'être ajouté, puisque l'objet de stockage utilise la propriété <code>ssn</code> pour le key path. Notez que la fonction <code>add()</code> requiert qu'aucun objet déjà présent dans la base ait la même clé. Si vous essayez de modifier une entrée existante, ou si vous ne vous en occupez pas, vous pouvez utiliser la fonction <code>put()</code>, comme montré plus loin dans la section {{ anch("Updating an entry in the database") }}.</div> + +<div></div> + +<h3 id="Supprimer_des_données_dans_la_base_de_données">Supprimer des données dans la base de données</h3> + +<p>Supprimer des données est très similaire :</p> + +<pre class="brush: js language-js"><code class="language-js"><span class="keyword token">var</span> request <span class="operator token">=</span> db<span class="punctuation token">.</span><span class="function token">transaction<span class="punctuation token">(</span></span><span class="punctuation token">[</span><span class="string token">"customers"</span><span class="punctuation token">]</span><span class="punctuation token">,</span> <span class="string token">"readwrite"</span><span class="punctuation token">)</span> + <span class="punctuation token">.</span><span class="function token">objectStore<span class="punctuation token">(</span></span><span class="string token">"customers"</span><span class="punctuation token">)</span> + <span class="punctuation token">.</span><span class="keyword token">delete</span><span class="punctuation token">(</span><span class="string token">"444-44-4444"</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +request<span class="punctuation token">.</span>onsuccess <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span>event<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="comment token"> // c'est supprimé ! +</span><span class="punctuation token">}</span><span class="punctuation token">;</span></code></pre> + +<h3 id="Récupérer_des_données_de_la_base_de_données">Récupérer des données de la base de données</h3> + +<p>Maintenant que la base de données dispose de quelques informations, vous pouvez les récupérer de plusieurs façons. D'abord, la plus simple <code>get()</code>. Vous devez fournir une clé pour récupérer la valeur, comme ceci :</p> + +<pre class="brush: js language-js"><code class="language-js"><span class="keyword token">var</span> transaction <span class="operator token">=</span> db<span class="punctuation token">.</span><span class="function token">transaction<span class="punctuation token">(</span></span><span class="punctuation token">[</span><span class="string token">"customers"</span><span class="punctuation token">]</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="keyword token">var</span> objectStore <span class="operator token">=</span> transaction<span class="punctuation token">.</span><span class="function token">objectStore<span class="punctuation token">(</span></span><span class="string token">"customers"</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="keyword token">var</span> request <span class="operator token">=</span> objectStore<span class="punctuation token">.</span><span class="keyword token">get</span><span class="punctuation token">(</span><span class="string token">"444-44-4444"</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +request<span class="punctuation token">.</span>onerror <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span>event<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="comment token"> // gestion des erreurs! +</span><span class="punctuation token">}</span><span class="punctuation token">;</span> +request<span class="punctuation token">.</span>onsuccess <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span>event<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="comment token"> // Faire quelque chose avec request.result ! +</span> <span class="function token">alert<span class="punctuation token">(</span></span><span class="string token">"Name for SSN 444-44-4444 is "</span> <span class="operator token">+</span> request<span class="punctuation token">.</span>result<span class="punctuation token">.</span>name<span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="punctuation token">}</span><span class="punctuation token">;</span></code></pre> + +<p>Ça fait beaucoup de code pour une "simple" récupération. Voici comment le raccourcir un peu, en supposant que vous gériez les erreurs au niveau de la base de données :</p> + +<pre class="brush: js language-js"><code class="language-js">db<span class="punctuation token">.</span><span class="function token">transaction<span class="punctuation token">(</span></span><span class="string token">"customers"</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">objectStore<span class="punctuation token">(</span></span><span class="string token">"customers"</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="keyword token">get</span><span class="punctuation token">(</span><span class="string token">"444-44-4444"</span><span class="punctuation token">)</span><span class="punctuation token">.</span>onsuccess <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span>event<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="function token">alert<span class="punctuation token">(</span></span><span class="string token">"Name for SSN 444-44-4444 is "</span> <span class="operator token">+</span> event<span class="punctuation token">.</span>target<span class="punctuation token">.</span>result<span class="punctuation token">.</span>name<span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="punctuation token">}</span><span class="punctuation token">;</span></code></pre> + +<div>Vous voyez comment ça fonctionne ? Comme il n'y a qu'un seul objet de stockage, vous pouvez éviter de passer une liste d'objets dont vous avez besoin dans votre transaction, et juste passer le nom comme une chaîne de caractères. Aussi, nous faisons seulement une lecture de la base, donc nous n'avons pas besoin d'une transaction <code>"readwrite"</code>. Appeler une <code>transaction()</code> sans spécifier de mode nous donne une transaction <code>"readonly"</code>. Une autre subtilité ici est que nous n'enregistrons pas l'objet de notre requête dans une variable. Comme l’évènement DOM a la requête comme cible, vous pouvez utiliser l'évènement pour récupérer la propriété <code>result</code>.</div> + +<div></div> + +<p>Vous pouvez accélérer l’accès à vos données en limitant la portée et le mode de la transaction. Voici deux astuces :</p> + +<ul> + <li>Lors de la définition de la <a href="https://developer.mozilla.org/fr/docs/IndexedDB/Using_IndexedDB$edit#scope">scope</a> <em>(portée)</em>, spécifiez seulement l’objet de stockage dont vous avez besoin. De cette manière, vous pouvez avoir de multiples opérations simultanées sans qu’elles se chevauchent.</li> + <li>Spécifier une transaction en mode readwrite uniquement lorsque c’est nécessaire. Vous pouvez avoir de multiples opérations simultanées en lecture seule, mais vous ne pouvez avoir qu’une transaction "readwrite" <em>(lecture/écriture)</em> sur un objet de stockage. Pour en savoir plus, voir la définition relative aux <a href="https://developer.mozilla.org/en-US/docs/IndexedDB/Basic_Concepts_Behind_IndexedDB#gloss_transaction">transactions in the Basic Concepts article</a>.</li> +</ul> + +<h3 id="Mettre_à_jour_une_entrée_dans_la_base_de_données">Mettre à jour une entrée dans la base de données</h3> + +<p>Maintenant que nous avons récupéréré quelques données, les mettre à jour et en insérer est assez simple. Mettons à jour l’exemple précédent :</p> + +<pre class="brush: js language-js"><code class="language-js"><span class="keyword token">var</span> objectStore <span class="operator token">=</span> db<span class="punctuation token">.</span><span class="function token">transaction<span class="punctuation token">(</span></span><span class="punctuation token">[</span><span class="string token">"customers"</span><span class="punctuation token">]</span><span class="punctuation token">,</span> <span class="string token">"readwrite"</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">objectStore<span class="punctuation token">(</span></span><span class="string token">"customers"</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="keyword token">var</span> request <span class="operator token">=</span> objectStore<span class="punctuation token">.</span><span class="keyword token">get</span><span class="punctuation token">(</span><span class="string token">"444-44-4444"</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +request<span class="punctuation token">.</span>onerror <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span>event<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="comment token"> // Gestion des erreurs! +</span><span class="punctuation token">}</span><span class="punctuation token">;</span> +request<span class="punctuation token">.</span>onsuccess <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span>event<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="comment token"> // On récupère l'ancienne valeur que nous souhaitons mettre à jour +</span> <span class="keyword token">var</span> data <span class="operator token">=</span> request<span class="punctuation token">.</span>result<span class="punctuation token">;</span> + + <span class="comment token"> // On met à jour ce(s) valeur(s) dans l'objet +</span> data<span class="punctuation token">.</span>age <span class="operator token">=</span> <span class="number token">42</span><span class="punctuation token">;</span> + + <span class="comment token"> // Et on remet cet objet à jour dans la base +</span> <span class="keyword token">var</span> requestUpdate <span class="operator token">=</span> objectStore<span class="punctuation token">.</span><span class="function token">put<span class="punctuation token">(</span></span>data<span class="punctuation token">)</span><span class="punctuation token">;</span> + requestUpdate<span class="punctuation token">.</span>onerror <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span>event<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="comment token"> // Faire quelque chose avec l’erreur +</span> <span class="punctuation token">}</span><span class="punctuation token">;</span> + requestUpdate<span class="punctuation token">.</span>onsuccess <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span>event<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="comment token"> // Succès - la donnée est mise à jour ! +</span> <span class="punctuation token">}</span><span class="punctuation token">;</span> +<span class="punctuation token">}</span><span class="punctuation token">;</span></code></pre> + +<div>Ici, nous avons créé une variable <code>objectStore</code> et nous avons recherché un enregistrement d’un client, identifié par la valeur ssn (<code>444-44-4444</code>). Nous avons ensuite mis le résultat dans une variable (<code>data</code>), mis à jour la propriété <code>age</code> de cet objet, puis créé une deuxième requête (<code>requestUpdate</code>) pour mettre l'enregistrement du client dans l'<code>objectStore</code>, en écrasant la valeur précédente.</div> + +<div class="note"> +<p><strong>Note</strong>: dans ce cas, nous avons eu à spécifier une transaction <code>readwrite</code> puisque nous voulions écrire dans la base, et pas seulement la lire.</p> +</div> + +<h3 id="Utiliser_un_curseur">Utiliser un curseur</h3> + +<p>Utiliser <code>get()</code> nécessite de connaître la clé que vous souhaitez récupérer. Si vous voulez parcourir toutes les valeurs de l’objet de stockage, alors vous devez utiliser un curseur. Voici comment ça marche :</p> + +<pre class="brush: js language-js"><code class="language-js"><span class="keyword token">var</span> objectStore <span class="operator token">=</span> db<span class="punctuation token">.</span><span class="function token">transaction<span class="punctuation token">(</span></span><span class="string token">"customers"</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">objectStore<span class="punctuation token">(</span></span><span class="string token">"customers"</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + +objectStore<span class="punctuation token">.</span><span class="function token">openCursor<span class="punctuation token">(</span></span><span class="punctuation token">)</span><span class="punctuation token">.</span>onsuccess <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span>event<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> cursor <span class="operator token">=</span> event<span class="punctuation token">.</span>target<span class="punctuation token">.</span>result<span class="punctuation token">;</span> + <span class="keyword token">if</span> <span class="punctuation token">(</span>cursor<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="function token">alert<span class="punctuation token">(</span></span><span class="string token">"Name for SSN "</span> <span class="operator token">+</span> cursor<span class="punctuation token">.</span>key <span class="operator token">+</span> <span class="string token">" is "</span> <span class="operator token">+</span> cursor<span class="punctuation token">.</span>value<span class="punctuation token">.</span>name<span class="punctuation token">)</span><span class="punctuation token">;</span> + cursor<span class="punctuation token">.</span><span class="keyword token">continue</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> + <span class="keyword token">else</span> <span class="punctuation token">{</span> + <span class="function token">alert<span class="punctuation token">(</span></span><span class="string token">"No more entries!"</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> +<span class="punctuation token">}</span><span class="punctuation token">;</span></code></pre> + +<p>La fonction <code>openCursor()</code> prend en compte plusieurs arguments. En premier, vous pouvez spécifier une plage de résultats à récupérer en utilisant un objet "key range" que nous allons voir dans une minute. En deuxième, vous pouvez spécifier la direction vers laquelle vous souhaitez itérer. Dans l’exemple ci-dessus, nous avons itéré tous les objets dans l’ordre ascendant. Le "callback" <em>(rappel)</em> de réussite pour les curseurs est un peu spécial. L'objet cursor lui-même est le <code>result</code> <em>(résutat)</em> de la requête (au-dessus, nous utilisons le raccourci <code>event.target.result</code>). Puis la clé et valeur courante peuvent être trouvées dans les propriétés <code>key</code><em>(clé)</em> et <code>value</code> <em>(valeur)</em> de l’objet cursor. Si vous souhaitez continuer, vous devez appeler <code>continue()</code> sur le curseur. Lorsque vous avez atteint la fin des données (ou s’il n’y a plus d’entrées qui correspondent à votre requête <code>openCursor()</code> ) , vous aurez toujours votre callback success, mais la propriété <code>result</code> sera <code>undefined</code>.</p> + +<p>Une utilisation classique avec les curseurs est de récupérer tous les objets dans un objet de stockage et de les mettre dans un tableau, comme ceci :</p> + +<pre class="brush: js language-js"><code class="language-js"><span class="keyword token">var</span> customers <span class="operator token">=</span> <span class="punctuation token">[</span><span class="punctuation token">]</span><span class="punctuation token">;</span> + +objectStore<span class="punctuation token">.</span><span class="function token">openCursor<span class="punctuation token">(</span></span><span class="punctuation token">)</span><span class="punctuation token">.</span>onsuccess <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span>event<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> cursor <span class="operator token">=</span> event<span class="punctuation token">.</span>target<span class="punctuation token">.</span>result<span class="punctuation token">;</span> + <span class="keyword token">if</span> <span class="punctuation token">(</span>cursor<span class="punctuation token">)</span> <span class="punctuation token">{</span> + customers<span class="punctuation token">.</span><span class="function token">push<span class="punctuation token">(</span></span>cursor<span class="punctuation token">.</span>value<span class="punctuation token">)</span><span class="punctuation token">;</span> + cursor<span class="punctuation token">.</span><span class="keyword token">continue</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> + <span class="keyword token">else</span> <span class="punctuation token">{</span> + <span class="function token">alert<span class="punctuation token">(</span></span><span class="string token">"Got all customers: "</span> <span class="operator token">+</span> customers<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> +<span class="punctuation token">}</span><span class="punctuation token">;</span></code></pre> + +<div class="note"> +<p><strong>Note</strong>: Mozilla a aussi implémenté <code>getAll()</code> pour gérer ce cas (et <code>getAllKeys()</code>, <span class="short_text" id="result_box" lang="fr"><span>qui est actuellement caché derrière la préférence</span></span> <code>dom.indexedDB.experimental</code> dans about:config) . ceux-ci ne font pas partie d' IndexedDB standard, et peuvent disparaître dans le futur. Nous les avons inclus partceque nous pensons qu'ils sont utiles. Le code suivant fait exactement la même chose que ci-dessus :</p> + +<pre class="brush: js language-js"><code class="language-js">objectStore<span class="punctuation token">.</span><span class="function token">getAll<span class="punctuation token">(</span></span><span class="punctuation token">)</span><span class="punctuation token">.</span>onsuccess <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span>event<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="function token">alert<span class="punctuation token">(</span></span><span class="string token">"Got all customers: "</span> <span class="operator token">+</span> event<span class="punctuation token">.</span>target<span class="punctuation token">.</span>result<span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="punctuation token">}</span><span class="punctuation token">;</span></code></pre> + +<p>Il y a un coût de performance associé avec la recherche de la propriété <code>value</code> du curseur, parce que l'objet est créé paresseusement. Quand vous utilisez <code>getAll()</code> par exemple, Gecko doit créer tous les objets à la fois. Si vous êtes seulement intéressé par la lecture de chaque clé, pour l'instance, il est beaucoup plus efficace d'utiliser un curseur que <code>getAll()</code>. <span id="result_box" lang="fr"><span>Si vous essayez d'obtenir un tableau de tous les objets d'un objet de stockage, utilisez</span></span> <code>getAll()</code>.</p> +</div> + +<h3 id="Utiliser_un_index">Utiliser un index</h3> + +<p><span id="result_box" lang="fr"><span>Le stockage des données des clients utilisant le SSN comme clé est logique puisque le SSN identifie un individu unique.</span> <span>(Que ce soit une bonne idée pour la vie privée est une question différente, et en dehors du champ de cet article). Si vous devez rechercher un client par son nom, vous devrez toutefois faire itérer sur toutes les clés SSN dans la base de données jusqu'à ce que vous</span> <span>trouviez la bonne.</span> <span>La recherche de cette manière serait très lente, alors, vous pouvez utiliser un index.</span></span></p> + +<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="comment token">// D'abord, assurez-vous de créer un index dans request.onupgradeneeded:</span> +<span class="comment token">// objectStore.createIndex("name", "name");</span> +<span class="comment token">// Autrement, vous obtiendrez une DOMException.</span> + +<span class="keyword token">var</span> index <span class="operator token">=</span> objectStore<span class="punctuation token">.</span><span class="function token">index</span><span class="punctuation token">(</span><span class="string token">"name"</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + +index<span class="punctuation token">.</span><span class="keyword token">get</span><span class="punctuation token">(</span><span class="string token">"Donna"</span><span class="punctuation token">)</span><span class="punctuation token">.</span>onsuccess <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span>event<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="function token">alert</span><span class="punctuation token">(</span><span class="string token">"Donna's SSN is "</span> <span class="operator token">+</span> event<span class="punctuation token">.</span>target<span class="punctuation token">.</span>result<span class="punctuation token">.</span>ssn<span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="punctuation token">}</span><span class="punctuation token">;</span></code></pre> + +<p>Le "name" du curseur n'est pas unique, <span class="short_text" id="result_box" lang="fr"><span>donc il pourrait y avoir plus d'une entrée avec le</span></span> <code>name</code> attribué à <code>"Donna"</code>. <span id="result_box" lang="fr"><span>Dans ce cas, vous obtenez toujours celui qui a la valeur clé la plus basse</span></span> .</p> + +<p>Si vous avez besoin d'accèder à toutes les entrées avec un <code>name</code> donné, vous pouvez utiliser un curseur. Vous pouvez ouvrir deux types différents de curseurs sur les index. Un curseur normal situe la propriété index de l'objet dans l'objet de stockage. Un curseur de clés situe la propriété index des clés utilisées pour stocker l'objet dans l'objet de stockage. Les différences sont illustrées ici :</p> + +<pre class="brush: js language-js"><code class="language-js"><span class="comment token">// Utilisation d'un curseur normal pour saisir tous les enregistrements des objets client +</span>index<span class="punctuation token">.</span><span class="function token">openCursor<span class="punctuation token">(</span></span><span class="punctuation token">)</span><span class="punctuation token">.</span>onsuccess <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span>event<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> cursor <span class="operator token">=</span> event<span class="punctuation token">.</span>target<span class="punctuation token">.</span>result<span class="punctuation token">;</span> + <span class="keyword token">if</span> <span class="punctuation token">(</span>cursor<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="comment token"> // cursor.key est un nom, comme "Bill", et cursor.value est l'objet entier. +</span> <span class="function token">alert<span class="punctuation token">(</span></span><span class="string token">"Name: "</span> <span class="operator token">+</span> cursor<span class="punctuation token">.</span>key <span class="operator token">+</span> <span class="string token">", SSN: "</span> <span class="operator token">+</span> cursor<span class="punctuation token">.</span>value<span class="punctuation token">.</span>ssn <span class="operator token">+</span> <span class="string token">", email: "</span> <span class="operator token">+</span> cursor<span class="punctuation token">.</span>value<span class="punctuation token">.</span>email<span class="punctuation token">)</span><span class="punctuation token">;</span> + cursor<span class="punctuation token">.</span><span class="keyword token">continue</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> +<span class="punctuation token">}</span><span class="punctuation token">;</span> +<span class="comment token"> +// Utilisation d'un curseur de clés pour saisir les clés des enregistrements des objets client +</span>index<span class="punctuation token">.</span><span class="function token">openKeyCursor<span class="punctuation token">(</span></span><span class="punctuation token">)</span><span class="punctuation token">.</span>onsuccess <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span>event<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> cursor <span class="operator token">=</span> event<span class="punctuation token">.</span>target<span class="punctuation token">.</span>result<span class="punctuation token">;</span> + <span class="keyword token">if</span> <span class="punctuation token">(</span>cursor<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="comment token"> // cursor.key est un nom, comme "Bill", et cursor.value est le SSN. +</span> <span class="comment token"> // </span></code><span id="result_box" lang="fr"><span>Pas moyen d'obtenir directement le reste de l'objet stocké</span></span> <code class="language-js"><span class="comment token">. +</span> <span class="function token">alert<span class="punctuation token">(</span></span><span class="string token">"Name: "</span> <span class="operator token">+</span> cursor<span class="punctuation token">.</span>key <span class="operator token">+</span> <span class="string token">", SSN: "</span> <span class="operator token">+</span> cursor<span class="punctuation token">.</span>value<span class="punctuation token">)</span><span class="punctuation token">;</span> + cursor<span class="punctuation token">.</span><span class="keyword token">continue</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> +<span class="punctuation token">}</span><span class="punctuation token">;</span></code></pre> + +<h3 id="Spécifier_lintervalle_et_la_direction_du_curseur">Spécifier l'intervalle et la direction du curseur</h3> + +<p>Si vous souhaitez limiter l'intervalle de valeurs que vous voyez dans un curseur, vous pouvez utiliser un objet <code>IDBKeyRange</code> et le donner comme premier argument à <code>openCursor()</code> ou <code>openKeyCursor()</code> . Vous pouvez créer un intervalle de clés qui n'autorise qu'une seule clé, ou qui a des limites inférieure et supérieure, ou qui a des bornes inférieure et supérieure. La limite peut être "closed" <em>(fermée)</em> (c'est-à-dire que l'intervalle de clés comprend les valeurs données) ou "open" <em>(ouverte)</em> (c'est-à-dire que la plage de clés n'inclut pas les valeurs données. Voici comment cela fonctionne :</p> + +<pre class="brush: js language-js"><code class="language-js"><span class="comment token">// Correspond seulement à "Donna" +</span><span class="keyword token">var</span> singleKeyRange <span class="operator token">=</span> IDBKeyRange<span class="punctuation token">.</span><span class="function token">only<span class="punctuation token">(</span></span><span class="string token">"Donna"</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="comment token"> +// Correspond à n'importe quoi contenant "Bill", y compris "Bill" +</span><span class="keyword token">var</span> lowerBoundKeyRange <span class="operator token">=</span> IDBKeyRange<span class="punctuation token">.</span><span class="function token">lowerBound<span class="punctuation token">(</span></span><span class="string token">"Bill"</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="comment token"> +// Correspond à n'importe quoi contenant "Bill", mais pas "Bill" +</span><span class="keyword token">var</span> lowerBoundOpenKeyRange <span class="operator token">=</span> IDBKeyRange<span class="punctuation token">.</span><span class="function token">lowerBound<span class="punctuation token">(</span></span><span class="string token">"Bill"</span><span class="punctuation token">,</span> <span class="keyword token">true</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="comment token"> +// Correspond à n'importe quoi, mais "Donna" exclus. +</span><span class="keyword token">var</span> upperBoundOpenKeyRange <span class="operator token">=</span> IDBKeyRange<span class="punctuation token">.</span><span class="function token">upperBound<span class="punctuation token">(</span></span><span class="string token">"Donna"</span><span class="punctuation token">,</span> <span class="keyword token">true</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="comment token"> +// Correspond à n'importe quoi compris entre "Bill" et "Donna", mais "Donna" exclus. +</span><span class="keyword token">var</span> boundKeyRange <span class="operator token">=</span> IDBKeyRange<span class="punctuation token">.</span><span class="function token">bound<span class="punctuation token">(</span></span><span class="string token">"Bill"</span><span class="punctuation token">,</span> <span class="string token">"Donna"</span><span class="punctuation token">,</span> <span class="keyword token">false</span><span class="punctuation token">,</span> <span class="keyword token">true</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="comment token"> +// Pour utiliser un des intervalles de clés, placez le en premier argument de openCursor()/openKeyCursor() +</span>index<span class="punctuation token">.</span><span class="function token">openCursor<span class="punctuation token">(</span></span>boundKeyRange<span class="punctuation token">)</span><span class="punctuation token">.</span>onsuccess <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span>event<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> cursor <span class="operator token">=</span> event<span class="punctuation token">.</span>target<span class="punctuation token">.</span>result<span class="punctuation token">;</span> + <span class="keyword token">if</span> <span class="punctuation token">(</span>cursor<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="comment token"> // Faire quelque chose avec la sélection. +</span> cursor<span class="punctuation token">.</span><span class="keyword token">continue</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> +<span class="punctuation token">}</span><span class="punctuation token">;</span></code></pre> + +<p>Parfois, <span id="result_box" lang="fr"><span>vous voudrez peut-être itérer dans l'ordre décroissant plutôt que dans l'ordre croissant (la direction par défaut pour tous les curseurs).</span> <span>Le changement de direction est réalisé en passant</span></span> <code>prev</code> <span lang="fr"><span> à la fonction </span></span> <code>openCursor()</code> <span lang="fr"><span> antérieure comme second argument :</span></span></p> + +<pre class="brush: js language-js"><code class="language-js">objectStore<span class="punctuation token">.</span><span class="function token">openCursor<span class="punctuation token">(</span></span>boundKeyRange<span class="punctuation token">,</span> <span class="string token">"prev"</span><span class="punctuation token">)</span><span class="punctuation token">.</span>onsuccess <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span>event<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> cursor <span class="operator token">=</span> event<span class="punctuation token">.</span>target<span class="punctuation token">.</span>result<span class="punctuation token">;</span> + <span class="keyword token">if</span> <span class="punctuation token">(</span>cursor<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="comment token"> // Faire quelque chose avec les entrées. +</span> cursor<span class="punctuation token">.</span><span class="keyword token">continue</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> +<span class="punctuation token">}</span><span class="punctuation token">;</span></code></pre> + +<p><span id="result_box" lang="fr"><span>Si vous souhaitez simplement spécifier un changement de direction, mais ne pas limiter les résultats, vous pouvez simplement passer "null" comme premier argument :</span></span></p> + +<pre class="brush: js language-js"><code class="language-js">objectStore<span class="punctuation token">.</span><span class="function token">openCursor<span class="punctuation token">(</span></span><span class="keyword token">null</span><span class="punctuation token">,</span> <span class="string token">"prev"</span><span class="punctuation token">)</span><span class="punctuation token">.</span>onsuccess <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span>event<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> cursor <span class="operator token">=</span> event<span class="punctuation token">.</span>target<span class="punctuation token">.</span>result<span class="punctuation token">;</span> + <span class="keyword token">if</span> <span class="punctuation token">(</span>cursor<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="comment token"> // Faire quelque chose avec les entrées. +</span> cursor<span class="punctuation token">.</span><span class="keyword token">continue</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> +<span class="punctuation token">}</span><span class="punctuation token">;</span></code></pre> + +<p><span id="result_box" lang="fr"><span>Étant donné que l'index "</span></span>name<span lang="fr"><span>" n'est pas unique, il peut y avoir plusieurs entrées où le </span></span> <code>name</code> <span lang="fr"><span> est le même.</span> <span>Notez qu'une telle situation ne peut pas se produire avec les objets stockés car la clé doit toujours être unique.</span> <span>Si vous souhaitez filtrer les doublons pendant l'itération du curseur sur les index, vous pouvez passer </span></span> <code>nextunique</code> <span lang="fr"><span> (ou </span></span> <code>prevunique</code> <span lang="fr"><span> si vous revenez en arrière) comme paramètre de direction.</span> <span>Lorsque nextunique ou prevunique sont utilisés, l'entrée avec la clé la plus basse est toujours celle retournée.</span></span></p> + +<pre class="brush: js language-js"><code class="language-js">index<span class="punctuation token">.</span><span class="function token">openKeyCursor<span class="punctuation token">(</span></span><span class="keyword token">null</span><span class="punctuation token">,</span> <span class="string token">"nextunique"</span><span class="punctuation token">)</span><span class="punctuation token">.</span>onsuccess <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span>event<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> cursor <span class="operator token">=</span> event<span class="punctuation token">.</span>target<span class="punctuation token">.</span>result<span class="punctuation token">;</span> + <span class="keyword token">if</span> <span class="punctuation token">(</span>cursor<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="comment token"> // Faire quelque chose avec les entrées. +</span> cursor<span class="punctuation token">.</span><span class="keyword token">continue</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> +<span class="punctuation token">}</span><span class="punctuation token">;</span></code></pre> + +<p>Voyez "<a href="https://developer.mozilla.org/en-US/docs/Web/API/IDBCursor?redirectlocale=en-US&redirectslug=IndexedDB%2FIDBCursor#Constants">IDBCursor Constants</a>" <span class="short_text" id="result_box" lang="fr"><span>pour les arguments de direction valides</span></span>.</p> + +<h2 id="La_version_change_alors_quune_application_Web_est_ouverte_dans_un_autre_onglet"><span id="result_box" lang="fr"><span>La version change alors qu'une application Web est ouverte dans un autre onglet</span></span></h2> + +<p><span id="result_box" lang="fr"><span>Lorsque votre application Web change de telle sorte qu'une modification de version est nécessaire pour votre base de données, vous devez considérer ce qui se passe si l'utilisateur a l'ancienne version de votre application ouverte dans un onglet, puis charge la nouvelle version de votre application dans une autre</span> <span>.</span> <span>Lorsque vous appelez </span></span> <code>open()</code> <span lang="fr"><span> avec une version plus grande que la version actuelle de la base de données, toutes les autres bases de données ouvertes doivent reconnaître explicitement la demande avant de commencer à modifier la base de données (un événement </span></span> <code>onblocked</code> <em>(bloqué)</em><span lang="fr"><span> est déclenché jusqu'à ce qu'elles soient fermées ou rechargées).</span> <span>Voici comment cela fonctionne :</span></span></p> + +<pre class="brush: js language-js"><code class="language-js"><span class="keyword token">var</span> openReq <span class="operator token">=</span> mozIndexedDB<span class="punctuation token">.</span><span class="function token">open<span class="punctuation token">(</span></span><span class="string token">"MyTestDatabase"</span><span class="punctuation token">,</span> <span class="number token">2</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + +openReq<span class="punctuation token">.</span>onblocked <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span>event<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="comment token"> // </span></code> <span id="result_box" lang="fr"><span>Si un autre onglet est chargé avec la base de données, il doit être fermé</span></span> <code class="language-js"><span class="comment token"> +</span> <span class="comment token"> // avant que nous puissions continuer. +</span> <span class="function token">alert<span class="punctuation token">(</span></span><span class="string token">"Veuillez fermer tous les ongles ouverts sur ce site!"</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="punctuation token">}</span><span class="punctuation token">;</span> + +openReq<span class="punctuation token">.</span>onupgradeneeded <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span>event<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="comment token"> // Toutes les autres bases de données ont été fermées. Tout régler. +</span> db<span class="punctuation token">.</span><span class="function token">createObjectStore<span class="punctuation token">(</span></span><span class="comment token">/* ... */</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="function token">useDatabase<span class="punctuation token">(</span></span>db<span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="punctuation token">}</span> + +openReq<span class="punctuation token">.</span>onsuccess <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span>event<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> db <span class="operator token">=</span> event<span class="punctuation token">.</span>target<span class="punctuation token">.</span>result<span class="punctuation token">;</span> + <span class="function token">useDatabase<span class="punctuation token">(</span></span>db<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">return</span><span class="punctuation token">;</span> +<span class="punctuation token">}</span> + +<span class="keyword token">function</span> <span class="function token">useDatabase<span class="punctuation token">(</span></span>db<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="comment token"> // </span></code><span id="result_box" lang="fr"><span>Assurez-vous d'ajouter un gestionnaire pour être averti si une autre page demande</span></span> <code class="language-js"><span class="comment token"> +</span> <span class="comment token"> // un changement de version. Nous devons fermer la base de données. </span></code> +<code class="language-js"><span class="comment token"> // </span></code><span lang="fr"><span>Cela permet à l'autre page de mettre à niveau la base de données.</span></span> <code class="language-js"><span class="comment token"> +</span> <span class="comment token"> // </span></code> <span id="result_box" lang="fr"><span>Si vous ne le faites pas, la mise à niveau ne se produira que lorsque l'utilisateur fermera l'onglet</span></span> <code class="language-js"><span class="comment token">. +</span> db<span class="punctuation token">.</span>onversionchange <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span>event<span class="punctuation token">)</span> <span class="punctuation token">{</span> + db<span class="punctuation token">.</span><span class="function token">close<span class="punctuation token">(</span></span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="function token">alert<span class="punctuation token">(</span></span><span class="string token">"A new version of this page is ready. Please reload!"</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span><span class="punctuation token">;</span> + + <span class="comment token"> // </span></code> <span class="short_text" id="result_box" lang="fr"><span>Faire quelque chose avec la base de données</span></span> <code class="language-js"><span class="comment token">. +</span><span class="punctuation token">}</span></code></pre> + +<p><span id="result_box" lang="fr"><span>Vous devriez également écouter les erreurs </span></span> <code>VersionError</code> <span lang="fr"><span> pour gérer le cas où les applications déjà ouvertes déclencheraient un code conduisant à une nouvelle tentative d'ouverture de la base de données, mais en utilisant une version désuète.</span></span></p> + +<h2 id="Sécurité">Sécurité</h2> + +<p><span id="result_box" lang="fr"><span>IndexedDB utilise le principe "</span></span> same-origin " <span lang="fr"><span><em>(même origine)</em>, ce qui signifie qu'il relie le stockage à l'origine du site qui le crée (généralement, c'est le domaine ou le sous-domaine du site), de sorte qu'il ne peut être consulté par aucune autre origine.</span></span></p> + +<p>Le contenu de la fenêtre de tiers (par exemple le contenu de {{htmlelement("iframe")}}) peut accèder à IndexedDB pour l'origine dans laquelle il est intégré, à moins que le navigateur ne soit configuré pour <a href="https://support.mozilla.org/en-US/kb/disable-third-party-cookies">ne jamais accepter de cookies tiers</a> (voir le {{bug("1147821")}}).</p> + +<h2 id="Avertissement_concernant_larrêt_du_navigateur"><span class="short_text" id="result_box" lang="fr"><span>Avertissement concernant l'arrêt du navigateur</span></span></h2> + +<p><span id="result_box" lang="fr"><span>Lorsque le navigateur s'arrête (parce que l'utilisateur a choisi l'option Quit ou Exit), le disque contenant la base de données est supprimé de manière inattendue ou les permissions sont perdues dans le magasin de base de données, les choses suivantes se produisent :</span></span></p> + +<ol> + <li><span id="result_box" lang="fr"><span>Chaque transaction sur chaque base de données affectée (ou toutes les bases de données ouvertes, dans le cas de l'arrêt du navigateur) est interrompue avec un </span></span> <code>AbortError</code>. L'effet est le même que si {{domxref("IDBTransaction.abort()")}} est appelé sur chaque transaction.</li> + <li><span id="result_box" lang="fr"><span>Une fois toutes les transactions terminées, la connexion à la base de données est fermée</span></span> .</li> + <li>Enfin, l'objet {{domxref("IDBDatabase")}} <span id="result_box" lang="fr"><span>représentant la connexion à la base de données reçoit un</span></span> évènement {{event("close")}} . Vous pouvez utiliser un gestionnaire d'évènements {{domxref("IDBDatabase.onclose")}} pour écouter ces évènements, <span id="result_box" lang="fr"><span>afin de savoir quand une base de données est fermée de façon inattendue</span></span> .</li> +</ol> + +<p><span id="result_box" lang="fr"><span>Le comportement décrit ci-dessus est nouveau et n'est disponible que pour les versions de navigateur suivantes : Firefox 50, Google Chrome 31 (approximativement).</span></span></p> + +<p><span id="result_box" lang="fr"><span>Avant ces versions de navigateurs, les transactions étaient interrompues silencieusement et aucun événement {{event ("close")}} n'était déclenché, donc il n'y avait aucun moyen de détecter une fermeture de base de données inattendue.</span></span></p> + +<p><span id="result_box" lang="fr"><span>Étant donné que l'utilisateur peut quitter le navigateur à tout moment, cela signifie que vous ne pouvez pas compter sur une transaction particulière à compléter, et sur les navigateurs plus anciens, vous n'êtes même pas informé quand elles ne sont pas terminées.</span> <span>Il y a plusieurs conséquences à ce comportement.</span></span></p> + +<p><span id="result_box" lang="fr"><span>Tout d'abord, vous devez vous occuper de toujours laisser votre base de données dans un état cohérent à la fin de chaque transaction.</span> <span>Par exemple, supposons que vous utilisiez IndexedDB pour stocker une liste d'éléments que l'utilisateur est autorisé à éditer.</span> <span>Vous enregistrez la liste après l'édition en effaçant l'objet de stockage puis en écrivant la nouvelle liste.</span> <span>Si vous effacez l'objet de stockage dans une transaction et que vous écrivez la nouvelle liste dans une autre transaction, il existe un danger : si le navigateur se ferme après l'effacement mais avant l'écriture, votre base de données est vide.</span> <span>Pour éviter cela, vous devez combiner l'effacement et l'écriture en une seule transaction.</span></span></p> + +<p><span id="result_box" lang="fr"><span>Ensuite, vous ne devez jamais lier les transactions de base de données pour les événements </span></span> unload <em>(déchargement</em>)<span lang="fr"><span>.</span> <span>Si l'événement </span></span> unload <span lang="fr"><span>est déclenché par la fermeture du navigateur, toutes les transactions créées dans le gestionnaire d'événements </span></span>unload<span lang="fr"><span> ne seront jamais terminées.</span> <span>Une approche intuitive, pour le maintien de certaines informations dans les sessions du navigateur, est de le lire à partir de la base de données, lorsque le navigateur (ou une page particulière) est ouvert, le mettre à jour à mesure que l'utilisateur interagit avec le navigateur, puis l'enregistrer dans la base de données lorsque le navigateur (</span> <span>ou page) se ferme.</span> <span>Cependant, cela ne fonctionne pas.</span> <span>Les transactions de la base de données sont créées dans le gestionnaire d'événements </span></span>unload<span lang="fr"><span>, mais comme elles sont asynchrones, elles sont interrompues avant qu'elles puissent s'exécuter.</span></span></p> + +<p><span id="result_box" lang="fr"><span>En fait, il n'y a aucun moyen de garantir que les transactions IndexedDB seront terminées, même avec un arrêt normal du navigateur.</span> <span>Voir {{bug (870645)}}.</span> <span>Comme solution de rechange pour cette notification d'arrêt normal, vous pouvez suivre vos transactions et ajouter un événement </span></span> <code>beforeunload</code> <span lang="fr"><span> pour avertir l'utilisateur si des transactions ne sont pas encore terminées au moment du déchargement.</span></span></p> + +<p><span id="result_box" lang="fr"><span>Au-moins, avec l'ajout des notifications d'annulation et {{domxref ("IDBDatabase.onclose")}}, vous pouvez savoir quand cela s'est produit.</span></span></p> + +<h2 id="Le_tri_et_les_langues">Le tri et les langues</h2> + +<p>Mozilla <span id="result_box" lang="fr"><span>a implémenté la capacité d'effectuer un tri des données IndexedDB localisées sur Firefox 43+.</span> <span>Par défaut, IndexedDB n'a pas pris en charge l'internationalisation des chaînes de tri, et était trié comme s'il s'agissait d'un texte anglais.</span> <span>Par exemple, "b", "á", "z", "a" devaient être triés comme suit :</span></span></p> + +<ul> + <li>a</li> + <li>b</li> + <li>z</li> + <li>á</li> +</ul> + +<p><span id="result_box" lang="fr"><span>ce qui n'est évidemment pas la façon dont les utilisateurs souhaitent que leurs données soient triées - Aaron et Áaron, par exemple, doivent aller l'un à côté de l'autre dans une liste de contacts.</span> <span>L'obtention d'un tri international approprié exige donc que l'ensemble des données soit appelé dans la mémoire et que le tri soit exécuté par le JavaScript côté client, ce qui n'est pas très efficace.</span></span></p> + +<p><span id="result_box" lang="fr"><span>Cette nouvelle fonctionnalité permet aux développeurs de spécifier une "locale" <em>(langue)</em> lors de la création d'un index en utilisant </span></span> {{domxref("IDBObjectStore.createIndex()")}} <span lang="fr"><span> (vérifiez ses paramètres). Dans ce cas, lorsqu'un curseur est utilisé pour itérer sur l'ensemble de données</span> <span>, et si vous souhaitez spécifier un tri local, vous pouvez utiliser un {{domxref ("IDBLocaleAwareKeyRange")}}.</span></span></p> + +<p>{{domxref("IDBIndex")}} <span id="result_box" lang="fr"><span>a également eu de nouvelles propriétés qui lui ont été ajoutées pour spécifier la langue :</span></span> <code>locale</code> (retourne la langue si elle est spécifiée, ou null sinon) et <code>isAutoLocale</code> (retourne <code>true</code><em> (vrai)</em> si l'index a été créé avec une "locale auto", <span id="result_box" lang="fr"><span>ce qui signifie que la langue par défaut de la plate-forme est utilisée,</span></span> sinon <code>false</code>).</p> + +<div class="note"> +<p><strong>Note </strong>: Cette fonctionnalité est couramment cachée derrière une marque (flag) — <span class="short_text" id="result_box" lang="fr"><span>pour l'activer et l'expérimenter, aller à</span></span> <a>about:config</a> et activez <code>dom.indexedDB.experimental</code>.</p> +</div> + +<h2 id="Full_IndexedDB_example" name="Full_IndexedDB_example">Exemple complet d'IndexedDB</h2> + +<h3 id="HTML_Content">HTML Content</h3> + +<pre class="brush: html language-html"><code class="language-html"><span class="script token"><span class="tag token"><span class="tag token"><span class="punctuation token"><</span>script</span> <span class="attr-name token">type</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>text/javascript<span class="punctuation token">"</span></span> <span class="attr-name token">src</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js<span class="punctuation token">"</span></span><span class="punctuation token">></span></span><span class="tag token"><span class="tag token"><span class="punctuation token"></</span>script</span><span class="punctuation token">></span></span></span> + + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>h1</span><span class="punctuation token">></span></span>IndexedDB Demo: storing blobs, e-publication example<span class="tag token"><span class="tag token"><span class="punctuation token"></</span>h1</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>div</span> <span class="attr-name token">class</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>note<span class="punctuation token">"</span></span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>p</span><span class="punctuation token">></span></span> + Works and tested with: + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>p</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>div</span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>compat<span class="punctuation token">"</span></span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>div</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>div</span><span class="punctuation token">></span></span> + + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>div</span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>msg<span class="punctuation token">"</span></span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>div</span><span class="punctuation token">></span></span> + + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>form</span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>register-form<span class="punctuation token">"</span></span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>table</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>tbody</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>tr</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>td</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>label</span> <span class="attr-name token">for</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>pub-title<span class="punctuation token">"</span></span> <span class="attr-name token">class</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>required<span class="punctuation token">"</span></span><span class="punctuation token">></span></span> + Title: + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>label</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>td</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>td</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>input</span> <span class="attr-name token">type</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>text<span class="punctuation token">"</span></span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>pub-title<span class="punctuation token">"</span></span> <span class="attr-name token">name</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>pub-title<span class="punctuation token">"</span></span> <span class="punctuation token">/></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>td</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>tr</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>tr</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>td</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>label</span> <span class="attr-name token">for</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>pub-biblioid<span class="punctuation token">"</span></span> <span class="attr-name token">class</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>required<span class="punctuation token">"</span></span><span class="punctuation token">></span></span> + Bibliographic ID:<span class="tag token"><span class="tag token"><span class="punctuation token"><</span>br</span><span class="punctuation token">/></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>span</span> <span class="attr-name token">class</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>note<span class="punctuation token">"</span></span><span class="punctuation token">></span></span>(ISBN, ISSN, etc.)<span class="tag token"><span class="tag token"><span class="punctuation token"></</span>span</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>label</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>td</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>td</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>input</span> <span class="attr-name token">type</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>text<span class="punctuation token">"</span></span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>pub-biblioid<span class="punctuation token">"</span></span> <span class="attr-name token">name</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>pub-biblioid<span class="punctuation token">"</span></span><span class="punctuation token">/></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>td</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>tr</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>tr</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>td</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>label</span> <span class="attr-name token">for</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>pub-year<span class="punctuation token">"</span></span><span class="punctuation token">></span></span> + Year: + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>label</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>td</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>td</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>input</span> <span class="attr-name token">type</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>number<span class="punctuation token">"</span></span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>pub-year<span class="punctuation token">"</span></span> <span class="attr-name token">name</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>pub-year<span class="punctuation token">"</span></span> <span class="punctuation token">/></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>td</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>tr</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>tbody</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>tbody</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>tr</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>td</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>label</span> <span class="attr-name token">for</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>pub-file<span class="punctuation token">"</span></span><span class="punctuation token">></span></span> + File image: + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>label</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>td</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>td</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>input</span> <span class="attr-name token">type</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>file<span class="punctuation token">"</span></span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>pub-file<span class="punctuation token">"</span></span><span class="punctuation token">/></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>td</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>tr</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>tr</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>td</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>label</span> <span class="attr-name token">for</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>pub-file-url<span class="punctuation token">"</span></span><span class="punctuation token">></span></span> + Online-file image URL:<span class="tag token"><span class="tag token"><span class="punctuation token"><</span>br</span><span class="punctuation token">/></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>span</span> <span class="attr-name token">class</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>note<span class="punctuation token">"</span></span><span class="punctuation token">></span></span>(same origin URL)<span class="tag token"><span class="tag token"><span class="punctuation token"></</span>span</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>label</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>td</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>td</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>input</span> <span class="attr-name token">type</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>text<span class="punctuation token">"</span></span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>pub-file-url<span class="punctuation token">"</span></span> <span class="attr-name token">name</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>pub-file-url<span class="punctuation token">"</span></span><span class="punctuation token">/></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>td</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>tr</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>tbody</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>table</span><span class="punctuation token">></span></span> + + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>div</span> <span class="attr-name token">class</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>button-pane<span class="punctuation token">"</span></span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>input</span> <span class="attr-name token">type</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>button<span class="punctuation token">"</span></span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>add-button<span class="punctuation token">"</span></span> <span class="attr-name token">value</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>Add Publication<span class="punctuation token">"</span></span> <span class="punctuation token">/></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>input</span> <span class="attr-name token">type</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>reset<span class="punctuation token">"</span></span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>register-form-reset<span class="punctuation token">"</span></span><span class="punctuation token">/></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>div</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>form</span><span class="punctuation token">></span></span> + + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>form</span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>delete-form<span class="punctuation token">"</span></span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>table</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>tbody</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>tr</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>td</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>label</span> <span class="attr-name token">for</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>pub-biblioid-to-delete<span class="punctuation token">"</span></span><span class="punctuation token">></span></span> + Bibliographic ID:<span class="tag token"><span class="tag token"><span class="punctuation token"><</span>br</span><span class="punctuation token">/></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>span</span> <span class="attr-name token">class</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>note<span class="punctuation token">"</span></span><span class="punctuation token">></span></span>(ISBN, ISSN, etc.)<span class="tag token"><span class="tag token"><span class="punctuation token"></</span>span</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>label</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>td</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>td</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>input</span> <span class="attr-name token">type</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>text<span class="punctuation token">"</span></span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>pub-biblioid-to-delete<span class="punctuation token">"</span></span> + <span class="attr-name token">name</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>pub-biblioid-to-delete<span class="punctuation token">"</span></span> <span class="punctuation token">/></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>td</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>tr</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>tr</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>td</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>label</span> <span class="attr-name token">for</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>key-to-delete<span class="punctuation token">"</span></span><span class="punctuation token">></span></span> + Key:<span class="tag token"><span class="tag token"><span class="punctuation token"><</span>br</span><span class="punctuation token">/></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>span</span> <span class="attr-name token">class</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>note<span class="punctuation token">"</span></span><span class="punctuation token">></span></span>(for example 1, 2, 3, etc.)<span class="tag token"><span class="tag token"><span class="punctuation token"></</span>span</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>label</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>td</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>td</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>input</span> <span class="attr-name token">type</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>text<span class="punctuation token">"</span></span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>key-to-delete<span class="punctuation token">"</span></span> + <span class="attr-name token">name</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>key-to-delete<span class="punctuation token">"</span></span> <span class="punctuation token">/></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>td</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>tr</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>tbody</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>table</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>div</span> <span class="attr-name token">class</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>button-pane<span class="punctuation token">"</span></span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>input</span> <span class="attr-name token">type</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>button<span class="punctuation token">"</span></span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>delete-button<span class="punctuation token">"</span></span> <span class="attr-name token">value</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>Delete Publication<span class="punctuation token">"</span></span> <span class="punctuation token">/></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>input</span> <span class="attr-name token">type</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>button<span class="punctuation token">"</span></span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>clear-store-button<span class="punctuation token">"</span></span> + <span class="attr-name token">value</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>Clear the whole store<span class="punctuation token">"</span></span> <span class="attr-name token">class</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>destructive<span class="punctuation token">"</span></span> <span class="punctuation token">/></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>div</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>form</span><span class="punctuation token">></span></span> + + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>form</span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>search-form<span class="punctuation token">"</span></span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>div</span> <span class="attr-name token">class</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>button-pane<span class="punctuation token">"</span></span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>input</span> <span class="attr-name token">type</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>button<span class="punctuation token">"</span></span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>search-list-button<span class="punctuation token">"</span></span> + <span class="attr-name token">value</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>List database content<span class="punctuation token">"</span></span> <span class="punctuation token">/></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>div</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>form</span><span class="punctuation token">></span></span> + + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>div</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>div</span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>pub-msg<span class="punctuation token">"</span></span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>div</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>div</span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>pub-viewer<span class="punctuation token">"</span></span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>div</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>ul</span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>pub-list<span class="punctuation token">"</span></span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>ul</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>div</span><span class="punctuation token">></span></span></code></pre> + +<h3 id="CSS_Content">CSS Content</h3> + +<pre class="brush: css language-css"><code class="language-css"><span class="selector token">body </span><span class="punctuation token">{</span> + <span class="property token">font-size</span><span class="punctuation token">:</span> 0.8em<span class="punctuation token">;</span> + <span class="property token">font-family</span><span class="punctuation token">:</span> Sans-Serif<span class="punctuation token">;</span> +<span class="punctuation token">}</span> + +<span class="selector token">form </span><span class="punctuation token">{</span> + <span class="property token">background-color</span><span class="punctuation token">:</span> #cccccc<span class="punctuation token">;</span> + <span class="property token">border-radius</span><span class="punctuation token">:</span> 0.3em<span class="punctuation token">;</span> + <span class="property token">display</span><span class="punctuation token">:</span> inline-block<span class="punctuation token">;</span> + <span class="property token">margin-bottom</span><span class="punctuation token">:</span> 0.5em<span class="punctuation token">;</span> + <span class="property token">padding</span><span class="punctuation token">:</span> 1em<span class="punctuation token">;</span> +<span class="punctuation token">}</span> + +<span class="selector token">table </span><span class="punctuation token">{</span> + <span class="property token">border-collapse</span><span class="punctuation token">:</span> collapse<span class="punctuation token">;</span> +<span class="punctuation token">}</span> + +<span class="selector token">input </span><span class="punctuation token">{</span> + <span class="property token">padding</span><span class="punctuation token">:</span> 0.3em<span class="punctuation token">;</span> + <span class="property token">border-color</span><span class="punctuation token">:</span> #cccccc<span class="punctuation token">;</span> + <span class="property token">border-radius</span><span class="punctuation token">:</span> 0.3em<span class="punctuation token">;</span> +<span class="punctuation token">}</span> + +<span class="selector token">.required:after </span><span class="punctuation token">{</span> + <span class="property token">content</span><span class="punctuation token">:</span> <span class="string token">"*"</span><span class="punctuation token">;</span> + <span class="property token">color</span><span class="punctuation token">:</span> red<span class="punctuation token">;</span> +<span class="punctuation token">}</span> + +<span class="selector token">.button-pane </span><span class="punctuation token">{</span> + <span class="property token">margin-top</span><span class="punctuation token">:</span> 1em<span class="punctuation token">;</span> +<span class="punctuation token">}</span> + +<span class="selector token">#pub-viewer </span><span class="punctuation token">{</span> + <span class="property token">float</span><span class="punctuation token">:</span> right<span class="punctuation token">;</span> + <span class="property token">width</span><span class="punctuation token">:</span> 48%<span class="punctuation token">;</span> + <span class="property token">height</span><span class="punctuation token">:</span> 20em<span class="punctuation token">;</span> + <span class="property token">border</span><span class="punctuation token">:</span> solid #d092ff 0.1em<span class="punctuation token">;</span> +<span class="punctuation token">}</span> +<span class="selector token">#pub-viewer iframe </span><span class="punctuation token">{</span> + <span class="property token">width</span><span class="punctuation token">:</span> 100%<span class="punctuation token">;</span> + <span class="property token">height</span><span class="punctuation token">:</span> 100%<span class="punctuation token">;</span> +<span class="punctuation token">}</span> + +<span class="selector token">#pub-list </span><span class="punctuation token">{</span> + <span class="property token">width</span><span class="punctuation token">:</span> 46%<span class="punctuation token">;</span> + <span class="property token">background-color</span><span class="punctuation token">:</span> #eeeeee<span class="punctuation token">;</span> + <span class="property token">border-radius</span><span class="punctuation token">:</span> 0.3em<span class="punctuation token">;</span> +<span class="punctuation token">}</span> +<span class="selector token">#pub-list li </span><span class="punctuation token">{</span> + <span class="property token">padding-top</span><span class="punctuation token">:</span> 0.5em<span class="punctuation token">;</span> + <span class="property token">padding-bottom</span><span class="punctuation token">:</span> 0.5em<span class="punctuation token">;</span> + <span class="property token">padding-right</span><span class="punctuation token">:</span> 0.5em<span class="punctuation token">;</span> +<span class="punctuation token">}</span> + +<span class="selector token">#msg </span><span class="punctuation token">{</span> + <span class="property token">margin-bottom</span><span class="punctuation token">:</span> 1em<span class="punctuation token">;</span> +<span class="punctuation token">}</span> + +<span class="selector token">.action-success </span><span class="punctuation token">{</span> + <span class="property token">padding</span><span class="punctuation token">:</span> 0.5em<span class="punctuation token">;</span> + <span class="property token">color</span><span class="punctuation token">:</span> #00d21e<span class="punctuation token">;</span> + <span class="property token">background-color</span><span class="punctuation token">:</span> #eeeeee<span class="punctuation token">;</span> + <span class="property token">border-radius</span><span class="punctuation token">:</span> 0.2em<span class="punctuation token">;</span> +<span class="punctuation token">}</span> + +<span class="selector token">.action-failure </span><span class="punctuation token">{</span> + <span class="property token">padding</span><span class="punctuation token">:</span> 0.5em<span class="punctuation token">;</span> + <span class="property token">color</span><span class="punctuation token">:</span> #ff1408<span class="punctuation token">;</span> + <span class="property token">background-color</span><span class="punctuation token">:</span> #eeeeee<span class="punctuation token">;</span> + <span class="property token">border-radius</span><span class="punctuation token">:</span> 0.2em<span class="punctuation token">;</span> +<span class="punctuation token">}</span> + +<span class="selector token">.note </span><span class="punctuation token">{</span> + <span class="property token">font-size</span><span class="punctuation token">:</span> smaller<span class="punctuation token">;</span> +<span class="punctuation token">}</span> + +<span class="selector token">.destructive </span><span class="punctuation token">{</span> + <span class="property token">background-color</span><span class="punctuation token">:</span> orange<span class="punctuation token">;</span> +<span class="punctuation token">}</span> +<span class="selector token">.destructive:hover </span><span class="punctuation token">{</span> + <span class="property token">background-color</span><span class="punctuation token">:</span> #ff8000<span class="punctuation token">;</span> +<span class="punctuation token">}</span> +<span class="selector token">.destructive:active </span><span class="punctuation token">{</span> + <span class="property token">background-color</span><span class="punctuation token">:</span> red<span class="punctuation token">;</span> +<span class="punctuation token">}</span></code></pre> + +<h3 id="JavaScript_Content">JavaScript Content</h3> + +<pre class="brush: js language-js"><code class="language-js"><span class="punctuation token">(</span><span class="keyword token">function</span> <span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> COMPAT_ENVS <span class="operator token">=</span> <span class="punctuation token">[</span> + <span class="punctuation token">[</span><span class="string token">'Firefox'</span><span class="punctuation token">,</span> <span class="string token">">= 16.0"</span><span class="punctuation token">]</span><span class="punctuation token">,</span> + <span class="punctuation token">[</span><span class="string token">'Google Chrome'</span><span class="punctuation token">,</span> + <span class="string token">">= 24.0 (you may need to get Google Chrome Canary), NO Blob storage support"</span><span class="punctuation token">]</span> + <span class="punctuation token">]</span><span class="punctuation token">;</span> + <span class="keyword token">var</span> compat <span class="operator token">=</span> $<span class="punctuation token">(</span><span class="string token">'#compat'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + compat<span class="punctuation token">.</span><span class="function token">empty<span class="punctuation token">(</span></span><span class="punctuation token">)</span><span class="punctuation token">;</span> + compat<span class="punctuation token">.</span><span class="function token">append<span class="punctuation token">(</span></span><span class="string token">'<ul id="compat-list"></ul>'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + COMPAT_ENVS<span class="punctuation token">.</span><span class="function token">forEach<span class="punctuation token">(</span></span><span class="keyword token">function</span><span class="punctuation token">(</span>val<span class="punctuation token">,</span> idx<span class="punctuation token">,</span> array<span class="punctuation token">)</span> <span class="punctuation token">{</span> + $<span class="punctuation token">(</span><span class="string token">'#compat-list'</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">append<span class="punctuation token">(</span></span><span class="string token">'<li>'</span> <span class="operator token">+</span> val<span class="punctuation token">[</span><span class="number token">0</span><span class="punctuation token">]</span> <span class="operator token">+</span> <span class="string token">': '</span> <span class="operator token">+</span> val<span class="punctuation token">[</span><span class="number token">1</span><span class="punctuation token">]</span> <span class="operator token">+</span> <span class="string token">'</li>'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="keyword token">const</span> DB_NAME <span class="operator token">=</span> <span class="string token">'mdn-demo-indexeddb-epublications'</span><span class="punctuation token">;</span> + <span class="keyword token">const</span> DB_VERSION <span class="operator token">=</span> <span class="number token">1</span><span class="punctuation token">;</span><span class="comment token"> // </span></code> <span id="result_box" lang="fr"><span>Utilisez un "long long" pour cette valeur (ne pas utiliser un flottant (float))</span></span> <code class="language-js"><span class="comment token"> +</span> <span class="keyword token">const</span> DB_STORE_NAME <span class="operator token">=</span> <span class="string token">'publications'</span><span class="punctuation token">;</span> + + <span class="keyword token">var</span> db<span class="punctuation token">;</span> + + <span class="comment token"> // </span></code> <span id="result_box" lang="fr"><span>Utilisé pour garder une trace de la vue affichée pour éviter de la recharger inutilement</span></span><code class="language-js"><span class="comment token"> +</span> <span class="keyword token">var</span> current_view_pub_key<span class="punctuation token">;</span> + + <span class="keyword token">function</span> <span class="function token">openDb<span class="punctuation token">(</span></span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + console<span class="punctuation token">.</span><span class="function token">log<span class="punctuation token">(</span></span><span class="string token">"openDb ..."</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">var</span> req <span class="operator token">=</span> indexedDB<span class="punctuation token">.</span><span class="function token">open<span class="punctuation token">(</span></span>DB_NAME<span class="punctuation token">,</span> DB_VERSION<span class="punctuation token">)</span><span class="punctuation token">;</span> + req<span class="punctuation token">.</span>onsuccess <span class="operator token">=</span> <span class="keyword token">function</span> <span class="punctuation token">(</span>evt<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="comment token"> // </span></code> <span id="result_box" lang="fr"><span>Le mieux utiliser "this" que "req" pour obtenir le résultat et éviter </span></span> <code class="language-js"><span class="comment token"> +</span> <span class="comment token"> // </span></code><span id="result_box" lang="fr"><span>les problèmes avec "</span></span><code class="language-js"><span class="comment token">garbage collection". +</span> <span class="comment token"> // db = req.result; +</span> db <span class="operator token">=</span> <span class="keyword token">this</span><span class="punctuation token">.</span>result<span class="punctuation token">;</span> + console<span class="punctuation token">.</span><span class="function token">log<span class="punctuation token">(</span></span><span class="string token">"openDb DONE"</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span><span class="punctuation token">;</span> + req<span class="punctuation token">.</span>onerror <span class="operator token">=</span> <span class="keyword token">function</span> <span class="punctuation token">(</span>evt<span class="punctuation token">)</span> <span class="punctuation token">{</span> + console<span class="punctuation token">.</span><span class="function token">error<span class="punctuation token">(</span></span><span class="string token">"openDb:"</span><span class="punctuation token">,</span> evt<span class="punctuation token">.</span>target<span class="punctuation token">.</span>errorCode<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span><span class="punctuation token">;</span> + + req<span class="punctuation token">.</span>onupgradeneeded <span class="operator token">=</span> <span class="keyword token">function</span> <span class="punctuation token">(</span>evt<span class="punctuation token">)</span> <span class="punctuation token">{</span> + console<span class="punctuation token">.</span><span class="function token">log<span class="punctuation token">(</span></span><span class="string token">"openDb.onupgradeneeded"</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">var</span> store <span class="operator token">=</span> evt<span class="punctuation token">.</span>currentTarget<span class="punctuation token">.</span>result<span class="punctuation token">.</span><span class="function token">createObjectStore<span class="punctuation token">(</span></span> + DB_STORE_NAME<span class="punctuation token">,</span> <span class="punctuation token">{</span> keyPath<span class="punctuation token">:</span> <span class="string token">'id'</span><span class="punctuation token">,</span> autoIncrement<span class="punctuation token">:</span> <span class="keyword token">true</span> <span class="punctuation token">}</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + + store<span class="punctuation token">.</span><span class="function token">createIndex<span class="punctuation token">(</span></span><span class="string token">'biblioid'</span><span class="punctuation token">,</span> <span class="string token">'biblioid'</span><span class="punctuation token">,</span> <span class="punctuation token">{</span> unique<span class="punctuation token">:</span> <span class="keyword token">true</span> <span class="punctuation token">}</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + store<span class="punctuation token">.</span><span class="function token">createIndex<span class="punctuation token">(</span></span><span class="string token">'title'</span><span class="punctuation token">,</span> <span class="string token">'title'</span><span class="punctuation token">,</span> <span class="punctuation token">{</span> unique<span class="punctuation token">:</span> <span class="keyword token">false</span> <span class="punctuation token">}</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + store<span class="punctuation token">.</span><span class="function token">createIndex<span class="punctuation token">(</span></span><span class="string token">'year'</span><span class="punctuation token">,</span> <span class="string token">'year'</span><span class="punctuation token">,</span> <span class="punctuation token">{</span> unique<span class="punctuation token">:</span> <span class="keyword token">false</span> <span class="punctuation token">}</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> + + <span class="comment token">/** + * @paramètre {string}<em>(chaîne de caractères)</em> store_name + * @paramètre {string}<em>(chaîne de caractères)</em> mode either "readonly" ou "readwrite" + */</span> + <span class="keyword token">function</span> <span class="function token">getObjectStore<span class="punctuation token">(</span></span>store_name<span class="punctuation token">,</span> mode<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> tx <span class="operator token">=</span> db<span class="punctuation token">.</span><span class="function token">transaction<span class="punctuation token">(</span></span>store_name<span class="punctuation token">,</span> mode<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">return</span> tx<span class="punctuation token">.</span><span class="function token">objectStore<span class="punctuation token">(</span></span>store_name<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> + + <span class="keyword token">function</span> <span class="function token">clearObjectStore<span class="punctuation token">(</span></span>store_name<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> store <span class="operator token">=</span> <span class="function token">getObjectStore<span class="punctuation token">(</span></span>DB_STORE_NAME<span class="punctuation token">,</span> <span class="string token">'readwrite'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">var</span> req <span class="operator token">=</span> store<span class="punctuation token">.</span><span class="function token">clear<span class="punctuation token">(</span></span><span class="punctuation token">)</span><span class="punctuation token">;</span> + req<span class="punctuation token">.</span>onsuccess <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span>evt<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="function token">displayActionSuccess<span class="punctuation token">(</span></span><span class="string token">"Store cleared"</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="function token">displayPubList<span class="punctuation token">(</span></span>store<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span><span class="punctuation token">;</span> + req<span class="punctuation token">.</span>onerror <span class="operator token">=</span> <span class="keyword token">function</span> <span class="punctuation token">(</span>evt<span class="punctuation token">)</span> <span class="punctuation token">{</span> + console<span class="punctuation token">.</span><span class="function token">error<span class="punctuation token">(</span></span><span class="string token">"clearObjectStore:"</span><span class="punctuation token">,</span> evt<span class="punctuation token">.</span>target<span class="punctuation token">.</span>errorCode<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="function token">displayActionFailure<span class="punctuation token">(</span></span><span class="keyword token">this</span><span class="punctuation token">.</span>error<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> + + <span class="keyword token">function</span> <span class="function token">getBlob<span class="punctuation token">(</span></span>key<span class="punctuation token">,</span> store<span class="punctuation token">,</span> success_callback<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> req <span class="operator token">=</span> store<span class="punctuation token">.</span><span class="keyword token">get</span><span class="punctuation token">(</span>key<span class="punctuation token">)</span><span class="punctuation token">;</span> + req<span class="punctuation token">.</span>onsuccess <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span>evt<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> value <span class="operator token">=</span> evt<span class="punctuation token">.</span>target<span class="punctuation token">.</span>result<span class="punctuation token">;</span> + <span class="keyword token">if</span> <span class="punctuation token">(</span>value<span class="punctuation token">)</span> + <span class="function token">success_callback<span class="punctuation token">(</span></span>value<span class="punctuation token">.</span>blob<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> + + <span class="comment token">/** + * @paramètre objet de stockage {IDBObjectStore=} + */</span> + <span class="keyword token">function</span> <span class="function token">displayPubList<span class="punctuation token">(</span></span>store<span class="punctuation token">)</span> <span class="punctuation token">{</span> + console<span class="punctuation token">.</span><span class="function token">log<span class="punctuation token">(</span></span><span class="string token">"displayPubList"</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="keyword token">if</span> <span class="punctuation token">(</span><span class="keyword token">typeof</span> store <span class="operator token">==</span> <span class="string token">'undefined'</span><span class="punctuation token">)</span> + store <span class="operator token">=</span> <span class="function token">getObjectStore<span class="punctuation token">(</span></span>DB_STORE_NAME<span class="punctuation token">,</span> <span class="string token">'readonly'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="keyword token">var</span> pub_msg <span class="operator token">=</span> $<span class="punctuation token">(</span><span class="string token">'#pub-msg'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + pub_msg<span class="punctuation token">.</span><span class="function token">empty<span class="punctuation token">(</span></span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">var</span> pub_list <span class="operator token">=</span> $<span class="punctuation token">(</span><span class="string token">'#pub-list'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + pub_list<span class="punctuation token">.</span><span class="function token">empty<span class="punctuation token">(</span></span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="comment token"> // </span></code> <span id="result_box" lang="fr"><span>Réinitialisation de l'iframe afin qu'il n'indique pas le contenu précédent</span></span> <code class="language-js"><span class="comment token"> +</span> <span class="function token">newViewerFrame<span class="punctuation token">(</span></span><span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="keyword token">var</span> req<span class="punctuation token">;</span> + req <span class="operator token">=</span> store<span class="punctuation token">.</span><span class="function token">count<span class="punctuation token">(</span></span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="comment token"> // </span></code><span id="result_box" lang="fr"><span>Les requêtes sont exécutées dans l'ordre où elles ont été faites en-dehors de la</span></span> <code class="language-js"><span class="comment token"> +</span> <span class="comment token"> // transaction, </span></code> <span id="result_box" lang="fr"><span>et leurs résultats sont retournés dans le même ordre.</span></span> <code class="language-js"><span class="comment token"> +</span> <span class="comment token"> // </span></code><span id="result_box" lang="fr"><span>Ainsi, le texte du compteur ci-dessous sera affiché avant la liste de pub actuelle</span></span> <code class="language-js"><span class="comment token"> +</span> <span class="comment token"> // </span></code><span id="result_box" lang="fr"><span>(ce n'est pas algorithmiquement important dans ce cas)</span></span> <code class="language-js"><span class="comment token">. +</span> req<span class="punctuation token">.</span>onsuccess <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span>evt<span class="punctuation token">)</span> <span class="punctuation token">{</span> + pub_msg<span class="punctuation token">.</span><span class="function token">append<span class="punctuation token">(</span></span><span class="string token">'<p>There are <strong>'</span> <span class="operator token">+</span> evt<span class="punctuation token">.</span>target<span class="punctuation token">.</span>result <span class="operator token">+</span> + <span class="string token">'</strong> record(s) in the object store.</p>'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span><span class="punctuation token">;</span> + req<span class="punctuation token">.</span>onerror <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span>evt<span class="punctuation token">)</span> <span class="punctuation token">{</span> + console<span class="punctuation token">.</span><span class="function token">error<span class="punctuation token">(</span></span><span class="string token">"add error"</span><span class="punctuation token">,</span> <span class="keyword token">this</span><span class="punctuation token">.</span>error<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="function token">displayActionFailure<span class="punctuation token">(</span></span><span class="keyword token">this</span><span class="punctuation token">.</span>error<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span><span class="punctuation token">;</span> + + <span class="keyword token">var</span> i <span class="operator token">=</span> <span class="number token">0</span><span class="punctuation token">;</span> + req <span class="operator token">=</span> store<span class="punctuation token">.</span><span class="function token">openCursor<span class="punctuation token">(</span></span><span class="punctuation token">)</span><span class="punctuation token">;</span> + req<span class="punctuation token">.</span>onsuccess <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span>evt<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> cursor <span class="operator token">=</span> evt<span class="punctuation token">.</span>target<span class="punctuation token">.</span>result<span class="punctuation token">;</span> + + <span class="comment token"> // </span></code> <span id="result_box" lang="fr"><span>Si le curseur pointe vers quelque chose, demandez les données</span></span> <code class="language-js"><span class="comment token"> +</span> <span class="keyword token">if</span> <span class="punctuation token">(</span>cursor<span class="punctuation token">)</span> <span class="punctuation token">{</span> + console<span class="punctuation token">.</span><span class="function token">log<span class="punctuation token">(</span></span><span class="string token">"displayPubList cursor:"</span><span class="punctuation token">,</span> cursor<span class="punctuation token">)</span><span class="punctuation token">;</span> + req <span class="operator token">=</span> store<span class="punctuation token">.</span><span class="keyword token">get</span><span class="punctuation token">(</span>cursor<span class="punctuation token">.</span>key<span class="punctuation token">)</span><span class="punctuation token">;</span> + req<span class="punctuation token">.</span>onsuccess <span class="operator token">=</span> <span class="keyword token">function</span> <span class="punctuation token">(</span>evt<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> value <span class="operator token">=</span> evt<span class="punctuation token">.</span>target<span class="punctuation token">.</span>result<span class="punctuation token">;</span> + <span class="keyword token">var</span> list_item <span class="operator token">=</span> $<span class="punctuation token">(</span><span class="string token">'<li>'</span> <span class="operator token">+</span> + <span class="string token">'['</span> <span class="operator token">+</span> cursor<span class="punctuation token">.</span>key <span class="operator token">+</span> <span class="string token">'] '</span> <span class="operator token">+</span> + <span class="string token">'(biblioid: '</span> <span class="operator token">+</span> value<span class="punctuation token">.</span>biblioid <span class="operator token">+</span> <span class="string token">') '</span> <span class="operator token">+</span> + value<span class="punctuation token">.</span>title <span class="operator token">+</span> + <span class="string token">'</li>'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">if</span> <span class="punctuation token">(</span>value<span class="punctuation token">.</span>year <span class="operator token">!</span><span class="operator token">=</span> <span class="keyword token">null</span><span class="punctuation token">)</span> + list_item<span class="punctuation token">.</span><span class="function token">append<span class="punctuation token">(</span></span><span class="string token">' - '</span> <span class="operator token">+</span> value<span class="punctuation token">.</span>year<span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="keyword token">if</span> <span class="punctuation token">(</span>value<span class="punctuation token">.</span><span class="function token">hasOwnProperty<span class="punctuation token">(</span></span><span class="string token">'blob'</span><span class="punctuation token">)</span> <span class="operator token">&&</span> + <span class="keyword token">typeof</span> value<span class="punctuation token">.</span>blob <span class="operator token">!</span><span class="operator token">=</span> <span class="string token">'undefined'</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> link <span class="operator token">=</span> $<span class="punctuation token">(</span><span class="string token">'<a href="'</span> <span class="operator token">+</span> cursor<span class="punctuation token">.</span>key <span class="operator token">+</span> <span class="string token">'">File</a>'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + link<span class="punctuation token">.</span><span class="function token">on<span class="punctuation token">(</span></span><span class="string token">'click'</span><span class="punctuation token">,</span> <span class="keyword token">function</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> <span class="keyword token">return</span> <span class="keyword token">false</span><span class="punctuation token">;</span> <span class="punctuation token">}</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + link<span class="punctuation token">.</span><span class="function token">on<span class="punctuation token">(</span></span><span class="string token">'mouseenter'</span><span class="punctuation token">,</span> <span class="keyword token">function</span><span class="punctuation token">(</span>evt<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="function token">setInViewer<span class="punctuation token">(</span></span>evt<span class="punctuation token">.</span>target<span class="punctuation token">.</span><span class="function token">getAttribute<span class="punctuation token">(</span></span><span class="string token">'href'</span><span class="punctuation token">)</span><span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="punctuation token">}</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + list_item<span class="punctuation token">.</span><span class="function token">append<span class="punctuation token">(</span></span><span class="string token">' / '</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + list_item<span class="punctuation token">.</span><span class="function token">append<span class="punctuation token">(</span></span>link<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> <span class="keyword token">else</span> <span class="punctuation token">{</span> + list_item<span class="punctuation token">.</span><span class="function token">append<span class="punctuation token">(</span></span><span class="string token">" / No attached file"</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> + pub_list<span class="punctuation token">.</span><span class="function token">append<span class="punctuation token">(</span></span>list_item<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span><span class="punctuation token">;</span> + + <span class="comment token"> // </span></code> <span class="short_text" id="result_box" lang="fr"><span>Passer à l'objet de stockage suivant</span></span><code class="language-js"><span class="comment token"> +</span> cursor<span class="punctuation token">.</span><span class="keyword token">continue</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="comment token"> // Ce compteur sert seulement à créer des identifiants distincts +</span> i<span class="operator token">++</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> <span class="keyword token">else</span> <span class="punctuation token">{</span> + console<span class="punctuation token">.</span><span class="function token">log<span class="punctuation token">(</span></span><span class="string token">"No more entries"</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> + <span class="punctuation token">}</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> + + <span class="keyword token">function</span> <span class="function token">newViewerFrame<span class="punctuation token">(</span></span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> viewer <span class="operator token">=</span> $<span class="punctuation token">(</span><span class="string token">'#pub-viewer'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + viewer<span class="punctuation token">.</span><span class="function token">empty<span class="punctuation token">(</span></span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">var</span> iframe <span class="operator token">=</span> $<span class="punctuation token">(</span><span class="string token">'<iframe />'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + viewer<span class="punctuation token">.</span><span class="function token">append<span class="punctuation token">(</span></span>iframe<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">return</span> iframe<span class="punctuation token">;</span> + <span class="punctuation token">}</span> + + <span class="keyword token">function</span> <span class="function token">setInViewer<span class="punctuation token">(</span></span>key<span class="punctuation token">)</span> <span class="punctuation token">{</span> + console<span class="punctuation token">.</span><span class="function token">log<span class="punctuation token">(</span></span><span class="string token">"setInViewer:"</span><span class="punctuation token">,</span> arguments<span class="punctuation token">)</span><span class="punctuation token">;</span> + key <span class="operator token">=</span> <span class="function token">Number<span class="punctuation token">(</span></span>key<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">if</span> <span class="punctuation token">(</span>key <span class="operator token">==</span> current_view_pub_key<span class="punctuation token">)</span> + <span class="keyword token">return</span><span class="punctuation token">;</span> + + current_view_pub_key <span class="operator token">=</span> key<span class="punctuation token">;</span> + + <span class="keyword token">var</span> store <span class="operator token">=</span> <span class="function token">getObjectStore<span class="punctuation token">(</span></span>DB_STORE_NAME<span class="punctuation token">,</span> <span class="string token">'readonly'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="function token">getBlob<span class="punctuation token">(</span></span>key<span class="punctuation token">,</span> store<span class="punctuation token">,</span> <span class="keyword token">function</span><span class="punctuation token">(</span>blob<span class="punctuation token">)</span> <span class="punctuation token">{</span> + console<span class="punctuation token">.</span><span class="function token">log<span class="punctuation token">(</span></span><span class="string token">"setInViewer blob:"</span><span class="punctuation token">,</span> blob<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">var</span> iframe <span class="operator token">=</span> <span class="function token">newViewerFrame<span class="punctuation token">(</span></span><span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="comment token"> // </span></code><span id="result_box" lang="fr"><span>Il n'est pas possible de définir un lien direct vers</span></span> <code class="language-js"><span class="comment token"> +</span> <span class="comment token"> // </span></code>le <span id="result_box" lang="fr"><span>blob pour fournir un moyen de le télécharger directement.</span></span> <code class="language-js"><span class="comment token"> +</span> <span class="keyword token">if</span> <span class="punctuation token">(</span>blob<span class="punctuation token">.</span>type <span class="operator token">==</span> <span class="string token">'text/html'</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> reader <span class="operator token">=</span> <span class="keyword token">new</span> <span class="class-name token">FileReader</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + reader<span class="punctuation token">.</span>onload <span class="operator token">=</span> <span class="punctuation token">(</span><span class="keyword token">function</span><span class="punctuation token">(</span>evt<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> html <span class="operator token">=</span> evt<span class="punctuation token">.</span>target<span class="punctuation token">.</span>result<span class="punctuation token">;</span> + iframe<span class="punctuation token">.</span><span class="function token">load<span class="punctuation token">(</span></span><span class="keyword token">function</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + $<span class="punctuation token">(</span><span class="keyword token">this</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">contents<span class="punctuation token">(</span></span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">find<span class="punctuation token">(</span></span><span class="string token">'html'</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">html<span class="punctuation token">(</span></span>html<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + reader<span class="punctuation token">.</span><span class="function token">readAsText<span class="punctuation token">(</span></span>blob<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> <span class="keyword token">else</span> <span class="keyword token">if</span> <span class="punctuation token">(</span>blob<span class="punctuation token">.</span>type<span class="punctuation token">.</span><span class="function token">indexOf<span class="punctuation token">(</span></span><span class="string token">'image/'</span><span class="punctuation token">)</span> <span class="operator token">==</span> <span class="number token">0</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + iframe<span class="punctuation token">.</span><span class="function token">load<span class="punctuation token">(</span></span><span class="keyword token">function</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> img_id <span class="operator token">=</span> <span class="string token">'image-'</span> <span class="operator token">+</span> key<span class="punctuation token">;</span> + <span class="keyword token">var</span> img <span class="operator token">=</span> $<span class="punctuation token">(</span><span class="string token">'<img id="'</span> <span class="operator token">+</span> img_id <span class="operator token">+</span> <span class="string token">'"/>'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + $<span class="punctuation token">(</span><span class="keyword token">this</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">contents<span class="punctuation token">(</span></span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">find<span class="punctuation token">(</span></span><span class="string token">'body'</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">html<span class="punctuation token">(</span></span>img<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">var</span> obj_url <span class="operator token">=</span> window<span class="punctuation token">.</span>URL<span class="punctuation token">.</span><span class="function token">createObjectURL<span class="punctuation token">(</span></span>blob<span class="punctuation token">)</span><span class="punctuation token">;</span> + $<span class="punctuation token">(</span><span class="keyword token">this</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">contents<span class="punctuation token">(</span></span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">find<span class="punctuation token">(</span></span><span class="string token">'#'</span> <span class="operator token">+</span> img_id<span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">attr<span class="punctuation token">(</span></span><span class="string token">'src'</span><span class="punctuation token">,</span> obj_url<span class="punctuation token">)</span><span class="punctuation token">;</span> + window<span class="punctuation token">.</span>URL<span class="punctuation token">.</span><span class="function token">revokeObjectURL<span class="punctuation token">(</span></span>obj_url<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> <span class="keyword token">else</span> <span class="keyword token">if</span> <span class="punctuation token">(</span>blob<span class="punctuation token">.</span>type <span class="operator token">==</span> <span class="string token">'application/pdf'</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + $<span class="punctuation token">(</span><span class="string token">'*'</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">css<span class="punctuation token">(</span></span><span class="string token">'cursor'</span><span class="punctuation token">,</span> <span class="string token">'wait'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">var</span> obj_url <span class="operator token">=</span> window<span class="punctuation token">.</span>URL<span class="punctuation token">.</span><span class="function token">createObjectURL<span class="punctuation token">(</span></span>blob<span class="punctuation token">)</span><span class="punctuation token">;</span> + iframe<span class="punctuation token">.</span><span class="function token">load<span class="punctuation token">(</span></span><span class="keyword token">function</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + $<span class="punctuation token">(</span><span class="string token">'*'</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">css<span class="punctuation token">(</span></span><span class="string token">'cursor'</span><span class="punctuation token">,</span> <span class="string token">'auto'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + iframe<span class="punctuation token">.</span><span class="function token">attr<span class="punctuation token">(</span></span><span class="string token">'src'</span><span class="punctuation token">,</span> obj_url<span class="punctuation token">)</span><span class="punctuation token">;</span> + window<span class="punctuation token">.</span>URL<span class="punctuation token">.</span><span class="function token">revokeObjectURL<span class="punctuation token">(</span></span>obj_url<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> <span class="keyword token">else</span> <span class="punctuation token">{</span> + iframe<span class="punctuation token">.</span><span class="function token">load<span class="punctuation token">(</span></span><span class="keyword token">function</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + $<span class="punctuation token">(</span><span class="keyword token">this</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">contents<span class="punctuation token">(</span></span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">find<span class="punctuation token">(</span></span><span class="string token">'body'</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">html<span class="punctuation token">(</span></span><span class="string token">"No view available"</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> + + <span class="punctuation token">}</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> + + <span class="comment token">/** + * @paramètre {string} <em>(chaîne de caractères)</em> biblioid <em>(identifiant bibliothèque)</em> + * @paramètre {string} <em>(chaîne de caractères) </em>title <em>(titre)</em> + * @paramètre {number} <em>(nombre)</em> year <em>(année)</em> + * @paramètre {string} <em>(chaîne de caractères) </em>url : l'URL de l'image à télécharger et stocker sur le pc + * IndexedDB database. La ressource derrière cette URL assujettie à + * "Same origin policy", donc pour que cette méthode fonctionne, l'URL doit venir de + * la même origine que le site web/l'application sur lequel le code est déployé. + */</span> + <span class="keyword token">function</span> <span class="function token">addPublicationFromUrl<span class="punctuation token">(</span></span>biblioid<span class="punctuation token">,</span> title<span class="punctuation token">,</span> year<span class="punctuation token">,</span> url<span class="punctuation token">)</span> <span class="punctuation token">{</span> + console<span class="punctuation token">.</span><span class="function token">log<span class="punctuation token">(</span></span><span class="string token">"addPublicationFromUrl:"</span><span class="punctuation token">,</span> arguments<span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="keyword token">var</span> xhr <span class="operator token">=</span> <span class="keyword token">new</span> <span class="class-name token">XMLHttpRequest</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + xhr<span class="punctuation token">.</span><span class="function token">open<span class="punctuation token">(</span></span><span class="string token">'GET'</span><span class="punctuation token">,</span> url<span class="punctuation token">,</span> <span class="keyword token">true</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="comment token"> // </span></code> <span class="short_text" id="result_box" lang="fr"><span>Définir le type de réponse recherché à "blob<code>"</code></span></span> <code class="language-js"><span class="comment token"> +</span> <span class="comment token"> // http://www.w3.org/TR/XMLHttpRequest2/#the-response-attribute +</span> xhr<span class="punctuation token">.</span>responseType <span class="operator token">=</span> <span class="string token">'blob'</span><span class="punctuation token">;</span> + xhr<span class="punctuation token">.</span>onload <span class="operator token">=</span> <span class="keyword token">function</span> <span class="punctuation token">(</span>evt<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">if</span> <span class="punctuation token">(</span>xhr<span class="punctuation token">.</span>status <span class="operator token">==</span> <span class="number token">200</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + console<span class="punctuation token">.</span><span class="function token">log<span class="punctuation token">(</span></span><span class="string token">"Blob retrieved"</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">var</span> blob <span class="operator token">=</span> xhr<span class="punctuation token">.</span>response<span class="punctuation token">;</span> + console<span class="punctuation token">.</span><span class="function token">log<span class="punctuation token">(</span></span><span class="string token">"Blob:"</span><span class="punctuation token">,</span> blob<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="function token">addPublication<span class="punctuation token">(</span></span>biblioid<span class="punctuation token">,</span> title<span class="punctuation token">,</span> year<span class="punctuation token">,</span> blob<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> <span class="keyword token">else</span> <span class="punctuation token">{</span> + console<span class="punctuation token">.</span><span class="function token">error<span class="punctuation token">(</span></span><span class="string token">"addPublicationFromUrl error:"</span><span class="punctuation token">,</span> + xhr<span class="punctuation token">.</span>responseText<span class="punctuation token">,</span> xhr<span class="punctuation token">.</span>status<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> + <span class="punctuation token">}</span><span class="punctuation token">;</span> + xhr<span class="punctuation token">.</span><span class="function token">send<span class="punctuation token">(</span></span><span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="comment token"> // </span></code><span id="result_box" lang="fr"><span>Nous ne pouvons pas utiliser jQuery ici car, à partir de jQuery 1.8.3<code>,</code> </span></span><code class="language-js"><span class="comment token"> +</span> <span class="comment token"> // </span></code><span id="result_box" lang="fr"><span>le nouveau "blob"</span></span> <code class="language-js"><span class="comment token">responseType n'est pas géré. +</span> <span class="comment token"> // http://bugs.jquery.com/ticket/11461 +</span> <span class="comment token"> // http://bugs.jquery.com/ticket/7248 +</span> <span class="comment token"> // $.ajax({ +</span> <span class="comment token"> // url: url, +</span> <span class="comment token"> // type: 'GET', +</span> <span class="comment token"> // xhrFields: { responseType: 'blob' }, +</span> <span class="comment token"> // success: function(data, textStatus, jqXHR) { +</span> <span class="comment token"> // console.log("Blob retrieved"); +</span> <span class="comment token"> // console.log("Blob:", data); +</span> <span class="comment token"> // // addPublication(biblioid, title, year, data); +</span> <span class="comment token"> // }, +</span> <span class="comment token"> // error: function(jqXHR, textStatus, errorThrown) { +</span> <span class="comment token"> // console.error(errorThrown); +</span> <span class="comment token"> // displayActionFailure("Error during blob retrieval"); +</span> <span class="comment token"> // } +</span> <span class="comment token"> // }); +</span> <span class="punctuation token">}</span> + + <span class="comment token">/** + * @paramètre {string} <em>(chaîne de caractères)</em> biblioid <em>(identifiant bibliothèque)</em> + * @paramètre {string} <em>(chaîne de caractères) </em>title <em>(titre)</em> + * @paramètre {number} <em>(nombre)</em> year <em>(année)</em> + * @paramètre {Blob=} blob + */</span> + <span class="keyword token">function</span> <span class="function token">addPublication<span class="punctuation token">(</span></span>biblioid<span class="punctuation token">,</span> title<span class="punctuation token">,</span> year<span class="punctuation token">,</span> blob<span class="punctuation token">)</span> <span class="punctuation token">{</span> + console<span class="punctuation token">.</span><span class="function token">log<span class="punctuation token">(</span></span><span class="string token">"addPublication arguments:"</span><span class="punctuation token">,</span> arguments<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">var</span> obj <span class="operator token">=</span> <span class="punctuation token">{</span> biblioid<span class="punctuation token">:</span> biblioid<span class="punctuation token">,</span> title<span class="punctuation token">:</span> title<span class="punctuation token">,</span> year<span class="punctuation token">:</span> year <span class="punctuation token">}</span><span class="punctuation token">;</span> + <span class="keyword token">if</span> <span class="punctuation token">(</span><span class="keyword token">typeof</span> blob <span class="operator token">!</span><span class="operator token">=</span> <span class="string token">'undefined'</span><span class="punctuation token">)</span> + obj<span class="punctuation token">.</span>blob <span class="operator token">=</span> blob<span class="punctuation token">;</span> + + <span class="keyword token">var</span> store <span class="operator token">=</span> <span class="function token">getObjectStore<span class="punctuation token">(</span></span>DB_STORE_NAME<span class="punctuation token">,</span> <span class="string token">'readwrite'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">var</span> req<span class="punctuation token">;</span> + <span class="keyword token">try</span> <span class="punctuation token">{</span> + req <span class="operator token">=</span> store<span class="punctuation token">.</span><span class="function token">add<span class="punctuation token">(</span></span>obj<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> <span class="keyword token">catch</span> <span class="punctuation token">(</span><span class="class-name token">e</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">if</span> <span class="punctuation token">(</span>e<span class="punctuation token">.</span>name <span class="operator token">==</span> <span class="string token">'DataCloneError'</span><span class="punctuation token">)</span> + <span class="function token">displayActionFailure<span class="punctuation token">(</span></span><span class="string token">"This engine doesn't know how to clone a Blob, "</span> <span class="operator token">+</span> + <span class="string token">"use Firefox"</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">throw</span> e<span class="punctuation token">;</span> + <span class="punctuation token">}</span> + req<span class="punctuation token">.</span>onsuccess <span class="operator token">=</span> <span class="keyword token">function</span> <span class="punctuation token">(</span>evt<span class="punctuation token">)</span> <span class="punctuation token">{</span> + console<span class="punctuation token">.</span><span class="function token">log<span class="punctuation token">(</span></span><span class="string token">"Insertion in DB successful"</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="function token">displayActionSuccess<span class="punctuation token">(</span></span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="function token">displayPubList<span class="punctuation token">(</span></span>store<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span><span class="punctuation token">;</span> + req<span class="punctuation token">.</span>onerror <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + console<span class="punctuation token">.</span><span class="function token">error<span class="punctuation token">(</span></span><span class="string token">"addPublication error"</span><span class="punctuation token">,</span> <span class="keyword token">this</span><span class="punctuation token">.</span>error<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="function token">displayActionFailure<span class="punctuation token">(</span></span><span class="keyword token">this</span><span class="punctuation token">.</span>error<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> + + <span class="comment token">/** + * @paramètre {string} <em>(chaîne de caractères)</em> biblioid <em>(identifiant bibliothèque)</em> + */</span> + <span class="keyword token">function</span> <span class="function token">deletePublicationFromBib<span class="punctuation token">(</span></span>biblioid<span class="punctuation token">)</span> <span class="punctuation token">{</span> + console<span class="punctuation token">.</span><span class="function token">log<span class="punctuation token">(</span></span><span class="string token">"deletePublication:"</span><span class="punctuation token">,</span> arguments<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">var</span> store <span class="operator token">=</span> <span class="function token">getObjectStore<span class="punctuation token">(</span></span>DB_STORE_NAME<span class="punctuation token">,</span> <span class="string token">'readwrite'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">var</span> req <span class="operator token">=</span> store<span class="punctuation token">.</span><span class="function token">index<span class="punctuation token">(</span></span><span class="string token">'biblioid'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + req<span class="punctuation token">.</span><span class="keyword token">get</span><span class="punctuation token">(</span>biblioid<span class="punctuation token">)</span><span class="punctuation token">.</span>onsuccess <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span>evt<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">if</span> <span class="punctuation token">(</span><span class="keyword token">typeof</span> evt<span class="punctuation token">.</span>target<span class="punctuation token">.</span>result <span class="operator token">==</span> <span class="string token">'undefined'</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="function token">displayActionFailure<span class="punctuation token">(</span></span><span class="string token">"No matching record found"</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">return</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> + <span class="function token">deletePublication<span class="punctuation token">(</span></span>evt<span class="punctuation token">.</span>target<span class="punctuation token">.</span>result<span class="punctuation token">.</span>id<span class="punctuation token">,</span> store<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span><span class="punctuation token">;</span> + req<span class="punctuation token">.</span>onerror <span class="operator token">=</span> <span class="keyword token">function</span> <span class="punctuation token">(</span>evt<span class="punctuation token">)</span> <span class="punctuation token">{</span> + console<span class="punctuation token">.</span><span class="function token">error<span class="punctuation token">(</span></span><span class="string token">"deletePublicationFromBib:"</span><span class="punctuation token">,</span> evt<span class="punctuation token">.</span>target<span class="punctuation token">.</span>errorCode<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> + + <span class="comment token">/** + * @paramètre {number} <em>(nombre)</em> key <em>(clé)</em> + * @paramètre {IDBObjectStore=} store <em>(objet de stockage)</em> + */</span> + <span class="keyword token">function</span> <span class="function token">deletePublication<span class="punctuation token">(</span></span>key<span class="punctuation token">,</span> store<span class="punctuation token">)</span> <span class="punctuation token">{</span> + console<span class="punctuation token">.</span><span class="function token">log<span class="punctuation token">(</span></span><span class="string token">"deletePublication:"</span><span class="punctuation token">,</span> arguments<span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="keyword token">if</span> <span class="punctuation token">(</span><span class="keyword token">typeof</span> store <span class="operator token">==</span> <span class="string token">'undefined'</span><span class="punctuation token">)</span> + store <span class="operator token">=</span> <span class="function token">getObjectStore<span class="punctuation token">(</span></span>DB_STORE_NAME<span class="punctuation token">,</span> <span class="string token">'readwrite'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="comment token"> // Selon les spécifications http://www.w3.org/TR/IndexedDB/#object-store-deletion-operation +</span> <span class="comment token"> // le résultat de l'objet de stockage, l'algorithme de l'opération de suppression est +</span> <span class="comment token"> // "undefined" (<em>indéfini</em>), donc il n'est pas possible de savoir si certains enregistrements +</span> <span class="comment token"> // ont été effectivement supprimés en lisant le résultat de la requête. +</span> <span class="keyword token">var</span> req <span class="operator token">=</span> store<span class="punctuation token">.</span><span class="keyword token">get</span><span class="punctuation token">(</span>key<span class="punctuation token">)</span><span class="punctuation token">;</span> + req<span class="punctuation token">.</span>onsuccess <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span>evt<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> record <span class="operator token">=</span> evt<span class="punctuation token">.</span>target<span class="punctuation token">.</span>result<span class="punctuation token">;</span> + console<span class="punctuation token">.</span><span class="function token">log<span class="punctuation token">(</span></span><span class="string token">"record:"</span><span class="punctuation token">,</span> record<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">if</span> <span class="punctuation token">(</span><span class="keyword token">typeof</span> record <span class="operator token">==</span> <span class="string token">'undefined'</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="function token">displayActionFailure<span class="punctuation token">(</span></span><span class="string token">"No matching record found"</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">return</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> + <span class="comment token"> // Attention: </span></code> <span id="result_box" lang="fr"><span>La même clé utilisée pour la création doit être transmise pour</span></span> <code class="language-js"><span class="comment token"> +</span> <span class="comment token"> // la suppression. </span></code> <span id="result_box" lang="fr"><span>Si la clé était un nombre pour la création, elle <code>doit</code></span></span><code class="language-js"><span class="comment token"> +</span> <span class="comment token"> // être un nombre pour la suppression. +</span> req <span class="operator token">=</span> store<span class="punctuation token">.</span><span class="keyword token">delete</span><span class="punctuation token">(</span>key<span class="punctuation token">)</span><span class="punctuation token">;</span> + req<span class="punctuation token">.</span>onsuccess <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span>evt<span class="punctuation token">)</span> <span class="punctuation token">{</span> + console<span class="punctuation token">.</span><span class="function token">log<span class="punctuation token">(</span></span><span class="string token">"evt:"</span><span class="punctuation token">,</span> evt<span class="punctuation token">)</span><span class="punctuation token">;</span> + console<span class="punctuation token">.</span><span class="function token">log<span class="punctuation token">(</span></span><span class="string token">"evt.target:"</span><span class="punctuation token">,</span> evt<span class="punctuation token">.</span>target<span class="punctuation token">)</span><span class="punctuation token">;</span> + console<span class="punctuation token">.</span><span class="function token">log<span class="punctuation token">(</span></span><span class="string token">"evt.target.result:"</span><span class="punctuation token">,</span> evt<span class="punctuation token">.</span>target<span class="punctuation token">.</span>result<span class="punctuation token">)</span><span class="punctuation token">;</span> + console<span class="punctuation token">.</span><span class="function token">log<span class="punctuation token">(</span></span><span class="string token">"delete successful"</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="function token">displayActionSuccess<span class="punctuation token">(</span></span><span class="string token">"Deletion successful"</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="function token">displayPubList<span class="punctuation token">(</span></span>store<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span><span class="punctuation token">;</span> + req<span class="punctuation token">.</span>onerror <span class="operator token">=</span> <span class="keyword token">function</span> <span class="punctuation token">(</span>evt<span class="punctuation token">)</span> <span class="punctuation token">{</span> + console<span class="punctuation token">.</span><span class="function token">error<span class="punctuation token">(</span></span><span class="string token">"deletePublication:"</span><span class="punctuation token">,</span> evt<span class="punctuation token">.</span>target<span class="punctuation token">.</span>errorCode<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span><span class="punctuation token">;</span> + req<span class="punctuation token">.</span>onerror <span class="operator token">=</span> <span class="keyword token">function</span> <span class="punctuation token">(</span>evt<span class="punctuation token">)</span> <span class="punctuation token">{</span> + console<span class="punctuation token">.</span><span class="function token">error<span class="punctuation token">(</span></span><span class="string token">"deletePublication:"</span><span class="punctuation token">,</span> evt<span class="punctuation token">.</span>target<span class="punctuation token">.</span>errorCode<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> + + <span class="keyword token">function</span> <span class="function token">displayActionSuccess<span class="punctuation token">(</span></span>msg<span class="punctuation token">)</span> <span class="punctuation token">{</span> + msg <span class="operator token">=</span> <span class="keyword token">typeof</span> msg <span class="operator token">!</span><span class="operator token">=</span> <span class="string token">'undefined'</span> <span class="operator token">?</span> <span class="string token">"Success: "</span> <span class="operator token">+</span> msg <span class="punctuation token">:</span> <span class="string token">"Success"</span><span class="punctuation token">;</span> + $<span class="punctuation token">(</span><span class="string token">'#msg'</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">html<span class="punctuation token">(</span></span><span class="string token">'<span class="action-success">'</span> <span class="operator token">+</span> msg <span class="operator token">+</span> <span class="string token">'</span>'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> + <span class="keyword token">function</span> <span class="function token">displayActionFailure<span class="punctuation token">(</span></span>msg<span class="punctuation token">)</span> <span class="punctuation token">{</span> + msg <span class="operator token">=</span> <span class="keyword token">typeof</span> msg <span class="operator token">!</span><span class="operator token">=</span> <span class="string token">'undefined'</span> <span class="operator token">?</span> <span class="string token">"Failure: "</span> <span class="operator token">+</span> msg <span class="punctuation token">:</span> <span class="string token">"Failure"</span><span class="punctuation token">;</span> + $<span class="punctuation token">(</span><span class="string token">'#msg'</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">html<span class="punctuation token">(</span></span><span class="string token">'<span class="action-failure">'</span> <span class="operator token">+</span> msg <span class="operator token">+</span> <span class="string token">'</span>'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> + <span class="keyword token">function</span> <span class="function token">resetActionStatus<span class="punctuation token">(</span></span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + console<span class="punctuation token">.</span><span class="function token">log<span class="punctuation token">(</span></span><span class="string token">"resetActionStatus ..."</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + $<span class="punctuation token">(</span><span class="string token">'#msg'</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">empty<span class="punctuation token">(</span></span><span class="punctuation token">)</span><span class="punctuation token">;</span> + console<span class="punctuation token">.</span><span class="function token">log<span class="punctuation token">(</span></span><span class="string token">"resetActionStatus DONE"</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> + + <span class="keyword token">function</span> <span class="function token">addEventListeners<span class="punctuation token">(</span></span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + console<span class="punctuation token">.</span><span class="function token">log<span class="punctuation token">(</span></span><span class="string token">"addEventListeners"</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + + $<span class="punctuation token">(</span><span class="string token">'#register-form-reset'</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">click<span class="punctuation token">(</span></span><span class="keyword token">function</span><span class="punctuation token">(</span>evt<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="function token">resetActionStatus<span class="punctuation token">(</span></span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + + $<span class="punctuation token">(</span><span class="string token">'#add-button'</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">click<span class="punctuation token">(</span></span><span class="keyword token">function</span><span class="punctuation token">(</span>evt<span class="punctuation token">)</span> <span class="punctuation token">{</span> + console<span class="punctuation token">.</span><span class="function token">log<span class="punctuation token">(</span></span><span class="string token">"add ..."</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">var</span> title <span class="operator token">=</span> $<span class="punctuation token">(</span><span class="string token">'#pub-title'</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">val<span class="punctuation token">(</span></span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">var</span> biblioid <span class="operator token">=</span> $<span class="punctuation token">(</span><span class="string token">'#pub-biblioid'</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">val<span class="punctuation token">(</span></span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">if</span> <span class="punctuation token">(</span><span class="operator token">!</span>title <span class="operator token">||</span> <span class="operator token">!</span>biblioid<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="function token">displayActionFailure<span class="punctuation token">(</span></span><span class="string token">"Required field(s) missing"</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">return</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> + <span class="keyword token">var</span> year <span class="operator token">=</span> $<span class="punctuation token">(</span><span class="string token">'#pub-year'</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">val<span class="punctuation token">(</span></span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">if</span> <span class="punctuation token">(</span>year <span class="operator token">!</span><span class="operator token">=</span> <span class="string token">''</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="comment token"> // Le mieux est d'utiliser Number.isInteger si le moteur a EcmaScript 6 +</span> <span class="keyword token">if</span> <span class="punctuation token">(</span><span class="function token">isNaN<span class="punctuation token">(</span></span>year<span class="punctuation token">)</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="function token">displayActionFailure<span class="punctuation token">(</span></span><span class="string token">"Invalid year"</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">return</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> + year <span class="operator token">=</span> <span class="function token">Number<span class="punctuation token">(</span></span>year<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> <span class="keyword token">else</span> <span class="punctuation token">{</span> + year <span class="operator token">=</span> <span class="keyword token">null</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> + + <span class="keyword token">var</span> file_input <span class="operator token">=</span> $<span class="punctuation token">(</span><span class="string token">'#pub-file'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">var</span> selected_file <span class="operator token">=</span> file_input<span class="punctuation token">.</span><span class="keyword token">get</span><span class="punctuation token">(</span><span class="number token">0</span><span class="punctuation token">)</span><span class="punctuation token">.</span>files<span class="punctuation token">[</span><span class="number token">0</span><span class="punctuation token">]</span><span class="punctuation token">;</span> + console<span class="punctuation token">.</span><span class="function token">log<span class="punctuation token">(</span></span><span class="string token">"selected_file:"</span><span class="punctuation token">,</span> selected_file<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="comment token"> // </span></code><span id="result_box" lang="fr"><span>Garder une référence sur la façon de réinitialiser l'entrée du fichier dans l'interface</span></span><code class="language-js"><span class="comment token"> +</span> <span class="comment token"> // </span></code><span lang="fr"><span>utilisateur une fois que nous</span></span><code> avons sa valeur</code><code class="language-js"><span class="comment token">, mais au lieu de faire cela nous utiliserons +</span> <span class="comment token"> // plutôt un type "reset" entré dans le formulaire HTML . +</span> <span class="comment token"> // file_input.val(null); +</span> <span class="keyword token">var</span> file_url <span class="operator token">=</span> $<span class="punctuation token">(</span><span class="string token">'#pub-file-url'</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">val<span class="punctuation token">(</span></span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">if</span> <span class="punctuation token">(</span>selected_file<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="function token">addPublication<span class="punctuation token">(</span></span>biblioid<span class="punctuation token">,</span> title<span class="punctuation token">,</span> year<span class="punctuation token">,</span> selected_file<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> <span class="keyword token">else</span> <span class="keyword token">if</span> <span class="punctuation token">(</span>file_url<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="function token">addPublicationFromUrl<span class="punctuation token">(</span></span>biblioid<span class="punctuation token">,</span> title<span class="punctuation token">,</span> year<span class="punctuation token">,</span> file_url<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> <span class="keyword token">else</span> <span class="punctuation token">{</span> + <span class="function token">addPublication<span class="punctuation token">(</span></span>biblioid<span class="punctuation token">,</span> title<span class="punctuation token">,</span> year<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> + + <span class="punctuation token">}</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + + $<span class="punctuation token">(</span><span class="string token">'#delete-button'</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">click<span class="punctuation token">(</span></span><span class="keyword token">function</span><span class="punctuation token">(</span>evt<span class="punctuation token">)</span> <span class="punctuation token">{</span> + console<span class="punctuation token">.</span><span class="function token">log<span class="punctuation token">(</span></span><span class="string token">"delete ..."</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">var</span> biblioid <span class="operator token">=</span> $<span class="punctuation token">(</span><span class="string token">'#pub-biblioid-to-delete'</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">val<span class="punctuation token">(</span></span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">var</span> key <span class="operator token">=</span> $<span class="punctuation token">(</span><span class="string token">'#key-to-delete'</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">val<span class="punctuation token">(</span></span><span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="keyword token">if</span> <span class="punctuation token">(</span>biblioid <span class="operator token">!</span><span class="operator token">=</span> <span class="string token">''</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="function token">deletePublicationFromBib<span class="punctuation token">(</span></span>biblioid<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> <span class="keyword token">else</span> <span class="keyword token">if</span> <span class="punctuation token">(</span>key <span class="operator token">!</span><span class="operator token">=</span> <span class="string token">''</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="comment token"> // Le mieux est d'utiliser Number.isInteger si le moteur a EcmaScript 6 +</span> <span class="keyword token">if</span> <span class="punctuation token">(</span>key <span class="operator token">==</span> <span class="string token">''</span> <span class="operator token">||</span> <span class="function token">isNaN<span class="punctuation token">(</span></span>key<span class="punctuation token">)</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="function token">displayActionFailure<span class="punctuation token">(</span></span><span class="string token">"Invalid key"</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">return</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> + key <span class="operator token">=</span> <span class="function token">Number<span class="punctuation token">(</span></span>key<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="function token">deletePublication<span class="punctuation token">(</span></span>key<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> + <span class="punctuation token">}</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + + $<span class="punctuation token">(</span><span class="string token">'#clear-store-button'</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">click<span class="punctuation token">(</span></span><span class="keyword token">function</span><span class="punctuation token">(</span>evt<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="function token">clearObjectStore<span class="punctuation token">(</span></span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="keyword token">var</span> search_button <span class="operator token">=</span> $<span class="punctuation token">(</span><span class="string token">'#search-list-button'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + search_button<span class="punctuation token">.</span><span class="function token">click<span class="punctuation token">(</span></span><span class="keyword token">function</span><span class="punctuation token">(</span>evt<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="function token">displayPubList<span class="punctuation token">(</span></span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="punctuation token">}</span> + + <span class="function token">openDb<span class="punctuation token">(</span></span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="function token">addEventListeners<span class="punctuation token">(</span></span><span class="punctuation token">)</span><span class="punctuation token">;</span> + +<span class="punctuation token">}</span><span class="punctuation token">)</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span><span class="comment token"> // Immediately-Invoked Function Expression (IIFE)</span></code></pre> + +<p>{{ LiveSampleLink('Full_IndexedDB_example', "Test the online live demo") }}</p> + +<h2 id="Voir_aussi">Voir aussi</h2> + +<p>Référence :</p> + +<ul> + <li><a href="/en/IndexedDB" title="https://developer.mozilla.org/en/IndexedDB">IndexedDB API Reference</a></li> + <li><a class="external" href="http://www.w3.org/TR/IndexedDB/" title="http://www.w3.org/TR/IndexedDB/">Indexed Database API Specification</a></li> + <li><a href="/en-US/docs/IndexedDB/Using_IndexedDB_in_chrome" title="/en-US/docs/IndexedDB/Using_IndexedDB_in_chrome">Using IndexedDB in chrome</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Using_JavaScript_Generators_in_Firefox">Using JavaScript generators in Firefox</a></li> + <li>IndexedDB <a class="link-https" href="https://mxr.mozilla.org/mozilla-central/find?text=&string=dom%2FindexedDB%2F.*%5C.idl&regexp=1" title="https://mxr.mozilla.org/mozilla-central/find?text=&string=dom/indexedDB/.*\.idl&regexp=1">interface files</a> dans le code source de Firefox</li> +</ul> + +<p>Tutoriels :</p> + +<ul> + <li><a href="http://www.html5rocks.com/en/tutorials/indexeddb/uidatabinding/" title="http://www.html5rocks.com/en/tutorials/indexeddb/uidatabinding/">Databinding UI Elements with IndexedDB</a></li> + <li><a class="external external-icon" href="http://msdn.microsoft.com/en-us/scriptjunkie/gg679063.aspx" title="http://msdn.microsoft.com/en-us/scriptjunkie/gg679063.aspx">IndexedDB — The Store in Your Browser</a></li> +</ul> + +<p>Bibliothèques :</p> + +<ul> + <li><a href="http://mozilla.github.io/localForage/">localForage </a>: Un Polyfill <span id="result_box" lang="fr"><span>qui fournit un nom simple : la syntaxe de valeur pour le stockage de données côté client, qui utilise IndexedDB en arrière-plan, mais retourne à WebSQL puis à localStorage pour les navigateurs qui ne prennent pas en charge IndexedDB.</span></span></li> + <li><a href="http://www.dexie.org/">dexie.js </a>: <span id="result_box" lang="fr"><span>Une enveloppe pour IndexedDB qui permet un développement de code beaucoup plus rapide grâce à une syntaxe simple et agréable.</span></span></li> + <li><a href="https://github.com/erikolson186/zangodb">ZangoDB </a>: Un MongoDB-like interface pour IndexedDB <span id="result_box" lang="fr"><span>qui prend en charge la plupart des fonctionnalités familières de filtrage, projection, tri, mise à jour et agrégation de </span></span> MongoDB.</li> + <li><a href="http://jsstore.net/">JsStore</a> : <span id="result_box" lang="fr"><span>Une enveloppe d'IndexedDB simple et avancée ayant une syntaxe SQL.</span></span></li> +</ul> |