tdf#117092 dbahsql: handle multiple primary keys
Set primary keys at the end of the sql statement instead of putting it right after the column definition. This way multiple primary keys can be defined. Change-Id: I7956a536b0516fd8a773d4aa64ccb930ae5c715d Reviewed-on: https://gerrit.libreoffice.org/54204 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Tamás Bunth <btomi96@gmail.com>
This commit is contained in:
@@ -154,17 +154,36 @@ namespace dbahsql
|
|||||||
{
|
{
|
||||||
CreateStmtParser::CreateStmtParser() {}
|
CreateStmtParser::CreateStmtParser() {}
|
||||||
|
|
||||||
|
void CreateStmtParser::parsePrimaryKeys(const OUString& sPrimaryPart)
|
||||||
|
{
|
||||||
|
sal_Int32 nParenPos = sPrimaryPart.indexOf("(");
|
||||||
|
if (nParenPos > 0)
|
||||||
|
{
|
||||||
|
OUString sParamStr
|
||||||
|
= sPrimaryPart.copy(nParenPos + 1, sPrimaryPart.lastIndexOf(")") - nParenPos - 1);
|
||||||
|
auto sParams = string::split(sParamStr, sal_Unicode(u','));
|
||||||
|
for (auto& sParam : sParams)
|
||||||
|
{
|
||||||
|
m_PrimaryKeys.push_back(sParam);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CreateStmtParser::parseColumnPart(const OUString& sColumnPart)
|
void CreateStmtParser::parseColumnPart(const OUString& sColumnPart)
|
||||||
{
|
{
|
||||||
auto sColumns = lcl_splitColumnPart(sColumnPart);
|
auto sColumns = lcl_splitColumnPart(sColumnPart);
|
||||||
for (OUString& sColumn : sColumns)
|
for (OUString& sColumn : sColumns)
|
||||||
{
|
{
|
||||||
|
if (sColumn.startsWithIgnoreAsciiCase("PRIMARY KEY"))
|
||||||
|
{
|
||||||
|
parsePrimaryKeys(sColumn);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<OUString> words = string::split(sColumn, sal_Unicode(u' '));
|
std::vector<OUString> words = string::split(sColumn, sal_Unicode(u' '));
|
||||||
|
|
||||||
if (words[0] == "CONSTRAINT")
|
if (words[0] == "CONSTRAINT")
|
||||||
{
|
{
|
||||||
// TODO parse foreign key part instead of just saving the string
|
|
||||||
// part
|
|
||||||
m_aForeignParts.push_back(sColumn);
|
m_aForeignParts.push_back(sColumn);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -192,8 +211,14 @@ void CreateStmtParser::parseColumnPart(const OUString& sColumnPart)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool bCaseInsensitive = sTypeName.indexOf("IGNORECASE") >= 0;
|
bool bCaseInsensitive = sTypeName.indexOf("IGNORECASE") >= 0;
|
||||||
ColumnDefinition aColDef(words[0], lcl_getDataTypeFromHsql(sTypeName), aParams,
|
const OUString& rTableName = words[0];
|
||||||
lcl_isPrimaryKey(sColumn), lcl_getAutoIncrementDefault(sColumn),
|
bool isPrimaryKey = lcl_isPrimaryKey(sColumn);
|
||||||
|
|
||||||
|
if (isPrimaryKey)
|
||||||
|
m_PrimaryKeys.push_back(rTableName);
|
||||||
|
|
||||||
|
ColumnDefinition aColDef(rTableName, lcl_getDataTypeFromHsql(sTypeName), aParams,
|
||||||
|
isPrimaryKey, lcl_getAutoIncrementDefault(sColumn),
|
||||||
lcl_isNullable(sColumn), bCaseInsensitive);
|
lcl_isNullable(sColumn), bCaseInsensitive);
|
||||||
|
|
||||||
m_aColumns.push_back(aColDef);
|
m_aColumns.push_back(aColDef);
|
||||||
|
@@ -20,10 +20,12 @@ class SAL_DLLPUBLIC_EXPORT CreateStmtParser
|
|||||||
private:
|
private:
|
||||||
std::vector<ColumnDefinition> m_aColumns;
|
std::vector<ColumnDefinition> m_aColumns;
|
||||||
std::vector<OUString> m_aForeignParts;
|
std::vector<OUString> m_aForeignParts;
|
||||||
|
std::vector<OUString> m_PrimaryKeys;
|
||||||
OUString m_sTableName;
|
OUString m_sTableName;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void parseColumnPart(const OUString& sColumnPart);
|
void parseColumnPart(const OUString& sColumnPart);
|
||||||
|
void parsePrimaryKeys(const OUString& sPrimaryPart);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CreateStmtParser();
|
CreateStmtParser();
|
||||||
@@ -34,6 +36,11 @@ public:
|
|||||||
*/
|
*/
|
||||||
OUString getTableName() const { return m_sTableName; }
|
OUString getTableName() const { return m_sTableName; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return primary keys of parsed table.
|
||||||
|
*/
|
||||||
|
std::vector<OUString> getPrimaryKeys() const { return m_PrimaryKeys; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return a vector of column descriptors, representing the columns of the
|
* @return a vector of column descriptors, representing the columns of the
|
||||||
* parsed statement.
|
* parsed statement.
|
||||||
|
@@ -158,18 +158,25 @@ OUString FbCreateStmtParser::compose() const
|
|||||||
else if (!columnIter->isNullable())
|
else if (!columnIter->isNullable())
|
||||||
lcl_appendWithSpace(sSql, "NOT NULL");
|
lcl_appendWithSpace(sSql, "NOT NULL");
|
||||||
|
|
||||||
if (columnIter->isPrimaryKey())
|
|
||||||
lcl_appendWithSpace(sSql, "PRIMARY KEY");
|
|
||||||
|
|
||||||
if (columnIter->isCaseInsensitive())
|
if (columnIter->isCaseInsensitive())
|
||||||
lcl_appendWithSpace(sSql, "COLLATE UNICODE_CI");
|
lcl_appendWithSpace(sSql, "COLLATE UNICODE_CI");
|
||||||
|
|
||||||
++columnIter;
|
++columnIter;
|
||||||
if (columnIter != rColumns.end())
|
sSql.append(",");
|
||||||
|
}
|
||||||
|
|
||||||
|
sSql.append("PRIMARY KEY(");
|
||||||
|
const std::vector<OUString>& sPrimaryKeys = getPrimaryKeys();
|
||||||
|
auto it = sPrimaryKeys.cbegin();
|
||||||
|
while (it != sPrimaryKeys.end())
|
||||||
|
{
|
||||||
|
sSql.append(*it);
|
||||||
|
++it;
|
||||||
|
if (it != sPrimaryKeys.end())
|
||||||
sSql.append(",");
|
sSql.append(",");
|
||||||
}
|
}
|
||||||
|
|
||||||
sSql.append(")"); // end of column declaration
|
sSql.append("))"); // end of column declaration and primary keys
|
||||||
return sSql.makeStringAndClear();
|
return sSql.makeStringAndClear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -147,6 +147,7 @@ void SchemaParser::parseSchema()
|
|||||||
|
|
||||||
// save column definitions
|
// save column definitions
|
||||||
m_ColumnTypes[aCreateParser.getTableName()] = aCreateParser.getColumnDef();
|
m_ColumnTypes[aCreateParser.getTableName()] = aCreateParser.getColumnDef();
|
||||||
|
|
||||||
m_sCreateStatements.push_back(sSql);
|
m_sCreateStatements.push_back(sSql);
|
||||||
}
|
}
|
||||||
else if (sSql.startsWith("ALTER"))
|
else if (sSql.startsWith("ALTER"))
|
||||||
@@ -173,6 +174,11 @@ const std::map<OUString, std::vector<sal_Int32>>& SchemaParser::getTableIndexes(
|
|||||||
return m_Indexes;
|
return m_Indexes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::map<OUString, std::vector<OUString>>& SchemaParser::getPrimaryKeys() const
|
||||||
|
{
|
||||||
|
return m_PrimaryKeys;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace dbahsql
|
} // namespace dbahsql
|
||||||
|
|
||||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||||
|
@@ -32,6 +32,9 @@ private:
|
|||||||
// root element's position of data for each table
|
// root element's position of data for each table
|
||||||
std::map<OUString, std::vector<sal_Int32>> m_Indexes;
|
std::map<OUString, std::vector<sal_Int32>> m_Indexes;
|
||||||
|
|
||||||
|
// primary keys of each table
|
||||||
|
std::map<OUString, std::vector<OUString>> m_PrimaryKeys;
|
||||||
|
|
||||||
SqlStatementVector m_sCreateStatements;
|
SqlStatementVector m_sCreateStatements;
|
||||||
SqlStatementVector m_sAlterStatements;
|
SqlStatementVector m_sAlterStatements;
|
||||||
|
|
||||||
@@ -71,6 +74,12 @@ public:
|
|||||||
* contains one row.
|
* contains one row.
|
||||||
*/
|
*/
|
||||||
const std::map<OUString, std::vector<sal_Int32>>& getTableIndexes() const;
|
const std::map<OUString, std::vector<sal_Int32>>& getTableIndexes() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a vector of column names for each table. These columns are the
|
||||||
|
* primary keys of the table.
|
||||||
|
*/
|
||||||
|
const std::map<OUString, std::vector<OUString>>& getPrimaryKeys() const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user