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 "mysqlc_resultsetmetadata.hxx"
21 #include "mysqlc_resultset.hxx"
22 #include "mysqlc_general.hxx"
24 #include <com/sun/star/sdbc/XRow.hpp>
25 #include <rtl/ustrbuf.hxx>
26 #include <sal/log.hxx>
28 using namespace connectivity::mysqlc
;
29 using namespace com::sun::star::uno
;
30 using namespace com::sun::star::lang
;
31 using namespace com::sun::star::sdbc
;
33 OResultSetMetaData::OResultSetMetaData(OConnection
& rConn
, MYSQL_RES
* pResult
)
34 : m_rConnection(rConn
)
36 MYSQL_FIELD
* fields
= mysql_fetch_field(pResult
);
37 unsigned nFieldCount
= mysql_num_fields(pResult
);
38 for (unsigned i
= 0; i
< nFieldCount
; ++i
)
40 MySqlFieldInfo fieldInfo
{
41 OUString
{ fields
[i
].name
, static_cast<sal_Int32
>(fields
[i
].name_length
),
42 m_rConnection
.getConnectionEncoding() }, // column name
43 static_cast<sal_Int32
>(fields
[i
].length
), // length
44 mysqlc_sdbc_driver::mysqlToOOOType(fields
[i
].type
, fields
[i
].charsetnr
), // type
45 fields
[i
].type
, // mysql_type
46 fields
[i
].charsetnr
, // charset number
48 OUString
{ fields
[i
].db
, static_cast<sal_Int32
>(fields
[i
].db_length
),
49 m_rConnection
.getConnectionEncoding() }, // schema name
50 OUString
{ fields
[i
].table
, static_cast<sal_Int32
>(fields
[i
].table_length
),
51 m_rConnection
.getConnectionEncoding() }, // table name
52 OUString
{ fields
[i
].catalog
, static_cast<sal_Int32
>(fields
[i
].catalog_length
),
53 m_rConnection
.getConnectionEncoding() }, // catalog
54 static_cast<sal_Int32
>(fields
[i
].decimals
),
55 static_cast<sal_Int32
>(fields
[i
].max_length
)
57 m_fields
.push_back(std::move(fieldInfo
));
61 sal_Int32 SAL_CALL
OResultSetMetaData::getColumnDisplaySize(sal_Int32 column
)
63 checkColumnIndex(column
);
64 return m_fields
.at(column
- 1).length
;
67 sal_Int32 SAL_CALL
OResultSetMetaData::getColumnType(sal_Int32 column
)
69 checkColumnIndex(column
);
70 return m_fields
.at(column
- 1).type
;
73 sal_Int32 SAL_CALL
OResultSetMetaData::getColumnCount() { return m_fields
.size(); }
75 sal_Bool SAL_CALL
OResultSetMetaData::isCaseSensitive(sal_Int32 column
)
77 // MYSQL_FIELD::charsetnr is the collation identifier
78 // _ci postfix means it's insensitive
79 OUStringBuffer sql
{ "SHOW COLLATION WHERE Id =" };
80 sql
.append(OUString::number(m_fields
.at(column
- 1).charsetNumber
));
82 Reference
<XStatement
> stmt
= m_rConnection
.createStatement();
83 Reference
<XResultSet
> rs
= stmt
->executeQuery(sql
.makeStringAndClear());
84 Reference
<XRow
> xRow(rs
, UNO_QUERY_THROW
);
86 if (!rs
->next()) // fetch first and only row
89 OUString sColName
= xRow
->getString(1); // first column is Collation name
91 return !sColName
.isEmpty() && !sColName
.endsWith("_ci");
94 OUString SAL_CALL
OResultSetMetaData::getSchemaName(sal_Int32 column
)
96 checkColumnIndex(column
);
97 return m_fields
.at(column
- 1).schemaName
;
100 OUString SAL_CALL
OResultSetMetaData::getColumnName(sal_Int32 column
)
102 checkColumnIndex(column
);
103 return m_fields
.at(column
- 1).columnName
;
106 OUString SAL_CALL
OResultSetMetaData::getTableName(sal_Int32 column
)
108 checkColumnIndex(column
);
109 return m_fields
.at(column
- 1).tableName
;
112 OUString SAL_CALL
OResultSetMetaData::getCatalogName(sal_Int32 column
)
114 checkColumnIndex(column
);
115 return m_fields
.at(column
- 1).catalogName
;
118 OUString SAL_CALL
OResultSetMetaData::getColumnTypeName(sal_Int32 column
)
120 checkColumnIndex(column
);
121 return mysqlc_sdbc_driver::mysqlTypeToStr(m_fields
.at(column
- 1).mysql_type
,
122 m_fields
.at(column
- 1).flags
);
125 OUString SAL_CALL
OResultSetMetaData::getColumnLabel(sal_Int32 column
)
127 checkColumnIndex(column
);
128 return getColumnName(column
);
131 OUString SAL_CALL
OResultSetMetaData::getColumnServiceName(sal_Int32
/*column*/)
136 sal_Bool SAL_CALL
OResultSetMetaData::isCurrency(sal_Int32
/*column*/)
138 return false; // TODO
141 sal_Bool SAL_CALL
OResultSetMetaData::isAutoIncrement(sal_Int32 column
)
143 checkColumnIndex(column
);
144 return (m_fields
.at(column
- 1).flags
& AUTO_INCREMENT_FLAG
) != 0;
147 sal_Bool SAL_CALL
OResultSetMetaData::isSigned(sal_Int32 column
)
149 checkColumnIndex(column
);
150 return !(m_fields
.at(column
- 1).flags
& UNSIGNED_FLAG
);
153 sal_Int32 SAL_CALL
OResultSetMetaData::getPrecision(sal_Int32 column
)
155 checkColumnIndex(column
);
156 return m_fields
.at(column
- 1).max_length
- m_fields
.at(column
- 1).decimals
;
159 sal_Int32 SAL_CALL
OResultSetMetaData::getScale(sal_Int32 column
)
161 checkColumnIndex(column
);
162 return m_fields
.at(column
- 1).decimals
;
165 sal_Int32 SAL_CALL
OResultSetMetaData::isNullable(sal_Int32 column
)
167 checkColumnIndex(column
);
168 return (m_fields
.at(column
- 1).flags
& NOT_NULL_FLAG
) ? 0 : 1;
171 sal_Bool SAL_CALL
OResultSetMetaData::isSearchable(sal_Int32 column
)
173 checkColumnIndex(column
);
177 sal_Bool SAL_CALL
OResultSetMetaData::isReadOnly(sal_Int32 column
)
179 checkColumnIndex(column
);
180 return m_fields
.at(column
- 1).schemaName
.isEmpty();
183 sal_Bool SAL_CALL
OResultSetMetaData::isDefinitelyWritable(sal_Int32 column
)
185 checkColumnIndex(column
);
186 return !isReadOnly(column
);
189 sal_Bool SAL_CALL
OResultSetMetaData::isWritable(sal_Int32 column
)
191 checkColumnIndex(column
);
192 return !isReadOnly(column
);
195 void OResultSetMetaData::checkColumnIndex(sal_Int32 columnIndex
)
197 auto nColCount
= m_fields
.size();
198 if (columnIndex
< 1 || columnIndex
> static_cast<sal_Int32
>(nColCount
))
200 OUString str
= "Column index out of range (expected 1 to "
201 + OUString::number(sal_Int32(nColCount
)) + ", got "
202 + OUString::number(columnIndex
) + ".";
203 throw SQLException(str
, *this, OUString(), 1, Any());
207 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */