Using LiteDB in PowerShell 7

0
564

LiteDB is a .NET native NoSQL embedded database. Built-in .NET, LiteDB is easily accessible to PowerShell and works wonderfully as a local and flexible database. Built-in encryption, SQL-like commands, and ACID-compliant with full transaction support LiteDB is simple and easy to use. In this article, we will talk about you can use LiteDB within PowerShell and potential use cases!

Installing LiteDB in PowerShell

Available as a NuGet package, LiteDB is easily installable as a package using the Install-Package cmdlet. The latest version, at the time of publication, is version 5.0.9, which we are targeting as the minimum version. Additionally, to avoid the need for administrative rights, we are installing this under the CurrentUser scope.

Install-Package -Name ‘LiteDB’ -MinimumVersion ‘5.0.9’ -Source ‘nuget.org’ -Scope ‘CurrentUser’

Next, we are going to import the library for use. You can simply use Add-Type and point to the path of the assembly, but we can automate that.

# Test if we have already loaded the assembly by looking for the PSType of LiteDB.LiteDatabase
If ( -Not ([System.Management.Automation.PSTypeName]’LiteDB.LiteDatabase’).Type ) {
# 1) Get the path of the LiteDB package using the Source
# 2) This returns the *.nupkg file, so we use Split-Path to only return the package root path
# 3) Multiple DLL’s will exist, usually for .NET 4.5, .NET Standard 1.3, and .NET Standard 2.0. Locate only the .NET Standard and the latest version, in this case 2.0.
# The path will look something like: C:\Users\username\AppData\Local\PackageManagement\NuGet\Packages\LiteDB.5.0.9\lib\netstandard2.0\LiteDB.dll
$standardAssemblyFullPath = (Get-ChildItem -Filter ‘*.dll’ -Recurse (Split-Path (Get-Package -Name ‘LiteDB’).Source)).FullName | Where-Object {$_ -Like “*standard*”} | Select-Object -Last 1

Add-Type -Path $standardAssemblyFullPath -ErrorAction ‘SilentlyContinue’
}

Now that we have loaded the module for use, read on to create a new LiteDB database in the next section!

Creating a New LiteDB Database

There are a number of commands available for LiteDB, which you can learn about here, but we first need to create a brand new database. We will need to define the path where to create the database file. Since LiteDB creates single file databases, the database can be located anywhere. In this case, we will locate the DB in our current path and use the name of Test.db.

# Create the Test.db database in the current directory
$Database = [LiteDB.LiteDatabase]::New((Join-Path -Path “.” -ChildPath “Test.db”))

Keep in mind that until you call $Database.Dispose() on the database file, the Test.db file will remain locked.

In the next section we will create a table, add an index, and create a new record in our database.

Creating a Table and Adding a Record into LiteDB

Similar to tables in SQL, LiteDB uses Collections, similar to MongoDB. For this article, we will create a new collection named TestCollection, and by using GetCollection() the collection will be created if it doesn’t already exist.

# Retrieve the collection (i.e. table) to store our data in.
$Collection = $Database.GetCollection(‘TestCollection’)

# Make sure that an index exists on the Name field so that queries work easier and quicker.
# To allow for named queries, such as using the Name field, we ensure an index is created.
# The result is sent to Out-Null to avoid the True console output on creation.
$Collection.EnsureIndex(‘Name’) | Out-Null

Indexes are valuable as they increase performance and allow for easily named queries when searching for a record. Implemented using skip-lists, indexes avoid a full-scan and deserialization of the database every time a search is done.

Adding a Record Into a LiteDB Collection

First, we need to set up the LiteDB.BSONMapper. This is LiteDB’s implementation of documents, which stores key-value pairs. We first create a mapper that we can parse a PowerShell object into a document that can then be added to our collection using the Insert() method.

$BSONMapper = [LiteDB.BSONMapper]::New()

$Object = @{
“Name” = ‘TestName’
“Value” = ‘TestValue’
}

Try {
# Attempt to insert the object as a new collection entry.
$Collection.Insert($BSONMapper.ToDocument($Object))
} Catch {
Throw “Unable to insert item.”
}

Querying Records in LiteDB

To query an object in LiteDB, we can use several different methods such as:

  • FindAll() – Return all documents in a collection.
  • FindOne() – Returns FirstOrDefault of a Find() query.
  • FindById() – Returns SingleOrDefault result of Find() by using the primary key of _id index.
  • Find() – Return all documents using the defined expression.

In this example, let’s query all the documents and then just the one that we are looking for. We can also test if the document exists, using the Exists() method. To demonstrate this, we will first verify that the document exists, then locate the first document with the name TestName and finally locate all documents. To demonstrate the last method, we have added an additional document of the same name but a different value.

# Test if the `TestName` document exists
$Collection.Exists(“`$.Name = ‘TestName'”)
# Return the first `TestName` document found
$Collection.FindOne(“`$.Name = ‘TestName'”)
# Display all documents in a collection
$Collection.FindAll()

Verify that the document exists, located the specific document, and then all documents.

Updating and Removing a Document

Now that we have created a document, let’s update the value. This is done using the aptly named Update() method.

$Item = $Collection.FindOne(“`$.Name = ‘TestName'”)

$Item[‘Value’] = ‘UpdatedValue’

Try {
# Attempt to update the existing document with the updated value
$Collection.Update($Item)
} Catch {
Throw “Unable to update item.”
}

Of course, we may not want to keep this document. Therefore, we can remove the document using the Remove() method. This requires us to know the ID of the document. Since we already have the information in the $Item variable, we can leverage the _id property to remove the document.

Try {
# Remove the entry using the _id attribute, internal to the LiteDB database
$Collection.Delete($Item[‘_id’].RawValue)
} Catch {
Throw “Unable to delete item.”
}

Cleaning up the Database and Next Steps

Since the database is locked when in use, we need to call the Dispose() method to remove the lock. This is an important step, otherwise, we may end up with corruption.

$Database.Dispose()

With that, we have demonstrated end-to-end examples of creating a database, creating and updating documents, and removing those documents. There are many possible uses for LiteDB, such as a temporary data collection database on a server, to a fast and portable document storage system that can be easily backed up. Explore LiteDB and see what you can do with it today!