Cet article est très ancien. Les choses ont bien changées depuis 2012. Le sujet abordé est conservé pour référence mais n'est certainement plus applicable en l'état.
Cet article est susceptible de référencer des images manquantes ou de contenir des erreurs de formatage sur son contenu. Il s'agit d'un import provenant d'un ancien blog.
Ce n’est pas forcément recommandé lorsqu’on utilise un CMS d’exploiter sa base hors de son contexte (web), mais c’est parfois nécessaire. Notamment si l’on veut effectuer des traitements différés, à partir d’un automate ou d’un service Windows par exemple.
C’est exactement ce qu’il m’a fallu faire pour un service d’indexation. Pour la petite histoire, le cas qui m’a intéressé est celui-ci : responsable de plusieurs sites Umbraco hébergés sur un partage réseau (NAS), j’ai mis en place un service Windows pour l’indexation des documents et des médias dans un répertoire Lucene. Lucene n’appréciant guère les partages réseau, sans compter que la mise à jour de l’index ne peut être effectuée que par un thread à la fois, cela rend la mise à jour de cet index plus compliquée depuis le site d’une ferme web. Le service en question devait donc être en mesure de lire en base de données les propriétés des noeuds (de type contenu et média) afin de les indexer.
Version d’Umbraco
Cet article est basé sur Umbraco 4.7. Au moment de la rédaction de cet article, la dernière version est la 4.11.1 (voir le projet sur Codeplex pour connaître la version actuelle).
Bien qu’assez ancienne, il est à noter que le modèle de données d’Umbraco 4.7 n’a que peu évolué. Je pense que les requêtes ci-dessous fonctionneront avec les versions suivantes (peut-être avec de très légères adaptations). Umbraco 4.11.1 se base toujours sur la base de données de la version 4.8.
SQL
C’est en fait relativement simple. Il faut savoir deux choses :
- La fonctionnalité de rollback d’Umbraco (c’est-à-dire sa capacité de restaurer une ancienne version d’un noeud) s’appuie sur un versioning de chaque propriété de ce noeud. Ceci permet notamment de restaurer une ancienne version d’un noeud même si sa structure (ses propriétés) a changée.
- Les médias ne sont pas versionnés.
À chaque noeud est associé un historique de propriétés, chacune appartenant à une version particulière. La version est identifiée par un GUID. Les propriétés d’un média ont également une version, mais il n’y en a qu’une seule (pas d’historisation).
Voici un schéma simplifié (Hendy Racher propose également un schéma instructif sur son blog) :
SELECT
data.contentNodeId,
data.versionId,
data.propertytypeid,
ISNULL
(
CAST(dataInt as varchar(max)),
ISNULL
(
CAST(dataDate as varchar(max)),
ISNULL(
CAST(dataNtext as varchar(max)),
CAST([dataNvarchar] as varchar(max)))
)
) as dataString,
dataInt,
dataDate,
dataNText,
dataNvarchar,
t.dataTypeId,
t.contentTypeId,
t.Alias
FROM cmsPropertyData data
INNER JOIN cmsPropertyType t ON t.id = data.propertytypeid
WHERE
data.contentNodeId = 1056
AND data.versionId = 'EF8553C5-59C1-4E6A-A091-D8DEAE85B4CA'
La requête ci-dessus retourne les propriétés du noeud 1056, en version EF8553C5-59C1-4E6A-A091-D8DEAE85B4CA. La colonne dataString contient la valeur de la propriété sous forme de chaîne. Le nom de la propriété est contenu dans la colonne Alias. Dans la base de données, la colonne cmsPropertyData.versionId peut valoir null
. À ma connaissance, cela n’est cependant pas possible en pratique et l’on peut considérer que ce cas n’arrivera pas. Je me suis appuyé sur un historique de plus d’un an et toutes les lignes ont une version.
Noter que la nature du noeud n’est pas connue ici. Il peut s’agir d’un document (contenu), d’un média, mais également d’une feuille de style, d’un template, etc..
Dans Umbraco, chaque noeud a une nature identifiée par un GUID. Par exemple :
- C66BA18E-EAF3-4CFF-8A22-41B16D66A972 : document
- B796F64C-1F99-4FFB-B886-4BF4BC011A9C : media
La liste complète des types de noeud est dans la documentation officielle.
La requête suivante permet d’obtenir la liste des documents du site (noeuds de contenu) afin de connaître notamment l’identifiant du noeud et sa dernière version:
SELECT
doc.nodeId,
doc.published,
doc.documentUser,
doc.versionId,
doc.text,
doc.releaseDate,
doc.expireDate,
doc.updateDate,
doc.templateId,
doc.alias,
doc.newest
FROM umbracoNode node
INNER JOIN cmsDocument doc
ON
node.trashed = 0
AND node.id = doc.nodeId
AND doc.newest = 1
-- AND node.nodeObjectType = 'C66BA18E-EAF3-4CFF-8A22-41B16D66A972'
La table cmsDocument ne contient en fait que les noeuds de contenu, il est donc inutile d’ajouter un critère sur la nature du noeud (umbracoNode.nodeObjectType).
Pour obtenir les médias (et de façon générale tout noeud de nature autre que document), il faut interroger la table umbracoNode de la même façon. La version devra être récupérée avec une requête distincte sur la table cmsContentVersion:
SELECT
id,
parentID,
nodeUser,
level,
path,
sortOrder,
uniqueID,
text,
nodeObjectType,
createDate
FROM umbracoNode node
WHERE
node.nodeObjectType = 'B796F64C-1F99-4FFB-B886-4BF4BC011A9C'
AND trashed=0
Pour obtenir la dernière version du noeud 1059:
SELECT TOP 1 VersionId
FROM cmsContentVersion
WHERE contentid = 1059
ORDER BY VersionDate DESC
Les deux précédentes requêtes peuvent évidemment être fusionnées:
SELECT
id,
parentID,
nodeUser,
level,
path,
sortOrder,
uniqueID,
text,
nodeObjectType,
createDate,
(
SELECT TOP 1 VersionId
FROM cmsContentVersion ver
WHERE ver.ContentId=node.id
ORDER BY VersionDate DESC
) as VersionId
FROM umbracoNode node
WHERE
node.nodeObjectType='B796F64C-1F99-4FFB-B886-4BF4BC011A9C'
AND trashed=0
Avec ces cinq requêtes, on est en mesure d’obtenir facilement la liste des noeuds du site, quelque soit leur nature, et l’ensemble de leurs propriétés.