Make Field constructor functions generic (#8)

F# can upcast types to `obj` if those types are used in place. However, a `string seq` (`IEnumerable<string>` in C#) cannot be upcast to an `obj seq` (`IEnumerable<object>`) without mapping each item in the sequence. Making the `Field` constructor functions generic will allow them to take any object type, and these functions handle the conversion to `obj` (for `In` and `InArray`; others work transparently).

Reviewed-on: #8
This commit is contained in:
Daniel J. Summers 2024-09-18 13:36:14 +00:00
parent 168bf0cd14
commit 740767661c
3 changed files with 39 additions and 24 deletions

View File

@ -75,68 +75,68 @@ type Field =
with with
/// Create a comparison against a field /// Create a comparison against a field
static member Where name comparison = static member Where name (comparison: Comparison) =
{ Name = name; Comparison = comparison; ParameterName = None; Qualifier = None } { Name = name; Comparison = comparison; ParameterName = None; Qualifier = None }
/// Create an equals (=) field criterion /// Create an equals (=) field criterion
static member Equal name (value: obj) = static member Equal<'T> name (value: 'T) =
Field.Where name (Equal value) Field.Where name (Equal value)
/// Create an equals (=) field criterion (alias) /// Create an equals (=) field criterion (alias)
static member EQ name (value: obj) = Field.Equal name value static member EQ<'T> name (value: 'T) = Field.Equal name value
/// Create a greater than (>) field criterion /// Create a greater than (>) field criterion
static member Greater name (value: obj) = static member Greater<'T> name (value: 'T) =
Field.Where name (Greater value) Field.Where name (Greater value)
/// Create a greater than (>) field criterion (alias) /// Create a greater than (>) field criterion (alias)
static member GT name (value: obj) = Field.Greater name value static member GT<'T> name (value: 'T) = Field.Greater name value
/// Create a greater than or equal to (>=) field criterion /// Create a greater than or equal to (>=) field criterion
static member GreaterOrEqual name (value: obj) = static member GreaterOrEqual<'T> name (value: 'T) =
Field.Where name (GreaterOrEqual value) Field.Where name (GreaterOrEqual value)
/// Create a greater than or equal to (>=) field criterion (alias) /// Create a greater than or equal to (>=) field criterion (alias)
static member GE name (value: obj) = Field.GreaterOrEqual name value static member GE<'T> name (value: 'T) = Field.GreaterOrEqual name value
/// Create a less than (<) field criterion /// Create a less than (<) field criterion
static member Less name (value: obj) = static member Less<'T> name (value: 'T) =
Field.Where name (Less value) Field.Where name (Less value)
/// Create a less than (<) field criterion (alias) /// Create a less than (<) field criterion (alias)
static member LT name (value: obj) = Field.Less name value static member LT<'T> name (value: 'T) = Field.Less name value
/// Create a less than or equal to (<=) field criterion /// Create a less than or equal to (<=) field criterion
static member LessOrEqual name (value: obj) = static member LessOrEqual<'T> name (value: 'T) =
Field.Where name (LessOrEqual value) Field.Where name (LessOrEqual value)
/// Create a less than or equal to (<=) field criterion (alias) /// Create a less than or equal to (<=) field criterion (alias)
static member LE name (value: obj) = Field.LessOrEqual name value static member LE<'T> name (value: 'T) = Field.LessOrEqual name value
/// Create a not equals (<>) field criterion /// Create a not equals (<>) field criterion
static member NotEqual name (value: obj) = static member NotEqual<'T> name (value: 'T) =
Field.Where name (NotEqual value) Field.Where name (NotEqual value)
/// Create a not equals (<>) field criterion (alias) /// Create a not equals (<>) field criterion (alias)
static member NE name (value: obj) = Field.NotEqual name value static member NE<'T> name (value: 'T) = Field.NotEqual name value
/// Create a Between field criterion /// Create a Between field criterion
static member Between name (min: obj) (max: obj) = static member Between<'T> name (min: 'T) (max: 'T) =
Field.Where name (Between(min, max)) Field.Where name (Between(min, max))
/// Create a Between field criterion (alias) /// Create a Between field criterion (alias)
static member BT name (min: obj) (max: obj) = Field.Between name min max static member BT<'T> name (min: 'T) (max: 'T) = Field.Between name min max
/// Create an In field criterion /// Create an In field criterion
static member In name (values: obj seq) = static member In<'T> name (values: 'T seq) =
Field.Where name (In values) Field.Where name (In (Seq.map box values))
/// Create an In field criterion (alias) /// Create an In field criterion (alias)
static member IN name (values: obj seq) = Field.In name values static member IN<'T> name (values: 'T seq) = Field.In name values
/// Create an InArray field criterion /// Create an InArray field criterion
static member InArray name tableName (values: obj seq) = static member InArray<'T> name tableName (values: 'T seq) =
Field.Where name (InArray(tableName, values)) Field.Where name (InArray(tableName, Seq.map box values))
/// Create an exists (IS NOT NULL) field criterion /// Create an exists (IS NOT NULL) field criterion
static member Exists name = static member Exists name =

View File

@ -6,8 +6,17 @@
<AssemblyVersion>4.0.0.0</AssemblyVersion> <AssemblyVersion>4.0.0.0</AssemblyVersion>
<FileVersion>4.0.0.0</FileVersion> <FileVersion>4.0.0.0</FileVersion>
<VersionPrefix>4.0.0</VersionPrefix> <VersionPrefix>4.0.0</VersionPrefix>
<VersionSuffix>rc4</VersionSuffix> <VersionSuffix>rc5</VersionSuffix>
<PackageReleaseNotes>From rc3: Add In/InArray field comparisons, revamp internal comparison handling. From rc2: preserve additional ORDER BY qualifiers. From rc1: add case-insensitive ordering. From v3.1: Change ByField to ByFields; support dot-access to nested document fields; add Find*Ordered functions/methods; see project site for breaking changes and compatibility</PackageReleaseNotes> <PackageReleaseNotes>From v3.1: (see project site for breaking changes and compatibility)
- Change ByField to ByFields
- Support dot-access to nested document fields
- Add Find*Ordered functions/methods
Release Candidate Changes:
- from v4-rc4: Field construction functions are now generic.
- from v4-rc3: Add In/InArray field comparisons, revamp internal comparison handling.
- from v4-rc2: preserve additional ORDER BY qualifiers.
- from v4-rc1: add case-insensitive ordering.</PackageReleaseNotes>
<Authors>danieljsummers</Authors> <Authors>danieljsummers</Authors>
<Company>Bit Badger Solutions</Company> <Company>Bit Badger Solutions</Company>
<PackageReadmeFile>README.md</PackageReadmeFile> <PackageReadmeFile>README.md</PackageReadmeFile>

View File

@ -97,14 +97,20 @@ let fieldTests = testList "Field" [
test "In succeeds" { test "In succeeds" {
let field = Field.In "Here" [| 8; 16; 32 |] let field = Field.In "Here" [| 8; 16; 32 |]
Expect.equal field.Name "Here" "Field name incorrect" Expect.equal field.Name "Here" "Field name incorrect"
Expect.equal field.Comparison (In [| 8; 16; 32 |]) "Comparison incorrect" match field.Comparison with
| In values -> Expect.equal (List.ofSeq values) [ box 8; box 16; box 32 ] "Comparison incorrect"
| it -> Expect.isTrue false $"Expected In, received %A{it}"
Expect.isNone field.ParameterName "The default parameter name should be None" Expect.isNone field.ParameterName "The default parameter name should be None"
Expect.isNone field.Qualifier "The default table qualifier should be None" Expect.isNone field.Qualifier "The default table qualifier should be None"
} }
test "InArray succeeds" { test "InArray succeeds" {
let field = Field.InArray "ArrayField" "table" [| "z" |] let field = Field.InArray "ArrayField" "table" [| "z" |]
Expect.equal field.Name "ArrayField" "Field name incorrect" Expect.equal field.Name "ArrayField" "Field name incorrect"
Expect.equal field.Comparison (InArray("table", [| "z" |])) "Comparison incorrect" match field.Comparison with
| InArray (table, values) ->
Expect.equal table "table" "Comparison table incorrect"
Expect.equal (List.ofSeq values) [ box "z" ] "Comparison values incorrect"
| it -> Expect.isTrue false $"Expected InArray, received %A{it}"
Expect.isNone field.ParameterName "The default parameter name should be None" Expect.isNone field.ParameterName "The default parameter name should be None"
Expect.isNone field.Qualifier "The default table qualifier should be None" Expect.isNone field.Qualifier "The default table qualifier should be None"
} }