/src/Dsl.fs

http://github.com/kolosy/FunctionalDivan · F# · 77 lines · 63 code · 14 blank · 0 comment · 7 complexity · a570f45649db94556cb2119d256f68b6 MD5 · raw file

  1. #light
  2. namespace FunctionalDivan
  3. module Dsl =
  4. open Divan
  5. open RecordMapping
  6. open Microsoft.FSharp.Reflection
  7. open System.Reflection
  8. let server address port = CouchServer(address, port)
  9. let db name (server: CouchServer) = server.GetDatabase(name)
  10. let query design view (db: CouchDatabase) = db.Query(design, view)
  11. let byKeys (key: obj[]) (query: CouchQuery) = query.Keys key
  12. let byKey (key: obj) (query: CouchQuery) = query.Key key
  13. let limitTo limit (query: CouchQuery) = query.Limit limit
  14. let offsetBy offset (query: CouchQuery) = query.Skip offset
  15. let startAt (startKey: obj) (query: CouchQuery) = query.StartKey startKey
  16. let endAt (endKey: obj) (query: CouchQuery) = query.EndKey endKey
  17. let startAtId startKey (query: CouchQuery) = query.StartKeyDocumentId startKey
  18. let endAtId endKey (query: CouchQuery) = query.EndKeyDocumentId endKey
  19. let select (query: CouchQuery) = query.GetResult()
  20. let selectDocs<'a when 'a: (new: unit -> 'a) and 'a:> ICouchDocument> (query: CouchQuery) =
  21. List.ofSeq <| query.IncludeDocuments().GetResult().Documents<'a>()
  22. let selectRecords<'a> (query: CouchQuery) =
  23. let results = (select <| query.IncludeDocuments()).Documents<CouchJsonDocument>()
  24. List.ofSeq results |>
  25. List.map (fun elem -> (readJson typeof<'a> elem.Obj) :?> 'a)
  26. let from<'a> (db: CouchDatabase) id =
  27. let jsonDoc = db.GetDocument(id)
  28. if not (jsonDoc = null) then Some <| (readJson typeof<'a> (jsonDoc.Obj) :?> 'a)
  29. else None
  30. let internal saveRecord (db: CouchDatabase) r includeType =
  31. let parms, hasId, hasRev =
  32. Array.fold
  33. (fun s (e: PropertyInfo) ->
  34. let map, id, rev = s
  35. (Map.add (e.Name) e map, id || e.Name = "id", rev || e.Name = "rev"))
  36. (Map.empty, false, false)
  37. (FSharpType.GetRecordFields(r.GetType()))
  38. if not (hasId && hasRev) then
  39. failwith "both id and rev are required on the record"
  40. else
  41. let _id, _rev = ref (parms.["id"].GetValue(r, null) :?> string), ref (parms.["rev"].GetValue(r, null) :?> string)
  42. ignore <| db.SaveDocument
  43. { new ICouchDocument with
  44. member x.ReadJson jObj = ()
  45. member x.WriteJson writer = writeJson r writer includeType
  46. member x.Id with get() = !_id and set v = _id := v
  47. member x.Rev with get() = !_rev and set v = _rev := v }
  48. !_id, !_rev
  49. let into (db: CouchDatabase) r = saveRecord db r true
  50. let intoSilent (db: CouchDatabase) r = saveRecord db r false
  51. module Fti =
  52. open Divan.Lucene
  53. let query name index (db: CouchDatabase) = db.Query(CouchLuceneViewDefinition(index, new CouchDesignDocument(name, db)))
  54. let q text (query: CouchLuceneQuery) = query.Q text
  55. let limitTo limit (query: CouchLuceneQuery) = query.Limit limit
  56. let offsetBy offset (query: CouchLuceneQuery) = query.Skip offset
  57. let select (query: CouchLuceneQuery) = query.GetResult()
  58. let selectDocs<'a when 'a: (new: unit -> 'a) and 'a:> ICouchDocument> (query: CouchLuceneQuery) =
  59. List.ofSeq <| query.IncludeDocuments().GetResult().GetDocuments<'a>()
  60. let selectRecords<'a> (query: CouchLuceneQuery) =
  61. let results = (select <| query.IncludeDocuments()).GetDocuments<CouchJsonDocument>()
  62. List.ofSeq results |>
  63. List.map (fun elem -> (readJson typeof<'a> elem.Obj) :?> 'a)