diff --git a/integration-tests/sqlite/src/Main.gren b/integration-tests/sqlite/src/Main.gren index 517db2f..bb9588a 100644 --- a/integration-tests/sqlite/src/Main.gren +++ b/integration-tests/sqlite/src/Main.gren @@ -115,7 +115,30 @@ tests fsPerm = , await "Open db for multiple inserts" createTestDb <| \db -> await "Insert all people" (insertPeople people db) <| \summary -> concat - [ test "summary.changes is 1 (only reports from last execution)" <| \_ -> + [ awaitError "foldl with a bad decoder produces expected error" + (Sqlite.foldl (\_ acc -> acc + 1) 0 db { allPeopleQ | rowDecoder = badPersonDecoder }) <| \err -> + test "expected decoding error" <| \_ -> + when err is + Sqlite.DecodingError _ -> + Expect.pass + + _ -> + Expect.fail "Expected `DecodingError` from failed decoding" + , await "can foldl over people and count them" + (Sqlite.foldl (\_ acc -> acc + 1) 0 db allPeopleQ) <| \count -> + test "Count is expected" <| \_ -> + Expect.equal count 2 + , await "can foldl over people to build an list of names" + (Sqlite.foldl (\{ name } acc -> Array.pushLast name acc) [] db allPeopleQ) <| \namesArray -> + concat + [ test "Array contains the name Robin" <| \_ -> + Expect.equal (Array.member "Robin" namesArray) True + , test "Array contains the name Justin" <| \_ -> + Expect.equal (Array.member "Justin" namesArray) True + , test "Array is of expected shape" <| \_ -> + Expect.equal namesArray [ "Robin", "Justin" ] + ] + , test "summary.changes is 1 (only reports from last execution)" <| \_ -> Expect.equal 1 summary.changes , test "summary.lastInsertedRowid is > 0" <| \_ -> Expect.greaterThan 0 summary.lastInsertRowid @@ -283,6 +306,13 @@ personDecoder = Decode.succeed { name = name, role = role } +badPersonDecoder : Decoder Person +badPersonDecoder = + Decode.string "namee" <| \name -> + Decode.string "role_" <| \role -> + Decode.succeed { name = name, role = role } + + insertPerson : Person -> Sqlite.Database -> Task Sqlite.Error Sqlite.ExecutionSummary insertPerson person db = Sqlite.execute db diff --git a/src/Gren/Kernel/Sqlite.js b/src/Gren/Kernel/Sqlite.js index f346e0d..5ee456c 100644 --- a/src/Gren/Kernel/Sqlite.js +++ b/src/Gren/Kernel/Sqlite.js @@ -52,10 +52,10 @@ var _Sqlite_close = function (db) { }); }; -var _Sqlite_getAll = F2(function (query, db) { +var _Sqlite_foldl = F4(function (query, db, func, acc) { return __Scheduler_binding(function (callback) { try { - const results = []; + var acc_ = acc; const prepped = db.prepare(query.__$query); const params = __Json_unwrap(__SqliteEncode_toJson(query.__$parameters)); const rowDecoder = __SqliteDecode_toJson(query.__$rowDecoder); @@ -68,15 +68,14 @@ var _Sqlite_getAll = F2(function (query, db) { ); if (__Result_isOk(jsonResult)) { - results.push(jsonResult.a); + acc_ = A2(func, jsonResult.a, acc_); } else { return callback( __Scheduler_fail(__Sqlite_DecodingError(jsonResult.a)), ); } } - - callback(__Scheduler_succeed(results)); + callback(__Scheduler_succeed(acc_)); } catch (e) { callback(_Sqlite_constructError(e)); } diff --git a/src/Sqlite.gren b/src/Sqlite.gren index 68ca15f..66c6207 100644 --- a/src/Sqlite.gren +++ b/src/Sqlite.gren @@ -1,6 +1,7 @@ module Sqlite exposing (..) +import Array.Builder import FileSystem import FileSystem.Path exposing (Path) import Json.Decode as Decode @@ -95,7 +96,13 @@ getMaybeOne db query = getAll : Database -> Query value -> Task Error (Array value) getAll db query = - Gren.Kernel.Sqlite.getAll query db + foldl Array.Builder.pushLast (Array.Builder.empty 0) db query + |> Task.map Array.Builder.toArray + + +foldl : (a -> b -> b) -> b -> Database -> Query a -> Task Error b +foldl func acc db query = + Gren.Kernel.Sqlite.foldl query db func acc -- EXECUTIONS