January 02, 2017 Re: Databases and the D Standard Library | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam Wilson | On 02/01/2017 4:44 PM, Adam Wilson wrote: > rikki cattermole wrote: >> On 02/01/2017 3:03 PM, Adam Wilson wrote: >>> rikki cattermole wrote: >>>> On 01/01/2017 5:19 PM, Adam D. Ruppe wrote: >>>>> On Sunday, 1 January 2017 at 03:51:52 UTC, rikki cattermole wrote: >>>>>> Which is fine if all you use is c's sockets or only that database >>>>>> connection for a thread. >>>>> >>>>> The C drivers typically offer handles of some sort (Windows HANDLE, >>>>> *nix >>>>> file descriptor, that kind of thing) that you can integrate into other >>>>> event loops. >>>> >>>> That's fine and all, but you've still got to deal with it on D's >>>> side so >>>> you can mix and match libraries that require access to the same event >>>> loop (such as Windows). >>> >>> Vibe.d is working on a native D event loop. We would probably want to >>> integrate with that. >>> >>> EventCore: https://code.dlang.org/packages/eventcore >>> >> >> No, it isn't generic enough. >> Nor can it handle windowing without a good bit of modifications. >> >> Mine in SPEW[0] is however ready for this task. >> >> [0] >> https://github.com/Devisualization/spew/tree/master/src/base/cf/spew/event_loop >> >> > > How much effort to make the changes? Their plans seem to indicate that > they want to support UI integration. I ask because I need to use the > library that is going to get the most support over time and that is > vibe.d right now. Read and compare the code. To add anything into the Vibe.d one requires direct modification which is unacceptable for Phobos IMO. My aim for SPEW was to be as close as glib's[0] as reasonably possible. A well tested set of features. I'm sorry but this is just not acceptable[1] for an event loop: interface EventDriver { @safe: /*@nogc:*/ nothrow: @property EventDriverCore core(); @property EventDriverTimers timers(); @property EventDriverEvents events(); @property EventDriverSignals signals(); @property EventDriverSockets sockets(); @property EventDriverDNS dns(); @property EventDriverFiles files(); @property EventDriverWatchers watchers(); /// Releases all resources associated with the driver void dispose(); } Its fine for a web framework, aka a specific task but not when its generic. When we're discussing a generic event loop it shouldn't care about the different usage of it. All it knows is that there are events that come from sources and then mapped to a consumer. It isn't the most performant but that is ok. You would use a different implementation depending on your use case e.g. 1:1 is easy enough to do without a event loop manager. Just so you're aware, windowing is extremely hard to get right. Sockets, DNS, signals and timers ext. are easy to implement compared. [0] https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html [1] https://github.com/vibe-d/eventcore/blob/master/source/eventcore/driver.d |
January 02, 2017 Re: Databases and the D Standard Library | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris Wright | On 2017-01-01 17:50, Chris Wright wrote: > Those both limit your ability to use the underlying database to its full > potential. They offer a chance for queries that seem simple and efficient > to become horribly inefficient. I'm perfectly aware of the limitations and capabilities of ORM's. I'm just saying that making the interface/names different just to make it different is not a good idea. It should be up to the user to choose if an ORM is used or not and this interface should try to, as much as possible, to make it possible to use an ORM just as well as not using an ORM. This whole idea seems fail even before it's barely stared. If this idea is going to work then all the layers need to be designed correctly and the lower layers should not know anything about the higher layers. -- /Jacob Carlborg |
January 02, 2017 Re: Databases and the D Standard Library | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam Wilson | On 2017-01-02 02:34, Adam Wilson wrote: > That was my intention, the knee-jerk reaction that class and interfaces > get here sometimes strikes me as a bit histrionic sometimes. They are a > tool with a use case. :) I think that the design should try to avoid classes as much as possible for things that will be frequently created. It's always possible to wrap a struct in a class, the other way around is a bit more difficult. But when it comes to the connection object I think it's fine to use classes since it will most likely only be created once per thread. -- /Jacob Carlborg |
January 02, 2017 Re: Databases and the D Standard Library | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam Wilson | On Sun, 01 Jan 2017 17:55:01 -0800, Adam Wilson wrote:
> On that I beg to differ. The C libraries are not @safe, they have wildly different API's, and they have high-complexity, which is a large risk-factor for bugs and/or security flaws.
If we have the database interface defined, there's no reason we couldn't provide, for instance, a postgres-c-wrapper driver and a postgres-pure-d driver.
|
January 02, 2017 Re: Databases and the D Standard Library | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris Wright | On 1/2/17 8:33 AM, Chris Wright wrote: > On Sun, 01 Jan 2017 17:55:01 -0800, Adam Wilson wrote: >> On that I beg to differ. The C libraries are not @safe, they have wildly >> different API's, and they have high-complexity, which is a large >> risk-factor for bugs and/or security flaws. > > If we have the database interface defined, there's no reason we couldn't > provide, for instance, a postgres-c-wrapper driver and a postgres-pure-d > driver. > Precisely, I would love to enable this! -- Adam Wilson IRC: LightBender import quiet.dlang.dev; |
January 02, 2017 Re: Databases and the D Standard Library | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On 1/2/17 12:05 AM, Jacob Carlborg wrote: > On 2017-01-01 17:50, Chris Wright wrote: > >> Those both limit your ability to use the underlying database to its full >> potential. They offer a chance for queries that seem simple and efficient >> to become horribly inefficient. > > I'm perfectly aware of the limitations and capabilities of ORM's. I'm > just saying that making the interface/names different just to make it > different is not a good idea. It should be up to the user to choose if > an ORM is used or not and this interface should try to, as much as > possible, to make it possible to use an ORM just as well as not using an > ORM. > Is there a assumption here that there are no classes? Because and ORM could quite easily work with base classes, and indeed both NHibernate and EntityFramework function exactly this way. > This whole idea seems fail even before it's barely stared. If this idea > is going to work then all the layers need to be designed correctly and > the lower layers should not know anything about the higher layers. > I absolutely agree, which, ironically, is why I am having this conversation. -- Adam Wilson IRC: LightBender import quiet.dlang.dev; |
January 02, 2017 Re: Databases and the D Standard Library | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On 1/2/17 12:09 AM, Jacob Carlborg wrote: > On 2017-01-02 02:34, Adam Wilson wrote: > >> That was my intention, the knee-jerk reaction that class and interfaces >> get here sometimes strikes me as a bit histrionic sometimes. They are a >> tool with a use case. :) > > I think that the design should try to avoid classes as much as possible > for things that will be frequently created. It's always possible to wrap > a struct in a class, the other way around is a bit more difficult. But > when it comes to the connection object I think it's fine to use classes > since it will most likely only be created once per thread. > Ok. How would you design a database API for D? The requirements I am operating under are: 1. Individual data-store driver implementations are not included in the D Standard Library. Driver licensing and implementation details vary. For example libpq5 uses it's own mix of licenses that is not Boost compatible. 2. The D Standard Library provides a common API and implementation of shared components, but leaves the data-store specific implementation up to the implementer. We don't care how the implementation is constructed or licensed, only that the API is followed. 3. In order to support higher level abstractions like ORM's we need a base class model that can be extended by implementers but still consumed by the ORM without knowing implementation specific details. As far as I am aware, the only way to meet those requirements is to use a base-class model. Is there something I am missing? -- Adam Wilson IRC: LightBender import quiet.dlang.dev; |
January 03, 2017 Re: Databases and the D Standard Library | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam Wilson | On 2017-01-03 06:25, Adam Wilson wrote: > Ok. How would you design a database API for D? I don't know. I think it's difficult to design something upfront without trying out different API's to see what's possible to implement in code. Structs and functions, with or without templates. Could something like this work: module db_interface; version (Postgres) public import pg.db_interface; else version (MySQL) public import mysql.db_interface; static assert(isInterfaceImplemented, "The DB interface is not implemented"); -- /Jacob Carlborg |
January 03, 2017 Re: Databases and the D Standard Library | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam Wilson | On Mon, 02 Jan 2017 21:25:42 -0800, Adam Wilson wrote:
> As far as I am aware, the only way to meet those requirements is to use a base-class model. Is there something I am missing?
Templates. Templates everywhere.
Every method in your application that might possibly touch a database, or touch anything that touches a database, and so on, needs to be templated according to what type of database might be used.
|
January 03, 2017 Re: Databases and the D Standard Library | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On Tue, 03 Jan 2017 08:25:55 +0100, Jacob Carlborg wrote:
> Structs and functions, with or without templates. Could something like this work:
>
> module db_interface;
>
> version (Postgres)
> public import pg.db_interface;
> else version (MySQL)
> public import mysql.db_interface;
You are unable to interact with two different databases in the same executable using the same library. For instance, if you're using hibernated, either you compiled it to connect to mysql, or you compiled it to connect to oracle.
This means you can't, for instance, use mysql for the CI server (because it's open source and doesn't have licensing fees), then use oracle for production (because it's faster for your workflow), because then you're testing with a different binary. You can't have some data in postgres and some in SQL Server because you're in the middle of a migration.
You can still use both if you are using the database interface directly. But if you're connecting via a library, you're SOL.
You have to recompile everything whenever you switch databases. That's a barrier to proprietary libraries that interact with databases. They're not impossible, but they have to release separate binaries for every database the maintainer thinks you might want to connect to.
Every library that lets you access a database must maintain a list of db drivers that it supports. If you have a new or private driver you want to use, you need to modify any library you use that talks to a database.
In exchange, you get...slightly less GC usage. It's not *no* GC usage -- you'll see a bunch of buffers allocated to hold incoming and outgoing messages. You'll just peel back one layer of it.
You'd be much better off asking that we encourage the use of std.experimental.allocator in the driver interface.
|
Copyright © 1999-2021 by the D Language Foundation