23 #ifndef __ODBC_DATA_SOURCE_H__
24 #define __ODBC_DATA_SOURCE_H__
32 #include "services/daal_memory.h"
34 #include "data_management/data_source/data_source.h"
35 #include "data_management/data/data_dictionary.h"
36 #include "data_management/data/numeric_table.h"
37 #include "data_management/data/homogen_numeric_table.h"
38 #include "data_management/data_source/mysql_feature_manager.h"
39 #include "data_management/data_source/internal/data_source_options.h"
43 namespace data_management
60 class ODBCDataSourceOptions
66 allocateNumericTable = 1 << 0,
67 createDictionaryFromContext = 1 << 1
70 static ODBCDataSourceOptions::Value unite(
const ODBCDataSourceOptions::Value &lhs,
71 const ODBCDataSourceOptions::Value &rhs)
73 return internal::DataSourceOptionsImpl<Value>::unite(lhs, rhs);
76 ODBCDataSourceOptions(Value flags = byDefault) :
79 DataSource::NumericTableAllocationFlag getNumericTableAllocationFlag()
const
81 return (_impl.getFlag(allocateNumericTable))
82 ? DataSource::doAllocateNumericTable
83 : DataSource::notAllocateNumericTable;
86 DataSource::DictionaryCreationFlag getDictionaryCreationFlag()
const
88 return (_impl.getFlag(createDictionaryFromContext))
89 ? DataSource::doDictionaryFromContext
90 : DataSource::notDictionaryFromContext;
94 internal::DataSourceOptionsImpl<Value> _impl;
103 template<
typename FeatureManager,
typename SummaryStatisticsType = DAAL_SUMMARY_STATISTICS_TYPE>
104 class ODBCDataSource :
public DataSourceTemplate<data_management::HomogenNumericTable<DAAL_DATA_TYPE>, SummaryStatisticsType>
107 typedef data_management::HomogenNumericTable<DAAL_DATA_TYPE> DefaultNumericTableType;
108 typedef DataSourceTemplate<DefaultNumericTableType, SummaryStatisticsType> super;
113 using super::_initialMaxRows;
114 using super::_autoNumericTableFlag;
115 using super::_autoDictionaryFlag;
116 using super::_status;
132 ODBCDataSource(
const std::string &dbname,
133 const std::string &tableName =
"",
134 const std::string &userName =
"",
135 const std::string &password =
"",
136 DataSourceIface::NumericTableAllocationFlag doAllocateNumericTable = DataSource::notAllocateNumericTable,
137 DataSourceIface::DictionaryCreationFlag doCreateDictionaryFromContext = DataSource::notDictionaryFromContext,
138 size_t initialMaxRows = 10) :
139 super(doAllocateNumericTable,
140 doCreateDictionaryFromContext)
142 if (dbname.find(
'\0') != std::string::npos || tableName.find(
'\0') != std::string::npos ||
143 userName.find(
'\0') != std::string::npos || password.find(
'\0') != std::string::npos)
145 this->_status.add(services::throwIfPossible(services::ErrorNullByteInjection));
148 initialize(initialMaxRows);
149 _status |= connectUsingUserNameAndPassword(dbname, userName, password);
150 if (!_status) {
return; }
151 _status |= executeSelectAllQuery(tableName);
164 ODBCDataSource(
const std::string &dbname,
165 const std::string &tableName,
166 const std::string &userName,
167 const std::string &password,
168 const ODBCDataSourceOptions &options,
169 size_t initialMaxRows = 10) :
170 super(options.getNumericTableAllocationFlag(),
171 options.getDictionaryCreationFlag())
173 if (dbname.find(
'\0') != std::string::npos || tableName.find(
'\0') != std::string::npos ||
174 userName.find(
'\0') != std::string::npos || password.find(
'\0') != std::string::npos)
176 this->_status.add(services::throwIfPossible(services::ErrorNullByteInjection));
179 initialize(initialMaxRows);
180 _status |= connectUsingUserNameAndPassword(dbname, userName, password);
181 if (!_status) {
return; }
182 _status |= executeSelectAllQuery(tableName);
192 ODBCDataSource(
const std::string &connectionString,
193 const ODBCDataSourceOptions &options,
194 size_t initialMaxRows = 10) :
195 super(options.getNumericTableAllocationFlag(),
196 options.getDictionaryCreationFlag())
198 if (connectionString.find(
'\0') != std::string::npos)
200 this->_status.add(services::throwIfPossible(services::ErrorNullByteInjection));
203 initialize(initialMaxRows);
204 _status |= connectUsingConnectionString(connectionString);
207 virtual ~ODBCDataSource()
209 freeHandlesInternal();
212 services::Status executeQuery(
const std::string &query)
214 if (query.find(
'\0') != std::string::npos)
216 this->_status.add(services::throwIfPossible(services::ErrorNullByteInjection));
221 if (_autoNumericTableFlag == DataSource::doAllocateNumericTable)
224 if (_autoDictionaryFlag == DataSource::doDictionaryFromContext)
229 SQLRETURN ret = SQLFreeHandle(SQL_HANDLE_STMT, _hdlStmt);
230 if (!SQL_SUCCEEDED(ret)) {
return services::throwIfPossible(services::ErrorSQLstmtHandle); }
231 _hdlStmt = SQL_NULL_HSTMT;
234 SQLRETURN ret = SQLAllocHandle(SQL_HANDLE_STMT, _hdlDbc, &_hdlStmt);
235 if (!SQL_SUCCEEDED(ret)) {
return services::throwIfPossible(services::ErrorSQLstmtHandle); }
237 ret = SQLExecDirect(_hdlStmt, (SQLCHAR *)query.c_str(), SQL_NTS);
238 if (!SQL_SUCCEEDED(ret)) {
return services::throwIfPossible(services::ErrorODBC); }
240 _connectionStatus = DataSource::readyForLoad;
241 return services::Status();
247 services::Status freeHandles()
249 SQLRETURN ret = freeHandlesInternal();
250 if (!SQL_SUCCEEDED(ret)) {
return services::throwIfPossible(services::ErrorODBC); }
252 _connectionStatus = DataSource::notReady;
253 return services::Status();
256 virtual size_t loadDataBlock(
size_t maxRows) DAAL_C11_OVERRIDE
258 services::Status s = checkConnection();
259 if (!s) {
return 0; }
261 s = super::checkDictionary();
262 if (!s) {
return 0; }
264 s = super::checkNumericTable();
265 if (!s) {
return 0; }
267 return loadDataBlock(maxRows, _spnt.get());
276 virtual size_t loadDataBlock(
size_t maxRows, NumericTable *nt)
278 services::Status s = checkConnection();
281 s = super::checkDictionary();
284 if( nt == NULL ) { this->_status.add(services::throwIfPossible(services::ErrorNullInputNumericTable));
return 0; }
286 super::resizeNumericTableImpl( maxRows, nt );
288 if(nt->getDataMemoryStatus() == NumericTableIface::userAllocated)
290 if(nt->getNumberOfRows() < maxRows)
292 this->_status.add(services::throwIfPossible(services::ErrorIncorrectNumberOfObservations));
295 if(nt->getNumberOfColumns() != _dict->getNumberOfFeatures())
297 this->_status.add(services::throwIfPossible(services::ErrorIncorrectNumberOfFeatures));
302 _connectionStatus = _featureManager.statementResultsNumericTable(_hdlStmt, nt, maxRows);
304 size_t nRead = nt->getNumberOfRows();
305 _idxLastRead += nRead;
307 if(nt->basicStatistics.get(NumericTableIface::minimum ).get() != NULL &&
308 nt->basicStatistics.get(NumericTableIface::maximum ).get() != NULL &&
309 nt->basicStatistics.get(NumericTableIface::sum ).get() != NULL &&
310 nt->basicStatistics.get(NumericTableIface::sumSquares).get() != NULL)
312 for(
size_t i = 0; i < nRead; i++)
314 super::updateStatistics( i, nt );
318 NumericTableDictionaryPtr ntDict = nt->getDictionarySharedPtr();
319 size_t nFeatures = _dict->getNumberOfFeatures();
320 ntDict->setNumberOfFeatures(nFeatures);
321 for (
size_t i = 0; i < nFeatures; i++)
323 ntDict->setFeature((*_dict)[i].ntFeature, i);
329 size_t loadDataBlock() DAAL_C11_OVERRIDE
333 s = checkConnection();
336 s = super::checkDictionary();
339 s = super::checkNumericTable();
342 return loadDataBlock(_spnt.get());
345 size_t loadDataBlock(NumericTable* nt) DAAL_C11_OVERRIDE
349 s = checkConnection();
352 s = super::checkDictionary();
355 if( nt == NULL ) {this->_status.add(services::throwIfPossible(services::ErrorNullInputNumericTable));
return 0; }
357 size_t maxRows = (_initialMaxRows > 0 ? _initialMaxRows : 10);
359 size_t ncols = _dict->getNumberOfFeatures();
361 DataCollection tables;
365 NumericTablePtr ntCurrent = HomogenNumericTable<DAAL_DATA_TYPE>::create(ncols, maxRows, NumericTableIface::doAllocate, &s);
368 this->_status.add(services::throwIfPossible(services::ErrorNumericTableNotAllocated));
371 tables.push_back(ntCurrent);
372 size_t rows = loadDataBlock(maxRows, ntCurrent.get());
374 if (rows < maxRows) {
break; }
378 super::resizeNumericTableImpl( nrows, nt );
379 nt->setNormalizationFlag(NumericTable::nonNormalized);
381 BlockDescriptor<DAAL_DATA_TYPE> blockCurrent, block;
386 for (
size_t i = 0; i < tables.size(); i++) {
387 NumericTable *ntCurrent = (NumericTable*)(tables[i].
get());
388 size_t rows = ntCurrent->getNumberOfRows();
390 if (rows == 0) {
continue; }
392 ntCurrent->getBlockOfRows(0, rows, readOnly, blockCurrent);
393 nt->getBlockOfRows(pos, rows, writeOnly, block);
395 result |= services::internal::daal_memcpy_s(block.getBlockPtr(), rows * ncols *
sizeof(DAAL_DATA_TYPE),
396 blockCurrent.getBlockPtr(), rows * ncols *
sizeof(DAAL_DATA_TYPE));
398 ntCurrent->releaseBlockOfRows(blockCurrent);
399 nt->releaseBlockOfRows(block);
401 super::combineStatistics( ntCurrent, nt, pos == 0);
406 this->_status.add(services::throwIfPossible(services::ErrorMemoryCopyFailedInternal));
409 NumericTableDictionaryPtr ntDict = nt->getDictionarySharedPtr();
410 size_t nFeatures = _dict->getNumberOfFeatures();
411 ntDict->setNumberOfFeatures(nFeatures);
412 for (
size_t i = 0; i < nFeatures; i++)
414 ntDict->setFeature((*_dict)[i].ntFeature, i);
420 services::Status createDictionaryFromContext() DAAL_C11_OVERRIDE
422 services::Status status = checkConnection();
423 DAAL_CHECK_STATUS_VAR(status);
425 _connectionStatus = DataSource::notReady;
428 {
return services::throwIfPossible(services::ErrorDictionaryAlreadyAvailable); }
430 _dict = DataSourceDictionary::create(&status);
431 DAAL_CHECK_STATUS_VAR(status);
433 status |= _featureManager.createDictionary(_hdlStmt, _dict.get());
434 DAAL_CHECK_STATUS_VAR(status);
436 _connectionStatus = DataSource::readyForLoad;
440 DataSourceIface::DataSourceStatus getStatus() DAAL_C11_OVERRIDE
442 return _connectionStatus;
445 size_t getNumberOfAvailableRows() DAAL_C11_OVERRIDE
450 FeatureManager &getFeatureManager()
452 return _featureManager;
456 void initialize(
size_t initialMaxRows)
458 _hdlDbc = SQL_NULL_HDBC;
459 _hdlEnv = SQL_NULL_HENV;
460 _hdlStmt = SQL_NULL_HSTMT;
463 _initialMaxRows = initialMaxRows;
464 _connectionStatus = DataSource::notReady;
467 services::Status connectUsingUserNameAndPassword(
const std::string &dbname,
468 const std::string &username,
469 const std::string &password)
471 SQLRETURN ret = setupHandlesInternal();
472 if (!SQL_SUCCEEDED(ret)) {
return services::throwIfPossible(services::ErrorHandlesSQL); }
474 ret = connectInternal(dbname, username, password);
475 if (!SQL_SUCCEEDED(ret)) {
return services::throwIfPossible(services::ErrorODBC); }
477 return services::Status();
480 services::Status connectUsingConnectionString(
const std::string &connectionString)
482 SQLRETURN ret = setupHandlesInternal();
483 if (!SQL_SUCCEEDED(ret)) {
return services::throwIfPossible(services::ErrorHandlesSQL); }
485 ret = connectDriverInternal(connectionString);
486 if (!SQL_SUCCEEDED(ret)) {
return services::throwIfPossible(services::ErrorODBC); }
488 return services::Status();
491 services::Status executeSelectAllQuery(
const std::string &tableName)
493 if (!tableName.empty())
495 return executeQuery(
"SELECT * FROM " + tableName);
497 return services::Status();
500 SQLRETURN connectInternal(
const std::string &dbname,
501 const std::string &username,
502 const std::string &password)
504 return SQLConnect(_hdlDbc, (SQLCHAR *)dbname.c_str(), (SQLSMALLINT)dbname.size(),
505 (SQLCHAR *)username.c_str(), (SQLSMALLINT)username.size(),
506 (SQLCHAR *)password.c_str(), (SQLSMALLINT)password.size());
509 SQLRETURN connectDriverInternal(
const std::string &connectionString)
511 SQLSMALLINT outConnectionStringLength;
512 return SQLDriverConnect(_hdlDbc, SQL_NULL_HANDLE,
513 (SQLCHAR *)connectionString.c_str(),
514 (SQLSMALLINT)connectionString.size(),
517 &outConnectionStringLength,
518 SQL_DRIVER_NOPROMPT);
521 SQLRETURN setupHandlesInternal()
523 SQLRETURN ret = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &_hdlEnv);
524 if (!SQL_SUCCEEDED(ret)) {
return ret; }
526 ret = SQLSetEnvAttr(_hdlEnv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3, SQL_IS_UINTEGER);
527 if (!SQL_SUCCEEDED(ret)) {
return ret; }
529 ret = SQLAllocHandle(SQL_HANDLE_DBC, _hdlEnv, &_hdlDbc);
530 if (!SQL_SUCCEEDED(ret)) {
return ret; }
535 SQLRETURN freeHandlesInternal()
537 if (_hdlDbc == SQL_NULL_HDBC || _hdlEnv == SQL_NULL_HENV) {
return SQL_SUCCESS; }
539 SQLRETURN ret = SQLDisconnect(_hdlDbc);
540 if (!SQL_SUCCEEDED(ret)) {
return ret; }
542 ret = SQLFreeHandle(SQL_HANDLE_DBC, _hdlDbc);
543 if (!SQL_SUCCEEDED(ret)) {
return ret; }
545 ret = SQLFreeHandle(SQL_HANDLE_ENV, _hdlEnv);
546 if (!SQL_SUCCEEDED(ret)) {
return ret; }
548 _hdlDbc = SQL_NULL_HDBC;
549 _hdlEnv = SQL_NULL_HENV;
554 services::Status checkConnection()
556 if (_connectionStatus == DataSource::notReady)
557 {
return services::throwIfPossible(services::ErrorSourceDataNotAvailable); }
559 return services::Status();
564 FeatureManager _featureManager;
565 DataSourceIface::DataSourceStatus _connectionStatus;
575 using interface1::ODBCDataSource;
576 using interface1::ODBCDataSourceOptions;
578 inline ODBCDataSourceOptions::Value operator |(
const ODBCDataSourceOptions::Value &lhs,
579 const ODBCDataSourceOptions::Value &rhs)
580 {
return ODBCDataSourceOptions::unite(lhs, rhs); }
daal::services::ErrorODBC
Definition: error_indexes.h:390
daal::data_management::interface1::ODBCDataSource::getNumberOfAvailableRows
size_t getNumberOfAvailableRows() DAAL_C11_OVERRIDE
Definition: odbc_data_source.h:445
daal::data_management::interface1::DataSourceIface::NumericTableAllocationFlag
NumericTableAllocationFlag
Specifies whether a Numeric Table is allocated inside of the Data Source object.
Definition: data_source.h:80
daal::data_management::interface1::NumericTableIface::sumSquares
Definition: numeric_table.h:301
daal::data_management::interface1::NumericTableIface::maximum
Definition: numeric_table.h:299
daal::data_management::interface1::DataSource::checkNumericTable
services::Status checkNumericTable()
Definition: data_source.h:346
daal::services::ErrorDictionaryAlreadyAvailable
Definition: error_indexes.h:156
daal::data_management::interface1::NumericTable::getDataMemoryStatus
virtual MemoryStatus getDataMemoryStatus() const
Definition: numeric_table.h:722
daal::data_management::interface1::DataSource::status
services::Status status() const
Definition: data_source.h:310
daal::data_management::interface1::ODBCDataSource::freeHandles
services::Status freeHandles()
Definition: odbc_data_source.h:247
daal::data_management::interface1::NumericTableIface::doAllocate
Definition: numeric_table.h:289
daal::services::ErrorIncorrectNumberOfObservations
Definition: error_indexes.h:73
daal::data_management::interface1::DataSourceIface::doDictionaryFromContext
Definition: data_source.h:73
daal::data_management::interface1::ODBCDataSource::ODBCDataSource
ODBCDataSource(const std::string &dbname, const std::string &tableName, const std::string &userName, const std::string &password, const ODBCDataSourceOptions &options, size_t initialMaxRows=10)
Definition: odbc_data_source.h:164
daal::data_management::interface1::DataSourceIface::notAllocateNumericTable
Definition: data_source.h:82
daal::data_management::interface1::NumericTable
Class for a data management component responsible for representation of data in the numeric format...
Definition: numeric_table.h:577
daal::services::ErrorSQLstmtHandle
Definition: error_indexes.h:391
daal::data_management::interface1::ODBCDataSource::ODBCDataSource
ODBCDataSource(const std::string &dbname, const std::string &tableName="", const std::string &userName="", const std::string &password="", DataSourceIface::NumericTableAllocationFlag doAllocateNumericTable=DataSource::notAllocateNumericTable, DataSourceIface::DictionaryCreationFlag doCreateDictionaryFromContext=DataSource::notDictionaryFromContext, size_t initialMaxRows=10)
Definition: odbc_data_source.h:132
daal::data_management::interface1::ODBCDataSource::loadDataBlock
size_t loadDataBlock() DAAL_C11_OVERRIDE
Definition: odbc_data_source.h:329
daal::data_management::interface1::DataSourceIface::notDictionaryFromContext
Definition: data_source.h:72
daal::data_management::interface1::DataCollection::size
size_t size() const
daal::data_management::interface1::DataSourceIface::readyForLoad
Definition: data_source.h:60
daal::data_management::interface1::ODBCDataSource::ODBCDataSource
ODBCDataSource(const std::string &connectionString, const ODBCDataSourceOptions &options, size_t initialMaxRows=10)
Definition: odbc_data_source.h:192
daal::data_management::interface1::HomogenNumericTable::create
static services::SharedPtr< HomogenNumericTable< DataType > > create(NumericTableDictionaryPtr ddictForHomogenNumericTable, services::Status *stat=NULL)
Definition: homogen_numeric_table.h:95
daal::data_management::interface1::NumericTableIface::minimum
Definition: numeric_table.h:298
daal::data_management::interface1::DataSourceIface::notReady
Definition: data_source.h:63
daal::services::ErrorSourceDataNotAvailable
Definition: error_indexes.h:167
daal::data_management::interface1::NumericTableIface::userAllocated
Definition: numeric_table.h:277
daal::services::ErrorHandlesSQL
Definition: error_indexes.h:389
daal::services::ErrorNullByteInjection
Definition: error_indexes.h:394
daal::data_management::interface1::DataSourceIface::DataSourceStatus
DataSourceStatus
Specifies the status of the Data Source.
Definition: data_source.h:58
daal::data_management::interface1::NumericTable::getNumberOfColumns
size_t getNumberOfColumns() const
Definition: numeric_table.h:654
daal::data_management::internal::DataSourceOptionsImpl
Class that helps to define data source options.
Definition: data_source_options.h:33
daal::data_management::interface1::DataSourceIface::doAllocateNumericTable
Definition: data_source.h:83
daal::data_management::interface1::NumericTable::getNumberOfRows
size_t getNumberOfRows() const
Definition: numeric_table.h:663
daal::data_management::interface1::ODBCDataSource
Connects to data sources with the ODBC API.
Definition: odbc_data_source.h:104
daal::services::daal_memcpy_s
DAAL_DEPRECATED DAAL_EXPORT void daal_memcpy_s(void *dest, size_t numberOfElements, const void *src, size_t count)
daal::data_management::interface1::ODBCDataSource::createDictionaryFromContext
services::Status createDictionaryFromContext() DAAL_C11_OVERRIDE
Definition: odbc_data_source.h:420
daal::data_management::interface1::NumericTableIface::nonNormalized
Definition: numeric_table.h:319
daal::services::ErrorNullInputNumericTable
Definition: error_indexes.h:83
daal::data_management::interface1::DataSourceIface::DictionaryCreationFlag
DictionaryCreationFlag
Specifies whether a Data Dictionary is created from the context of a Data Source. ...
Definition: data_source.h:70
daal::services::ErrorNumericTableNotAllocated
Definition: error_indexes.h:160
daal::data_management::interface1::ODBCDataSource::loadDataBlock
virtual size_t loadDataBlock(size_t maxRows) DAAL_C11_OVERRIDE
Definition: odbc_data_source.h:256
daal::data_management::interface1::Dictionary::create
static services::SharedPtr< Dictionary > create(size_t nfeat, FeaturesEqual featuresEqual=notEqual, services::Status *stat=NULL)
Definition: data_dictionary.h:188
daal::data_management::interface1::DenseNumericTableIface::getBlockOfRows
virtual services::Status getBlockOfRows(size_t vector_idx, size_t vector_num, ReadWriteMode rwflag, BlockDescriptor< double > &block)=0
daal::data_management::interface1::BlockDescriptor< DAAL_DATA_TYPE >
daal::data_management::interface1::DenseNumericTableIface::releaseBlockOfRows
virtual services::Status releaseBlockOfRows(BlockDescriptor< double > &block)=0
daal::data_management::interface1::NumericTable::getDictionarySharedPtr
virtual NumericTableDictionaryPtr getDictionarySharedPtr() const DAAL_C11_OVERRIDE
Definition: numeric_table.h:635
daal::services::ErrorIncorrectNumberOfFeatures
Definition: error_indexes.h:72
daal::data_management::interface1::ODBCDataSource::getStatus
DataSourceIface::DataSourceStatus getStatus() DAAL_C11_OVERRIDE
Definition: odbc_data_source.h:440
daal::services::ErrorMemoryCopyFailedInternal
Definition: error_indexes.h:152
daal::data_management::interface1::NumericTableIface::sum
Definition: numeric_table.h:300
daal::data_management::interface1::ODBCDataSource::loadDataBlock
size_t loadDataBlock(NumericTable *nt) DAAL_C11_OVERRIDE
Definition: odbc_data_source.h:345
daal::data_management::interface1::DataCollection::push_back
DataCollection & push_back(const SerializationIfacePtr &x)
daal::data_management::interface1::ODBCDataSource::loadDataBlock
virtual size_t loadDataBlock(size_t maxRows, NumericTable *nt)
Definition: odbc_data_source.h:276
daal::data_management::interface1::DataSourceTemplate
Implements the abstract DataSourceIface interface.
Definition: data_source.h:464
daal::data_management::interface1::DataSource::checkDictionary
services::Status checkDictionary()
Definition: data_source.h:360
daal::data_management::interface1::ODBCDataSourceOptions
Options of ODBC data source.
Definition: odbc_data_source.h:60
daal::data_management::interface1::DataCollection
Class that provides functionality of Collection container for objects derived from SerializationIface...
Definition: data_collection.h:47
daal::data_management::interface1::BlockDescriptor::getBlockPtr
DataType * getBlockPtr() const
Definition: numeric_table.h:71