Subject | Re: [Firebird-devel] Gpre, Jdbc, and a Modest Proposal |
---|---|
Author | Brad Pepers |
Post date | 2004-01-26T07:09:30Z |
Just a comment on a new API idea is that I think using pointers for ResultSet,
PreparedStatement, and any other classes is a bad idea. Rewrite your example
code with proper error handling all along and the possiblity of exceptions
and see what you get. If you use a smart pointer type of class that hides
the actual pointer and calls new/delete for you then you can handle things
much more clearly and you can depend on the object lifetime rules to destruct
things properly in the case of exceptions raised and such. I would like to
see your example coded like this:
PreparedStatement statement(connection);
statement.setCommand("select * from RDB$RELATIONS where "
"RDB$RELATION_ID=?");
statement.setInt(1, relationId);
ResultSet resultSet = statement.executeQuery();
while (resultSet.next()) {
const char* relationName = resultSet.getString("RDB$RELATION_NAME)
printf("Got one: %s\n", relationName);
}
The benefits:
1. The cleanup code at the end to close is not needed (though explicit close
methods could still be provided but object destruction would do a close for
you)
2. Less chance of a code path that forgets to call close and leaves a
transaction open
3. Easier error handling since any error along the way doesn't require you to
remember what to close
What also needs to be discussed for a new API is a clear set of rules on how
errors are handled. Possible ways:
1. Use C++ exceptions. I wouldn't recommend this personally since I've fought
this battle a few times and its not worth the hassle. It should work well
and should be easy but there are still compiler issues (g++ in particular)
and it still causes a huge overhead.
2. Return bool results from methods that can fail. Limited when the method
naturally returns some other result type. In that case you can decide on an
error value in the result type (ie: -1 for integer) but then you hit times
when all possible results are valid so there is no error code.
3. Pass in a status vector sort of thing like is done now. Works but I think
there is a better way.
4. Keep the status of the last call in the class so it can be checked. Better
than creating and passing around status vectors all the time. This is what I
would suggest.
Anyway just some random thoughts on the matter with the decision of using
pointers vrs objects the main point of consideration.
Oh and as an aside, since these comments and proposals are posted to both the
devel and architect lists, I've responded in both. If anyone has strong
opinions on keeping these discussions in one list, let them be known!
--
Brad Pepers
brad@...
PreparedStatement, and any other classes is a bad idea. Rewrite your example
code with proper error handling all along and the possiblity of exceptions
and see what you get. If you use a smart pointer type of class that hides
the actual pointer and calls new/delete for you then you can handle things
much more clearly and you can depend on the object lifetime rules to destruct
things properly in the case of exceptions raised and such. I would like to
see your example coded like this:
PreparedStatement statement(connection);
statement.setCommand("select * from RDB$RELATIONS where "
"RDB$RELATION_ID=?");
statement.setInt(1, relationId);
ResultSet resultSet = statement.executeQuery();
while (resultSet.next()) {
const char* relationName = resultSet.getString("RDB$RELATION_NAME)
printf("Got one: %s\n", relationName);
}
The benefits:
1. The cleanup code at the end to close is not needed (though explicit close
methods could still be provided but object destruction would do a close for
you)
2. Less chance of a code path that forgets to call close and leaves a
transaction open
3. Easier error handling since any error along the way doesn't require you to
remember what to close
What also needs to be discussed for a new API is a clear set of rules on how
errors are handled. Possible ways:
1. Use C++ exceptions. I wouldn't recommend this personally since I've fought
this battle a few times and its not worth the hassle. It should work well
and should be easy but there are still compiler issues (g++ in particular)
and it still causes a huge overhead.
2. Return bool results from methods that can fail. Limited when the method
naturally returns some other result type. In that case you can decide on an
error value in the result type (ie: -1 for integer) but then you hit times
when all possible results are valid so there is no error code.
3. Pass in a status vector sort of thing like is done now. Works but I think
there is a better way.
4. Keep the status of the last call in the class so it can be checked. Better
than creating and passing around status vectors all the time. This is what I
would suggest.
Anyway just some random thoughts on the matter with the decision of using
pointers vrs objects the main point of consideration.
Oh and as an aside, since these comments and proposals are posted to both the
devel and architect lists, I've responded in both. If anyone has strong
opinions on keeping these discussions in one list, let them be known!
--
Brad Pepers
brad@...