Wednesday 11 March 2020

DaggerTech.Data finally converted

It has been a long road converting my C# ORM to Go, but it is finally done (although I do need to clean up the code)
Unfortunately, my day job got in the way of working on this, but I still gotta eat.
Anyway, the ORM (called GoDagger), like DaggerTech.Data works by creating the tables when it needs them, so no initial setup required. This does mean that any application using it can start up faster, but it can have a minimal performance hit in the early stages of execution.
The programmer is completely shielded from the SQL of the underlying database, allowing him, or her, to focus directly on the logic.
Each table is given 4 fields:
        ID                         VARCHAR(36) NOT NULL PRIMARY KEY
        CreateDate         BIGINT NOT NULL
        LastUpdate         BIGINT NOT NULL
        DeleteDate        BIGINT NULL
As you can see, I am using numeric values for dates. This allows me to port GoDagger to other databases without the need for any other conversion of date values.
The Model struct in Go to match to this is as follows:
type Model struct {
        ID                        *string
        CreateDate        time.Time
        LastUpdate        time.Time
        DeleteDate        *time.Time
}
As you can see in Model, both ID and DeleteDate are pointers. This allows me to have nil values in those fields. We use a nil value in ID to indicate if the record has ever been saved and the DeleteDate is nil if the record has not been deleted. The reason for the DeleteDate is that in some systems, it is better to disable a record rather than delete it. By default, GoDagger will not retrieve any record that has a DeleteDate, but this can be overridden.
To create a new model, we use composition of the Model struct, plus the use of struct tags:
type TestModel struct {
        godagger.Model
        Age         int                 `dagger:""`
        Name         string         `dagger:"size:20"`
        Nickname        *int                 `dagger:”size:20”`
}
For this familiar with GORM, you will see a resemblance. This is purely coincidental as I had not looked at GORM until a few days ago. The big difference, though, is GORM will include fields by default, unless specified to be ignored. GoDagger, on the other hand, will only include fields with a ‘dagger’ struct tag.
This is a very lightweight ORM as it does not create links between models for you. That is up to the developer. This is how DaggerTech.Data works as a lot of the data is to be passed as JSON to web applications and if I were to allow automatic linking and loading, then there would be the potential for massive amounts of data to be passed, as well as infinite loops.
To save a model to the database, it is simply a case of calling the Save function in GoDagger. This will look at the ID field and determine if the record needs to be created or updated.
tm1 := &TestModel{
        Name: "Test1",
        Age: 42,
}
godagger.Save(tm1)
Note that the save method requires a pointer, as do all the functions in GoDagger.
Searching, deletion, and some other helper functions are also available, which I will detail in a future post.