1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "fbcreateparser.hxx"
21 #include "columndef.hxx"
24 #include <com/sun/star/sdbc/DataType.hpp>
26 #include <rtl/ustrbuf.hxx>
28 using namespace css::sdbc
;
32 void lcl_appendWithSpace(OUStringBuffer
& sBuff
, const OUString
& sStr
)
38 OUString
lcl_DataTypetoFbTypeName(sal_Int32 eType
)
43 case DataType::BINARY
:
45 case DataType::VARCHAR
:
46 case DataType::VARBINARY
:
48 case DataType::TINYINT
: // no such type in Firebird
49 case DataType::SMALLINT
:
51 case DataType::INTEGER
:
53 case DataType::BIGINT
:
55 case DataType::NUMERIC
:
57 case DataType::DECIMAL
:
59 case DataType::BOOLEAN
:
61 case DataType::LONGVARCHAR
:
62 case DataType::LONGVARBINARY
:
71 case DataType::TIMESTAMP
:
73 case DataType::DOUBLE
:
75 return "DOUBLE PRECISION";
84 OUString
lcl_getTypeModifier(sal_Int32 eType
)
86 // TODO bind -9546 magic number to a common definition. It also appears
87 // in the connectivity module.
91 case DataType::LONGVARCHAR
:
93 case DataType::LONGVARBINARY
:
94 return "SUB_TYPE -9546";
95 case DataType::BINARY
:
96 case DataType::VARBINARY
:
97 return "CHARACTER SET OCTETS";
103 } // unnamed namespace
107 void FbCreateStmtParser::appendPrimaryKeyPart(OUStringBuffer
& rSql
) const
109 const std::vector
<OUString
>& sPrimaryKeys
= getPrimaryKeys();
110 if (sPrimaryKeys
.empty())
111 return; // no primary key specified
114 rSql
.append("PRIMARY KEY(");
115 auto it
= sPrimaryKeys
.cbegin();
116 while (it
!= sPrimaryKeys
.end())
120 if (it
!= sPrimaryKeys
.end())
124 rSql
.append(")"); // end of primary key declaration
127 void FbCreateStmtParser::ensureProperTableLengths() const
129 const std::vector
<ColumnDefinition
>& rColumns
= getColumnDef();
130 for (const auto& col
: rColumns
)
131 utils::ensureFirebirdTableLength(col
.getName());
134 OUString
FbCreateStmtParser::compose() const
136 ensureProperTableLengths();
137 OUStringBuffer
sSql(128);
138 sSql
.append("CREATE TABLE ");
139 sSql
.append(getTableName());
141 lcl_appendWithSpace(sSql
, "("); // column declaration
142 auto& rColumns
= getColumnDef();
143 auto columnIter
= rColumns
.cbegin();
144 while (columnIter
!= rColumns
.end())
146 lcl_appendWithSpace(sSql
, columnIter
->getName());
147 lcl_appendWithSpace(sSql
, lcl_DataTypetoFbTypeName(columnIter
->getDataType()));
149 std::vector
<sal_Int32
> params
{ columnIter
->getParams() };
151 if (columnIter
->getDataType() == DataType::NUMERIC
152 || columnIter
->getDataType() == DataType::DECIMAL
)
154 // max precision is 18 here
155 if (params
.at(0) > 18)
159 // Firebird SQL dialect does not like parameters for TIMESTAMP
160 if (!params
.empty() && columnIter
->getDataType() != DataType::TIMESTAMP
)
163 auto it
= params
.cbegin();
164 while (it
!= params
.end())
166 sSql
.append(OUString::number(*it
));
168 if (it
!= params
.end())
171 sSql
.append(")"); // end of param declaration
174 // special modifiers here, based on type (e.g. charset, subtype)
175 OUString sModifier
= lcl_getTypeModifier(columnIter
->getDataType());
176 if (!sModifier
.isEmpty())
177 lcl_appendWithSpace(sSql
, sModifier
);
179 if (columnIter
->isAutoIncremental())
181 lcl_appendWithSpace(sSql
, "GENERATED BY DEFAULT AS IDENTITY (START WITH ");
184 // HSQLDB: first value will be 0.
185 // Firebird: first value will be 1.
186 sSql
.append(columnIter
->getStartValue() - 1);
189 else if (!columnIter
->isNullable())
190 lcl_appendWithSpace(sSql
, "NOT NULL");
192 if (columnIter
->isCaseInsensitive())
193 lcl_appendWithSpace(sSql
, "COLLATE UNICODE_CI");
195 const OUString
& sDefaultVal
= columnIter
->getDefault();
196 if (!sDefaultVal
.isEmpty())
198 lcl_appendWithSpace(sSql
, "DEFAULT");
199 if (sDefaultVal
.equalsIgnoreAsciiCase("NOW"))
200 lcl_appendWithSpace(sSql
, "\'NOW\'"); // Fb likes it single quoted
202 lcl_appendWithSpace(sSql
, sDefaultVal
);
206 if (columnIter
!= rColumns
.end())
210 appendPrimaryKeyPart(sSql
);
212 sSql
.append(")"); // end of column declaration
213 return sSql
.makeStringAndClear();
218 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */