Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions src/odbc/DatabaseMetaData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,75 @@ ResultSetRef DatabaseMetaData::getPrimaryKeys(const char* catalogName,
return ret;
}
//------------------------------------------------------------------------------
ResultSetRef DatabaseMetaData::getSpecialColumns(
RowIdentifierType identifierType,
const char* catalogName, const char* schemaName, const char* tableName,
RowIdentifierScope scope, ColumnNullableValue nullable)
{
SQLUSMALLINT fColType;
switch (identifierType)
{
case RowIdentifierType::BEST_ROWID:
fColType = SQL_BEST_ROWID;
break;
case RowIdentifierType::ROWVER:
fColType = SQL_ROWVER;
break;
default:
throw Exception("Unknown rowid type");
}

size_t catalogLen = catalogName ? strlen(catalogName) : 0;
size_t schemaLen = schemaName ? strlen(schemaName) : 0;
size_t tableLen = tableName ? strlen(tableName) : 0;

size_t maxLen = (1 << 8 * sizeof(SQLSMALLINT)) - 1;
if (catalogLen > maxLen)
throw Exception("The catalog name is too long");
if (schemaLen > maxLen)
throw Exception("The schema name is too long");
if (tableLen > maxLen)
throw Exception("The table name is too long");

SQLUSMALLINT fScope;
switch (scope)
{
case RowIdentifierScope::CURRENT_ROW:
fScope = SQL_SCOPE_CURROW;
break;
case RowIdentifierScope::TRANSACTION:
fScope = SQL_SCOPE_TRANSACTION;
break;
case RowIdentifierScope::SESSION:
fScope = SQL_SCOPE_SESSION;
break;
default:
throw Exception("Unknown rowid scope");
}

SQLUSMALLINT fNullable;
switch (nullable)
{
case ColumnNullableValue::NO_NULLS:
fNullable = SQL_NO_NULLS;
break;
case ColumnNullableValue::NULLABLE:
fNullable = SQL_NULLABLE;
break;
default:
throw Exception("Unknown nullable value");
}

StatementRef stmt = createStatement();
ResultSetRef ret(new ResultSet(stmt.get()));
EXEC_STMT(SQLSpecialColumnsA, stmt->hstmt_, fColType,
(SQLCHAR*)catalogName, (SQLSMALLINT)catalogLen,
(SQLCHAR*)schemaName, (SQLSMALLINT)schemaLen,
(SQLCHAR*)tableName, (SQLSMALLINT)tableLen,
fScope, fNullable);
return ret;
}
//------------------------------------------------------------------------------
ResultSetRef DatabaseMetaData::getTables(const char* catalogName,
const char* schemaName, const char* tableName, const char* tableType)
{
Expand Down
37 changes: 36 additions & 1 deletion src/odbc/DatabaseMetaData.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ class ODBC_EXPORT DatabaseMetaData : public DatabaseMetaDataBase
* 5. Primary column sequence number in key (1-based)
* 6. Primary key name
*
* This functions uses the ODBC function SQLPrimaryKeys. Refer to its
* This function uses the ODBC function SQLPrimaryKeys. Refer to its
* documentation for further details on the data in the ResultSet object.
*
* @param catalogName A string indicating the catalog name.
Expand All @@ -126,6 +126,41 @@ class ODBC_EXPORT DatabaseMetaData : public DatabaseMetaDataBase
const char* schemaName,
const char* tableName);

/**
* Retrieves information about the unique row identifier of a table.
*
* The list of columns is returned as a ResultSet object, in which each
* returned row has the following columns:
* 1. Actual scope of the rowid
* 2. Column name
* 3. SQL data type
* 4. Data source-dependent data type name
* 5. The size of the column on the data source
* 6. The length in bytes of data transferred
* 7. The decimal digits of the column on the data source
* 8. Indicates whether the column is a pseudo-column
*
* This function uses the ODBC function SQLSpecialColumns. Refer to its
* documentation for further details on the data in the ResultSet object.
*
* @param identifierType Type of unique row identifier to return.
* @param catalogName A string indicating the catalog name.
* @param schemaName A string indicating the schema name.
* @param tableName A string indicating the table name.
* @param scope Minimum required scope of the rowid.
* @param nullable Determines whether to return special columns that
* can have a NULL value.
* @return Returns a ResultSet object containing the
* unique row identifier information.
*/
ResultSetRef getSpecialColumns(
RowIdentifierType identifierType,
const char* catalogName,
const char* schemaName,
const char* tableName,
RowIdentifierScope scope,
ColumnNullableValue nullable);

/**
* Retrieves a description of the tables that are available in the connected
* database.
Expand Down
69 changes: 69 additions & 0 deletions src/odbc/DatabaseMetaDataUnicode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,75 @@ ResultSetRef DatabaseMetaDataUnicode::getPrimaryKeys(
return ret;
}
//------------------------------------------------------------------------------
ResultSetRef DatabaseMetaDataUnicode::getSpecialColumns(
RowIdentifierType identifierType, const char16_t* catalogName,
const char16_t* schemaName, const char16_t* tableName,
RowIdentifierScope scope, ColumnNullableValue nullable)
{
SQLUSMALLINT fColType;
switch (identifierType)
{
case RowIdentifierType::BEST_ROWID:
fColType = SQL_BEST_ROWID;
break;
case RowIdentifierType::ROWVER:
fColType = SQL_ROWVER;
break;
default:
throw Exception("Unknown rowid type");
}

size_t catalogLen = catalogName ? strlen16(catalogName) : 0;
size_t schemaLen = schemaName ? strlen16(schemaName) : 0;
size_t tableLen = tableName ? strlen16(tableName) : 0;

size_t maxLen = (1 << 8 * sizeof(SQLSMALLINT)) - 1;
if (catalogLen > maxLen)
throw Exception("The catalog name is too long");
if (schemaLen > maxLen)
throw Exception("The schema name is too long");
if (tableLen > maxLen)
throw Exception("The table name is too long");

SQLUSMALLINT fScope;
switch (scope)
{
case RowIdentifierScope::CURRENT_ROW:
fScope = SQL_SCOPE_CURROW;
break;
case RowIdentifierScope::TRANSACTION:
fScope = SQL_SCOPE_TRANSACTION;
break;
case RowIdentifierScope::SESSION:
fScope = SQL_SCOPE_SESSION;
break;
default:
throw Exception("Unknown rowid scope");
}

SQLUSMALLINT fNullable;
switch (nullable)
{
case ColumnNullableValue::NO_NULLS:
fNullable = SQL_NO_NULLS;
break;
case ColumnNullableValue::NULLABLE:
fNullable = SQL_NULLABLE;
break;
default:
throw Exception("Unknown nullable value");
}

StatementRef stmt = createStatement();
ResultSetRef ret(new ResultSet(stmt.get()));
EXEC_STMT(SQLSpecialColumnsW, stmt->hstmt_, fColType,
(SQLWCHAR*)catalogName, (SQLSMALLINT)catalogLen,
(SQLWCHAR*)schemaName, (SQLSMALLINT)schemaLen,
(SQLWCHAR*)tableName, (SQLSMALLINT)tableLen,
fScope, fNullable);
return ret;
}
//------------------------------------------------------------------------------
ResultSetRef DatabaseMetaDataUnicode::getTables(const char16_t* catalogName,
const char16_t* schemaName, const char16_t* tableName,
const char16_t* tableType)
Expand Down
35 changes: 35 additions & 0 deletions src/odbc/DatabaseMetaDataUnicode.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,41 @@ class ODBC_EXPORT DatabaseMetaDataUnicode : public DatabaseMetaDataBase
const char16_t* schemaName,
const char16_t* tableName);

/**
* Retrieves information about the unique row identifier of a table.
*
* The list of columns is returned as a ResultSet object, in which each
* returned row has the following columns:
* 1. Actual scope of the rowid
* 2. Column name
* 3. SQL data type
* 4. Data source-dependent data type name
* 5. The size of the column on the data source
* 6. The length in bytes of data transferred
* 7. The decimal digits of the column on the data source
* 8. Indicates whether the column is a pseudo-column
*
* This function uses the ODBC function SQLSpecialColumns. Refer to its
* documentation for further details on the data in the ResultSet object.
*
* @param identifierType Type of unique row identifier to return.
* @param catalogName A string indicating the catalog name.
* @param schemaName A string indicating the schema name.
* @param tableName A string indicating the table name.
* @param scope Minimum required scope of the rowid.
* @param nullable Determines whether to return special columns that
* can have a NULL value.
* @return Returns a ResultSet object containing the
* unique row identifier information.
*/
ResultSetRef getSpecialColumns(
RowIdentifierType identifierType,
const char16_t* catalogName,
const char16_t* schemaName,
const char16_t* tableName,
RowIdentifierScope scope,
ColumnNullableValue nullable);

/**
* Retrieves a description of the tables that are available in the connected
* database.
Expand Down
59 changes: 59 additions & 0 deletions src/odbc/Types.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,65 @@ enum class DSNType
USER
};
//------------------------------------------------------------------------------
/**
* Specifies the constants that identify whether the column allows NULL values.
*/
enum class ColumnNullableValue
{
/**
* Column does not allow NULL values.
*/
NO_NULLS,
/**
* Column allows NULL values.
*/
NULLABLE
};
//------------------------------------------------------------------------------
/**
* Specifies the type of unique row identifier.
*/
enum class RowIdentifierType
{
/**
* Returns the optimal column or set of columns that, by retrieving values
* from the column or columns, allows any row in the specified table to be
* uniquely identified. A column can be either a pseudo - column
* specifically designed for this purpose (as in Oracle ROWID or Ingres TID)
* or the column or columns of any unique index for the table.
*/
BEST_ROWID,
/**
* Returns the column or columns in the specified table, if any, that are
* automatically updated by the data source when any value in the row is
* updated by any transaction (as in SQLBase ROWID or Sybase TIMESTAMP).
*/
ROWVER
};
//------------------------------------------------------------------------------
/**
* Specifies the required scope of the row identifier (rowid).
*/
enum class RowIdentifierScope
{
/**
* The rowid is guaranteed to be valid only while positioned on that row.
* A later reselect using rowid may not return a row if the row was updated
* or deleted by another transaction.
*/
CURRENT_ROW,
/**
* The rowid is guaranteed to be valid for the duration of the session
* (across transaction boundaries).
*/
SESSION,
/**
* The rowid is guaranteed to be valid for the duration of the current
* transaction.
*/
TRANSACTION
};
//------------------------------------------------------------------------------
/**
* Specifies the constants that identify ODBC SQL data types.
*/
Expand Down