LibreOffice Module dbaccess (master) 1
fbcreateparser.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include "fbcreateparser.hxx"
21#include "columndef.hxx"
22#include "utils.hxx"
23
24#include <com/sun/star/sdbc/DataType.hpp>
25
26#include <rtl/ustrbuf.hxx>
27
28using namespace css::sdbc;
29
30namespace
31{
32OUString lcl_DataTypetoFbTypeName(sal_Int32 eType)
33{
34 switch (eType)
35 {
36 case DataType::CHAR:
37 case DataType::BINARY:
38 return "CHAR";
39 case DataType::VARCHAR:
40 case DataType::VARBINARY:
41 return "VARCHAR";
42 case DataType::TINYINT: // no such type in Firebird
43 case DataType::SMALLINT:
44 return "SMALLINT";
45 case DataType::INTEGER:
46 return "INTEGER";
47 case DataType::BIGINT:
48 return "BIGINT";
49 case DataType::NUMERIC:
50 return "NUMERIC";
51 case DataType::DECIMAL:
52 return "DECIMAL";
53 case DataType::BOOLEAN:
54 return "BOOLEAN";
55 case DataType::LONGVARCHAR:
56 case DataType::LONGVARBINARY:
57 case DataType::CLOB:
58 case DataType::BLOB:
59 case DataType::OTHER:
60 return "BLOB";
61 case DataType::DATE:
62 return "DATE";
63 case DataType::TIME:
64 return "TIME";
65 case DataType::TIMESTAMP:
66 return "TIMESTAMP";
67 case DataType::DOUBLE:
68 case DataType::REAL:
69 return "DOUBLE PRECISION";
70 case DataType::FLOAT:
71 return "FLOAT";
72 default:
73 assert(false);
74 return OUString();
75 }
76}
77
78OUString lcl_getTypeModifier(sal_Int32 eType)
79{
80 // TODO bind -9546 magic number to a common definition. It also appears
81 // in the connectivity module.
82 switch (eType)
83 {
84 case DataType::CLOB:
85 case DataType::LONGVARCHAR:
86 return "SUB_TYPE 1";
87 case DataType::LONGVARBINARY:
88 return "SUB_TYPE -9546";
89 case DataType::BINARY:
90 case DataType::VARBINARY:
91 return "CHARACTER SET OCTETS";
92 default:
93 return OUString();
94 }
95}
96
97} // unnamed namespace
98
99namespace dbahsql
100{
101void FbCreateStmtParser::appendPrimaryKeyPart(OUStringBuffer& rSql) const
102{
103 const std::vector<OUString>& sPrimaryKeys = getPrimaryKeys();
104 if (sPrimaryKeys.empty())
105 return; // no primary key specified
106
107 rSql.append(",PRIMARY KEY(");
108 auto it = sPrimaryKeys.cbegin();
109 while (it != sPrimaryKeys.end())
110 {
111 rSql.append(*it);
112 ++it;
113 if (it != sPrimaryKeys.end())
114 rSql.append(",");
115 }
116
117 rSql.append(")"); // end of primary key declaration
118}
119
121{
122 const std::vector<ColumnDefinition>& rColumns = getColumnDef();
123 for (const auto& col : rColumns)
125}
126
128{
130 OUStringBuffer sSql(128);
131 sSql.append("CREATE TABLE " + getTableName() + " ("); // column declaration
132
133 auto& rColumns = getColumnDef();
134 auto columnIter = rColumns.cbegin();
135 while (columnIter != rColumns.end())
136 {
137 sSql.append(" " + columnIter->getName() + " "
138 + lcl_DataTypetoFbTypeName(columnIter->getDataType()));
139
140 std::vector<sal_Int32> params{ columnIter->getParams() };
141
142 if (columnIter->getDataType() == DataType::NUMERIC
143 || columnIter->getDataType() == DataType::DECIMAL)
144 {
145 // max precision is 18 here
146 if (params.at(0) > 18)
147 params[0] = 18;
148 }
149
150 // Firebird SQL dialect does not like parameters for TIMESTAMP
151 if (!params.empty() && columnIter->getDataType() != DataType::TIMESTAMP)
152 {
153 sSql.append("(");
154 auto it = params.cbegin();
155 while (it != params.end())
156 {
157 sSql.append(*it);
158 ++it;
159 if (it != params.end())
160 sSql.append(",");
161 }
162 sSql.append(")"); // end of param declaration
163 }
164
165 // special modifiers here, based on type (e.g. charset, subtype)
166 OUString sModifier = lcl_getTypeModifier(columnIter->getDataType());
167 if (!sModifier.isEmpty())
168 sSql.append(" " + sModifier);
169
170 if (columnIter->isAutoIncremental())
171 {
172 // start with 0:
173 // HSQLDB: first value will be 0.
174 // Firebird: first value will be 1.
175 sSql.append(" GENERATED BY DEFAULT AS IDENTITY (START WITH "
176 + OUString::number(columnIter->getStartValue() - 1) + ")");
177 }
178 else if (!columnIter->isNullable())
179 sSql.append(" NOT NULL");
180
181 if (columnIter->isCaseInsensitive())
182 sSql.append(" COLLATE UNICODE_CI");
183
184 const OUString& sDefaultVal = columnIter->getDefault();
185 if (!sDefaultVal.isEmpty())
186 {
187 sSql.append(" DEFAULT ");
188 if (sDefaultVal.equalsIgnoreAsciiCase("NOW"))
189 sSql.append("'NOW'"); // Fb likes it single quoted
190 else
191 sSql.append(sDefaultVal);
192 }
193
194 ++columnIter;
195 if (columnIter != rColumns.end())
196 sSql.append(",");
197 }
198
200
201 sSql.append(")"); // end of column declaration
202 return sSql.makeStringAndClear();
203}
204
205} // dbahsql
206
207/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
std::vector< OUString > const & getPrimaryKeys() const
OUString const & getTableName() const
const std::vector< ColumnDefinition > & getColumnDef() const
void appendPrimaryKeyPart(rtl::OUStringBuffer &rSql) const
virtual OUString compose() const override
Compose the result of the parser to statements of Firebird dialect.
OUString eType
Definition: generalpage.cxx:78
RttiCompleteObjectLocator col
void ensureFirebirdTableLength(std::u16string_view sName)
Definition: utils.cxx:134