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:
Tamas Bunth
2018-05-14 07:30:37 +02:00
committed by Tamás Bunth
parent d9c2523b0c
commit 4f043c0a26
5 changed files with 63 additions and 9 deletions

View File

@@ -154,17 +154,36 @@ namespace dbahsql
{
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)
{
auto sColumns = lcl_splitColumnPart(sColumnPart);
for (OUString& sColumn : sColumns)
{
if (sColumn.startsWithIgnoreAsciiCase("PRIMARY KEY"))
{
parsePrimaryKeys(sColumn);
continue;
}
std::vector<OUString> words = string::split(sColumn, sal_Unicode(u' '));
if (words[0] == "CONSTRAINT")
{
// TODO parse foreign key part instead of just saving the string
// part
m_aForeignParts.push_back(sColumn);
continue;
}
@@ -192,8 +211,14 @@ void CreateStmtParser::parseColumnPart(const OUString& sColumnPart)
}
bool bCaseInsensitive = sTypeName.indexOf("IGNORECASE") >= 0;
ColumnDefinition aColDef(words[0], lcl_getDataTypeFromHsql(sTypeName), aParams,
lcl_isPrimaryKey(sColumn), lcl_getAutoIncrementDefault(sColumn),
const OUString& rTableName = words[0];
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);
m_aColumns.push_back(aColDef);

View File

@@ -20,10 +20,12 @@ class SAL_DLLPUBLIC_EXPORT CreateStmtParser
private:
std::vector<ColumnDefinition> m_aColumns;
std::vector<OUString> m_aForeignParts;
std::vector<OUString> m_PrimaryKeys;
OUString m_sTableName;
protected:
void parseColumnPart(const OUString& sColumnPart);
void parsePrimaryKeys(const OUString& sPrimaryPart);
public:
CreateStmtParser();
@@ -34,6 +36,11 @@ public:
*/
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
* parsed statement.

View File

@@ -158,18 +158,25 @@ OUString FbCreateStmtParser::compose() const
else if (!columnIter->isNullable())
lcl_appendWithSpace(sSql, "NOT NULL");
if (columnIter->isPrimaryKey())
lcl_appendWithSpace(sSql, "PRIMARY KEY");
if (columnIter->isCaseInsensitive())
lcl_appendWithSpace(sSql, "COLLATE UNICODE_CI");
++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(")"); // end of column declaration
sSql.append("))"); // end of column declaration and primary keys
return sSql.makeStringAndClear();
}

View File

@@ -147,6 +147,7 @@ void SchemaParser::parseSchema()
// save column definitions
m_ColumnTypes[aCreateParser.getTableName()] = aCreateParser.getColumnDef();
m_sCreateStatements.push_back(sSql);
}
else if (sSql.startsWith("ALTER"))
@@ -173,6 +174,11 @@ const std::map<OUString, std::vector<sal_Int32>>& SchemaParser::getTableIndexes(
return m_Indexes;
}
const std::map<OUString, std::vector<OUString>>& SchemaParser::getPrimaryKeys() const
{
return m_PrimaryKeys;
}
} // namespace dbahsql
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View File

@@ -32,6 +32,9 @@ private:
// root element's position of data for each table
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_sAlterStatements;
@@ -71,6 +74,12 @@ public:
* contains one row.
*/
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;
};
}