Skip to content

Commit 3a8926d

Browse files
authored
DRV-598: Add missing functions to C# driver (#139)
1 parent d4d3473 commit 3a8926d

File tree

6 files changed

+626
-1
lines changed

6 files changed

+626
-1
lines changed

FaunaDB.Client.Test/ClientTest.cs

Lines changed: 287 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2355,6 +2355,293 @@ public async Task TestHasCurrentTokenWithInternalKey()
23552355
Assert.IsFalse((await adminClient.Query(HasCurrentToken())).To<bool>().Value);
23562356
}
23572357

2358+
[Test]
2359+
public async Task TestTypeCheckers()
2360+
{
2361+
var coll = (await adminClient.Query(CreateCollection(Obj("name", RandomStartingWith())))).Get(REF_FIELD);
2362+
var index = (await adminClient.Query(CreateIndex(Obj("name", RandomStartingWith(), "source", coll, "active", true)))).Get(REF_FIELD);
2363+
var doc = (await adminClient.Query(Create(coll, Obj("credentials", Obj("password", "sekret"))))).Get(REF_FIELD);
2364+
var db = (await adminClient.Query(CreateDatabase(Obj("name", RandomStartingWith())))).Get(REF_FIELD);
2365+
var fn = (await adminClient.Query(CreateFunction(Obj("name", RandomStartingWith(), "body", Query(Lambda("x", Var("x"))))))).Get(REF_FIELD);
2366+
var key = (await adminClient.Query(CreateKey(Obj("database", db, "role", "admin")))).Get(REF_FIELD);
2367+
var tok = await adminClient.Query(Login(doc, Obj("password", "sekret")));
2368+
var role = (await adminClient.Query(CreateRole(Obj("name", RandomStartingWith(), "membership", Arr(), "privileges", Arr())))).Get(REF_FIELD);
2369+
2370+
var cli = adminClient.NewSessionClient(tok.Get(SECRET_FIELD));
2371+
var cred = (await cli.Query(Get(Ref("credentials/self")))).Get(REF_FIELD);
2372+
var token = tok.Get(REF_FIELD);
2373+
2374+
var trueExprs = new List<Expr>
2375+
{
2376+
IsNumber(3.14),
2377+
IsNumber(10L),
2378+
IsDouble(3.14),
2379+
IsInteger(10L),
2380+
IsBoolean(true),
2381+
IsBoolean(false),
2382+
IsNull(Null()),
2383+
IsBytes(new byte[] {0x1, 0x2, 0x3, 0x4}),
2384+
IsTimestamp(Now()),
2385+
IsTimestamp(Epoch(1, TimeUnit.Second)),
2386+
IsTimestamp(Time("1970-01-01T00:00:00Z")),
2387+
IsDate(ToDate(Now())),
2388+
IsDate(Date("1970-01-01")),
2389+
IsString("string"),
2390+
IsArray(Arr(10)),
2391+
IsObject(Obj("x", 10)),
2392+
IsObject(Paginate(Collections())),
2393+
IsObject(Get(doc)),
2394+
IsRef(coll),
2395+
IsSet(Collections()),
2396+
IsSet(Match(index)),
2397+
IsSet(Union(Match(index))),
2398+
IsDoc(doc),
2399+
IsDoc(Get(doc)),
2400+
IsLambda(Query(Lambda("x", Var("x")))),
2401+
IsCollection(coll),
2402+
IsCollection(Get(coll)),
2403+
IsDatabase(db),
2404+
IsDatabase(Get(db)),
2405+
IsIndex(index),
2406+
IsIndex(Get(index)),
2407+
IsFunction(fn),
2408+
IsFunction(Get(fn)),
2409+
IsKey(key),
2410+
IsKey(Get(key)),
2411+
IsToken(token),
2412+
IsToken(Get(token)),
2413+
IsCredentials(cred),
2414+
IsCredentials(Get(cred)),
2415+
IsRole(role),
2416+
IsRole(Get(role))
2417+
};
2418+
2419+
var falseExprs = new List<Expr>
2420+
{
2421+
IsNumber("string"),
2422+
IsNumber(Arr()),
2423+
IsDouble(10L),
2424+
IsInteger(3.14),
2425+
IsBoolean("string"),
2426+
IsBoolean(10),
2427+
IsNull("string"),
2428+
IsBytes(Arr(0x1, 0x2, 0x3, 0x4)),
2429+
IsTimestamp(ToDate(Now())),
2430+
IsTimestamp(10),
2431+
IsDate(Now()),
2432+
IsString(Arr()),
2433+
IsString(10),
2434+
IsArray(Obj("x", 10)),
2435+
IsObject(Arr(10)),
2436+
IsRef(Match(index)),
2437+
IsRef(10),
2438+
IsSet("string"),
2439+
IsDoc(Obj()),
2440+
IsLambda(fn),
2441+
IsLambda(Get(fn)),
2442+
IsCollection(db),
2443+
IsCollection(Get(db)),
2444+
IsDatabase(coll),
2445+
IsDatabase(Get(coll)),
2446+
IsIndex(coll),
2447+
IsIndex(Get(db)),
2448+
IsFunction(index),
2449+
IsFunction(Get(coll)),
2450+
IsKey(db),
2451+
IsKey(Get(index)),
2452+
IsToken(index),
2453+
IsToken(Get(cred)),
2454+
IsCredentials(token),
2455+
IsCredentials(Get(role)),
2456+
IsRole(coll),
2457+
IsRole(Get(index))
2458+
};
2459+
2460+
var trueResults = await adminClient.Query(trueExprs);
2461+
foreach (var result in trueResults)
2462+
{
2463+
Assert.IsTrue(result.To<bool>().Value);
2464+
}
2465+
2466+
var falseResults = await adminClient.Query(falseExprs);
2467+
foreach (var result in falseResults)
2468+
{
2469+
Assert.IsFalse(result.To<bool>().Value);
2470+
}
2471+
}
2472+
2473+
[Test]
2474+
public async Task TestAllAny()
2475+
{
2476+
var coll = await adminClient.Query(CreateCollection(Obj("name", RandomStartingWith())));
2477+
var index = await adminClient.Query(CreateIndex(Obj(
2478+
"name", RandomStartingWith(),
2479+
"source", coll.Get(REF_FIELD),
2480+
"active", true,
2481+
"terms", Arr(Obj("field", Arr("data", "foo"))),
2482+
"values", Arr(Obj("field", Arr("data", "value")))
2483+
)));
2484+
2485+
await adminClient.Query(Do(
2486+
Create(coll.Get(REF_FIELD), Obj("data", Obj("foo", "true", "value", true))),
2487+
Create(coll.Get(REF_FIELD), Obj("data", Obj("foo", "true", "value", true))),
2488+
Create(coll.Get(REF_FIELD), Obj("data", Obj("foo", "true", "value", true))),
2489+
2490+
Create(coll.Get(REF_FIELD), Obj("data", Obj("foo", "false", "value", false))),
2491+
Create(coll.Get(REF_FIELD), Obj("data", Obj("foo", "false", "value", false))),
2492+
Create(coll.Get(REF_FIELD), Obj("data", Obj("foo", "false", "value", false))),
2493+
2494+
Create(coll.Get(REF_FIELD), Obj("data", Obj("foo", "mixed", "value", true))),
2495+
Create(coll.Get(REF_FIELD), Obj("data", Obj("foo", "mixed", "value", false))),
2496+
Create(coll.Get(REF_FIELD), Obj("data", Obj("foo", "mixed", "value", true))),
2497+
Create(coll.Get(REF_FIELD), Obj("data", Obj("foo", "mixed", "value", false)))
2498+
));
2499+
2500+
//all: array
2501+
Assert.IsTrue((await adminClient.Query(All(Arr(true, true, true)))).To<bool>().Value);
2502+
Assert.IsFalse((await adminClient.Query(All(Arr(true, false, true)))).To<bool>().Value);
2503+
2504+
//all: page
2505+
Assert.IsTrue(
2506+
(await adminClient.Query(Select(Path("data").At(0), All(Paginate(Match(index.Get(REF_FIELD), "true")))))).To<bool>().Value
2507+
);
2508+
Assert.IsFalse(
2509+
(await adminClient.Query(Select(Path("data").At(0), All(Paginate(Match(index.Get(REF_FIELD), "false")))))).To<bool>().Value
2510+
);
2511+
Assert.IsFalse(
2512+
(await adminClient.Query(Select(Path("data").At(0), All(Paginate(Match(index.Get(REF_FIELD), "mixed")))))).To<bool>().Value
2513+
);
2514+
2515+
//all: set
2516+
Assert.IsTrue((await adminClient.Query(All(Match(index.Get(REF_FIELD), "true")))).To<bool>().Value);
2517+
Assert.IsFalse((await adminClient.Query(All(Match(index.Get(REF_FIELD), "false")))).To<bool>().Value);
2518+
Assert.IsFalse((await adminClient.Query(All(Match(index.Get(REF_FIELD), "mixed")))).To<bool>().Value);
2519+
2520+
//any: array
2521+
Assert.IsFalse((await adminClient.Query(Any(Arr(false, false, false)))).To<bool>().Value);
2522+
Assert.IsTrue((await adminClient.Query(Any(Arr(true, false, true)))).To<bool>().Value);
2523+
2524+
//any: page
2525+
Assert.IsTrue(
2526+
(await adminClient.Query(Select(Path("data").At(0), Any(Paginate(Match(index.Get(REF_FIELD), "true")))))).To<bool>().Value
2527+
);
2528+
Assert.IsFalse(
2529+
(await adminClient.Query(Select(Path("data").At(0), Any(Paginate(Match(index.Get(REF_FIELD), "false")))))).To<bool>().Value
2530+
);
2531+
Assert.IsTrue(
2532+
(await adminClient.Query(Select(Path("data").At(0), Any(Paginate(Match(index.Get(REF_FIELD), "mixed")))))).To<bool>().Value
2533+
);
2534+
2535+
//any: set
2536+
Assert.IsTrue((await adminClient.Query(Any(Match(index.Get(REF_FIELD), "true")))).To<bool>().Value);
2537+
Assert.IsFalse((await adminClient.Query(Any(Match(index.Get(REF_FIELD), "false")))).To<bool>().Value);
2538+
Assert.IsTrue((await adminClient.Query(Any(Match(index.Get(REF_FIELD), "mixed")))).To<bool>().Value);
2539+
}
2540+
2541+
[Test]
2542+
public async Task TestToArray()
2543+
{
2544+
Assert.AreEqual(
2545+
new ArrayV(new List<Value>() {
2546+
new ArrayV(new List<Value>() {new StringV("k0"), new LongV(10)}),
2547+
new ArrayV(new List<Value>() {new StringV("k1"), new LongV(20)})
2548+
}),
2549+
await adminClient.Query(ToArray(Obj("k0", 10, "k1", 20)))
2550+
);
2551+
}
2552+
2553+
[Test]
2554+
public async Task TestToArrayAndToObject()
2555+
{
2556+
var keys = new Dictionary<string, Value> {["k0"] = new LongV(10), ["k1"] = new LongV(20)};
2557+
var obj = new ObjectV(keys);
2558+
2559+
Assert.AreEqual(
2560+
obj,
2561+
await adminClient.Query(ToObject(ToArray(obj)))
2562+
);
2563+
}
2564+
2565+
[Test]
2566+
public async Task TestToDouble()
2567+
{
2568+
var res1 = await adminClient.Query(ToDouble(10L));
2569+
Assert.AreEqual(res1.To<double>().Value, 10.0);
2570+
2571+
var res2 = await adminClient.Query(ToDouble(3.14));
2572+
Assert.AreEqual(res2.To<double>().Value, 3.14);
2573+
2574+
var res3 = await adminClient.Query(ToDouble("3.14"));
2575+
Assert.AreEqual(res3.To<double>().Value, 3.14);
2576+
}
2577+
2578+
[Test]
2579+
public async Task TestThrowBadRequestOnDouble()
2580+
{
2581+
var ex = Assert.ThrowsAsync<BadRequest>(
2582+
async () => await adminClient.Query(ToDouble(Now()))
2583+
);
2584+
Assert.AreEqual("invalid argument: Cannot cast Time to Double.", ex.Message);
2585+
}
2586+
2587+
[Test]
2588+
public async Task TestToInteger()
2589+
{
2590+
var res1 = await adminClient.Query(ToInteger(10L));
2591+
Assert.AreEqual(res1.To<long>().Value, 10L);
2592+
2593+
var res2 = await adminClient.Query(ToInteger(10.0));
2594+
Assert.AreEqual(res2.To<long>().Value, 10L);
2595+
2596+
var res3 = await adminClient.Query(ToInteger("10"));
2597+
Assert.AreEqual(res3.To<long>().Value, 10L);
2598+
}
2599+
2600+
[Test]
2601+
public async Task TestThrowBadRequestOnInteger()
2602+
{
2603+
var ex = Assert.ThrowsAsync<BadRequest>(
2604+
async () => await adminClient.Query(ToInteger(Now()))
2605+
);
2606+
Assert.AreEqual("invalid argument: Cannot cast Time to Integer.", ex.Message);
2607+
}
2608+
2609+
[Test]
2610+
public async Task TestTimeAdd()
2611+
{
2612+
var res1 = await adminClient.Query(TimeAdd(Epoch(0, TimeUnit.Second), 1, TimeUnit.Hour));
2613+
var res2 = await adminClient.Query(TimeAdd(Date("1970-01-01"), 1, TimeUnit.Day));
2614+
var res3 = await adminClient.Query(TimeAdd(Date("1970-01-01"), 2, "days"));
2615+
2616+
Assert.AreEqual(new DateTime(1970, 1, 1).AddHours(1), res1.To<DateTime>().Value);
2617+
Assert.AreEqual(new DateTime(1970, 1, 1).AddDays(1), res2.To<DateTime>().Value);
2618+
Assert.AreEqual(new DateTime(1970, 1, 1).AddDays(2), res3.To<DateTime>().Value);
2619+
}
2620+
2621+
[Test]
2622+
public async Task TestTimeSubtract()
2623+
{
2624+
var res1 = await adminClient.Query(TimeSubtract(Epoch(0, TimeUnit.Second), 1, TimeUnit.Hour));
2625+
var res2 = await adminClient.Query(TimeSubtract(Date("1970-01-01"), 1, TimeUnit.Day));
2626+
var res3 = await adminClient.Query(TimeSubtract(Date("1970-01-01"), 2, "days"));
2627+
2628+
Assert.AreEqual(new DateTime(1970, 1, 1).AddHours(-1), res1.To<DateTime>().Value);
2629+
Assert.AreEqual(new DateTime(1970, 1, 1).AddDays(-1), res2.To<DateTime>().Value);
2630+
Assert.AreEqual(new DateTime(1970, 1, 1).AddDays(-2), res3.To<DateTime>().Value);
2631+
}
2632+
2633+
[Test]
2634+
public async Task TestTimeDiff()
2635+
{
2636+
var res1 = await adminClient.Query(TimeDiff(Epoch(0, TimeUnit.Second), Epoch(1, TimeUnit.Second), TimeUnit.Second));
2637+
var res2 = await adminClient.Query(TimeDiff(Date("1970-01-01"), Date("1970-01-02"), TimeUnit.Day));
2638+
var res3 = await adminClient.Query(TimeDiff(Date("1970-01-01"), Date("1970-01-03"), "days"));
2639+
2640+
Assert.AreEqual(1L, res1.To<long>().Value);
2641+
Assert.AreEqual(1L, res2.To<long>().Value);
2642+
Assert.AreEqual(2L, res3.To<long>().Value);
2643+
}
2644+
23582645
private async Task<Value> NewCollectionWithValues(string colName, string indexName, int size = 10, bool indexWithAllValues = false)
23592646
{
23602647
RefV aCollection = (await client.Query(CreateCollection(Obj("name", colName))))

FaunaDB.Client/Query/Expr.Operators.cs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,18 @@ public static implicit operator Expr(TimeUnit unit)
6565

6666
case TimeUnit.Second:
6767
return "second";
68+
69+
case TimeUnit.Minute:
70+
return "minute";
71+
72+
case TimeUnit.Hour:
73+
return "hour";
74+
75+
case TimeUnit.HalfDay:
76+
return "half day";
77+
78+
case TimeUnit.Day:
79+
return "day";
6880
}
6981

7082
throw new ArgumentException("Invalid time unit value");
@@ -169,9 +181,21 @@ public static explicit operator TimeUnit(Expr unit)
169181

170182
case "second":
171183
return TimeUnit.Second;
184+
185+
case "minute":
186+
return TimeUnit.Minute;
187+
188+
case "hour":
189+
return TimeUnit.Hour;
190+
191+
case "half day":
192+
return TimeUnit.HalfDay;
193+
194+
case "day":
195+
return TimeUnit.Day;
172196
}
173197

174-
throw new ArgumentException("Invalid string value. Should be \"second\", \"millisecond\", \"microsecond\" or \"nanosecond\"");
198+
throw new ArgumentException("Invalid string value. Should be \"day\", \"half day\", \"hour\", \"minute\", \"second\", \"millisecond\", \"microsecond\" or \"nanosecond\"");
175199
}
176200

177201
public static explicit operator Normalizer(Expr normalizer)

FaunaDB.Client/Query/Language.Collection.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,5 +205,39 @@ public static Expr IsNonEmpty(Expr collection) =>
205205
/// </example>
206206
public static Expr Reverse(Expr expr) =>
207207
UnescapedObject.With("reverse", expr);
208+
209+
/// <summary>
210+
/// Evaluates to true if all elements of the collection is true.
211+
/// <para>
212+
/// <see href="https://docs.fauna.com/fauna/current/api/fql/functions/all">All function</see>
213+
/// </para>
214+
/// </summary>
215+
/// <param name="collection">A collection expression</param>
216+
/// <example>
217+
/// <code>
218+
/// var result = await client.Query(All(Arr(true, true, true)));
219+
///
220+
/// Assert.IsTrue(true, result.To<bool>().Value);
221+
/// </code>
222+
/// </example>
223+
public static Expr All(Expr collection) =>
224+
UnescapedObject.With("all", collection);
225+
226+
/// <summary>
227+
/// Evaluates to true if any element of the collection is true.
228+
/// <para>
229+
/// <see href="https://docs.fauna.com/fauna/current/api/fql/functions/any">Any function</see>
230+
/// </para>
231+
/// </summary>
232+
/// <param name="collection">A collection expression</param>
233+
/// <example>
234+
/// <code>
235+
/// var result = await client.Query(Any(Arr(true, false, false)));
236+
///
237+
/// Assert.IsTrue(true, result.To<bool>().Value);
238+
/// </code>
239+
/// </example>
240+
public static Expr Any(Expr collection) =>
241+
UnescapedObject.With("any", collection);
208242
}
209243
}

0 commit comments

Comments
 (0)