LibreOffice Module connectivity (master) 1
mysqlc_resultsetmetadata.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
21#include "mysqlc_general.hxx"
22
23#include <com/sun/star/sdbc/XRow.hpp>
24#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
25#include <o3tl/safeint.hxx>
26
27using namespace connectivity::mysqlc;
28using namespace com::sun::star::uno;
29using namespace com::sun::star::lang;
30using namespace com::sun::star::sdbc;
31
32OResultSetMetaData::OResultSetMetaData(OConnection& rConn, MYSQL_RES* pResult)
33 : m_rConnection(rConn)
34{
35 MYSQL_FIELD* fields = mysql_fetch_field(pResult);
36 unsigned nFieldCount = mysql_num_fields(pResult);
37 for (unsigned i = 0; i < nFieldCount; ++i)
38 {
39 MySqlFieldInfo fieldInfo;
40 {
41 fieldInfo.columnName
42 = OUString{ fields[i].name, static_cast<sal_Int32>(fields[i].name_length),
44 fieldInfo.length = static_cast<sal_Int32>(fields[i].length);
45 fieldInfo.type
46 = mysqlc_sdbc_driver::mysqlToOOOType(fields[i].type, fields[i].charsetnr);
47 fieldInfo.mysql_type = fields[i].type;
48 fieldInfo.charsetNumber = fields[i].charsetnr;
49 fieldInfo.flags = fields[i].flags;
50 fieldInfo.schemaName
51 = OUString{ fields[i].db, static_cast<sal_Int32>(fields[i].db_length),
53 fieldInfo.tableName
54 = OUString{ fields[i].table, static_cast<sal_Int32>(fields[i].table_length),
56 fieldInfo.catalogName
57 = OUString{ fields[i].catalog, static_cast<sal_Int32>(fields[i].catalog_length),
59 fieldInfo.decimals = static_cast<sal_Int32>(fields[i].decimals);
60 fieldInfo.max_length = static_cast<sal_Int32>(fields[i].max_length);
61 }
62 m_fields.push_back(std::move(fieldInfo));
63 }
64}
65
66sal_Int32 SAL_CALL OResultSetMetaData::getColumnDisplaySize(sal_Int32 column)
67{
68 checkColumnIndex(column);
69 return m_fields.at(column - 1).length;
70}
71
72sal_Int32 SAL_CALL OResultSetMetaData::getColumnType(sal_Int32 column)
73{
74 checkColumnIndex(column);
75 return m_fields.at(column - 1).type;
76}
77
78sal_Int32 SAL_CALL OResultSetMetaData::getColumnCount() { return m_fields.size(); }
79
81{
82 // MYSQL_FIELD::charsetnr is the collation identifier
83 // _ci postfix means it's insensitive
84 OUString sql
85 = "SHOW COLLATION WHERE Id =" + OUString::number(m_fields.at(column - 1).charsetNumber);
86
87 Reference<XStatement> stmt = m_rConnection.createStatement();
88 Reference<XResultSet> rs = stmt->executeQuery(sql);
89 Reference<XRow> xRow(rs, UNO_QUERY_THROW);
90
91 if (!rs->next()) // fetch first and only row
92 return false;
93
94 OUString sColName = xRow->getString(1); // first column is Collation name
95
96 return !sColName.isEmpty() && !sColName.endsWith("_ci");
97}
98
99OUString SAL_CALL OResultSetMetaData::getSchemaName(sal_Int32 column)
100{
101 checkColumnIndex(column);
102 return m_fields.at(column - 1).schemaName;
103}
104
105OUString SAL_CALL OResultSetMetaData::getColumnName(sal_Int32 column)
106{
107 checkColumnIndex(column);
108 return m_fields.at(column - 1).columnName;
109}
110
111OUString SAL_CALL OResultSetMetaData::getTableName(sal_Int32 column)
112{
113 checkColumnIndex(column);
114 return m_fields.at(column - 1).tableName;
115}
116
117OUString SAL_CALL OResultSetMetaData::getCatalogName(sal_Int32 column)
118{
119 checkColumnIndex(column);
120 return m_fields.at(column - 1).catalogName;
121}
122
123OUString SAL_CALL OResultSetMetaData::getColumnTypeName(sal_Int32 column)
124{
125 checkColumnIndex(column);
126 return mysqlc_sdbc_driver::mysqlTypeToStr(m_fields.at(column - 1).mysql_type,
127 m_fields.at(column - 1).flags);
128}
129
130OUString SAL_CALL OResultSetMetaData::getColumnLabel(sal_Int32 column)
131{
132 checkColumnIndex(column);
133 return getColumnName(column);
134}
135
136OUString SAL_CALL OResultSetMetaData::getColumnServiceName(sal_Int32 /*column*/)
137{
138 return OUString{};
139}
140
141sal_Bool SAL_CALL OResultSetMetaData::isCurrency(sal_Int32 /*column*/)
142{
143 return false; // TODO
144}
145
147{
148 checkColumnIndex(column);
149 return (m_fields.at(column - 1).flags & AUTO_INCREMENT_FLAG) != 0;
150}
151
152sal_Bool SAL_CALL OResultSetMetaData::isSigned(sal_Int32 column)
153{
154 checkColumnIndex(column);
155 return !(m_fields.at(column - 1).flags & UNSIGNED_FLAG);
156}
157
158sal_Int32 SAL_CALL OResultSetMetaData::getPrecision(sal_Int32 column)
159{
160 checkColumnIndex(column);
161 return m_fields.at(column - 1).max_length - m_fields.at(column - 1).decimals;
162}
163
164sal_Int32 SAL_CALL OResultSetMetaData::getScale(sal_Int32 column)
165{
166 checkColumnIndex(column);
167 return m_fields.at(column - 1).decimals;
168}
169
170sal_Int32 SAL_CALL OResultSetMetaData::isNullable(sal_Int32 column)
171{
172 checkColumnIndex(column);
173 return (m_fields.at(column - 1).flags & NOT_NULL_FLAG) ? 0 : 1;
174}
175
177{
178 checkColumnIndex(column);
179 return true;
180}
181
182sal_Bool SAL_CALL OResultSetMetaData::isReadOnly(sal_Int32 column)
183{
184 checkColumnIndex(column);
185 return m_fields.at(column - 1).schemaName.isEmpty();
186}
187
189{
190 checkColumnIndex(column);
191 return !isReadOnly(column);
192}
193
194sal_Bool SAL_CALL OResultSetMetaData::isWritable(sal_Int32 column)
195{
196 checkColumnIndex(column);
197 return !isReadOnly(column);
198}
199
200void OResultSetMetaData::checkColumnIndex(sal_Int32 columnIndex)
201{
202 auto nColCount = m_fields.size();
203 if (columnIndex < 1 || o3tl::make_unsigned(columnIndex) > nColCount)
204 {
205 OUString str = "Column index out of range (expected 1 to "
206 + OUString::number(sal_Int32(nColCount)) + ", got "
207 + OUString::number(columnIndex) + ".";
208 throw SQLException(str, *this, OUString(), 1, Any());
209 }
210}
211
212/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
rtl_TextEncoding getConnectionEncoding() const
css::uno::Reference< css::sdbc::XStatement > SAL_CALL createStatement() override
sal_Bool SAL_CALL isSearchable(sal_Int32 column) override
sal_Int32 SAL_CALL getPrecision(sal_Int32 column) override
OUString SAL_CALL getSchemaName(sal_Int32 column) override
sal_Bool SAL_CALL isCaseSensitive(sal_Int32 column) override
sal_Bool SAL_CALL isCurrency(sal_Int32 column) override
sal_Int32 SAL_CALL getColumnType(sal_Int32 column) override
OUString SAL_CALL getColumnTypeName(sal_Int32 column) override
sal_Bool SAL_CALL isReadOnly(sal_Int32 column) override
OUString SAL_CALL getColumnLabel(sal_Int32 column) override
sal_Bool SAL_CALL isWritable(sal_Int32 column) override
sal_Bool SAL_CALL isAutoIncrement(sal_Int32 column) override
OUString SAL_CALL getCatalogName(sal_Int32 column) override
sal_Int32 SAL_CALL isNullable(sal_Int32 column) override
OUString SAL_CALL getColumnServiceName(sal_Int32 column) override
sal_Bool SAL_CALL isSigned(sal_Int32 column) override
OUString SAL_CALL getTableName(sal_Int32 column) override
OUString SAL_CALL getColumnName(sal_Int32 column) override
sal_Int32 SAL_CALL getScale(sal_Int32 column) override
sal_Int32 SAL_CALL getColumnDisplaySize(sal_Int32 column) override
sal_Bool SAL_CALL isDefinitelyWritable(sal_Int32 column) override
int i
sal_Int32 mysqlToOOOType(int eType, int charsetnr) noexcept
OUString mysqlTypeToStr(unsigned type, unsigned flags)
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
sal_Int32 type
Definition: pq_statics.cxx:60
unsigned char sal_Bool