Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plans for [<BsonIgnore>] #26

Closed
srlopez opened this issue May 4, 2019 · 6 comments
Closed

Plans for [<BsonIgnore>] #26

srlopez opened this issue May 4, 2019 · 6 comments

Comments

@srlopez
Copy link

srlopez commented May 4, 2019

Hello, as you can see in the F# forum. Studying how to introduce my students in F#, we were converting a small java project to F#, and to avoid philosophical discussions about SQL and ORM, LiteDB is the perfect solution. But the attributes calculated according to other attributes are also saved in LiteDB, we have used [<BsonIgnore>] (on BsonMapper.cs Line 252,) but we have already seen that there is no account.
You have plans to implement it.
And what about [<BsonField>]?

@Zaid-Ajaj
Copy link
Owner

Hello @srlopez, I finally got around and made allocated some time to work on these issues. Ok, first of all the BsonIgnore attributes isn't taken into account when persisting documents from records. This choice is by design as record fields in F# should not depend on each other, instead you should use calculated using either members or standalone functions:

type Disk = { SizeGb : int }
 
type Computer =
    { Id: int
      Manufacturer: string
      Disks: Disk list }

    with member this.Ignored = sprintf "%d => %s" this.Id this.Manufacturer

here you see the member Ignored will be persisted inside the database.

This is an interesting case of separating data and behavior from each other. If you want to introduce F# to your students, it is better to showcase best practices with idiomatic F# code: no mutation, only data transformations. here is a full example:

// Learn more about F# at http://fsharp.org

open LiteDB 
open LiteDB.FSharp 
open System.IO

[<CLIMutable>]
type Disk = 
    { SizeGb : int }

[<CLIMutable>]
type Computer =
    { Id: int
      Manufacturer: string
      Disks: Disk list }

    // this is not persisted
    with member this.Ignored = sprintf "%d => %s" this.Id this.Manufacturer

[<EntryPoint>]
let main argv =

    let myPc =
        { Id = 0
          Manufacturer = "Computers Inc."
          Disks =
            [ { SizeGb = 100 }
              { SizeGb = 250 }
              { SizeGb = 500 } ] }

    let mapper = FSharpBsonMapper()
    use memoryStream = new MemoryStream()
    use db = new LiteDatabase(memoryStream, mapper)
    let computers = db.GetCollection<Computer>("computers")

    // Insert & Print
    computers.Insert(myPc) |> ignore
    let insertedPc = computers.FindAll() |> Seq.head
    printfn "%A, %s" insertedPc insertedPc.Ignored
    0

Notice I am using InMemory database which is better when testing so that you won't get different versions of your document inside the databse

@srlopez
Copy link
Author

srlopez commented May 4, 2019

You are right.
... it is better to showcase best practices with idiomatic F# code: no mutation, only data transformations.
Good aproach to 'Ignore' members.
But my opinion, that sure that is incorrect since I am also a rookie with F#, is that as that attribute was in the original in C#, a wrapper should cover it, regardless of whether it is idiomatic or not in the language in which the wrapper is implemented.
Anyway thank you @Zaid-Ajaj very much, I have learned a lot from your implementation

@srlopez
Copy link
Author

srlopez commented May 4, 2019

Without InMemory, and persisting data to use db = new LiteDatabase("data.db", mapper).
Running LiteDB.Shell like this:

dotnet LiteDB.Shell.dll data.db --run data.cmd
Welcome to LiteDB Shell

Getting started with `help`, `help full` or `help <command>`

> open data.db
> run data.cmd
> show collections
computers
> db.computers.find
[1]: {"_id":1,"Manufacturer":"Computers Inc.","Disks":[{"SizeGb":100},{"SizeGb":250},{"SizeGb":500}],"Ignored":"0 => Computers Inc."}
[2]: {"_id":2,"Manufacturer":"Computers Inc.","Disks":[{"SizeGb":100},{"SizeGb":250},{"SizeGb":500}],"Ignored":"0 => Computers Inc."}
> exit

As you can see, member Ignored is persisted, with the ID original in code 0.
Some thing is not working to me.
Thanks

@Zaid-Ajaj
Copy link
Owner

Zaid-Ajaj commented May 4, 2019

is that as that attribute was in the original in C#, a wrapper should cover it, regardless of whether it is idiomatic or not in the language in which the wrapper is implemented.

I build a lot of these "wrappers" and usually I try to take just the good parts that make sense to use within F#

Some thing is not working to me.

Have you updated your nuget of LiteDB.FSharp from 2.7.0 to 2.8.0? I refactored the way records are persisted, only fields are persisted

@srlopez
Copy link
Author

srlopez commented May 4, 2019

OMG!
that's was the problem,

dotnet remove package LiteDB.FSharp
dotnet add package LiteDB.FSharp --version 2.8.0

and now Ignored is ignored.
Thanks

@Zaid-Ajaj
Copy link
Owner

Glad to hear that it is working! 😄

I will consider this issue as resolved, if you encounter any problem or need any help, just let know!

Cheers

humhei added a commit to humhei/LiteDB.FSharp that referenced this issue May 10, 2019
* Introduce auto-quoted query expressions, publish 2.7.0

* Support mutable values -> fixes Zaid-Ajaj#27. Take back control of record marshalling

* Add tests for ignored members just to be sure, see Zaid-Ajaj#26

* Add support for literal boolean values in query expressions

* Support comparison operators for id fields by @humhei at Zaid-Ajaj#31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants