Does anybody have a quick snippet of how to use the db package from FJ? And ditto for the parallel stuff? I can’t quite figure out the entry point and how to get started, and I’d like to use these two for articles #3 and #4 (with the FJ collections being #2).
Ted Neward
Java, .NET, XML Services
Consulting, Teaching, Speaking, Writing
--
You received this message because you are subscribed to the Google Groups "Functional Java" group.
To post to this group, send email to functio...@googlegroups.com.
To unsubscribe from this group, send email to functionaljav...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/functionaljava?hl=en.
> To unsubscribe from this group, send email to functionaljav...@googlegroups.com.
Sorry for the late reply to this, but I’m finally getting around to trying this (fj.control.db), and I admit that it’s not clicking for me.
Couple of questions:
(*) Can’t I create prepareStatement() as an instance of F<Connection, F<String, DB<PreparedStatement>>? Then invoke it as prepareStatement.f(“select foo, bar from baz”)?
(*) Normally/frequently you want to bind parameters into a PreparedStatement; is there a generic way to capture that? Or do I have to write a prepareStatement(String, P2) and prepareStatement(String, P3), … ?
(*) Why does readResults return a HashMap<String,String>? Shouldn’t it return a List<HashMap<String,String>>, since this is a collection of tuples? (Is there any way to use Pn (product) types here?)
(*) DbState.reader() is for when you want to just query the database, correct? Modifications would need to go through a DbState.writer(), correct?
I get how the binding would work, so conceptually I’m on board with this; I’m just not seeing how the concepts should map to the concrete, so to speak.
Would you happen to have a simple example laying around showing all of this?
You really should not get a ResultSet out of DB. Instead, write
hasNext of type F<ResultSet,DB<Boolean>> and next F<ResultSet,
DB<Unit>> to step through the result set within the DB monad. Also
don't forget to close your ResultSets.
Runar
Thanks, Shlomi—I can’t decide between doing article #2 on collections or on the DB stuff. I think I need to do collections (List, Array, Tree, etc) next, but the DB stuff is kinda sexy, so…. *shrug* Oh, well, guess I have to consider writing more. :-)
But I need a bit of clarification on your sample code here. Runar, if you can join in, that’d be great.
> so, to answer your questions, if you want to have extra parameters, you can absolutely have them, without using P's at all, rather by passing them as an argument (like in prepareStatement(final String sql), and you can add as many as you'd like )
OK, but that means I have to write an overloaded prepareStatement() method for each arity and/or type of parameter I want to pass in. That seems wasteful—is there no way to compose that? (Part of me wants to reach for varargs or a List<> for the parameters, but I suspect that’s my O-O lizard brain talking. Maybe that’s an OK solution, but I want to exhaust the functional axis before I go back to what I know already.)
> ResultSet rs = DbState.reader("conn-url").run(prepareStatement("select * from table").bind(runStatement());
I think you’re missing a right-parens here, and I’m not in front of a Java command prompt to experiment, so I’m just going to ask—is the bind() against the return from DbState.reader(), or against the return from prepareStatement()? (There’s bind() on both, if I remember correctly, hence my confusion.) And if I wanted to do as Runar suggested (convert the ResultSet into a List-of-Map<String,Object> or List<Person> before handing it back), would that be inside the run()? Where does the bind() go in that case, is what I’m asking?
Part of me *wants* to see the DB stuff return Pn instances out of a query, because that provides a nicely-typed bundle of data to use in a constructor to an object.
What I've done in the past is to have an ADT for SQL, complete with
"holes" for bind variables (or literals, as the mood may strike you).
Then have an F<SQL, DB<PreparedStatement>>.
> is the bind() against
> the return from DbState.reader(), or against the return from
> prepareStatement()? (There’s bind() on both, if I remember correctly, hence
> my confusion.) And if I wanted to do as Runar suggested (convert the
> ResultSet into a List-of-Map<String,Object> or List<Person> before handing
> it back), would that be inside the run()? Where does the bind() go in that
> case, is what I’m asking?
Follow the types. If you want to convert ResultSet to List<Person>,
you would pass an F<ResultSet, DB<List<Person>>> to .bind() on an
object of type DB<ResultSet>.
Mind you, this is a really good excuse to use iteratees. It's too bad
we don't provide that interface in FJ.
> Part of me *wants* to see the DB stuff return Pn instances out of a query,
> because that provides a nicely-typed bundle of data to use in a constructor
> to an object.
Pro tip: Don't ever have DB.run return anything other than Unit. Don't
get data OUT. Put computations over that data IN with .map() and
.bind().
Runar
> > Part of me *wants* to see the DB stuff return Pn instances out of a
> > query, because that provides a nicely-typed bundle of data to use in a
> > constructor to an object.
>
> Pro tip: Don't ever have DB.run return anything other than Unit. Don't get
> data OUT. Put computations over that data IN with .map() and .bind().
>
OK, now you're intriguing me--is there a quick example you can send? Are you
advocating something like a SELECT FOR UPDATE or something?
Ted Neward
Java, .NET, XML Services
Consulting, Teaching, Speaking, Writing
http://www.tedneward.com
> -----Original Message-----
> From: functio...@googlegroups.com
> [mailto:functio...@googlegroups.com] On Behalf Of Runar Bjarnason
> Sent: Wednesday, December 15, 2010 4:00 PM
> To: functio...@googlegroups.com
> Subject: Re: [functionaljava] Quick examples/samples
>
--
Tony Morris
http://tmorris.net/
Something like...
public interface SQL {
public <B> B eval(F<Select, B> select, F<F<SQLVar, SQL>, B> freeVar,
F<SQLVar, B> boundVar);
}
public interface Select {
public <B> B eval(F<Map<String, Expr>> select, F<Map<String, SQL>,B>
from, F<Map<String, Expr>> where);
}
public interface Expr {
public <B> B eval(F3<String, B, B, B> binary, F2<String, B, B, B>
unary, F2<SQLLit, B> literal, F2<SQLVar, B> variable);
}
public interface SQLLit {
public <B> B eval(F<String, B> string, F<Integer, B> integer, ... );
}
public interface SQLVar {
public <B> B eval(F<String, B> string, F<Integer, B> integer, ...);
}
Alternatively, a simple intermingling of variables and string literals:
public interface SQL {
public <B> B eval(F2<B, B, B> append, F<String, B> literal,
F<SQLVar, B> variable);
}
> OK, now you're intriguing me--is there a quick example you can send? Are you
> advocating something like a SELECT FOR UPDATE or something?
No, I'm advocating doing all of your computation with functions of
type F<A, DB<B>>, for some A and B, wherever you have to use data of
type A that comes from the database (producing B). For example, if you
have DB<String> x and you want to println that String, don't run that
x. Instead, call x.map() with an argument of type F<String, DB<Unit>>
which prints the string. This is how you stay composable.
Runar
The first one will run in the NFJS Journal (which I think went out this month). A second will run in the Feb or March issue of the same periodical.
After a reasonable period of time, I’ll post them to my website, but the usual arrangement is that the articles run exclusively in the publication for a while first.
Of course, if you’re in this group, you could check the archives back about a month or so—I posted the text for the first article here for (extremely helpful!) review.
No immediate plans, but it would not be difficult to write pure
iteratees in Java.
Yep, that was kinda where my mind ended up. #2 will probably not be due for a few months yet, but I’m going to try and slam two or three of them out over the holidays and try to get ahead of my deadlines for a change. :-)