Form.Attributes
0.0.1
See the version list below for details.
dotnet add package Form.Attributes --version 0.0.1
NuGet\Install-Package Form.Attributes -Version 0.0.1
<PackageReference Include="Form.Attributes" Version="0.0.1" />
paket add Form.Attributes --version 0.0.1
#r "nuget: Form.Attributes, 0.0.1"
// Install Form.Attributes as a Cake Addin
#addin nuget:?package=Form.Attributes&version=0.0.1
// Install Form.Attributes as a Cake Tool
#tool nuget:?package=Form.Attributes&version=0.0.1
F# Object Relational Mapper
An attribute based ORM for fsharp.
Usage
To start, enumerate your databases:
type Contexts =
| Database1 = 1
| Database2 = 2
We use enumeration here as Unions are not supported by attributes as of yet. The number that each database is set to doesn't really matter, but at the moment this is the best way we have found to generalize and organize contextualized attributes.
Next, use attributes to perform your domain modeling:
[<Table("User", Contexts.Database1)>]
[<Table("Users", Contexts.Database2)>]
type User =
{ Id : int
[<Column("Name", Contexts.Database1)>]
[<Column("Login", Contexts.Database2)>]
Name : string
[<Column("Secret", Contexts.Database1)>]
Password : string
Salt : string
}
Table and Column attributes take a name and a context. The name must match that of the relevant object in the database which is referred to by the given context; that is to say, the User type refers to a table called "User" in Database1, and "Users" in Database2. If no attribute is given, the underlying logic will default to the name of the type/field, so if you use the same names in your project and your database(s), no Table/Column attribute is necessary; i.e., the "Id" field will be assumed to map to an "Id" field in both the "User" table in Database1, and the same in the "Users" table in Database2.
Before we connect, we must also declare some OrmStates. We will need one for each context:
let db1State = PSQL(db1ConnectionString, Contexts.Database1)
let db2State = MSSQL(db2ConnectionString, Contexts.Database2)
The connection strings should just be given as strings, deliver these however you see fit (we recommend either putting them in a .env file or setting an environmental variable the will deliver the connection string, we may add some helper functions for this later).
Now we can do some querying:
selectAll<User> db1State |> printfn "%A"
This should send a SELECT * query to the db1./.User table, if everything was setup correctly. Keep in mind that our querying functions return Result<[]^T, {| Message |}>, so be prepared to handle those accordingly.
We also include a custom query framework; an example:
let query =
{ clauses =
[ select<User>
; from<User>
; join<User> [First ("Id", Equals "42"); And ("Name", NotEquals "'Jim'")]
]
}.Compile db1State
The compilation returns a string, and if printed the above should be:
"SELECT "Id", "Name", "Secret", "Salt" FROM "User" JOIN "User" On "Id" = 42 AND "Name" = 'Jim'"
Obviously, you may need to specify Schema in table declarations. We are currently ruminating over the idea of a schema attribute, but for now just add the schema name to the table attribute:
[<Table("SchemaName.User", Contexts.Database1)>]
and the logic will sort it all out:
"SELECT "Id", "Name", "Secret", "Salt" FROM "SchemaName"."User" JOIN "SchemaName"."User" On "Id" = 42 AND "Name" = 'Jim'"
Disambiguation of columns will be necessary for joins, we will be adding that soon.
Once you have the query you need, simply execute it:
let rowsAffected = execute query db1State //This is a non-query execution, does not return a result set
let queryResults = executeReader query generatereader db1State //This DOES return a result set, in this case a Result<[]User, {| Message |}>
Though this package itself awaits full testing, we have taken most of these pieces from other projects which have been thoroughly tested, so this package should work more or less out of the box.
Contribution Guidelines
Currently no strict guidelines, just open a pull request or an issue. Feel free to shoot us an email if you have any questions!
Note:
- Contributions are welcome!
- This has yet to be tested fully.
- Under active development.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net7.0 is compatible. 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. |
-
net7.0
- FSharp.Core (>= 7.0.200)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Form.Attributes:
Package | Downloads |
---|---|
Form
Package Description |
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
0.0.15 | 91 | 3/20/2024 |
0.0.14 | 91 | 3/20/2024 |
0.0.13 | 97 | 3/14/2024 |
0.0.12 | 99 | 2/27/2024 |
0.0.11.1 | 124 | 4/25/2024 |
0.0.11 | 198 | 1/18/2024 |
0.0.9 | 87 | 1/17/2024 |
0.0.8 | 173 | 9/17/2023 |
0.0.7 | 167 | 8/2/2023 |
0.0.6 | 136 | 8/2/2023 |
0.0.5 | 136 | 8/2/2023 |
0.0.4 | 146 | 8/2/2023 |
0.0.3 | 238 | 5/18/2023 |
0.0.2 | 135 | 5/16/2023 |
0.0.1 | 150 | 5/6/2023 |