• Stars
    star
    179
  • Rank 206,202 (Top 5 %)
  • Language
    F#
  • License
    MIT License
  • Created over 6 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Advanced F# Support for LiteDB, an embedded NoSql database for .NET with type-safe query expression through F# quotations

LiteDB.FSharp Build Status Nuget

F# Support for LiteDB

This package relies on LiteDB 4.14 >= version > 5.0 Support for v5 is work in progress and might require a full rewrite.

LiteDB.FSharp provides serialization utilities making it possible for LiteDB to understand F# types such as records, unions, maps etc. with support for type-safe query expression through F# quotations

Usage

LiteDB.FSharp comes with a custom BsonMapper called FSharpBsonMapper that you would pass to a LiteDatabase instance during initialization:

open LiteDB
open LiteDB.FSharp
open LiteDB.FSharp.Extensions

let mapper = FSharpBsonMapper()
use db = new LiteDatabase("simple.db", mapper)

LiteDB.FSharp is made mainly to work with records as representations of the persisted documents. The library requires that records have a primary key called Id or id. This field is then mapped to _id when converted to a bson document for indexing.

type Genre = Rock | Pop | Metal

type Album = {
    Id: int
    Name: string
    DateReleased: DateTime
    Genre: Genre
}

Get a typed collection from the database:

let albums = db.GetCollection<Album>("albums")

Insert documents

let metallica = 
    { Id = 1; 
      Name = "Metallica";
      Genre = Metal;
      DateReleased = DateTime(1991, 8, 12) }

albums.Insert(metallica)

Query one document by Id

// result : Album
let result = albums.findOne <@ fun album -> album.Id = 1 @> 

// OR
let id = BsonValue(1)
// result : Album
let result = albums.FindById(id)

Query many documents depending on the value of a field

// metallicaAlbums : Seq<Album>
let metallicaAlbums = albums.findMany <@ fun album -> album.Name = "Metallica" @>
// OR
let name = BsonValue("Metallica")
let query = Query.EQ("Name", name)
// metallicaAlbums : Seq<Album>
let metallicaAlbums = albums.Find(query)

Query documents by value of discriminated union

// find all albums where Genre = Rock
// rockAlbums : Seq<Album>
let rockAlbums = albums.findMany <@ fun album -> album.Genre = Rock @>

// OR 

let genre = BsonValue("Rock")
let query = Query.EQ("Genre", genre)
// rockAlbums : Seq<Album>
let rockAlbums = albums.Find(query)

Query documents between or time intervals

// find all albums released last year
let now = DateTime.Now
let dateFrom = DateTime(now.Year - 1, 01, 01) |> BsonValue
let dateTo = DateTime(now.Year, 01, 01) |> BsonValue
let query = Query.Between("DateReleased", dateFrom, dateTo)
// albumsLastYear : Seq<Album>
let albumsLastYear = albums.Find(query)

Customized Full Search using quoted expressions

// Filtering albums released a year divisble by 5
// filtered : Seq<Album>
let filtered = 
    albums.fullSearch 
        <@ fun album -> album.DateReleased @> 
        (fun dateReleased -> dateReleased.Year % 5 = 0)

Customized Full Search using Query.Where

The function Query.Where expects a field name and a filter function of type BsonValue -> bool. You can deserialize the BsonValue using Bson.deserializeField<'t> where 't is the type of the serialized value.

// Filtering albums released a year divisble by 5
let searchQuery = 
    Query.Where("DateReleased", fun bsonValue ->
        // dateReleased : DateTime
        let dateReleased = Bson.deserializeField<DateTime> bsonValue
        let year = dateReleased.Year
        year % 5 = 0
    )

let searchResult = albums.Find(searchQuery)

Query.Where: Filtering documents by matching with values of a nested DU

type Shape = 
    | Circle of float
    | Rect of float * float
    | Composite of Shape list

type RecordWithShape = { Id: int; Shape: Shape }

let records = db.GetCollection<RecordWithShape>("shapes")

let shape = 
    Composite [ 
      Circle 2.0;
      Composite [ Circle 4.0; Rect(2.0, 5.0) ]
    ]

let record = { Id = 1; Shape = shape }
records.Insert(record) |> ignore

let searchQuery = 
    Query.Where("Shape", fun bsonValue -> 
        let shapeValue = Bson.deserializeField<Shape> bsonValue
        match shapeValue with
        | Composite [ Circle 2.0; other ] -> true
        | otherwise -> false
    )
records.Find(searchQuery)
|> Seq.length
|> function 
    | 1 -> pass() // passed!
    | n -> fail()

Id auto-incremented

Add CLIMutableAttribute to record type and set Id 0

[<CLIMutable>]
type Album = {
   Id: int
   Name: string
   DateReleased: DateTime
   Genre: Genre
}
let metallica = 
   { Id = 0; 
     Name = "Metallica";
     Genre = Metal;
     DateReleased = DateTime(1991, 8, 12) }

DbRef

just as https://github.com/mbdavid/LiteDB/wiki/DbRef

open LiteDB.FSharp.Linq

[<CLIMutable>]
type Company=
  { Id : int
    Name : string}   

[<CLIMutable>]    
type Order=
  { Id :int
    Company :Company }
    
let mapper = FSharpBsonMapper()
mapper.DbRef<Order,_>(fun c -> c.Company)

Inheritence

Item1 and Item2 are inherited from IItem

we must register the type relations first globally

FSharpBsonMapper.RegisterInheritedConverterType<IItem,Item1>()
FSharpBsonMapper.RegisterInheritedConverterType<IItem,Item2>()

By conversion, The inherited type must has mutable field for serializable and deserializable

val mutable Id : int

Note: Because json converter find inherited type by comparing the fields names from inherited type and database

let findType (jsonFields: seq<string>) =
    inheritedTypes |> Seq.maxBy (fun tp ->
        let fields = tp.GetFields() |> Seq.map (fun fd -> fd.Name)
        let fieldsLength = Seq.length fields
        (jsonFields |> Seq.filter(fun jsonField ->
            Seq.contains jsonField fields
        )
        |> Seq.length),-fieldsLength
    )        

This means that we should not implement the some interface with different fields For example,we should not do below implementations

type Item1 =

    val mutable Id : int
    val mutable Art : string
    val mutable Name : string
    val mutable Number : int

    interface IItem with 
        member this.Art = this.Art
        member this.Id = this.Id
        member this.Name = this.Name
        member this.Number = this.Number

/// unexpected codes
type Item2 =

    val mutable Id2 : int
    val mutable Art2 : string
    val mutable Name2 : string
    val mutable Number2 : int

    interface IItem with 
        member this.Art = this.Art2
        member this.Id = this.Id2
        member this.Name = this.Name2
        member this.Number = this.Number2

/// expected codes
type Item2 =

    val mutable Id : int
    val mutable Art : string
    val mutable Name : string
    val mutable Number : int

    interface IItem with 
        member this.Art = this.Art
        member this.Id = this.Id
        member this.Name = this.Name
        member this.Number = this.Number

Full sample codes:

/// classlibray.fs
[<CLIMutable>]    
type EOrder=
  { Id: int
    Items : IItem list
    OrderNumRange: string }   


/// consumer.fs
type Item1 =
    /// val mutable will make field serializable and deserializable
    val mutable Id : int
    val mutable Art : string
    val mutable Name : string
    val mutable Number : int

    
    interface IItem with 
        member this.Art = this.Art
        member this.Id = this.Id
        member this.Name = this.Name
        member this.Number = this.Number
    val mutable Barcode : string

    interface IBarcode with 
        member this.Barcode = this.Barcode    

    /// type constructor 
    new (id, art, name, number, barcode) =
        { Id = id; Art = art; Name = name; Number = number; Barcode = barcode }

type Item2 = 
    val mutable Id : int
    val mutable Art : string
    val mutable Name : string
    val mutable Number : int

    interface IItem with 
        member this.Art = this.Art
        member this.Id = this.Id
        member this.Name = this.Name
        member this.Number = this.Number

    val mutable Size : int
    interface ISize with 
        member this.Size = this.Size 
    val mutable Color : string

    interface IColor with 
        member this.Color = this.Color 

    new (id, art, name, number, size, color) =
        { Id = id; Art = art; Name = name; Number = number; Size = size; Color = color }

FSharpBsonMapper.RegisterInheritedConverterType<IItem,Item1>()
FSharpBsonMapper.RegisterInheritedConverterType<IItem,Item2>()

let item1 = 
    Item1 ( 
        id = 0,
        art = "art",
        name = "name",
        number = 1000,
        barcode = "7254301" 
    )

let item2 = 
    Item2 ( 
        id = 0,
        art = "art",
        name = "name",
        number = 1000,
        color = "red" ,
        size = 39 
    )

let eorder = { Id = 1; Items = [item1;item2];  OrderNumRange = "" }

let queryedEOrder =
    db 
    |> LiteRepository.insertItem eorder
    |> LiteRepository.query<EOrder> 
    |> LiteQueryable.first

match queryedEOrder.Items with 
| [item1;item2] -> 
    match item1,item2 with 
    | :? IBarcode,:? IColor -> 
        pass()
    | _ -> fail()    
| _ -> fail()   

More Repositories

1

Feliz

A fresh retake of the React API in Fable and a collection of high-quality components to build React applications in F#, optimized for happiness
F#
511
star
2

the-elmish-book

A practical guide to building modern and reliable web applications in F# from first principles
HTML
323
star
3

Npgsql.FSharp

Thin F# wrapper around Npgsql, the PostgreSQL database driver for .NET
F#
305
star
4

Fable.Remoting

Type-safe communication layer (RPC-style) for F# featuring Fable and .NET Apps
F#
269
star
5

tabula-rasa

Minimalistic real-worldish blogging platform, written entirely in F#, made as a learning reference for building large Elmish apps
F#
199
star
6

Snowflaqe

A dotnet CLI to generate type-safe GraphQL clients for F# and Fable with automatic deserialization, static query verification and type checking
F#
150
star
7

Femto

Femto is a CLI tool that automatically resolves npm packages used by Fable bindings
F#
145
star
8

ThrowawayDb

Dead simple integration tests with SQL Server or Postgres throwaway databases that are created on the fly, used briefly then disposed of automagically.
C#
140
star
9

Npgsql.FSharp.Analyzer

F# analyzer that provides embedded SQL syntax analysis, type-checking for parameters and result sets and nullable column detection when writing queries using Npgsql.FSharp.
C#
132
star
10

Hawaii

dotnet CLI tool to generate type-safe F# and Fable clients from OpenAPI/Swagger or OData services
F#
122
star
11

SAFE.Simplified

A lightweight alternative template of SAFE for happy cross-IDE full-stack F# development
F#
101
star
12

Fable.SimpleHttp

Http with Fable, made simple.
F#
82
star
13

ClosedXML.SimpleSheets

Easily generate Excel sheets from F#
F#
80
star
14

DustyTables

Thin F# API for SqlClient for easy data access to ms sql server with functional seasoning on top
F#
74
star
15

Giraffe.GoodRead

Practical dependency injection in Giraffe that gets out of your way
F#
73
star
16

Feliz.Router

A router component for React and Elmish that is focused, powerful and extremely easy to use.
F#
72
star
17

Fable.SimpleJson

A library for working with JSON in Fable projects
F#
56
star
18

SAFE.React

Full Stack F# powered by ASP.NET Core on the backend and modern React on the frontend.
F#
54
star
19

Fable.Mocha

Fable library for a proper testing story using different runners such as mocha, standalone browsers and dotnet
F#
51
star
20

fabulous-simple-elements

An alternative view rendering API for Fabulous (Elmish Xamarin.Forms) that is easy to use and simple to read, inspired by Elmish on the web.
F#
46
star
21

desktop-feliz-with-photino

F#
43
star
22

fsharp-weekly

F# Weekly mobile, available for Android (soon iOS and UWP too)
F#
42
star
23

SAFE-TodoList

The simplest Todo app showcasing a client-server application written entirely in F#
F#
41
star
24

Giraffe.SerilogExtensions

Dead simple library to integrate Serilog within Giraffe apps: implemented as a composable HttpHandler and has native destructuring of F# types.
F#
30
star
25

dotnetconf-react-with-fsharp

Demo application used in DotnetCONF to build React applications with F#
F#
30
star
26

Elmish.SweetAlert

SweetAlert integration for Fable, made with โค๏ธ to work in Elmish apps. https://zaid-ajaj.github.io/Elmish.SweetAlert/
F#
29
star
27

Fable.DateFunctions

Fable binding for date-fns javascript library, implemented as extension methods for DateTime. See https://zaid-ajaj.github.io/Fable.DateFunctions/
F#
27
star
28

Fable.CloudFlareWorkers

Write CloudFlare Workers in idiomatic, type-safe F# and compile them to JS using Fable
F#
24
star
29

Elmish.Toastr

Toastr integration with Fable, implemented as Elmish commands https://zaid-ajaj.github.io/Elmish.Toastr/
F#
24
star
30

elmish-getting-started

A simple and minimalistic template to easily get up and running with Elmish and Fable
F#
22
star
31

Giraffe.QueryReader

HttpHandler for easily working with query string parameters within Giraffe apps.
F#
21
star
32

navigation-bar-with-feliz

Modern navigation bar built with Feliz
JavaScript
20
star
33

Giraffe.JsonTherapy

Simply extract JSON values from HTTP requests without defining intermediate types or using model binding
F#
19
star
34

fable-getting-started

Template for getting started with Fable
JavaScript
19
star
35

Feliz.ViewEngine.Htmx

A library that allows using Htmx attributes with Feliz.ViewEngine
F#
18
star
36

Fable.SimpleXml

A library for easily parsing and working with XML in Fable projects
F#
17
star
37

AlgebraFs

A simple computer algebra system (CAS), written in F# for fun and learning.
F#
15
star
38

Fable.React.Flatpickr

Fable binding for react-flatpickr that is ready to use within Elmish applications
F#
14
star
39

elmish-login-flow-validation

Elmish sample that demonstrates a login flow with user input validation
F#
13
star
40

pulumi-schema-explorer

Web application and UI to explore Pulumi schemas
F#
13
star
41

Fable.SqlClient

Fable Node client for Microsoft SQL Server, built around a node-mssql binding
F#
12
star
42

Elmish.AnimatedTree

An animated tree user interface made for Elmish applications
JavaScript
11
star
43

pulumi-csharp-analyzer

Roslyn-based static code analysis for pulumi programs written in C#
C#
11
star
44

Cable

Type-safe client-server communication for C# featuring Bridge.NET and NancyFx
C#
10
star
45

elmish-composition

A library to compare the different compositional techniques in Elmish applications
JavaScript
10
star
46

Nancy.Serilog

Nancy plugin for application-wide logging using Serilog
C#
9
star
47

scaling-elmish-programs

FableConf 2018 slides and apps used in the presentation
F#
8
star
48

Suave.SerilogExtensions

Suave plugin to use the awesome Serilog library as the logger for your application
F#
8
star
49

ElmCounterWPF

Pure F#/Xaml counter using Elmish.WPF and XAML type provider
F#
7
star
50

ReactCSharpDemo

Using React in C# with Bridge
C#
7
star
51

Fable.SimpleJson.Python

A library for working with JSON in F# Fable projects targeting Python
F#
7
star
52

Feliz.AntDesign

AntDesign bindings using Feliz syntax for a clean, discoverable and type-safe React components. (WIP)
F#
6
star
53

hawaii-samples-feliz-petstore

This is a sample application that shows how to use Feliz with a client generated by Hawaii
F#
6
star
54

elmish-wpf-template

A template for easily getting started with building WPF apps using Elmish
F#
5
star
55

elmish-routing

F#
4
star
56

Bridge.Redux

Bindings of the Redux library for the Bridge transpiler
C#
4
star
57

Fable.Requests

Fable library for making HTTP requests targeting Python
F#
4
star
58

elmish-todo-exercises

F#
4
star
59

ExcelPluginTemplate

Template project to create Excel Add-ins with F# and ExcelDNA
F#
3
star
60

elmish-calc

Calculator application with Fable and Fable-Elmish
F#
3
star
61

interop-fableconf2019

JavaScript
3
star
62

FifteenPuzzleWithFeliz

The small fifteen puzzle game I am building live on Twitch
JavaScript
3
star
63

docute-starter

a simple and easy to use project to start writing documentation with Docute
HTML
3
star
64

Bridge.ChartJS

Bindings for Chart.js library to be used in Bridge.NET projects
C#
3
star
65

Bridge.CanvasJS

CanvasJS C#-wrapper for Bridge.NET project.
C#
3
star
66

pulumi-workshop-automation-fsharp

This workshop will walk you through the basics of using the Automation API of Pulumi to create and deploy a Pulumi stack programmatically with F#
F#
3
star
67

FSharp.SimpleJson

A library for easily parsing, transforming and converting JSON in F#, ported from Fable.SimpleJson
F#
3
star
68

MandelbrotHaskell

Mandelbrot fractal as text (ASCII), written in Haskell
Haskell
2
star
69

hawaii-samples-petstore

PetStore API sample with Hawaii
F#
2
star
70

fsharp-exchange-2021

Code repository for the F# eXchange 2021 conference
F#
2
star
71

Cable.ArticleSample

Type-safe web app sample used to demonstrate Cable
C#
2
star
72

terraform-basic-vpc-to-pulumi

HCL
2
star
73

SAFE-FileUploadDownload

F#
2
star
74

hawaii-samples-odata-trippin

F#
2
star
75

ReactReduxTodoApp

Todo app written in pure C# with React and Redux
C#
2
star
76

login-with-url-extended

F#
2
star
77

Simple-Feliz-i18n

Using Feliz template, this repository shows how to implement a simple internationalization mechanism that makes parts of the application be dependent on the current users' locale.
JavaScript
2
star
78

Fable.React.Responsive

Fable binding for react-responsive that is ready to use within Elmish applications
F#
1
star
79

remoting-pure-kestrel

The simplest AspNetCore sample with Fable.Remoting using the Kestrel server
F#
1
star
80

Bridge.SweetAlert

SweetAlert bindings for the Bridge.NET project.
CSS
1
star
81

FableSuaveSample

Fable and Suave sample for integration-testing Fable.Remoting with Suave to the death
F#
1
star
82

Image-Processor

A program to process and filter images, written in C#.
C#
1
star
83

ChristianHolidaysAssignment

C++
1
star
84

gitbook-enhanced-katex

Math typesetting using KaTex for gitBook
JavaScript
1
star
85

pulumi-codegen-dotnet

Building Pulumi Codegen tooling in F#
F#
1
star
86

RemotingJsonBenchmarks

F#
1
star
87

elmish-todo-part1

F#
1
star
88

WindowsExplorer

A WPF application that mimics Windows Explorer functionality
C#
1
star
89

elmish-hackernews-part1

F#
1
star
90

elmish-todo-part2

F#
1
star
91

elmish-todo-part3

F#
1
star
92

fast-refresh-bug-reproduction

JavaScript
1
star
93

tagmeme-analyzer

Static code analyzer that checks for exhaustive pattern matching, union case typos and redundant arguments in tagmeme
JavaScript
1
star
94

xmlhttprequest-in-elmish

F#
1
star
95

Bridge.Ractive

Bindings of Ractive.js to be used in Bridge.NET projects.
JavaScript
1
star
96

elmish-hackernews-part3

F#
1
star