-
Notifications
You must be signed in to change notification settings - Fork 125
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- added ValueAccessor SPI and default implementations, replaces TypeMap as a more effective means of resolving Java types corresponding with JDBC types, getting query result values, and setting parameter values - added schema information for database product name and version to special case sqlite's type-safety issues xerial/sqlite-jdbc#928 xerial/sqlite-jdbc#933
- Loading branch information
1 parent
426fdcf
commit 84e5553
Showing
51 changed files
with
2,196 additions
and
259 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
51 changes: 0 additions & 51 deletions
51
manifold-deps-parent/manifold-sql-rt/src/main/java/manifold/sql/rt/api/TypeMap.java
This file was deleted.
Oops, something went wrong.
109 changes: 109 additions & 0 deletions
109
manifold-deps-parent/manifold-sql-rt/src/main/java/manifold/sql/rt/api/ValueAccessor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
/* | ||
* Copyright (c) 2023 - Manifold Systems LLC | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package manifold.sql.rt.api; | ||
|
||
import manifold.rt.api.util.ServiceUtil; | ||
import manifold.util.concurrent.LocklessLazyVar; | ||
|
||
import java.sql.PreparedStatement; | ||
import java.sql.ResultSet; | ||
import java.sql.SQLException; | ||
import java.util.HashMap; | ||
import java.util.HashSet; | ||
import java.util.Map; | ||
import java.util.Set; | ||
|
||
/** | ||
* Each implementation of this interface handles a JDBC type from {@link java.sql.Types} and must be registered as a Java | ||
* Service Provider. Manifold provides default implementations that are suitable for most use-cases, however these implementations | ||
* can be overridden by returning a higher priority from {@link #getPriority()}. | ||
* <p/> | ||
* This interface performs the following:<br> | ||
* - resolves the Java type corresponding with the JDBC type from {@link java.sql.Types}<br> | ||
* - sets query parameter values<br> | ||
* - gets query result values<br> | ||
* <br> | ||
*/ | ||
public interface ValueAccessor | ||
{ | ||
LocklessLazyVar<Set<ValueAccessor>> ACCESSORS = | ||
LocklessLazyVar.make( () -> { | ||
Set<ValueAccessor> registered = new HashSet<>(); | ||
ServiceUtil.loadRegisteredServices( registered, ValueAccessor.class, ValueAccessor.class.getClassLoader() ); | ||
return registered; | ||
} ); | ||
|
||
LocklessLazyVar<Map<Integer, ValueAccessor>> BY_JDBC_TYPE = | ||
LocklessLazyVar.make( () -> { | ||
Map<Integer, ValueAccessor> map = new HashMap<>(); | ||
for( ValueAccessor acc : ACCESSORS.get() ) | ||
{ | ||
int jdbcType = acc.getJdbcType(); | ||
ValueAccessor existing = map.get( jdbcType ); | ||
if( existing == null || existing.getPriority() < acc.getPriority() ) | ||
{ | ||
map.put( jdbcType, acc ); | ||
} | ||
} | ||
return map; | ||
} ); | ||
|
||
static ValueAccessor get( int jdbcType ) | ||
{ | ||
return BY_JDBC_TYPE.get().get( jdbcType ); | ||
} | ||
|
||
/** | ||
* @return The {@link java.sql.Types} id this accessor handles. | ||
*/ | ||
int getJdbcType(); | ||
|
||
/** | ||
* Greater = higher priority. Higher priority overrides lower. Default implementations are lowest priority. They can be | ||
* overridden. | ||
*/ | ||
default int getPriority() | ||
{ | ||
return Integer.MIN_VALUE; | ||
} | ||
|
||
/** | ||
* @return The resulting type of the value in Java code. Note this type may not correspond with SQL-to-Java type mappings | ||
* from the JDBC specification. For instance, although {@code java.sql.Types#CLOB} maps to {@code java.sql.CLOB} (appendix | ||
* table B.3 from the JDBC 4.2 specification) the actual type generated for {@code CLOB} is {@code String}. | ||
*/ | ||
Class<?> getJavaType( BaseElement elem ); | ||
|
||
/** | ||
* Returns a query result value corresponding with a {@code elem} from {@code rs}. | ||
* @param rs The result set containing rows of column values | ||
* @param elem The query column from which to find a value | ||
* @return The value corresponding with {@code elem}. Note, the type of the value must match the Java type returned from | ||
* {@code elem.getType()}. | ||
* @throws SQLException | ||
*/ | ||
Object getRowValue( ResultSet rs, BaseElement elem ) throws SQLException; | ||
|
||
/** | ||
* Sets the query parameter value corresponding with {@code pos}. | ||
* @param ps The prepared statement containing the parameterized query. | ||
* @param pos The index of the parameter, beginning with 1. | ||
* @param value The value of the parameter | ||
* @throws SQLException | ||
*/ | ||
void setParameter( PreparedStatement ps, int pos, Object value ) throws SQLException; | ||
} |
Oops, something went wrong.