3 ms·
Before I reply let me clarify that I don't work there anymore and my thoughts could have diverged since leaving their corporate hive-mind collective of the sort
by SamReidHughes 11y ago
Before I reply let me clarify that I don't work there anymore and my thoughts could have diverged since leaving their corporate hive-mind collective of the sort that employees often claim not to represent.
> Why couldn't it just be a document flavored SQL? Having a DSL for writing in-database procedures is fine. But tying all external queries to a Builder is, from a purely aesthetic POV, pretty ugly IMO.
Having raw SQL in an application is insane. Being able to connect directly to a database and hand-rolling a query in SQL to look at stuff directly is not. But building such a query in Javascript like you do in the admin UI is fine too (actually, it's way more annoying than the Python or Ruby API's), with the benefit that you have only one way to learn to write queries, instead of two, and with the downside of not having infix operators and having to close many more parentheses and such. There might also be training costs if you have a semi-technical role that would have involved making SQL queries.
I don't believe in an aesthetic POV. Unless ease-of-use is the aesthetic.
> Yes, I realize the Builder supports map/reduce as well. In practice I'm skeptical how well that works in an on-demand fashion.
SQL databases already have aggregation queries, so there's nothing going on that they wouldn't already do. Map/reduce isn't, like, a big deal, other than in the mundane way that a table scan is generally a big deal.
- ssmoot 11y ago> SQL databases already have aggregation queries, so there's nothing going on that they wouldn't already do. That's true. I guess it depends on implementation. I was imagining something like CouchDB, which has to parse each document and run your map and reduce functions over them to build an index. Not something you'd want to do on-demand. > Having raw SQL in an application is insane. That's just like, your opinion man. We could argue all day on that one, but suffice it to say it's definitely one of those Novice -> Intermediate -> Expert -> Master circle-of-life things IME. You can syntax check SQL. It's easily understood by most developers regardless of background. You probably won't have to spend more than 5 minutes getting up to speed with whatever driver you're using. There's never been an app that didn't require major refactoring after swapping out the database layer. There's just very little point in abstracting it IME. I've written a number of O/R Mappers in my time, including creating the second most popular Ruby one. I wouldn't do it again. ;-) I'd use something like http://slick.typesafe.com/doc/3.1.1/introduction.html#plain-sql-support http://slick.typesafe.com/doc/3.1.1/introduction.html#plain-... write a few type-conversion protocols and call it a day. It's safe, simple, productive and can be maintained by anyone. Any downsides are pretty minor IMO. The comment on aesthetics is just that the primary interface to the database has a "JavaScript First" feel to it. It's an odd choice (to me) to use a context bound Builder as opposed to an AST Builder you just pass to connection.execute or something.
- SamReidHughes 11y ago> It's an odd choice (to me) to use a context bound Builder as opposed to an AST Builder you just pass to connection.execute or something. But that's what RethinkDB's query builder is. You construct a free-standing AST, let's call it x, then call x.run(conn) or (IIRC) conn.run(x) to run it. Edit: > You can syntax check ... O/R Mappers ... It's not a dichotomy between SQL and O/R mappers here, and sorry if you weren't trying to imply that. An SQL query building API can easily be understood by developers that know SQL (correct me if I'm wrong), you don't need to syntax check it, and it survives refactorings just as well. And it's hard not to need to dynamically construct queries anyway.
- ssmoot 11y ago> But that's what RethinkDB's query builder is. You construct a free-standing AST, let's call it x, then call x.run(conn) or (IIRC) conn.run(x) to run it. That's not what http://rethinkdb.com/docs/quickstart/ http://rethinkdb.com/docs/quickstart/ says. It shows a connection that exposes context-bound Builder methods with trigger (insert, changes, run, etc) methods. Though that is a little more high-level than I thought at first. You're right that not everything is a `run`. It feels like a stretch to call it an AST but maybe that's just a question of taking a closer look at the wire protocol. > An SQL query building API can easily be understood by developers that know SQL It can, but it's more complex with more mental overhead. It's the difference between Active Record scopes and HQL. Where HQL is a flavor of SQL with extensions for object notation that can feel pretty similar to qualified database.table.column syntax, AR scopes are (I feel) objectively more complex. > you don't need to syntax check it You actually do. It's just your interpreter or compiler that does so. A compiler plugin (for native support) or embedded DSL such as LINQ or the Slick DSL can accomplish the same for SQL though. > it's hard not to need to dynamically construct queries anyway True, but IME a Builder based API is a poor choice for that unless the scope of the Builder usage is private to a single class. Once you start passing around a mutable builder you can easily end up with unintentional side-effects. In SQL builders it's easy for example to override a sort clause to be incompatible with a previous aggregation if the builder doesn't go to a lot of care to make that impossible. And then you might well also end up in a situation where you need to discard previously defined scopes (such as the problematic aggregation). How do you do that? IME once you let a builder escape a very narrow scope (class-level at the most) you create a great maintenance burden and create a new category of very difficult to avoid bugs. Interpolation/materialization of terms into an AST is a much simpler, and encourages simpler designs (IME). IOW: Writing builders should be up to the user. If the "driver" provides it, it's too easy to fall into anti-pattern traps with unintended consequences. That's just my opinion. But bottom line, the API is much too high-level for my taste. I'd prefer something much closer to Cloudant, with a well defined syntax (if you imagined the HTTP end-points query-parameters folded into the request body instead; query vs update APIs aren't super consistent on which goes where, eg: _deleted or _rev vs keys or include_docs). Such a high-level interface for building queries being provided for the driver is fairly unique among the databases I'm familiar with. And while it seems like a nice affordance for JavaScript users, it feels like an anti-pattern for other platforms. I don't mean to trash RethinkDB though. On the other end of the spectrum you have DynamoDB's very cumbersome API. If I had to pick between the two I'd take RethinkDB's any day. I just think a more formal syntax for other platforms would make it feel less JavaScript centric and more at home on other platforms.