In fact, you can add a “final side effect” to the lazy sequence that will run once when the entire sequence is consumed for the first time:
(def s (lazy-cat (range 10) (do (println :foo) nil))) (first s) ; => returns 0, prints out nothing (doall (take 10 s)) ; => returns (0 1 2 3 4 5 6 7 8 9), prints nothing (last s) ; => returns 9, prints :foo (doall s) ; => returns (0 1 2 3 4 5 6 7 8 9), prints :foo ; or rather, prints :foo if it it the first time s has been ; consumed in full; you'll have to redefine it if you called ; (last s) earlier
I'm not sure that I will use this to close the connection to the database, although, in my opinion, it is considered best practice not to keep in touch with the database indefinitely and putting your call to close the connection at the end of your lazy sequence of results will not only maintain the connection longer than necessary, but also to open the possibility that your program will not work for an independent reason, without closing the connection. So for this scenario, I would usually just rip all the data. As Brian says, you can store anything you want, raw, than do any conversion lazily, so you should be fine until you try to pull a really huge data set into one piece.
But then I do not know your exact circumstances, therefore, if it makes sense from your point of view, you can definitely call the function to close the connection at the end of its sequence of results. As Michel Borkent points out, you cannot use with-connection if you want to do this.
Michał Marczyk
source share