vendredi 28 mai 2021

PowerShell et LiteDB v5

Nous allons voir dans cet article l'utilisation de la base de données LiteDB v5 dans un environnement Windows PowerShell. La nouvelle version LiteDB v5, présenté ici, tourne dans l'environnement FrameWork 4.5. 

Attention :
Les scripts PowerShell écrits pour la version LiteDB v3 ne sont pas compatible avec la version v5. Il n'est donc pas possible de simplement remplacer la Dll "LiteDB.Dll v3" par la Dll "LiteDB.Dll v5".

Référence


Toujours à la recherche d'une base de données légère pour mes scriptes PowerShell, j'ai découvert LiteDB. Cette base de données "sans serveur" se présente sous la forme d'une simple Dll de moins de 500Ko. Elle ne nécessite ni installation, ni droit administrateur. LiteDB est donc facilement portable pour peu que le FrameWork 4.5 (ou compatible) soit installé sur le système.

Site de référence : http://www.litedb.org

Notice :
- Ouvrir le site de Litedb.org.
- Cliquer sur "Download".
- Cliquer sur "Download package" (à droite).
- Ouvrir le dossier de téléchargement.
- Ouvrir le fichier "litedb.5.0.10.nupkg" avec WinZip (ou équivalent).
- Récupérer les fichiers "LiteDB.dll" et "LiteDB.xml" qui se trouvent dans le dossier "net45".

Exemple


Dans l'exemple ci-dessous, j'utilise la version LiteDB 5.0.10.

 
################################################################
#
#               Base de données : LiteBD v5.0.10
#                     Powershell.sekki.fr
#
# 1 - Créer un dossier ldb à côté du script.
# 2 - Télécharger et copier LiteDB.dll+xml dans le dossier ldb.
#
################################################################

#Chemin courant.
$curpath = ""
if ($psISE) { $curpath = split-path -parent $psISE.CurrentFile.Fullpath }
else        { $curpath = Split-Path $MyInvocation.MyCommand.Path  }

#Charge les fonctions LiteDB.
Try   { [void][Reflection.Assembly]::LoadFile($curpath+"\ldb\LiteDB.dll") }
Catch { write-host "LiteDB.dll manquant.";Return 2 }

###Fonctions personnalisées.
#Renvoi un nombre entre 0 et 100.
function GR() { Get-Random -minimum 0 -maximum 100 }

###Fonctions personnalisées.
#Converti le résultat de la query pour l'afficher.
function BsonToObj($bsn)
 {
   #Conversion avec la version (Modifié pour LiteDB v5).
   $obj = New-Object System.Object
   $obj | Add-Member -type NoteProperty -name id    -Value $bsn["_id"].AsObjectID
   $obj | Add-Member -type NoteProperty -name date  -Value $bsn["date"].AsString
   $obj | Add-Member -type NoteProperty -name info1 -Value $bsn["Nom"].AsString
   $obj | Add-Member -type NoteProperty -name info2 -Value $bsn["Prix"].AsInt32
   $obj | Add-Member -type NoteProperty -name info3 -Value $bsn["Cat"].AsString
   $obj
 }

#Ouvrir/Créer une Base de Données.
$db = New-Object LiteDB.LiteDatabase(($curpath+"\ldb\LiteDB.db"),$null)

#Ouvrir/Créer une Collection.
$coll = $db.GetCollection("Info")

#Créer un document Bson.
$bson = New-Object LiteDB.BsonDocument

#Créer 10 enregistrements.
for($i=0;$i -le 10;$i++)
 {
   $x = GR   #Nombre aléatoire entre 0 et 100.
   if ($x -le 50) { $nom = "Sekki";   $prix = $x; $cat = "Z" }
   else           { $nom = "Jumbor";  $prix = $x; $cat = "B" }
 
   #Ajouter un enregistrement dans la base de données.
   $bson["_id"]    = [LiteDB.ObjectId]::NewObjectId()
   $bson["date"]   = date -format "dd/MM/yyyy"
   $bson["Nom"]    = [string]$nom
   $bson["Prix"]   = [int]$prix
   $bson["Cat"]    = [string]$cat
   [void]$coll.Insert($bson)   #Insére le document dans la collection.
 }

#Afficher une requête.
$query = $coll.Find([LiteDB.Query]::all())
$query | %{BsonToObj $_} | Out-GridView

################################################################
### Modifier / Supprimer.
################################################################

#Modifier un enregistrement.
$query = $coll.Find([LiteDB.Query]::eq("Nom","Sekki"))
foreach ($q in $query)
 {
   $q["Cat"] = "A"
   [void]$coll.Update($q)
 }

#Supprimer un enregistrement : Méthode 1.
$query = $coll.Find([LiteDB.Query]::eq("Nom","Sekki"))
foreach ($q in $query)
 {
   $coll.Delete($q["_id"])
 }

#Supprimer un enregistrement : Méthode 2 (Modifié pour LiteDB v5).
$nb = $coll.DeleteMany([LiteDB.Query]::eq("Nom","Jumbor"))

################################################################
### Les requêtes.
################################################################

#Renvoi les articles dont le nom exact est :
$query = $coll.Find([LiteDB.Query]::eq("Nom","Sekki"))

#Renvoi les articles dont le prix est plus grand que :
$query = $coll.Find([LiteDB.Query]::gt("Prix",30))

#Renvoi les articles dont le prix est plus petit que :
$query = $coll.Find([LiteDB.Query]::lt("Prix",30))

#Renvoi les articles dont le nom commence par :
$query = $coll.Find([LiteDB.Query]::startswith("Nom","S"))

#Renvoi tout les enregistrements :
$query = $coll.Find([LiteDB.Query]::all())

#Afficher une requête.
$query = $coll.Find([LiteDB.Query]::all())
$query | %{BsonToObj $_} | Out-GridView

################################################################
### Les fichiers (Modifié pour LiteDB v5).
################################################################

###Charger des fichiers dans la base de données.
#Insérer/remplacer un fichier dans la base de données :
$db.FileStorage.Upload("$/Fichiers/file1.jpg", $curpath+"\file1.jpg")

#Lire un fichier dans la base de données et l'enregistrer sur le disque local :
$file = $db.FileStorage.FindById("$/Fichiers/file1.jpg")
$file.SaveAs($curpath+"\file2.jpg")

#Lire un fichier dans la base de données et le charger dans une variable :
$file = $db.FileStorage.FindById("$/Fichiers/file1.jpg")
$image = [System.Drawing.Image]::FromStream($file.OpenRead())

#Supprimer un fichier dans la base de données :
$db.FileStorage.Delete("$/Fichiers/file1.jpg")

################################################################

#Pause
if (!$psISE) { Write-Host -NoNewLine "Press any key to continue..."
               $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") }

#Compresser la base de données (Modifié pour LiteDB v5).
[void]$db.Rebuild()

#Fermer la base de données.
$db.Dispose()

#Fin.