Re: RE: [boost] Library Proposal: database (boost::db)

Hi Brian, ----- Mensaje original ----- De: Brian Braatz <brianb@rmtg.com> Fecha: Viernes, Octubre 15, 2004 6:56 pm Asunto: RE: [boost] Library Proposal: database (boost::db) [...]
I am currently going down this exact path and wanted to share what I ran into:
1- Boost does not have a 2dim "Table<>" - i.e. a Recordset 2- Boost.multi_index only works with concrete structures I would love it if I could use that to make a dynamic Table\ recordset
What do you mean by concrete structures?
3- I have had to build my own Table<> by internally using boost.multiindex
Do you mean, you have actually built a Table<> class using Boost.MultiIndex? [...]
I believe boost is missing a "recordset" analolgy and I would hope thatwhatever is created is not "struct only" like boost.multi_index. (don't get me wrong I LOVE the multi_index - it just doesn't work dynamically)
Well, in the past I thought about what a dynamic_multi_index_container (with run-time specification of indices) could look like: the implementation internals are not hard to solve with the same framework as Boost.MultiIndex, it is the interface that I don't have a clear idea about. Also, I don't envision a clear usage scenario for this, and there are RTTI-like issues involved as well (what should get<N>() return?) If you'd care to sketch what kind of dynamic multi_index you have in mind (from the user point of view) maybe we can come out with some solid design to implement in future releases of the lib. My intention is to stay away from relational stuff, but I'll go for a dynamic container if it can be made general purpose. On another topic, have you considered Arkadiy's RTL as another source of ideas/synergies? Seems like Arkady sort of diverted to his BOOST_TYPEOF facility, so I don't know what the current status of the lib is. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

"JOAQUIN LOPEZ MU?Z" <joaquin@tid.es> wrote
On another topic, have you considered Arkadiy's RTL as another source of ideas/synergies? Seems like Arkady sort of diverted to his BOOST_TYPEOF facility, so I don't know what the current status of the lib is.
Well, RTL needs a typeof badly, so it's not exactly a "diversion", but I can see what you mean :) There are two major problems with RTL: 1) The amount of feedback we have been receiving is unproportionaly lower than the amount of effort invested. This project started as kind of research rather than to fulfill the need of some concrete application. We hoped that, as we go, the applications would somehow emerge. After all the domain is pretty popular. Unfortunately this didn't seem to work. 2) The project turned out to be too ambitious for the two of us. We did implement all the functionality we wanted, but we could use a lot more testing, some parts might need to be re-written, re-designed, etc. IOW, if there is an interest in this library, we need help. Let me know if anybody is interested, and to which extent -- I could open a project at sourceforge, and we could proceed from there... http://groups.yahoo.com/group/boost/files/tables.zip (this version works with vc7.1 or GCC 3.2/3.3, Boost 1.31) Regards, Arkadiy

"Arkadiy Vertleyb" wrote:
1) The amount of feedback [for RTL] we have been receiving is unproportionaly lower than the amount of effort invested.
That's not unusual. New, innovative things are hard to graps in early stages.
IOW, if there is an interest in this library, we need help. Let me know if anybody is interested, and to which extent -- I could open a project at sourceforge, and we could proceed from there...
That would be very useful, IMHO. /Pavel

Arkadiy Vertleyb wrote:
[...] 1) The amount of feedback we have been receiving is unproportionaly lower than the amount of effort invested. This project started as kind of research rather than to fulfill the need of some concrete application. We hoped that, as we go, the applications would somehow emerge. After all the domain is pretty popular. Unfortunately this didn't seem to work.
The applications are there. But this is a domain in which most of the applications simply use the existing APIs, even if those are not C++- style APIs. Like sockets, threads, and everything else, we use a C API because that's what is available, but if a good C++ API were available, we would probably use that. So don't take the lack of strong demand to be an indicator that there is no demand. I absolutely guarantee that some relational db library in C++ is important, useful, and would find a large number of uses once it is created, validated, and made user-friendly.
2) The project turned out to be too ambitious for the two of us. We did implement all the functionality we wanted, but we could use a lot more testing, some parts might need to be re-written, re-designed, etc.
IOW, if there is an interest in this library, we need help. Let me know if anybody is interested, and to which extent -- I could open a project at sourceforge, and we could proceed from there... [...]
Unfortunately, I can cheer more than contribute. Obviously, there is a lot of interest in this type of library considering all the different projects that have been started. I personally find MySQL++ to be an abomination as far as support goes, and it is definitely an unfinished product, though it does some things really nicely. But that project also failed due to lack of resources. It seems to me that most Boost authors are not heavily involved in db-centric apps, which might explain the multitude of non-db-related libraries in Boost. But I think if all the different db-library authors were made aware of each other and conspired to work together, they could easily produce a Boost-quality db library, which I would like to see (and I'm sure many others would like to see as well). To reiterate what someone else said, one thing this library should almost certainly do is allow traversal of recordsets iterator-style, since that is The C++ Way (and It Is Good). Also, I think there is room for both statically-defined and dynamically-defined recordset types (think mapping to a predefined table or mapping to a query result set, possibly user-defined). I think a library that only offers one type is missing something important. If I only need to access raw tables for a db whose schema doesn't change, then I want statically defined recordsets to do so, without paying for any additional runtime burden. But I also want the ability to pass a raw SQL string to the library and possibly have it return a dynamically defined recordset with the appropriate fields included. That would be COOL. I, for one, use BDE, because BCB makes db access too easy for many apps. However, I would much rather use a C++ library if one were available. But it would need to be as easy to use as BDE/DAO/ADO to get me to switch, and I'm sure that is part of the reason for the slow adoption of libraries like RTL. You have a minimum usability barrier to cross before the user base will migrate to the library. Don't give up. DB apps are a huge portion of the market (possibly the biggest, I imagine), so I don't see how anyone who has done db work could think there isn't demand for good db libraries. The main problem, I think, is getting people to improve one good wheel instead of inventing many mediocre ones. Dave

On Sat, 16 Oct 2004 04:26:12 -0500, David B. Held wrote
Arkadiy Vertleyb wrote:
[...] 1) The amount of feedback we have been receiving is unproportionaly lower than the amount of effort invested. This project started as kind of research rather than to fulfill the need of some concrete application. We hoped that, as we go, the applications would somehow emerge. After all the domain is pretty popular. Unfortunately this didn't seem to work.
The applications are there.
No question. I think part of this is that RTL wasn't initially targeted at interfacing to databases - it essentially replaces the database by performing joins, etc.
But this is a domain in which most of the applications simply use the existing APIs, even if those are not C++- style APIs.
And there are c++ libraries not part of boost that serve many needs. Not to mention commercially developed libs. Several have been mentioned in the discussion.
Like sockets, threads, and everything else, we use a C API because that's what is available, but if a good C++ API were available, we would probably use that. So don't take the lack of strong demand to be an indicator that there is no demand.
Agree.
I absolutely guarantee that some relational db library in C++ is important, useful, and would find a large number of uses once it is created, validated, and made user-friendly.
No question. But since RTL doesn't provide an interface to a db currently...
2) The project turned out to be too ambitious for the two of us. We did implement all the functionality we wanted, but we could use a lot more testing, some parts might need to be re-written, re-designed, etc.
I'm not surprised - it's alot of work...
IOW, if there is an interest in this library, we need help. Let me know if anybody is interested, and to which extent -- I could open a project at sourceforge, and we could proceed from there... [...]
Unfortunately, I can cheer more than contribute. Obviously, there is a lot of interest in this type of library considering all the different projects that have been started. I personally find MySQL++ to be an abomination as far as support goes, and it is definitely an unfinished product, though it does some things really nicely. But that project also failed due to lack of resources.
At the end, I think resources are the big problem...
It seems to me that most Boost authors are not heavily involved in db-centric apps,
I wouldn't say that. They probably just don't have time to create such a library - even if they wanted to. I'd love to work on it, but I have to make a living, have a life, etc...
which might explain the multitude of non-db-related libraries in Boost.
I'm guessing there are other forces here that are more important.
But I think if all the different db-library authors were made aware of each other and conspired to work together, they could easily produce a Boost-quality db library, which I would like to see (and I'm sure many others would like to see as well).
Perhaps. There has been clear interest in a networking library for years - many have tinkered and helped, but we still aren't there. No one has had the huge amount of time it takes...
To reiterate what someone else said, one thing this library should almost certainly do is allow traversal of recordsets iterator-style, since that is The C++ Way (and It Is Good). Also, I think there is room for both statically-defined and dynamically-defined recordset types (think mapping to a predefined table or mapping to a query result set, possibly user-defined). I think a library that only offers one type is missing something important. If I only need to access raw tables for a db whose schema doesn't change, then I want statically defined recordsets to do so, without paying for any additional runtime burden. But I also want the ability to pass a raw SQL string to the library and possibly have it return a dynamically defined recordset with the appropriate fields included. That would be COOL.
Yeah, but RTL hasn't been aimed at this initially...
I, for one, use BDE, because BCB makes db access too easy for many apps. However, I would much rather use a C++ library if one were available. But it would need to be as easy to use as BDE/DAO/ADO to get me to switch, and I'm sure that is part of the reason for the slow adoption of libraries like RTL. You have a minimum usability barrier to cross before the user base will migrate to the library.
Don't give up. DB apps are a huge portion of the market (possibly the biggest, I imagine), so I don't see how anyone who has done db work could think there isn't demand for good db libraries. The main problem, I think, is getting people to improve one good wheel instead of inventing many mediocre ones.
I would put a library that provides portable odbc based RDB access on my top 5 list of libraries I'd like to see - and I mean not only in Boost, but in the standard. For most non-trivial applications this is a clear need and lots of time is spent on projects making this work. It's one of those things that makes people want to use JAVA or some other language. But, I recognize that it is a large and difficult effort - so I'm not that optimistic... Jeff

No question. I think part of this is that RTL wasn't initially targeted at interfacing to databases - it essentially replaces the database by
"Jeff Garland" <jeff@crystalclearsoftware.com> wrote performing
joins, etc.
RTL wasn't initialy, or ever, targeted at interfacing to databases. What we tried to achieve was to add relational tables to C++, in the same fashion STL adds vectors, sets, or maps. Adding relational tables assumes defining operations on them, which is relational algebra. So we do not provide the interface to real databases, but OTOH, I don't know any other library around that would allow you to perform join on an std::pair, functor, or a [smart] pointer. RTL does. Futhermore, this approach dictates compile-time record type generation. This follows more from the type-safety rather than from the performance perspective.
No question. But since RTL doesn't provide an interface to a db currently...
Because we never meant to do this. For better or for worse.
At the end, I think resources are the big problem...
You bet. Arkadiy

On Sat, 16 Oct 2004 13:33:11 -0400, Arkadiy Vertleyb wrote
RTL wasn't initialy, or ever, targeted at interfacing to databases. What we tried to achieve was to add relational tables to C++, in the same fashion STL adds vectors, sets, or maps. Adding relational tables assumes defining operations on them, which is relational algebra. So we do not provide the interface to real databases, but OTOH, I don't know any other library around that would allow you to perform join on an std::pair, functor, or a [smart] pointer. RTL does.
Agree.
Futhermore, this approach dictates compile-time record type generation. This follows more from the type-safety rather than from the performance perspective.
No question. But since RTL doesn't provide an interface to a db currently...
Because we never meant to do this. For better or for worse.
Sorry to be confused about the target -- I thought there was some discussion of eventual rdb interfaces. Still, even without the db I think it is very interesting and useful work. Combined with serialization it seems clear that you can clearly create some elegant solutions to tricky problems without the weight of a full database system. That said, the level of interest is not as high as the interface to actual RDB's -- because once you start using an actual RDB you want to defer the join logic etc into the database engine itself and are mostly concerned with the resulting data and mapping it to C++ types, etc... Jeff

"Jeff Garland" <jeff@crystalclearsoftware.com> wrote
Sorry to be confused about the target -- I thought there was some discussion of eventual rdb interfaces.
Still, even without the db I think it is very interesting and useful work. Combined with serialization it seems clear
you can clearly create some elegant solutions to tricky problems without
I may be wrong -- there were some thoughts about providing some static ODBC wrapper, so that an SQL query could be represented as an RTL relation. In this case it could be combined with real RTL tables/relations using RTL operations. Of course this is not useful to, say, join two real database tables, since in this case you want operation performed on the server. that the
weight of a full database system.
That said, the level of interest is not as high as the interface to actual RDB's -- because once you start using an actual RDB you want to defer the join logic etc into the database engine itself and are mostly concerned with
This really was the idea. Considering ever growing amount of RAM, many applications could switch to in-memory databases. Also, the relational algebra could be applied to applications that don't really want the overhead of a real database. Providing C++ - style in-memory relational database, with all the typesafety and with no type limitations is the goal of RTL. A few months ago I had a discussion at comp.object, where I tried to introduce the RTL, hoping people can think of some unexpected solutions that can be derived from combining OO and relational approaches. But it seems that people are very much polarized. Most OO people don't want to consider an RDB for anything other then persistence. And most relational people don't really think C++ is the correct way to go anyway. I think relational algebra is a very good mechanism when you want to share data, and provide different views of it (that's why it is so popular in huge systems). Since the language (relational relational algebra) is so simple, it's possible to introduce as much redundancy (indexing) as one wants (at any level of a relational expression -- not only tables) and maintain this redundancy automatically and efficiently as underlying tables are changed. That was the goal of our second stage of development, and we've done this. the
resulting data and mapping it to C++ types, etc...
Yes, but again, do you always really want to use that RDB or you just don't have alternatives? Arkadiy

On Sat, 16 Oct 2004 15:04:11 -0400, Arkadiy Vertleyb wrote
A few months ago I had a discussion at comp.object, where I tried to introduce the RTL, hoping people can think of some unexpected solutions that can be derived from combining OO and relational approaches. But it seems that people are very much polarized. Most OO people don't want to consider an RDB for anything other then persistence. And most relational people don't really think C++ is the correct way to go anyway.
Well, they are probably all wrong ;-) OO and relational approaches are part of the solution fabric -- not ends in themselves -- some people can't seem to get that...
I think relational algebra is a very good mechanism when you want to share data, and provide different views of it (that's why it is so popular in huge systems). Since the language (relational relational algebra) is so simple, it's possible to introduce as much redundancy (indexing) as one wants (at any level of a relational expression -- not only tables) and maintain this redundancy automatically and efficiently as underlying tables are changed. That was the goal of our second stage of development, and we've done this.
Agree.
That said, the level of interest is not as high as the interface to actual RDB's -- because once you start using an actual RDB you want to defer the join logic etc into the database engine itself and are mostly concerned with the resulting data and mapping it to C++ types, etc...
Yes, but again, do you always really want to use that RDB or you just don't have alternatives?
Yes, I really do need the database because, for example, I have multiple distributed client apps that need access to the data, I want to build 'tactical' (small low use utility apps) in a scripting language using rapid development tools, I'm writing a new app that builds on something that already uses an RDB, etc. So there are real reasons, and I hate that when I'm writing a C++ app it's so hard to get that data in a style that is consistent with modern C++. Having said all that there's much database over-use on projects the could clearly benefit from the approach RTL offers... Jeff

On 2004-10-16, Jeff Garland <jeff@crystalclearsoftware.com> wrote:
On Sat, 16 Oct 2004 04:26:12 -0500, David B. Held wrote
Arkadiy Vertleyb wrote:
Don't give up. DB apps are a huge portion of the market (possibly the biggest, I imagine), so I don't see how anyone who has done db work could think there isn't demand for good db libraries. The main problem, I think, is getting people to improve one good wheel instead of inventing many mediocre ones.
I would put a library that provides portable odbc based RDB access on my top 5 list of libraries I'd like to see - and I mean not only in Boost, but in the standard. For most non-trivial applications this is a clear need and lots of time is spent on projects making this work. It's one of those things that makes people want to use JAVA or some other language. But, I recognize that it is a large and difficult effort - so I'm not that optimistic...
Yes, I think efforts to come up with a boost rdbms library have so far failed because it is a big task - the challenge is similar to creating a gui or networking library. I suggest that the best way around this is to work incrementally - starting with a first release that is limited in scope, and building momentum from there. Maciej Sobczak's soci library, referenced elsewhere in this thread, seems to have potential along those lines. Why not make simple boost::db that does 80% of what's commonly used, with a simple interface, and then go from there with later additions? Just having a modern library that can execute sql against the leading databases would be a huge win. Steve

Steve Hutton wrote:
I suggest that the best way around this is to work incrementally - starting with a first release that is limited in scope, and building momentum from there. Maciej Sobczak's soci library, referenced elsewhere in this thread, seems to have potential along those lines.
Why not make simple boost::db that does 80% of what's commonly used, with a simple interface, and then go from there with later additions? Just having a modern library that can execute sql against the leading databases would be a huge win.
I have just moved the SOCI project to SourceForge, to gain some attention of develpers who may have expertise in interfacing with database engines other than Oracle: http://soci.sourceforge.net/ The idea was to enable users with simple needs to write simple code. Yes, complete and sophisticated DB library is a huge effort, but straightforward solutions seem to fit the bill in most of the cases. The licensing of the existing code is based on the original Boost license (pre-1.0), so there is no problem with adapting and reusing the source code in any other development effort, be it on SourceForge or within Boost. Looking forward to see development of the Boost DB library. -- Maciej Sobczak : http://www.msobczak.com/ Programming : http://www.msobczak.com/prog/

In article <41727790.1040906@msobczak.com>, Maciej Sobczak wrote:
I have just moved the SOCI project to SourceForge, to gain some attention of develpers who may have expertise in interfacing with database engines other than Oracle:
The idea was to enable users with simple needs to write simple code. Yes, complete and sophisticated DB library is a huge effort, but straightforward solutions seem to fit the bill in most of the cases.
Actually I think you have done a good chunk of the work already. SOCI looks to be just a few features away from being complete: o explicit support for stored procedures o bulk updates o result set meta-data Have you considered these features and how they might be exposed through soci? Steve

Steve Hutton wrote:
I have just moved the SOCI project to SourceForge, to gain some attention of develpers who may have expertise in interfacing with database engines other than Oracle:
The idea was to enable users with simple needs to write simple code. Yes, complete and sophisticated DB library is a huge effort, but straightforward solutions seem to fit the bill in most of the cases.
Actually I think you have done a good chunk of the work already. SOCI looks to be just a few features away from being complete:
o explicit support for stored procedures
o bulk updates
o result set meta-data
You can also add array binds. One user asked for it. I'm not sure, though, whether this feature is Oracle-specific and can be applied with other DB interfaces.
Have you considered these features and how they might be exposed through soci?
To be frank, no. The library was meant to be a simple tool for simple needs and as a sword against anybody who got into belief that (db) programming in the language beginning with 'J' is easier. ;) OK, I'm serious again. The SOCI library is highly syntax-oriented and is meant to provide the functionality that I've seen in some RAD tools (SQL embedding). I avoided adding any functionality that would be inconsistent with the rest of the interface or that I just never used. For those who may need more advanced stuff, the OCI handles are publicly available, so it is possible to mix SOCI code with low-level OCI calls. Also, it should be possible to call stored procedures using just what is already provided. Something like: sql << "BEGIN myproc(:param1, :param2); END;", use(var1), use(var2); What do you mean by "explicit support"? If there is any interest in pushing this library forward, I would really need some help with judicious interface design, especially in the areas where I have not enough expertise as a user. Also, the library was initially writen with the idea to be free of any dependencies. Now, as we're talking *here*, it is sensible to point out that the library may benefit from some "boostifying". For example, the Boost optional may be used to cover NULL values, shared_ptr may be used to manage the lifetime of expression objects, etc. And last but not least - I have no expertise in ODBC (other than MFC wrappers, yuck...) and it looks to be highly requested. My choice of Oracle and OCI was obvious in the environments where I hang around for most of the time, but it seems to be not so obvious to more general audience. This is another area where some help would be needed. Looking with increasing interest how this topic may continue, -- Maciej Sobczak : http://www.msobczak.com/ Programming : http://www.msobczak.com/prog/

In article <4174BEAB.6070805@msobczak.com>, Maciej Sobczak wrote:
Steve Hutton wrote:
Actually I think you have done a good chunk of the work already. SOCI looks to be just a few features away from being complete:
o explicit support for stored procedures
o bulk updates
o result set meta-data
You can also add array binds. One user asked for it. I'm not sure, though, whether this feature is Oracle-specific and can be applied with other DB interfaces.
What do you mean by array binds? Bind which way ("into" or "use")?
The SOCI library is highly syntax-oriented and is meant to provide the functionality that I've seen in some RAD tools (SQL embedding). I avoided adding any functionality that would be inconsistent with the rest of the interface or that I just never used. For those who may need more advanced stuff, the OCI handles are publicly available, so it is possible to mix SOCI code with low-level OCI calls.
I understand, it's just that if these 3 features were there I think it would move coverage from say 85% of use cases to 99%. I was wondering if these features could be possibly added through additional explicit classes, similar to how explicit use of the Statement class provides prepared statement functionality, but can be ignored when not needed.
Also, it should be possible to call stored procedures using just what is already provided. Something like:
sql << "BEGIN myproc(:param1, :param2); END;", use(var1), use(var2);
Right, that is no problem for an Oracle only library. Unfortunately this is one of the errors where vendors do not use a consistant syntax. By explicit stored procedure support I meant a Procedure object that would take care of the required syntax automatically - users would just pass the name of the procedure.
If there is any interest in pushing this library forward, I would really need some help with judicious interface design, especially in the areas where I have not enough expertise as a user.
Also, the library was initially writen with the idea to be free of any dependencies. Now, as we're talking *here*, it is sensible to point out that the library may benefit from some "boostifying". For example, the Boost optional may be used to cover NULL values, shared_ptr may be used to manage the lifetime of expression objects, etc.
And last but not least - I have no expertise in ODBC (other than MFC wrappers, yuck...) and it looks to be highly requested. My choice of Oracle and OCI was obvious in the environments where I hang around for most of the time, but it seems to be not so obvious to more general audience. This is another area where some help would be needed.
I suspect ODBC is a popular choice for implementers because it brings support for multiple databases. There is certainly precedent for porting OCI code to ODBC - that's the path taken by OTL. Steve

In article <cl4lje$c8l$1@sea.gmane.org>, Steve Hutton wrote:
I suspect ODBC is a popular choice for implementers because it brings support for multiple databases. There is certainly precedent for porting OCI code to ODBC - that's the path taken by OTL.
To clarify - OTL today supports both OCI and ODBC. There are also some libraries that tout native drivers (without ODBC) has a feature. For example the commercial library sqlapi uses all native drivers, and in the JDBC world, ODBC-bridge drivers have been superceded by native drivers. So the relevance of ODBC is open to debate - the key IMHO is uniform support for all the major databases. ODBC may be a quick means to that end. Native drivers can always be added later, or vise-versa. Steve

Steve Hutton wrote:
[...] So the relevance of ODBC is open to debate - the key IMHO is uniform support for all the major databases. ODBC may be a quick means to that end. Native drivers can always be added later, or vise-versa.
In my experience, ODBC can be unbelievably slow, also. It is definitely not a cure-all. It should probably be supported, but creating an interface that will elegantly support native drivers should be a priority. Dave

On Wed, 20 Oct 2004 00:15:52 -0500, David B. Held wrote
Steve Hutton wrote:
[...] So the relevance of ODBC is open to debate - the key IMHO is uniform support for all the major databases. ODBC may be a quick means to that end. Native drivers can always be added later, or vise-versa.
Agree.
In my experience, ODBC can be unbelievably slow, also. It is definitely not a cure-all. It should probably be supported, but creating an interface that will elegantly support native drivers should be a priority.
Sure having good support for native drivers is fine, but I think it is much, much, harder to achieve. So my push for ODBC binding is primarily to meet the 'all major databases' supported quickly. Jeff

On Sat, Oct 16, 2004 at 04:26:12AM -0500, David B. Held wrote:
The applications are there. But this is a domain in which most of the applications simply use the existing APIs, even if those are not C++- style APIs. Like sockets, threads, and everything else, we use a C API because that's what is available,
This is certainly true for me, I do a lot of development using the mysql C API because it's the native one, and because MySQL++ is hideous, bloated, buggy and only half implemented. But even though I am the maintainer for mysqlcppapi, which fixes most of MySQL++'s glaring problems, where I work we use my own very lightweight wrapper around the MySQL C API. This does little more than automatic resource cleanup in dtors, provide an iterator interface to the query results and use std::string not char* - and that suits the purpose quite well, without adding overhead to the native C API. Unfortunately this wrapper is very closely tied to MySQL's C API, so probably wouldn't work well on top of another DB. Anyone interested can have a look at http://www.kayari.org/mymysql/ It only consists of three header files. jon -- "When I use a word, it means just what I choose it to mean -- neither more nor less." - Humpty Dumpty
participants (8)
-
Arkadiy Vertleyb
-
David B. Held
-
Jeff Garland
-
JOAQUIN LOPEZ MU?Z
-
Jonathan Wakely
-
Maciej Sobczak
-
Pavel Vozenilek
-
Steve Hutton