25#include <com/sun/star/sdbc/DataType.hpp>
28using namespace css::sdbc;
34std::u16string_view lcl_getColumnPart(std::u16string_view sSql)
36 size_t nBeginIndex = sSql.find(
'(');
37 if (nBeginIndex == std::u16string_view::npos)
39 SAL_WARN(
"dbaccess",
"No column definitions found");
40 return std::u16string_view();
42 sal_Int32
nCount = sSql.rfind(
')') - nBeginIndex - 1;
43 auto sPart = sSql.substr(nBeginIndex + 1, nCount);
52std::vector<OUString> lcl_splitColumnPart(std::u16string_view sColumnPart)
54 std::vector<OUString> sParts = string::split(sColumnPart,
sal_Unicode(u
','));
55 std::vector<OUString> sReturn;
57 OUStringBuffer current(128);
58 for (
auto const& part : sParts)
61 if (current.lastIndexOf(
"(") > current.lastIndexOf(
")"))
65 sReturn.push_back(current.toString());
72sal_Int32 lcl_getAutoIncrementDefault(std::u16string_view sColumnDef)
75 size_t nPos = sColumnDef.find(u
"GENERATED BY DEFAULT AS IDENTITY");
76 if (nPos != std::u16string_view::npos && nPos > 0)
84std::u16string_view lcl_getDefaultValue(std::u16string_view sColumnDef)
86 constexpr std::u16string_view DEFAULT_KW =
u"DEFAULT";
87 size_t nDefPos = sColumnDef.find(DEFAULT_KW);
88 if (nDefPos > 0 && nDefPos != std::u16string_view::npos
89 && lcl_getAutoIncrementDefault(sColumnDef) < 0)
91 std::u16string_view fromDefault
92 =
o3tl::trim(sColumnDef.substr(nDefPos + DEFAULT_KW.size()));
95 size_t nNextSpace = fromDefault.find(
' ');
96 return (nNextSpace > 0 && nNextSpace != std::u16string_view::npos)
97 ? fromDefault.substr(0, nNextSpace)
100 return std::u16string_view();
103bool lcl_isNullable(std::u16string_view sColumnDef)
105 return sColumnDef.find(u
"NOT NULL") == std::u16string_view::npos;
108bool lcl_isPrimaryKey(std::u16string_view sColumnDef)
110 return sColumnDef.find(u
"PRIMARY KEY") != std::u16string_view::npos;
113sal_Int32 lcl_getDataTypeFromHsql(std::u16string_view sTypeName)
115 if (sTypeName == u
"CHAR")
116 return DataType::CHAR;
117 else if (sTypeName == u
"VARCHAR" || sTypeName == u
"VARCHAR_IGNORECASE")
118 return DataType::VARCHAR;
119 else if (sTypeName == u
"TINYINT")
120 return DataType::TINYINT;
121 else if (sTypeName == u
"SMALLINT")
122 return DataType::SMALLINT;
123 else if (sTypeName == u
"INTEGER")
124 return DataType::INTEGER;
125 else if (sTypeName == u
"BIGINT")
126 return DataType::BIGINT;
127 else if (sTypeName == u
"NUMERIC")
128 return DataType::NUMERIC;
129 else if (sTypeName == u
"DECIMAL")
130 return DataType::DECIMAL;
131 else if (sTypeName == u
"BOOLEAN")
132 return DataType::BOOLEAN;
133 else if (sTypeName == u
"LONGVARCHAR")
134 return DataType::LONGVARCHAR;
135 else if (sTypeName == u
"LONGVARBINARY")
136 return DataType::LONGVARBINARY;
137 else if (sTypeName == u
"CLOB")
138 return DataType::CLOB;
139 else if (sTypeName == u
"BLOB")
140 return DataType::BLOB;
141 else if (sTypeName == u
"BINARY")
142 return DataType::BINARY;
143 else if (sTypeName == u
"VARBINARY")
144 return DataType::VARBINARY;
145 else if (sTypeName == u
"DATE")
146 return DataType::DATE;
147 else if (sTypeName == u
"TIME")
148 return DataType::TIME;
149 else if (sTypeName == u
"TIMESTAMP")
150 return DataType::TIMESTAMP;
151 else if (sTypeName == u
"DOUBLE")
152 return DataType::DOUBLE;
153 else if (sTypeName == u
"REAL")
154 return DataType::REAL;
155 else if (sTypeName == u
"FLOAT")
156 return DataType::FLOAT;
162void lcl_addDefaultParameters(std::vector<sal_Int32>& aParams, sal_Int32
eType)
164 if (
eType == DataType::CHAR ||
eType == DataType::BINARY ||
eType == DataType::VARBINARY
165 ||
eType == DataType::VARCHAR)
166 aParams.push_back(8000);
169struct ColumnTypeParts
172 std::vector<sal_Int32> params;
179ColumnTypeParts lcl_getColumnTypeParts(std::u16string_view sFullTypeName)
181 ColumnTypeParts parts;
182 auto nParenPos = sFullTypeName.find(
'(');
183 if (nParenPos > 0 && nParenPos != std::u16string_view::npos)
185 parts.typeName =
o3tl::trim(sFullTypeName.substr(0, nParenPos));
186 std::u16string_view sParamStr
187 = sFullTypeName.substr(nParenPos + 1, sFullTypeName.find(
')') - nParenPos - 1);
188 auto sParams = string::split(sParamStr,
sal_Unicode(u
','));
189 for (
const auto& sParam : sParams)
191 parts.params.push_back(sParam.toInt32());
197 lcl_addDefaultParameters(parts.params, lcl_getDataTypeFromHsql(parts.typeName));
210 size_t nParenPos = sPrimaryPart.find(
'(');
211 if (nParenPos > 0 && nParenPos != std::u16string_view::npos)
213 std::u16string_view sParamStr
214 = sPrimaryPart.substr(nParenPos + 1, sPrimaryPart.rfind(
')') - nParenPos - 1);
215 auto sParams = string::split(sParamStr,
sal_Unicode(
u','));
216 for (
const auto& sParam : sParams)
225 auto sColumns = lcl_splitColumnPart(sColumnPart);
226 for (
const OUString& sColumn : sColumns)
228 if (sColumn.startsWithIgnoreAsciiCase(
"PRIMARY KEY"))
234 if (sColumn.startsWithIgnoreAsciiCase(
"CONSTRAINT"))
240 bool bIsQuoteUsedForColumnName(sColumn[0] ==
'\"');
245 = bIsQuoteUsedForColumnName ? sColumn.indexOf(
"\"", 1) + 1 : sColumn.indexOf(
" ");
246 OUString rColumnName = sColumn.copy(0, nEndColumnName);
248 const OUString sFromTypeName(
o3tl::trim(sColumn.subView(nEndColumnName)));
253 auto nNextSpace = sFromTypeName.indexOf(
" ");
254 std::u16string_view sFullTypeName;
256 sFullTypeName = sFromTypeName.subView(0, nNextSpace);
259 sFullTypeName = sFromTypeName;
261 ColumnTypeParts typeParts = lcl_getColumnTypeParts(sFullTypeName);
263 bool bCaseInsensitive = typeParts.typeName.indexOf(
"IGNORECASE") >= 0;
264 bool isPrimaryKey = lcl_isPrimaryKey(sColumn);
269 const std::u16string_view sColumnWithoutName
270 = sColumn.subView(sColumn.indexOf(typeParts.typeName));
272 ColumnDefinition aColDef(rColumnName, lcl_getDataTypeFromHsql(typeParts.typeName),
273 std::move(typeParts.params), isPrimaryKey,
274 lcl_getAutoIncrementDefault(sColumnWithoutName),
275 lcl_isNullable(sColumnWithoutName), bCaseInsensitive,
276 OUString(lcl_getDefaultValue(sColumnWithoutName)));
287 SAL_WARN(
"dbaccess",
"Not a create statement");
292 std::u16string_view sColumnPart = lcl_getColumnPart(sSql);
nAutoIncrement: column is auto incremented started with value nAutoIncrement
std::vector< OUString > m_PrimaryKeys
void parse(std::u16string_view sSql)
Parses a create statement.
void parseColumnPart(std::u16string_view sColumnPart)
void parsePrimaryKeys(std::u16string_view sPrimaryPart)
std::vector< ColumnDefinition > m_aColumns
std::vector< OUString > m_aForeignParts
#define SAL_WARN(area, stream)
OUString getTableNameFromStmt(std::u16string_view sSql)
std::basic_string_view< charT, traits > trim(std::basic_string_view< charT, traits > str)
constexpr bool starts_with(std::basic_string_view< charT, traits > sv, std::basic_string_view< charT, traits > x) noexcept