/*
* This software is distributed under the terms of the FSF
* Gnu Lesser General Public License (see lgpl.txt).
*
* This program is distributed WITHOUT ANY WARRANTY. See the
* GNU General Public License for more details.
*/
package com.scooterframework.orm.sqldataexpress.vendor;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.sql.Blob;
import java.sql.CallableStatement;
import java.sql.Clob;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Map;
import java.util.Properties;
import com.scooterframework.common.util.Util;
import com.scooterframework.orm.sqldataexpress.config.DatabaseConfig;
import com.scooterframework.orm.sqldataexpress.object.Parameter;
import com.scooterframework.orm.sqldataexpress.processor.DataProcessor;
import com.scooterframework.orm.sqldataexpress.service.SqlServiceConstants;
import com.scooterframework.orm.sqldataexpress.util.SqlExpressUtil;
/**
* OracleDBAdapter class applies to Oracle database.
*
* @author (Fei) John Chen
*/
public class OracleDBAdapter extends DBAdapter {
@Override
public String[] getCatalogAndSchema(String connName) {
String s = getOracleSchema(connName);
if (s != null) s = s.toUpperCase();
String[] s2 = new String[2];
s2[0] = null;
s2[1] = s;
return s2;
}
protected String getOracleSchema(String connName) {
Properties p = SqlExpressUtil.getConnectionProperties(connName);
String schema = p.getProperty(DatabaseConfig.KEY_DB_CONNECTION_SCHEMA);
if (isEmpty(schema)) {
if (useLoginAsSchema(connName)) {
schema = getLoginUserId();
}
if (isEmpty(schema)) {
schema = SqlExpressUtil.getConnectionUser(connName);
}
}
return schema;
}
/**
* Oracle does not use <tt>catalog</tt>. Therefore it is ignored.
*/
@Override
public String getExpandedTableName(String catalog, String schema, String tableName) {
String[] s3 = resolveCatalogAndSchemaAndTable(catalog, schema, tableName);
schema = s3[1];
String table = s3[2];
if (isEmpty(schema)) {
tableName = "\"" + table + "\"";
}
else {
tableName = schema + "." +
SqlExpressUtil.checkSpecialCharacterInTableName(table);
}
return tableName;
}
@Override
public String getOneRowSelectSQL(String catalog, String schema, String table) {
String selectSQL = "SELECT * FROM ";
selectSQL += getExpandedTableName(catalog, schema, table);
selectSQL += " WHERE ROWNUM = 1";
return selectSQL;
}
@Override
public String preparePaginationSql(String selectSql, Map<String, Object> inputs, Map<String, String> outputFilters) {
int offset = Util.getIntValue(inputs, DataProcessor.input_key_records_offset, 0);
boolean hasOffset = (offset > 0)?true:false;
int limit = Util.getIntValue(inputs, DataProcessor.input_key_records_limit, DataProcessor.DEFAULT_PAGINATION_LIMIT);
int maxRowIndex = limit;
if (hasOffset) {
maxRowIndex = limit + offset;
}
StringBuilder newSelectSqlBF = new StringBuilder(selectSql.length() + 150);
if (hasOffset) {
newSelectSqlBF.append("SELECT * FROM (SELECT /*+ FIRST_ROWS(").append(limit).append(") */ a.*, rownum rnum FROM ( ");
}
else {
newSelectSqlBF.append("SELECT * FROM ( ");
}
newSelectSqlBF.append(selectSql);
if (hasOffset) {
newSelectSqlBF.append(" ) a WHERE rownum <= ?").append(DataProcessor.input_key_max_row_index).append(":INTEGER ) ");
newSelectSqlBF.append("WHERE rnum > ?").append(DataProcessor.input_key_records_offset).append(":INTEGER");
inputs.put(DataProcessor.input_key_max_row_index, Integer.valueOf(maxRowIndex));
inputs.put(DataProcessor.input_key_records_offset, Integer.valueOf(offset));
}
else {
newSelectSqlBF.append(" ) WHERE rownum <= ?").append(DataProcessor.input_key_max_row_index).append(":INTEGER");
inputs.put(DataProcessor.input_key_max_row_index, Integer.valueOf(maxRowIndex));
}
if (outputFilters == null)
throw new IllegalArgumentException("outputFilters cannot be null.");
outputFilters.put(SqlServiceConstants.OUTPUT_FILTER_EXCEPT, "RNUM");
return newSelectSqlBF.toString();
}
public Object getObjectFromResultSetByType(ResultSet rs, String javaClassType, int sqlDataType, int index)
throws SQLException {
if ("oracle.sql.BLOB".equals(javaClassType)) {
try {
Blob blob = rs.getBlob(index);
return getBlobData(blob);
}
catch(Exception ex) {
throw new SQLException(ex.getMessage());
}
}
else if ("oracle.sql.CLOB".equals(javaClassType)) {
try {
Clob clob = rs.getClob(index);
return getClobData(clob);
}
catch(Exception ex) {
throw new SQLException(ex.getMessage());
}
}
return super.getObjectFromResultSetByType(rs, javaClassType, sqlDataType, index);
}
public Object getObjectFromStatementByType(CallableStatement cstmt, String javaClassType, int sqlDataType, int index)
throws SQLException {
Object theObj = null;
if ("oracle.sql.BLOB".equals(javaClassType)) {
try {
Blob blob = cstmt.getBlob(index);
return getBlobData(blob);
}
catch(Exception ex) {
throw new SQLException(ex.getMessage());
}
}
else if ("oracle.sql.CLOB".equals(javaClassType) ) {
try {
Clob clob = cstmt.getClob(index);
return getClobData(clob);
}
catch(Exception ex) {
throw new SQLException(ex.getMessage());
}
}
return theObj;
}
@Override
public boolean vendorSpecificSetObject(PreparedStatement pstmt, Object obj, Parameter p, Map<String, Object> inputs)
throws Exception {
boolean status = false;
if ("oracle.sql.BLOB".equals(p.getJavaClassName())) {
if (obj != null) {
InputStream is = getInputStream(obj);
pstmt.setBinaryStream(p.getIndex(), is, is.available());
is.close();
}
else {
pstmt.setBinaryStream(p.getIndex(), (InputStream)null, 0);
}
status = true;
}
else if ("oracle.sql.CLOB".equals(p.getJavaClassName())) {
if (obj != null) {
String tmp = (String)obj;
int strLength = tmp.length();
StringReader r = new StringReader(tmp);
pstmt.setCharacterStream(p.getIndex(), r, strLength);
r.close();
}
else {
pstmt.setCharacterStream(p.getIndex(), (Reader)null, 0);
}
status = true;
}
return status;
}
}