Use SQLSTATE or database error codes if available instead of regexp parsing for more specific DatabaseErrors

If the SQLSTATE is available, use it instead of parsing exception
messages with regexps.  For adapters where SQLSTATE is unavailable
or not as accurate, but a database error code can be determined,
attempt to use the database error code before parsing exception
messages.

I may refactor this in the future to allow for more flexibility
(i.e. try SQLSTATE first, fallback to regexp parsing otherwise),
but this seems to work OK for now.
Use Oracle error codes instead of parsing exception messages in the oracle adapter
Use regexps instead of SQLSTATEs on jdbc/oracle