All Downloads are FREE. Search and download functionalities are using the official Maven repository.

manifold.sql.query.jdbc.JdbcParameter Maven / Gradle / Ivy

There is a newer version: 2024.1.41
Show newest version
/*
 * 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.query.jdbc;

import manifold.rt.api.util.Pair;
import manifold.sql.api.Statement;
import manifold.sql.api.Parameter;
import manifold.sql.rt.api.Dependencies;
import manifold.sql.rt.api.TypeProvider;

import java.sql.DatabaseMetaData;
import java.sql.ParameterMetaData;
import java.sql.SQLException;
import java.sql.Types;

public class JdbcParameter implements Parameter
{
  private final S _owner;
  private final int _position;
  private final String _name;
  private final int _jdbcType;
  private final String _sqlType;
  private final int _size;
  private final int _scale;
  private final boolean _isNullable;
  private final boolean _isSigned;
  private final String _javaClassNameForGetObject;

  public JdbcParameter( int paramIndex, String name, S owner, ParameterMetaData paramMetaData, DatabaseMetaData metaData ) throws SQLException
  {
    _position = paramIndex;
    _name = name == null ? "p" + paramIndex : name;
    _owner = owner;

    Pair types = getJdbcType( paramMetaData, paramIndex, metaData );
    _jdbcType = types.getFirst();
    boolean isFlakyDriver = types.getSecond();

    String sqlType;
    int size;
    int scale;
    boolean isNullable;
    boolean isSigned;
    String javaClassNameForGetObject;

    if( isFlakyDriver )
    {
      sqlType = "varchar";
      size = 0;
      scale = 0;
      isNullable = true;
      isSigned = true;
      javaClassNameForGetObject = Object.class.getTypeName();
    }
    else
    {
      sqlType = paramMetaData.getParameterTypeName( paramIndex );
      size = paramMetaData.getPrecision( paramIndex );
      scale = paramMetaData.getScale( paramIndex );
      isNullable = paramMetaData.isNullable( paramIndex ) != ParameterMetaData.parameterNoNulls;
      isSigned = paramMetaData.isSigned( paramIndex );
      javaClassNameForGetObject = paramMetaData.getParameterClassName( paramIndex );
    }
    
    _sqlType = sqlType;
    _size = size;
    _scale = scale;
    _isNullable = isNullable;
    _isSigned = isSigned;
    _javaClassNameForGetObject = javaClassNameForGetObject;
  }

  private Pair getJdbcType( ParameterMetaData paramMetaData, int paramIndex, DatabaseMetaData dbMetadata )
  {
    int jdbcType;
    boolean isFlakyDriver = false;
    try
    {
      TypeProvider typeProvider = Dependencies.instance().getTypeProvider();
      jdbcType = typeProvider.getQueryParameterType( paramIndex, paramMetaData, dbMetadata );
    }
    catch( SQLException se )
    {
      // (circus music)
      // Some drivers don't provide query parameter types when the parameter's value is not set. For instance, depending
      // on the version, SQLite will either return VARCHAR for all parameters or it will throw an exception when a parameter
      // is not set, hence this catch block. Mysql throws the borfin exception too unless the "generateSimpleParameterMetadata"
      // url parameter is set in which case it provides the same crap sandwich as sqlite (as of mysql driver 8.1).
      //
      jdbcType = Types.OTHER;
      isFlakyDriver = true;
    }

    return new Pair<>( jdbcType, isFlakyDriver );
  }

  @Override
  public int getJdbcType()
  {
    return _jdbcType;
  }

  @Override
  public String getSqlType()
  {
    return _sqlType;
  }

  @Override
  public String getColumnClassName()
  {
    return _javaClassNameForGetObject;
  }

  @Override
  public S getOwner()
  {
    return _owner;
  }

  @Override
  public int getPosition()
  {
    return _position;
  }

  @Override
  public String getName()
  {
    return _name;
  }

  @Override
  public int getSize()
  {
    return _size;
  }

  @Override
  public int getScale()
  {
    return _scale;
  }

  @Override
  public boolean isNullable()
  {
    return _isNullable;
  }

  @Override
  public boolean isSigned()
  {
    return _isSigned;
  }

  public boolean canBeNull()
  {
    return isNullable();
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy