The database API throws a RuntimeException for all error conditions. While it's good that exceptions are thrown, since this class is high in the Exception class chain (it's a direct descendent of Exception and is heavily subclassed by both PHP core and third party libraries) it's a rather generic class and doesn't offer much context about why the error was thrown without parsing the string.
This PR creates several contextual Exception classes for the database API and changes it to throw these subclasses instead of the more generic RuntimeException. As all of these new Exception classes all extend RuntimeException there is no B/C break with existing try/catch uses.
Testing Instructions
Mainly review/decision. Otherwise, if you cause errors from the database API, they should be using the more contextual Exception classes versus RuntimeException in most cases (there are some that aren't converted because they didn't fit these three general cases I started with).