<div dir="ltr"><br><br><div class="gmail_quote">On Sat, Jul 30, 2011 at 3:44 AM, Tim Watson <span dir="ltr"><<a href="mailto:watson.timothy@gmail.com">watson.timothy@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div class="im">On 29 July 2011 22:27, Alex Arnon <<a href="mailto:alex.arnon@gmail.com">alex.arnon@gmail.com</a>> wrote:<br>
> I had built a rather basic prototype that uses a jnode running a JDBC proxy.<br>
> This approach would increase latency, but provide access to every RDBMS<br>
> under the sun.<br>
<br>
</div>That really scares me, and I would hesitate to use it. If you planning<br>
on conquering the enterprise, I suspect that jumping out of you main<br>
language VM into another one just to do database access isn't going to<br>
go down too well. Although I could be wrong, because honestly I've<br>
seen big companies buy "All Kinds of Stuff" (TM).<br>
<br></blockquote><div><br>I assure you, I am not planning on conquering any Enterprises :) <br>However, I disagree with the above... please see below.<br> </div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">

Once I'd gone to that much trouble, I might as well write the whole<br>
shebang in Java. In fact, I prefer picking "the right tool for the<br>
job" for each part of a project and Erlang doesn't fit every niche so<br>
sometimes turning to Java, Python and other things is the correct<br>
choice. Erlang does have some decent open source libraries for doing<br>
database access (to postgres at least) and I've seen a very good<br>
closed source Oracle driver written as a port_driver using the OCL<br>
libraries - quick and stable, but sadly not available to the general<br>
public. The author claims he'll help do a rewrite when native<br>
processes get added to Erlang. :)<br>
<div class="im"><br></div></blockquote><div><br>I agree with the sentiment. Java will indeed usually get the least friction for any implementation, which for the Enterprise-minded is usually reason enough to use it for everything.<br>
However, in many places one could find instances where building at least a prototype in Erlang might be the Right Thing. Several back-end or even front-end services I have built I would certainly have knocked up in Erlang very rapidly, just as an idea to Show The Boss or even as a real deployment candidate. In all these instances, the database was either Oracle or MS-SQL, with reasonably low DB access performance expectations.<br>
Now, like you said above, just dropping into another VM for whatever service is going to "look bad". Certainly if you've really built it from scratch for your pet project, but what if we were talking about something that's been battle-proven? That maybe speaks Enterprise lingo? Maybe put a nice face on it, for instance - add a RESTful JSON interface or something, as a diversion? :) Like you said, the Enterprise is often willing to take a lot of crap just to have something that looks "standard" - and deploying a Lean JDBC Proxy can go down relatively easily.<br>
 </div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;"><div class="im">
><br>
> I think that what is truly missing is an agreed-upon, standard EDBC API<br>
> definition. IMHO one that is based on JDBC could certainly be good enough.<br>
> Once that is in place, implementation is just a detail :)<br>
> Erlang Community, time to claim your place in the Enterprise!!!! :)<br>
><br>
<br>
</div>I kind of agree that a standard API would be good. Unless it comes<br>
from Ericsson or gets into the OTP distro, it's not really going to be<br>
a standard though. If someone starts one, they really need to get on<br>
this list and push people for feedback. I'd also suggest making it as<br>
thin a veneer as possible on top of the real library/application being<br>
used, as this is less likely to introduce problems.<br>
<br></blockquote><div><br>Right.<br>Something that I'd use the JDBC Proxy Abomination suggested above is a fallback. In that case, you're not expecting blazing performance - however, you'll have a stable backend to bang your API out on. Gradually adding clean Erlang backends can come later.<br>
 </div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
I think a big part of the reason why medium/large enterprises don't<br>
tend to use Erlang as a core development language, actually has<br>
nothing to do with technology. It's a resourcing issue. It's harder to<br>
find real Erlang expertise (i.e., commercial experience) than it is to<br>
find Java and/or .NET developers and that increases both cost and<br>
risk. I certainly think that Erlang's productivity and other factors<br>
(like its built-in support for making fault tolerant applications) can<br>
actually outweigh the initial cost of hiring good developers, but<br>
again this is a risk that many big businesses (which are mainly run by<br>
accountants in my experience) won't take. Start-ups and niche sectors<br>
are a completely different kettle of fish.<br>
<br></blockquote><div><br>I think that's spot on.<br>Neither should they change this approach.<br>If you want to leap forward in language/tool technology in the Enterprise, there's always stuff like Scala (which is an excellent step up from Java, and starting to get some Traction).<br>
 </div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
Finally, I agree that JDBC has some good patterns to follow, but it's<br>
whole design is very Object Oriented (i.e., mutable state oriented)<br>
and therefore not much of it is really a good fit for Erlang. Things<br>
that might translate nicely as features are (IMHO):<br>
<br>
1. Runtime discovery of drivers<br>
2. Runtime discovery of data source(s) a la JNDI - this is very useful<br>
in Java applications and something like it (maybe gproc based?) would<br>
be nice<br>
3. Standard API for dealing with connections (and possibly connection<br>
pools, although I'm not sure I'd want to open that particular can of<br>
worms myself)<br>
4. Standard API for working with database metadata (e.g.,<br>
INFORMATION_SCHEMA, system views and the like)<br>
5. Standard API for working with result sets (e.g., moving/scrolling,<br>
indexed access to columns in the current row, etc)<br>
6. QLC queries for interacting with result sets?<br>
<br>
Not sure if that last one is really a good idea - it's very late here<br>
and I've had a busy week.<br>
<br>
AFAICT good API design for Erlang doesn't usually involve exposing<br>
internal data structures (records, etc) to the end user and any state<br>
is usually hidden as much as possible. My assumption is that the<br>
various API modules involved would usually just return an opaque<br>
handle to the user, which is then used during further calls. I<br>
certainly wouldn't go off using parameterised modules as they're not<br>
supported. So you'd get something more like:<br>
<br>
{ok, DSHandle} = edbc_datasource:get_named_datasource(postgres_test),<br>
{ok, ConnHandle} = edbc_connection:open(DSHandle, [PerConnOptions]),<br>
{ok, TxnHandle} = edbc_transaction:begin(ConnHandle, [{isolation,<br>
read_committed]),<br>
try<br>
    %% fall back to normal (not prepared) statement when this doesn't work...<br>
    {ok, StatementHandle} = ebdc_connection:prepare_statement(ConnHandle, SQL),<br>
    {ok, StatementHandle} = edbc_statement:bind_named_params([{id,<br>
12345}, {customer_name, "Mr Smith"}]),<br>
<br>
    {ok, Cursor} = edbc_connection:execute_query(ConnHandle, StatementHandle),<br>
    edbc_rowset:foreach(fun(Row, Col, Value) -> io:format("~p:~p =<br>
~p~n", [Row, Col, Value]) end, Cursor),<br>
<br>
    %% version of execute/2 that takes raw SQL instead of prepared statements<br>
    edbc_connection:execute_update(ConnHandle, "INSERT INTO Food<br>
VALUES ('Ice Cream', 'Vanilla')"),<br>
    {ok, committed} = edbc_transaction:commit(TxnHandle)<br>
catch<br>
    _:_ -> {ok, aborted} = edbc_transaction:rollback(TxnHandle)<br>
after<br>
    {ok, closed} = edbc_connection:close(ConnHandle)<br>
<br>
<br>
Probably a lot of these calls to specific modules could be hidden<br>
behind a slightly higher level API:<br>
<br>
{ok, Conn} = edbc:open_connection(postgres_test),<br>
Results = edbc:map(Conn, fun do_with_each_cell/2, SqlQuery),<br>
%% or<br>
Tree = edbc:fold(Conn, Query,<br>
    fun(Row, Col, Val, Acc) -> gb_trees:enter({Row, Col}, Val, Acc) end),<br>
etc.....<br>
<br>
You're right that having a good standard API against which all of the<br>
various implementations could be used is a very nice idea. The<br>
question is, how close are the existing libraries/applications to a<br>
*nice* API (whatever that is) and how much work is involved in<br>
bridging between them. This is why I'd like to see if the binding<br>
between API and implementation can be generated - I'd like to avoid<br>
having state in the API and let the underlying implementations deal<br>
with their own states, servers, errors, etc.<br>
</blockquote></div><br>AFAICT, the existing APIs are similar to a severely cut-down JDBC API. So nothing very surprising there - I'm guessing most (if not all) have been built on a per-need basis.<br>I agree that one should try to veer as much away from heavily-stateful APIs, and this can probably be avoided.<br>
However, since we ARE dealing with RDBMS's, some of the flavour of using them is bound to come through the API - connection pooling, transactions and error handling/reporting should definitely be part of any API that expects to be widely useful. I'd also add an Erlang-y flavour to some operations, like streaming of result sets, to work with the platform's grain and not so much against it.<br>
<br></div>