From ed5640d8b587fbcfed7dd7967f3de04b37a76f26 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 11:06:44 +0200 Subject: Adding upstream version 4:7.4.7. Signed-off-by: Daniel Baumann --- dbaccess/source/filter/hsqldb/fbcreateparser.cxx | 218 +++++++++++++++++++++++ 1 file changed, 218 insertions(+) create mode 100644 dbaccess/source/filter/hsqldb/fbcreateparser.cxx (limited to 'dbaccess/source/filter/hsqldb/fbcreateparser.cxx') diff --git a/dbaccess/source/filter/hsqldb/fbcreateparser.cxx b/dbaccess/source/filter/hsqldb/fbcreateparser.cxx new file mode 100644 index 000000000..f3399474c --- /dev/null +++ b/dbaccess/source/filter/hsqldb/fbcreateparser.cxx @@ -0,0 +1,218 @@ +/* -*- 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 . + */ + +#include "fbcreateparser.hxx" +#include "columndef.hxx" +#include "utils.hxx" + +#include + +#include + +using namespace css::sdbc; + +namespace +{ +void lcl_appendWithSpace(OUStringBuffer& sBuff, std::u16string_view sStr) +{ + sBuff.append(" "); + sBuff.append(sStr); +} + +OUString lcl_DataTypetoFbTypeName(sal_Int32 eType) +{ + switch (eType) + { + case DataType::CHAR: + case DataType::BINARY: + return "CHAR"; + case DataType::VARCHAR: + case DataType::VARBINARY: + return "VARCHAR"; + case DataType::TINYINT: // no such type in Firebird + case DataType::SMALLINT: + return "SMALLINT"; + case DataType::INTEGER: + return "INTEGER"; + case DataType::BIGINT: + return "BIGINT"; + case DataType::NUMERIC: + return "NUMERIC"; + case DataType::DECIMAL: + return "DECIMAL"; + case DataType::BOOLEAN: + return "BOOLEAN"; + case DataType::LONGVARCHAR: + case DataType::LONGVARBINARY: + case DataType::CLOB: + case DataType::BLOB: + case DataType::OTHER: + return "BLOB"; + case DataType::DATE: + return "DATE"; + case DataType::TIME: + return "TIME"; + case DataType::TIMESTAMP: + return "TIMESTAMP"; + case DataType::DOUBLE: + case DataType::REAL: + return "DOUBLE PRECISION"; + case DataType::FLOAT: + return "FLOAT"; + default: + assert(false); + return OUString(); + } +} + +OUString lcl_getTypeModifier(sal_Int32 eType) +{ + // TODO bind -9546 magic number to a common definition. It also appears + // in the connectivity module. + switch (eType) + { + case DataType::CLOB: + case DataType::LONGVARCHAR: + return "SUB_TYPE 1"; + case DataType::LONGVARBINARY: + return "SUB_TYPE -9546"; + case DataType::BINARY: + case DataType::VARBINARY: + return "CHARACTER SET OCTETS"; + default: + return OUString(); + } +} + +} // unnamed namespace + +namespace dbahsql +{ +void FbCreateStmtParser::appendPrimaryKeyPart(OUStringBuffer& rSql) const +{ + const std::vector& sPrimaryKeys = getPrimaryKeys(); + if (sPrimaryKeys.empty()) + return; // no primary key specified + + rSql.append(","); + rSql.append("PRIMARY KEY("); + auto it = sPrimaryKeys.cbegin(); + while (it != sPrimaryKeys.end()) + { + rSql.append(*it); + ++it; + if (it != sPrimaryKeys.end()) + rSql.append(","); + } + + rSql.append(")"); // end of primary key declaration +} + +void FbCreateStmtParser::ensureProperTableLengths() const +{ + const std::vector& rColumns = getColumnDef(); + for (const auto& col : rColumns) + utils::ensureFirebirdTableLength(col.getName()); +} + +OUString FbCreateStmtParser::compose() const +{ + ensureProperTableLengths(); + OUStringBuffer sSql(128); + sSql.append("CREATE TABLE "); + sSql.append(getTableName()); + + lcl_appendWithSpace(sSql, u"("); // column declaration + auto& rColumns = getColumnDef(); + auto columnIter = rColumns.cbegin(); + while (columnIter != rColumns.end()) + { + lcl_appendWithSpace(sSql, columnIter->getName()); + lcl_appendWithSpace(sSql, lcl_DataTypetoFbTypeName(columnIter->getDataType())); + + std::vector params{ columnIter->getParams() }; + + if (columnIter->getDataType() == DataType::NUMERIC + || columnIter->getDataType() == DataType::DECIMAL) + { + // max precision is 18 here + if (params.at(0) > 18) + params[0] = 18; + } + + // Firebird SQL dialect does not like parameters for TIMESTAMP + if (!params.empty() && columnIter->getDataType() != DataType::TIMESTAMP) + { + sSql.append("("); + auto it = params.cbegin(); + while (it != params.end()) + { + sSql.append(*it); + ++it; + if (it != params.end()) + sSql.append(","); + } + sSql.append(")"); // end of param declaration + } + + // special modifiers here, based on type (e.g. charset, subtype) + OUString sModifier = lcl_getTypeModifier(columnIter->getDataType()); + if (!sModifier.isEmpty()) + lcl_appendWithSpace(sSql, sModifier); + + if (columnIter->isAutoIncremental()) + { + lcl_appendWithSpace(sSql, u"GENERATED BY DEFAULT AS IDENTITY (START WITH "); + + // start with 0: + // HSQLDB: first value will be 0. + // Firebird: first value will be 1. + sSql.append(columnIter->getStartValue() - 1); + sSql.append(")"); + } + else if (!columnIter->isNullable()) + lcl_appendWithSpace(sSql, u"NOT NULL"); + + if (columnIter->isCaseInsensitive()) + lcl_appendWithSpace(sSql, u"COLLATE UNICODE_CI"); + + const OUString& sDefaultVal = columnIter->getDefault(); + if (!sDefaultVal.isEmpty()) + { + lcl_appendWithSpace(sSql, u"DEFAULT"); + if (sDefaultVal.equalsIgnoreAsciiCase("NOW")) + lcl_appendWithSpace(sSql, u"\'NOW\'"); // Fb likes it single quoted + else + lcl_appendWithSpace(sSql, sDefaultVal); + } + + ++columnIter; + if (columnIter != rColumns.end()) + sSql.append(","); + } + + appendPrimaryKeyPart(sSql); + + sSql.append(")"); // end of column declaration + return sSql.makeStringAndClear(); +} + +} // dbahsql + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ -- cgit v1.2.3