bool ODBCStatementImpl::isStoredProcedure() const 	 
{ 	 
	std::string str = toString(); 	 
	if (trimInPlace(str).size() < 2) return false; 	 

	return ('{' == str[0] && '}' == str[str.size()-1]); 	 
}
double getReal(const std::string& prompt,
               const std::string& reprompt) {
    std::string promptCopy = prompt;
    appendSpace(promptCopy);
    double value;
    while (true) {
        std::cout << promptCopy;
        std::string line;
        getline(std::cin, line);
        trimInPlace(line);
        std::istringstream stream(line);
        stream >> value;
        if (!stream.fail() && stream.eof()) {
            break;
        }
        std::cout << (reprompt.empty() ? GETREAL_DEFAULT_REPROMPT : reprompt) << std::endl;
        if (promptCopy.empty()) {
            promptCopy = GETREAL_DEFAULT_PROMPT;
        }
    }
    return value;
}
void SQLiteStatementImpl::compileImpl()
{
	if (!_pLeftover)
	{
		_bindBegin = bindings().begin();
	}

	std::string statement(toString());

	sqlite3_stmt* pStmt = 0;
	const char* pSql = _pLeftover ? _pLeftover->c_str() : statement.c_str();

	if (0 == std::strlen(pSql))
		throw InvalidSQLStatementException("Empty statements are illegal");

	int rc = SQLITE_OK;
	const char* pLeftover = 0;
	bool queryFound = false;

	do
	{
		rc = sqlite3_prepare_v2(_pDB, pSql, -1, &pStmt, &pLeftover);
		if (rc != SQLITE_OK)
		{
			if (pStmt) sqlite3_finalize(pStmt);
			pStmt = 0;
			std::string errMsg = sqlite3_errmsg(_pDB);
			Utility::throwException(_pDB, rc, errMsg);
		}
		else if (rc == SQLITE_OK && pStmt)
		{
			queryFound = true;
		}
		else if (rc == SQLITE_OK && !pStmt) // comment/whitespace ignore
		{
			pSql = pLeftover;
			if (std::strlen(pSql) == 0)
			{
				// empty statement or an conditional statement! like CREATE IF NOT EXISTS
				// this is valid
				queryFound = true;
			}
		}
	} while (rc == SQLITE_OK && !pStmt && !queryFound);

	//Finalization call in clear() invalidates the pointer, so the value is remembered here.
	//For last statement in a batch (or a single statement), pLeftover == "", so the next call
	// to compileImpl() shall return false immediately when there are no more statements left.
	std::string leftOver(pLeftover);
	trimInPlace(leftOver);
	clear();
	_pStmt = pStmt;
	if (!leftOver.empty())
	{
		_pLeftover = new std::string(leftOver);
		_canCompile = true;
	}
	else _canCompile = false;

	_pBinder = new Binder(_pStmt);
	_pExtractor = new Extractor(_pStmt);

	if (SQLITE_DONE == _nextResponse && _isExtracted)
	{
		//if this is not the first compile and there has already been extraction
		//during previous step, switch to the next set if there is one provided
		if (hasMoreDataSets())
		{
			activateNextDataSet();
			_isExtracted = false;
		}
	}

	int colCount = sqlite3_column_count(_pStmt);

	if (colCount)
	{
		std::size_t curDataSet = currentDataSet();
		if (curDataSet >= _columns.size()) _columns.resize(curDataSet + 1);
		for (int i = 0; i < colCount; ++i)
		{
			MetaColumn mc(i, sqlite3_column_name(_pStmt, i), Utility::getColumnType(_pStmt, i));
				_columns[curDataSet].push_back(mc);
		}
	}
}
void MyriadEnumSet::initialize(istream& in, size_t& currentLineNumber)
{
    enum READ_STATE { NOV, VLN, END };

    // reset old state
    reset();

    // reader variables
    READ_STATE currentState = NOV; // current reader machine state
    string currentLine; // the current line
    size_t currentItemIndex = 0; // current item index
    RegularExpression::MatchVec posVec; // a posVec for all regex matches

    // reader finite state machine
    while (currentState != END)
    {
        // read next line
        currentLine = "";
        getline(in, currentLine);

        // trim whitespace and unescape quotes
        trimInPlace(currentLine);

        // check if this line is empty or contains a single comment
        if (currentLine.empty() || currentLine.at(0) == '#')
        {
            if (!in.good()) // break on end of stream
            {
                if (currentState == VLN && currentItemIndex < _numberOfValues)
                {
                    throw DataException(format("line %z: Bad enum value line, should be: '%z ........... $value' (not enough items specified?)", currentLineNumber, currentItemIndex));
                }
                else
                {
                    currentState = END;
                }
            }

            currentLineNumber++;
            continue; // skip this line
        }

        if (currentState == NOV)
        {
            if (!headerLine1Format.match(currentLine, 0, posVec))
            {
                throw DataException(format("line %z: Bad header line, should be: '@numberofvalues = $N'", currentLineNumber));
            }

            I64 numberOfValues = NumberParser::parse64(currentLine.substr(posVec[1].offset, posVec[1].length).c_str());

            if (numberOfValues <= 0 && static_cast<size_t>(numberOfValues) > numeric_limits<size_t>::max())
            {
                throw DataException("Invalid number of values '" + toString(numberOfValues) +  "'");
            }

            _numberOfValues = numberOfValues;
            _values.resize(_numberOfValues);

            currentState = VLN;
        }
        else if (currentState == VLN)
        {
            if (!valueLineFormat.match(currentLine, 0, posVec))
            {
                throw DataException(format("line %z: Bad enum value line, should be: '%z ........... $value' (missing new line at the end of file?)", currentLineNumber, currentItemIndex));
            }

            String value = currentLine.substr(posVec[1].offset, posVec[1].length);
            replaceInPlace(value, "\\\"", "\"");
            replaceInPlace(value, "\\n", "\n");

            _values[currentItemIndex] = value;
            currentItemIndex++;

            if (currentItemIndex >= _numberOfValues)
            {
                currentState = END;
                currentItemIndex = 0;
            }
        }
    }

    // protect against unexpected reader state
    if (currentState != END)
    {
        throw RuntimeException("Unexpected state in CombinedPrFunction reader at line " + currentLineNumber);
    }
}