PocketBaseClient 0.6.1

dotnet add package PocketBaseClient --version 0.6.1                
NuGet\Install-Package PocketBaseClient -Version 0.6.1                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="PocketBaseClient" Version="0.6.1" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add PocketBaseClient --version 0.6.1                
#r "nuget: PocketBaseClient, 0.6.1"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install PocketBaseClient as a Cake Addin
#addin nuget:?package=PocketBaseClient&version=0.6.1

// Install PocketBaseClient as a Cake Tool
#tool nuget:?package=PocketBaseClient&version=0.6.1                

This project is in active development. Things described bellow could change.

PocketBaseClient

With PocketBaseClient and the code generated for your application with pbcodegen, you can interact with your PocketBase server without having to worry about communication, APIs, object binding, cache management, etc.

It is an ORM connected to your PocketBase server with your application.

You will be able to do things like:

var myApp = new MyTodoListApplication(); // Binding to PocketBase 'my-todo-list' application
var myData = myApp.Data; // The data of the application

var tasks = myData.TasksCollection; // Collection "tasks"

// Iterate over entire collection
foreach (var task in tasks)
    Console.WriteLine($"{task.Title} ({task.Status}): {task.Description}");

// Filter your data: Paused tasks updated long time ago
var oldPausedTasks = tasks.Filter(t => t.Status.Equal(Task.StatusEnum.Paused).And(
                                            t.Updated.LessThan(DateTime.Now.AddMonths(-1))));

// Find an element
var users = myData.UsersCollection; // Collection "users"
var me = users.GetById("qwertyuiop");

// Modify your elements
foreach (var oldPausedTask in oldPausedTasks)
{
    oldPausedTask.Status = Task.StatusEnum.ToDo; // Status is an Enum (type select)
    oldPausedTask.AssignedTo = me;  // AssignedTo is an User (type relation)
}

// Create a new element
var newTask = new Task
{
    Title = "A new Task",
    Description = "Lorem ipsum...",
    Status = Task.StatusEnum.ToDo,
};

// Save all changes to PocketBase (also new elements)
myData.SaveChanges();

PocketBaseClient-csharp is a Client library in C# for interacting with a particular PocketBase application: It maps all the PocketBase Collections and Registries to Objects and structures to work in c#

Set up an ORM to access your PocketBase application data in less than 1 minute with pbcodegen, the PocketBaseClient CodeGenerator

Installation

The only thing that you need is pbcodegen. Download the latest version from the Releases section, and follow the process.

In less than 1 minute you will have a customized ORM in c# for your PocketBase application, your own PocketBaseClient.

More information in pbcodegen

Overview

Code Generator

pbcodegen generates your PocketBaseClient, the ORM for your PocketBase application in less than 1 munute:

It connects to your PocketBase (with admin rights) and generates a c# project for you, with all the logic for the management of comunications with server and persistence of objects. Exposes custom classes and structures that maps to your Collections and Registries.

In your .NET projects, you will only need a reference to this generated project to access your PocketBase application.

See more information in pbcodegen

What PocketBaseClient can do

PocketBaseClient uses the classes generated to map data and operate with a particular PocketBase application:

  1. Creating enums for fields of type "Select".

  2. Assigning validation rules for all fields with restrictions.

  3. Mapping related registry Ids to relations between objects.

  4. Managing the comunication with PocketBase server.

  5. Caching objects in memory to minimize the api calls.

  6. Getting unknown object data from server when needed (lazy load).

  7. Registering changed objects that are in memory and not updated to server.

  8. Registering new objects in memory that will map to a new registry in the server.

  9. Exposing a simple fluent Filter adapted to the objects

  10. CRUD options with objects

  11. ...

Is a real ORM for a concrete PocketBase application.

Ok, it sounds good, but, how really works?

How it works

The magic happens at the junction of PocketBaseClient library and the code generated with PocketBaseClient.CodeGenerator:

  • Every Collection has its own class with internal cache for its Registries

  • Registries have their own class, mapping fields to properties

  • Each Registry field is mapped to the correct type, enum or class

Collections and Model Registries

Each collection has its own class, and internally mantains a cache for its objects. Every object in a Collection is (or will be) a Registry in the mapped PocketBase Collection.

Every registry belongs to a Collection. This is translated as every Modeled object belongs to a Collection: also new ones (that are only in memory, without a Registry in the server yet).

When is created a new object that would become a Registry in PocketBase, it is registered automatically to the correct Collection.

Every change in an object that maps to a registry, marks the object as "modified".

The changes in memory of the objects can be discarded or saved.

There is only a function Save to save objects to server, it does not matter if the Registry is to be created, updated or deleted in PocketBase.

Cache

Every time a Registry is downloaded from PocketBase, it will be mapped as an object and cached.

The new objects are also cached: they live in memory until they are saved to PocketBase.

The deleted objects are marked as "to be deleted in PocketBase"

When an element is requested, by default PocketBaseClient will try to serve it from memory and if it is not cached, from server. This behavior can be modified at every call.

Methods and Properties

There are a lot of properties and methods in any modeled object:

Collections

  • Information about the Collection (properties Id, Name and System)

  • Get all elements of the collection (enumerate over the collection, implements IEnumerable<T>, or use the method GetItems)

  • Get an element by Id (methods GetById and GetByIdAsync)

  • Check if contains an element (method Contains)

  • Delete an element (method Delete)

  • Save to server all changes in the collection and its elements (create, update or delete) (methods SaveChanges, SaveChangesAsync)

  • Discard changes in the collection that are not saved to server (method DiscardChanges)

  • Query elements (property Filter). This will be explained below

Object Models

  • Each field has its own Property with the correct type

  • Information about collection (properties Collection, CollectionId and CollectionName)

  • Information about the object status (property Metadata_, see Object Metadata)

  • Validate object data (method Validate or properties Metadata_.IsValid and Metadata_.ValidationErrors)

  • Reload the object with data in server (methods Reload and ReloadAsync)

  • Delete the element (method Delete)

  • Discard local changes of the object (method DiscardChanges)

  • Save element to server (create or update) (methods Save and SaveAsync)

  • Check if two objects references the same registry (method IsSame)

  • Update the object with data of other (method UpdateWith)

Object Metadata

Contains properties with information about the object:

  • Validation: IsValid, ValidationErrors

  • Changes: HasLocalChanges, FirstChange, LastChange

  • Status: IsCached, IsLoaded, IsNew, IsTobeDeleted, IsTrash, SyncStatus

Querying

(Documentation incomplete)

Usage

Supose this PocketBase Schema of an application with name 'my-todo-list':

 ┌──────────────────┐       ┌──────────────────┐
 │ todo_lists       │       │ tasks            │       ┌────────────────┐
 ├──────────────────┤       ├──────────────────┤       │ priorities     │
 │ name        :T   │       │ title       :T   │       ├────────────────┤
 │ description :T   │     N │ description :T   │     1 │ name        :T │
 │ tasks       :Rel ------->│ priority    :Rel ------->│ value       :# │
 └──────────────────┘       │ status      :Sel │       │ description :T │
                            │     │to do       │       └────────────────┘
                            │     │doing       │
                            │     │paused      │
                            │     │done        │
                            └──────────────────┘

With pbcodegen you can generate the Model and it can be used as:

// 'my-todo-list' application
var myApp = new MyTodoListApplication(); 

// The data of the application
var myData = myApp.Data;

// Print all todo_lists registries:
foreach (var todoList in myData.TodoListsCollection)
{
   Console.WriteLine($"{todoList.Name} ({todoList.Description})");
   foreach (var task in todoList.Tasks)
   {
      Console.WriteLine($"   - {task.Title} ({task.Description})");
      Console.WriteLine($"     {task.Priority.Name}");
      Console.WriteLine($"     {task.Status}");
      if (task.Status == Task.StatusEnum.Done)
         Console.WriteLine("Well done!!");
   }
}

// Filter over tasks collection in PocketBase (filter in server)
var oldPausedTasks = tasks.Filter(t => t.Status.Equal(Task.StatusEnum.Paused).And(
                                            t.Updated.LessThan(DateTime.Now.AddMonths(-1))));


// Use Linq (in-memory: intenal cache or get registries from server if needed)
var myTodoLists = myData.TodoListsCollection.Where(t => t.Name.Contains("my todo list"));

var allPriorities = myData.PrioritiesCollection;

// Getting by Id
var myList = myData.TodoListsCollection.GetById("qwertyuiop");
// Creating a new Task (it will be a registry in 'tasks' collection)
var newTask = new Task
{
   Title = "My Title",
   Description = "My Description",
   Priority = allPriorities.OrderByDescending(p => p.Value).First(),
   Status = Task.StatusEnum.ToDo
};
// Add it in the Tasks list (it will modify the 'tasks' field)
myList.Tasks.Add(newTask);

// Now, the changes are only in memory

// Save the todo_list (and its tasks)
myList.Save();

// Or save all todo_lists
myData.TodoListsCollection.SaveChanges();

//Or save all changes in all collections
myData.SaveChanges();

// Now, the changes are saved to PocketBase

(Documentation incomplete)

Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
0.6.1 775 2/7/2023
0.6.0 266 2/5/2023
0.4.1 312 1/14/2023
0.4.0 498 12/31/2022
0.3.0 295 12/18/2022
0.2.0 294 12/13/2022
0.1.5 298 12/10/2022
0.1.4 283 12/8/2022
0.1.3 286 12/8/2022
0.1.2 299 12/8/2022
0.1.1 306 12/8/2022
0.1.0 314 12/8/2022