/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
Reference<XColumnLocate> xColLocate(m_xColNames,UNO_QUERY); if(!xColLocate.is()) return; // Everything tested and we have the name of the Column. // What number is the Column?
::rtl::Reference<OSQLColumns> aSelectColumns = m_aSQLIterator.getSelectColumns();
::comphelper::UStringMixEqual aCase;
OSQLColumns::const_iterator aFind = ::connectivity::find(aSelectColumns->begin(),aSelectColumns->end(),aColumnName,aCase); if ( aFind == aSelectColumns->end() ) throw SQLException();
m_aOrderbyColumnNumber.push_back((aFind - aSelectColumns->begin()) + 1);
// Ascending or Descending?
m_aOrderbyAscending.push_back(SQL_ISTOKEN(pAscendingDescending,DESC) ? TAscendingOrder::DESC : TAscendingOrder::ASC);
}
// sanity checks if ( rTabs.empty() ) // no tables -> nothing to operate on -> error
m_pConnection->throwGenericSQLException(STR_QUERY_NO_TABLE,*this);
if ( rTabs.size() > 1 || m_aSQLIterator.hasErrors() ) // more than one table -> can't operate on them -> error
m_pConnection->throwGenericSQLException(STR_QUERY_MORE_TABLES,*this);
if ( (m_aSQLIterator.getStatementType() == OSQLStatementType::Select) && m_aSQLIterator.getSelectColumns()->empty() ) // SELECT statement without columns -> error
m_pConnection->throwGenericSQLException(STR_QUERY_NO_COLUMN,*this);
switch(m_aSQLIterator.getStatementType())
{ case OSQLStatementType::CreateTable: case OSQLStatementType::OdbcCall: case OSQLStatementType::Unknown:
m_pConnection->throwGenericSQLException(STR_QUERY_TOO_COMPLEX,*this); break; case OSQLStatementType::Select: if(SQL_ISRULE(m_aSQLIterator.getParseTree(), union_statement))
{
m_pConnection->throwGenericSQLException(STR_QUERY_TOO_COMPLEX, *this);
}
assert(SQL_ISRULE(m_aSQLIterator.getParseTree(), select_statement)); break; default: break;
}
// at this moment we support only one table per select statement
m_pTable = dynamic_cast<OFileTable*>(rTabs.begin()->second.get());
OSL_ENSURE(m_pTable.is(),"No table!"); if ( m_pTable.is() )
m_xColNames = m_pTable->getColumns();
Reference<XIndexAccess> xNames(m_xColNames,UNO_QUERY); // set the binding of the resultrow
m_aRow = new OValueRefVector(xNames->getCount());
(*m_aRow)[0]->setBound(true);
std::for_each(m_aRow->begin()+1,m_aRow->end(),TSetRefBound(false));
// set the binding of the resultrow
m_aEvaluateRow = new OValueRefVector(xNames->getCount());
// set the select row
m_aSelectRow = new OValueRefVector(m_aSQLIterator.getSelectColumns()->size());
std::for_each(m_aSelectRow->begin(),m_aSelectRow->end(),TSetRefBound(true));
// create the column mapping
createColumnMapping();
m_pSQLAnalyzer.reset( new OSQLAnalyzer(m_pConnection.get()) );
analyzeSQL();
}
void OStatement_Base::createColumnMapping()
{ // initialize the column index map (mapping select columns to table columns)
::rtl::Reference<connectivity::OSQLColumns> xColumns = m_aSQLIterator.getSelectColumns();
m_aColMapping.resize(xColumns->size() + 1); for (std::size_t i=0; i<m_aColMapping.size(); ++i)
m_aColMapping[i] = i;
Reference<XIndexAccess> xNames(m_xColNames,UNO_QUERY); // now check which columns are bound
OResultSet::setBoundedColumns(m_aRow,m_aSelectRow,xColumns,xNames,true,m_xDBMetaData,m_aColMapping);
}
if (SQL_ISRULE(m_pParseTree,select_statement)) // no values have to be set for SELECT return; elseif (SQL_ISRULE(m_pParseTree,insert_statement))
{ // Create Row for the values to be set (Reference through new) if(m_aAssignValues.is())
m_aAssignValues->clear();
sal_Int32 nCount = Reference<XIndexAccess>(m_xColNames,UNO_QUERY_THROW)->getCount();
m_aAssignValues = new OAssignValues(nCount); // unbound all
std::for_each(m_aAssignValues->begin()+1,m_aAssignValues->end(),TSetRefBound(false));
OSQLParseNode * pColumnCommalist = pOptColumnCommalist->getChild(1);
OSL_ENSURE(pColumnCommalist != nullptr,"OResultSet: Error in Parse Tree");
OSL_ENSURE(SQL_ISRULE(pColumnCommalist,column_commalist),"OResultSet: Error in Parse Tree");
OSL_ENSURE(pColumnCommalist->count() > 0,"OResultSet: Error in Parse Tree");
// All Columns in the column_commalist ... for (size_t i = 0; i < pColumnCommalist->count(); i++)
{
OSQLParseNode * pCol = pColumnCommalist->getChild(i);
OSL_ENSURE(pCol != nullptr,"OResultSet: Error in Parse Tree");
aColumnNameList.push_back(pCol->getTokenValue());
}
} if ( aColumnNameList.empty() )
throwFunctionSequenceException(*this);
// Values ...
OSQLParseNode * pValuesOrQuerySpec = m_pParseTree->getChild(4);
OSL_ENSURE(pValuesOrQuerySpec != nullptr,"OResultSet: pValuesOrQuerySpec must not be NULL!");
OSL_ENSURE(SQL_ISRULE(pValuesOrQuerySpec,values_or_query_spec),"OResultSet: ! SQL_ISRULE(pValuesOrQuerySpec,values_or_query_spec)");
OSL_ENSURE(pValuesOrQuerySpec->count() > 0,"OResultSet: pValuesOrQuerySpec->count() <= 0");
// just "VALUES" is allowed ... if (! SQL_ISTOKEN(pValuesOrQuerySpec->getChild(0),VALUES))
throwFunctionSequenceException(*this);
// List of values
OSQLParseNode * pInsertAtomCommalist = pValuesOrQuerySpec->getChild(2);
OSL_ENSURE(pInsertAtomCommalist != nullptr,"OResultSet: pInsertAtomCommalist must not be NULL!");
OSL_ENSURE(pInsertAtomCommalist->count() > 0,"OResultSet: pInsertAtomCommalist <= 0");
sal_Int32 nIndex=0; for (size_t i = 0; i < pInsertAtomCommalist->count(); i++)
{
OSQLParseNode * pRow_Value_Const = pInsertAtomCommalist->getChild(i); // row_value_constructor
OSL_ENSURE(pRow_Value_Const != nullptr,"OResultSet: pRow_Value_Const must not be NULL!"); if(SQL_ISRULE(pRow_Value_Const,parameter))
{
ParseAssignValues(aColumnNameList,pRow_Value_Const,nIndex++); // only one Columnname allowed per loop
} elseif(pRow_Value_Const->isToken())
ParseAssignValues(aColumnNameList,pRow_Value_Const,i); else
{ if(pRow_Value_Const->count() == aColumnNameList.size())
{ for (size_t j = 0; j < pRow_Value_Const->count(); ++j)
ParseAssignValues(aColumnNameList,pRow_Value_Const->getChild(j),nIndex++);
} else
throwFunctionSequenceException(*this);
}
}
} elseif (SQL_ISRULE(m_pParseTree,update_statement_searched))
{ if(m_aAssignValues.is())
m_aAssignValues->clear();
sal_Int32 nCount = Reference<XIndexAccess>(m_xColNames,UNO_QUERY_THROW)->getCount();
m_aAssignValues = new OAssignValues(nCount); // unbound all
std::for_each(m_aAssignValues->begin()+1,m_aAssignValues->end(),TSetRefBound(false));
void OStatement_Base::SetAssignValue(const OUString& aColumnName, const OUString& aValue, bool bSetNull,
sal_uInt32 nParameter)
{
Reference<XPropertySet> xCol;
m_xColNames->getByName(aColumnName) >>= xCol;
sal_Int32 nId = Reference<XColumnLocate>(m_xColNames,UNO_QUERY_THROW)->findColumn(aColumnName); // does this column actually exist in the file?
if (!xCol.is())
{ // This Column doesn't exist!
throwFunctionSequenceException(*this);
}
// Everything tested and we have the names of the Column. // Now allocate one Value, set the value and tie the value to the Row. if (bSetNull)
(*m_aAssignValues)[nId]->setNull(); else
{ switch (::comphelper::getINT32(xCol->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE))))
{ case DataType::BIT: if (aValue.equalsIgnoreAsciiCase("TRUE") || aValue[0] == '1')
*(*m_aAssignValues)[nId] = true; elseif (aValue.equalsIgnoreAsciiCase("FALSE") || aValue[0] == '0')
*(*m_aAssignValues)[nId] = false; else
throwFunctionSequenceException(*this); break; case DataType::CHAR: case DataType::VARCHAR: case DataType::LONGVARCHAR: //Characterset is already converted, since the entire statement was converted case DataType::TINYINT: case DataType::SMALLINT: case DataType::INTEGER: case DataType::DECIMAL: case DataType::NUMERIC: case DataType::REAL: case DataType::DOUBLE: case DataType::DATE: case DataType::TIME: case DataType::TIMESTAMP:
*(*m_aAssignValues)[nId] = ORowSetValue(aValue); break; default:
throwFunctionSequenceException(*this);
}
}
// save Parameter-No. (as User Data) // SQL_NO_PARAMETER = no Parameter.
m_aAssignValues->setParameterIndex(nId,nParameter); if(nParameter != SQL_NO_PARAMETER)
m_aParameterIndexes[nParameter] = nId;
}
void OStatement_Base::parseParamterElem(const OUString& /*_sColumnName*/,OSQLParseNode* /*pRow_Value_Constructor_Elem*/)
{ // do nothing here
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.