SQLRETURN StatementHandle::sqlColumns(SQLCHAR *catalogName,
                                      SQLSMALLINT catalogNameLen,
                                      SQLCHAR *schemaName,
                                      SQLSMALLINT schemaNameLen,
                                      SQLCHAR *tableName,
                                      SQLSMALLINT tableNameLen,
                                      SQLCHAR *columnName,
                                      SQLSMALLINT columnNameLen)
{
    _cursorColumns.clear();
    _cursor.reset();
    _resultSet.clear();
    _rowIdx = -1;

    std::list<std::string> schemas;
    int rc = _connHandle->getDbNames(&schemas);
    if (0 != rc) {
        return SQL_ERROR;
    }
    std::string schemaNameStr;
    if (NULL != schemaName) {
        if (schemaNameLen == SQL_NTS) {
            schemaNameStr.assign((char *)schemaName);
        } else {
            schemaNameStr.assign((char *)schemaName, (int)schemaNameLen);
        }
    }
    std::string tableNameStr;
    if (NULL != tableName) {
        if (tableNameLen == SQL_NTS) {
            tableNameStr.assign((char *)tableName);
        } else {
            tableNameStr.assign((char *)tableName, (int)tableNameLen);
        }
    }
    
    // map from schema name to table names
    for (std::list<std::string>::const_iterator it = schemas.begin();
         it != schemas.end();
         ++it) {
        if (schemaNameStr.size() && *it != schemaNameStr) {
            continue;
        }
        std::list<std::string> tables;
        int rc = _connHandle->getCollectionNames(*it, &tables);
        if (0 != rc) {
            return SQL_ERROR;
        }
        for (std::list<std::string>::const_iterator tableIt = tables.begin();
             tableIt != tables.end();
             ++tableIt) {
            size_t periodIdx = tableIt->find('.');
            size_t periodIdx2 = tableIt->find('.', periodIdx + 1);
            if (periodIdx2 != std::string::npos) {
                periodIdx2 = periodIdx2 - periodIdx - 1;
            }
            std::string tableName(*tableIt, periodIdx + 1, periodIdx2);
            if ("system" == tableName) {
                // skip mongodb internal tables
                continue;
            }
            if (tableNameStr.size() && tableName != tableNameStr) {
                continue;
            }

            std::auto_ptr<mongo::DBClientCursor> cursor =
                _connHandle->query(*tableIt);

            int columnNum = 1;
            while (cursor->more()) {
                mongo::BSONObj::iterator fieldIt = cursor->next().begin();
                while(fieldIt.more()) {
                    mongo::BSONElement elem = fieldIt.next();
                    SQLSMALLINT dataType = mapMongoToODBCDataType(elem.type());
                    _resultSet.push_back(std::list<Result>());
                    std::list<Result>& results = _resultSet.back();
                    results.push_back("NULL");
                    results.push_back(*it);
                    results.push_back(tableName);
                    results.push_back(elem.fieldName());
                    results.push_back(dataType);
                    results.push_back(dataTypeName(dataType));
                    results.push_back(columnSize(dataType));
                    results.push_back(bufferLength(dataType));
                    results.push_back(decimalDigits(dataType));
                    results.push_back(numPercRadix(dataType));
                    results.push_back((SQLSMALLINT)SQL_NULLABLE);
                    results.push_back("");
                    results.push_back("NULL");
                    results.push_back(mapODBCDataTypeToSQLDataType(dataType));
                    results.push_back(getDatetimeSubcode(dataType));
                    results.push_back(maxCharLen(dataType));
                    results.push_back(columnNum++);
                    results.push_back("\"YES\"");
                }
                break;
            }
        }
    }
    return SQL_SUCCESS;
}
Exemple #2
0
// =============================================================================
//
// Try to parse an expression symbol (i.e. an OPER_erator or OPER_erand or a colon)
// from the lexer.
//
ExpressionSymbol* Expression::parseSymbol()
{
	int pos = m_lexer->position();
	ExpressionValue* op = null;

	if (m_lexer->next (TK_Colon))
		return new ExpressionColon;

	// Check for OPER_erator
	for (const OperatorInfo& op : g_Operators)
		if (m_lexer->next (op.token))
			return new ExpressionOperator ((ExpressionOperatorType) (&op - &g_Operators[0]));

	// Check sub-expression
	if (m_lexer->next (TK_ParenStart))
	{
		Expression expr (m_parser, m_lexer, m_type);
		m_lexer->mustGetNext (TK_ParenEnd);
		return expr.getResult()->clone();
	}

	op = new ExpressionValue (m_type);

	// Check function
	if (CommandInfo* comm = findCommandByName (m_lexer->peekNextString()))
	{
		m_lexer->skip();

		if (m_type != TYPE_Unknown && comm->returnvalue != m_type)
			error ("%1 returns an incompatible data type", comm->name);

		op->setBuffer (m_parser->parseCommand (comm));
		return op;
	}

	// Check for variables
	if (m_lexer->next (TK_DollarSign))
	{
		m_lexer->mustGetNext (TK_Symbol);
		Variable* var = m_parser->findVariable (getTokenString());

		if (var == null)
			error ("unknown variable %1", getTokenString());

		if (var->type != m_type)
			error ("expression requires %1, variable $%2 is of type %3",
				dataTypeName (m_type), var->name, dataTypeName (var->type));

		if (var->isarray)
		{
			m_lexer->mustGetNext (TK_BracketStart);
			Expression expr (m_parser, m_lexer, TYPE_Int);
			expr.getResult()->convertToBuffer();
			DataBuffer* buf = expr.getResult()->buffer()->clone();
			buf->writeDWord (DH_PushGlobalArray);
			buf->writeDWord (var->index);
			op->setBuffer (buf);
			m_lexer->mustGetNext (TK_BracketEnd);
		}
		elif (var->writelevel == WRITE_Constexpr)
			op->setValue (var->value);
		else
		{