20#include <com/sun/star/sdbc/ResultSetType.hpp>
21#include <com/sun/star/sdbc/TransactionIsolation.hpp>
22#include <com/sun/star/sdbc/Deferrability.hpp>
23#include <com/sun/star/lang/XInitialization.hpp>
28#include <rtl/ustrbuf.hxx>
39static std::string
wild(
"%");
42 const std::vector<std::vector<Any>>& _rRows)
49 for (
const auto& rRow : _rRows)
58 xIni->initialize(aArgs);
61ODatabaseMetaData::ODatabaseMetaData(
OConnection& _rCon, MYSQL* pMySql)
62 : m_rConnection(_rCon)
75 return 2147483647L - 8;
90 SAL_WARN(
"connectivity.mysqlc",
"method not implemented");
100 SAL_WARN(
"connectivity.mysqlc",
"method not implemented");
114 SAL_WARN(
"connectivity.mysqlc",
"method not implemented");
121 SAL_WARN(
"connectivity.mysqlc",
"method not implemented");
128 SAL_WARN(
"connectivity.mysqlc",
"method not implemented");
136 SAL_WARN(
"connectivity.mysqlc",
"method not implemented");
143 SAL_WARN(
"connectivity.mysqlc",
"method not implemented");
150 SAL_WARN(
"connectivity.mysqlc",
"method not implemented");
259 SAL_WARN(
"connectivity.mysqlc",
"method not implemented");
353 Reference<XResultSet> rs = statement->executeQuery(
"select user()");
354 Reference<XRow> xRow(rs, UNO_QUERY_THROW);
357 OUString userWithConnection = xRow->getString(1);
358 sal_Int32 nIndexOfAt = userWithConnection.indexOf(
"@");
361 OUString user = userWithConnection.copy(0, nIndexOfAt);
364 return userWithConnection;
373 return OStringToOUString(mysql_get_server_info(
m_pMySql),
386 SAL_WARN(
"connectivity.mysqlc",
"method not implemented");
387 return MARIADBC_VERSION_MAJOR;
392 return TransactionIsolation::REPEATABLE_READ;
398 SAL_WARN(
"connectivity.mysqlc",
"method not implemented");
399 return MARIADBC_VERSION_MINOR;
404 return "ACCESSIBLE, ADD, ALL,"
405 "ALTER, ANALYZE, AND, AS, ASC, ASENSITIVE, BEFORE,"
406 "BETWEEN, BIGINT, BINARY, BLOB, BOTH, BY, CALL,"
407 "CASCADE, CASE, CHANGE, CHAR, CHARACTER, CHECK,"
408 "COLLATE, COLUMN, CONDITION, CONNECTION, CONSTRAINT,"
409 "CONTINUE, CONVERT, CREATE, CROSS, CURRENT_DATE,"
410 "CURRENT_TIME, CURRENT_TIMESTAMP, CURRENT_USER, CURSOR,"
411 "DATABASE, DATABASES, DAY_HOUR, DAY_MICROSECOND,"
412 "DAY_MINUTE, DAY_SECOND, DEC, DECIMAL, DECLARE,"
413 "DEFAULT, DELAYED, DELETE, DESC, DESCRIBE,"
414 "DETERMINISTIC, DISTINCT, DISTINCTROW, DIV, DOUBLE,"
415 "DROP, DUAL, EACH, ELSE, ELSEIF, ENCLOSED,"
416 "ESCAPED, EXISTS, EXIT, EXPLAIN, FALSE, FETCH,"
417 "FLOAT, FLOAT4, FLOAT8, FOR, FORCE, FOREIGN, FROM,"
418 "FULLTEXT, GRANT, GROUP, HAVING, HIGH_PRIORITY,"
419 "HOUR_MICROSECOND, HOUR_MINUTE, HOUR_SECOND, IF,"
420 "IGNORE, IN, INDEX, INFILE, INNER, INOUT,"
421 "INSENSITIVE, INSERT, INT, INT1, INT2, INT3, INT4,"
422 "INT8, INTEGER, INTERVAL, INTO, IS, ITERATE, JOIN,"
423 "KEY, KEYS, KILL, LEADING, LEAVE, LEFT, LIKE,"
424 "LOCALTIMESTAMP, LOCK, LONG, LONGBLOB, LONGTEXT,"
425 "LOOP, LOW_PRIORITY, MATCH, MEDIUMBLOB, MEDIUMINT,"
426 "MEDIUMTEXT, MIDDLEINT, MINUTE_MICROSECOND,"
427 "MINUTE_SECOND, MOD, MODIFIES, NATURAL, NOT,"
428 "NO_WRITE_TO_BINLOG, NULL, NUMERIC, ON, OPTIMIZE,"
429 "OPTION, OPTIONALLY, OR, ORDER, OUT, OUTER,"
430 "OUTFILE, PRECISION, PRIMARY, PROCEDURE, PURGE,"
431 "RANGE, READ, READS, READ_ONLY, READ_WRITE, REAL,"
432 "REFERENCES, REGEXP, RELEASE, RENAME, REPEAT,"
433 "REPLACE, REQUIRE, RESTRICT, RETURN, REVOKE, RIGHT,"
434 "RLIKE, SCHEMA, SCHEMAS, SECOND_MICROSECOND, SELECT,"
435 "SENSITIVE, SEPARATOR, SET, SHOW, SMALLINT, SPATIAL,"
436 "SPECIFIC, SQL, SQLEXCEPTION, SQLSTATE, SQLWARNING,"
437 "SQL_BIG_RESULT, SQL_CALC_FOUND_ROWS, SQL_SMALL_RESULT,"
438 "SSL, STARTING, STRAIGHT_JOIN, TABLE, TERMINATED,"
439 "THEN, TINYBLOB, TINYINT, TINYTEXT, TO, TRAILING,"
440 "TRIGGER, TRUE, UNDO, UNION, UNIQUE, UNLOCK,"
441 "UNSIGNED, UPDATE, USAGE, USE, USING, UTC_DATE,"
442 "UTC_TIME, UTC_TIMESTAMP, VALUES, VARBINARY, VARCHAR,"
443 "VARCHARACTER, VARYING, WHEN, WHERE, WHILE, WITH,"
444 "WRITE, X509, XOR, YEAR_MONTH, ZEROFILL"
445 "GENERAL, IGNORE_SERVER_IDS, MASTER_HEARTBEAT_PERIOD,"
446 "MAXVALUE, RESIGNAL, SIGNAL, SLOW";
453 return "ASCII,BIN,BIT_LENGTH,CHAR,CHARACTER_LENGTH,CHAR_LENGTH,CONCAT,"
454 "CONCAT_WS,CONV,ELT,EXPORT_SET,FIELD,FIND_IN_SET,HEX,INSERT,"
455 "INSTR,LCASE,LEFT,LENGTH,LOAD_FILE,LOCATE,LOCATE,LOWER,LPAD,"
456 "LTRIM,MAKE_SET,MATCH,MID,OCT,OCTET_LENGTH,ORD,POSITION,"
457 "QUOTE,REPEAT,REPLACE,REVERSE,RIGHT,RPAD,RTRIM,SOUNDEX,"
458 "SPACE,STRCMP,SUBSTRING,SUBSTRING,SUBSTRING,SUBSTRING,"
459 "SUBSTRING_INDEX,TRIM,UCASE,UPPER";
464 return "DAYOFWEEK,WEEKDAY,DAYOFMONTH,DAYOFYEAR,MONTH,DAYNAME,"
465 "MONTHNAME,QUARTER,WEEK,YEAR,HOUR,MINUTE,SECOND,PERIOD_ADD,"
466 "PERIOD_DIFF,TO_DAYS,FROM_DAYS,DATE_FORMAT,TIME_FORMAT,"
467 "CURDATE,CURRENT_DATE,CURTIME,CURRENT_TIME,NOW,SYSDATE,"
468 "CURRENT_TIMESTAMP,UNIX_TIMESTAMP,FROM_UNIXTIME,"
469 "SEC_TO_TIME,TIME_TO_SEC";
474 return "DATABASE,USER,SYSTEM_USER,"
475 "SESSION_USER,PASSWORD,ENCRYPT,LAST_INSERT_ID,VERSION";
480 return "ABS,ACOS,ASIN,ATAN,ATAN2,BIT_COUNT,CEILING,COS,"
481 "COT,DEGREES,EXP,FLOOR,LOG,LOG10,MAX,MIN,MOD,PI,POW,"
482 "POWER,RADIANS,RAND,ROUND,SIN,SQRT,TAN,TRUNCATE";
505 return setType == ResultSetType::SCROLL_SENSITIVE;
554 const char*
const table_types[] = {
"TABLE",
"VIEW" };
555 sal_Int32
const requiredVersion[] = { 0, 50000 };
558 "org.openoffice.comp.helper.DatabaseMetaDataResultSet"),
560 std::vector<std::vector<Any>> rRows;
563 for (sal_uInt32
i = 0;
i < 2;
i++)
578 "org.openoffice.comp.helper.DatabaseMetaDataResultSet"),
581 std::vector<std::vector<Any>> rRows;
598 Any(sal_Int32(0)),
Any(sal_Int32(10)) } });
610 "org.openoffice.comp.helper.DatabaseMetaDataResultSet"),
618 "org.openoffice.comp.helper.DatabaseMetaDataResultSet"),
620 std::vector<std::vector<Any>> rRows;
623 Reference<XInterface> executed = statement->executeQuery(
624 u"SELECT SCHEMA_NAME AS TABLE_SCHEM, CATALOG_NAME AS TABLE_CATALOG FROM INFORMATION_SCHEMA.SCHEMATA \
625 WHERE SCHEMA_NAME NOT IN ('information_schema', 'mysql', 'performance_schema') \
626 ORDER BY SCHEMA_NAME");
627 Reference<XResultSet> rs(executed, UNO_QUERY_THROW);
628 Reference<XResultSetMetaDataSupplier> supp(executed, UNO_QUERY_THROW);
629 Reference<XResultSetMetaData> rs_meta = supp->getMetaData();
631 Reference<XRow> xRow(rs, UNO_QUERY_THROW);
632 sal_uInt32 columns = rs_meta->getColumnCount();
635 std::vector<Any> aRow{
Any() };
636 for (sal_uInt32
i = 1;
i <= columns;
i++)
638 OUString columnStringValue = xRow->getString(
i);
639 aRow.push_back(
Any(columnStringValue));
641 rRows.push_back(aRow);
650 const OUString& table,
651 const OUString& columnNamePattern)
653 OUString
query(
"SELECT TABLE_CATALOG AS TABLE_CAT, TABLE_SCHEMA AS "
654 "TABLE_SCHEM, TABLE_NAME, COLUMN_NAME, NULL AS GRANTOR, "
655 "GRANTEE, PRIVILEGE_TYPE AS PRIVILEGE, IS_GRANTABLE FROM "
656 "INFORMATION_SCHEMA.COLUMN_PRIVILEGES WHERE TABLE_SCHEMA LIKE "
657 "'?' AND TABLE_NAME='?' AND COLUMN_NAME LIKE '?' ORDER BY "
658 "COLUMN_NAME, PRIVILEGE_TYPE");
662 query =
query.replaceFirst(
"?", columnNamePattern);
665 Reference<XResultSet> rs = statement->executeQuery(
query);
670 const OUString& schemaPattern,
671 const OUString& tableNamePattern,
672 const OUString& columnNamePattern)
674 OUStringBuffer queryBuf(
"SELECT TABLE_CATALOG, "
680 "CHARACTER_MAXIMUM_LENGTH, "
681 "NUMERIC_PRECISION, "
683 "NUMERIC_SCALE AS DECIMAL_DIGITS, "
686 "COLUMN_COMMENT AS REMARKS, "
687 "COLUMN_DEFAULT AS COLUMN_DEF,"
688 "CHARACTER_OCTET_LENGTH, "
692 "FROM INFORMATION_SCHEMA.COLUMNS "
694 if (!tableNamePattern.isEmpty())
697 if (tableNamePattern.match(
"%"))
698 sAppend =
"AND TABLE_NAME LIKE '%' ";
700 sAppend =
"AND TABLE_NAME = '%' ";
701 queryBuf.append(sAppend.replaceAll(
"%", tableNamePattern));
703 if (!schemaPattern.isEmpty())
706 if (schemaPattern.match(
"%"))
707 sAppend =
"AND TABLE_SCHEMA LIKE '%' ";
709 sAppend =
"AND TABLE_SCHEMA = '%' ";
710 queryBuf.append(sAppend.replaceAll(
"%", schemaPattern));
712 if (!columnNamePattern.isEmpty())
715 if (columnNamePattern.match(
"%"))
716 sAppend =
"AND COLUMN_NAME LIKE '%' ";
718 sAppend =
"AND COLUMN_NAME = '%' ";
719 queryBuf.append(sAppend.replaceAll(
"%", columnNamePattern));
722 OUString
query = queryBuf.makeStringAndClear();
724 Reference<XResultSet> rs = statement->executeQuery(
query);
725 Reference<XRow> xRow(rs, UNO_QUERY_THROW);
728 "org.openoffice.comp.helper.DatabaseMetaDataResultSet"),
730 std::vector<std::vector<Any>> aRows;
733 std::vector<Any> aRow{
Any() };
736 aRow.push_back(
Any(xRow->getString(1)));
738 aRow.push_back(
Any(xRow->getString(2)));
740 aRow.push_back(
Any(xRow->getString(3)));
742 aRow.push_back(
Any(xRow->getString(4)));
744 OUString sDataType = xRow->getString(5);
747 aRow.push_back(
Any(sDataType));
749 sal_Int32 nColumnSize = 0;
750 OUString sColumnType = xRow->getString(14);
751 sal_Int32 nCharMaxLen = xRow->getShort(6);
752 bool bIsCharMax = !xRow->wasNull();
753 if (sDataType.equalsIgnoreAsciiCase(
"year"))
755 else if (sDataType.equalsIgnoreAsciiCase(
"date"))
757 else if (sDataType.equalsIgnoreAsciiCase(
"time"))
759 else if (sDataType.equalsIgnoreAsciiCase(
"datetime")
760 || sDataType.equalsIgnoreAsciiCase(
"timestamp"))
762 else if (!bIsCharMax)
763 nColumnSize = xRow->getShort(7);
765 nColumnSize = nCharMaxLen;
766 aRow.push_back(
Any(nColumnSize));
767 aRow.push_back(
Any());
769 aRow.push_back(
Any(xRow->getShort(8)));
771 aRow.push_back(
Any(sal_Int32(10)));
773 OUString sIsNullable = xRow->getString(13);
775 aRow.push_back(
Any(ColumnValue::NULLABLE_UNKNOWN));
776 else if (sIsNullable.equalsIgnoreAsciiCase(
"YES"))
777 aRow.push_back(
Any(ColumnValue::NULLABLE));
779 aRow.push_back(
Any(ColumnValue::NO_NULLS));
781 aRow.push_back(
Any(xRow->getString(9)));
783 aRow.push_back(
Any(xRow->getString(10)));
785 aRow.push_back(
Any{});
786 aRow.push_back(
Any{});
789 aRow.push_back(
Any(xRow->getString(11)));
791 aRow.push_back(
Any(xRow->getString(12)));
793 aRow.push_back(
Any(sIsNullable));
794 aRows.push_back(aRow);
801 const OUString& schemaPattern,
802 const OUString& tableNamePattern,
803 const Sequence<OUString>& types)
805 OUStringBuffer buffer{
806 "SELECT TABLE_CATALOG AS TABLE_CAT, TABLE_SCHEMA AS TABLE_SCHEM, TABLE_NAME,"
807 "IF(STRCMP(TABLE_TYPE,'BASE TABLE'), TABLE_TYPE, 'TABLE') AS TABLE_TYPE, TABLE_COMMENT AS "
809 "FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA NOT IN ('information_schema', 'mysql', "
810 "'performance_schema') AND TABLE_SCHEMA LIKE '?' AND TABLE_NAME LIKE '?' "
813 if (types.getLength() == 1)
815 buffer.append(
"AND TABLE_TYPE LIKE '" + types[0] +
"'");
817 else if (types.getLength() > 1)
819 buffer.append(
"AND (TABLE_TYPE LIKE '" + types[0] +
"'");
820 for (sal_Int32 i = 1;
i < types.getLength(); ++
i)
822 buffer.append(
" OR TABLE_TYPE LIKE '" + types[i] +
"'");
827 buffer.append(
" ORDER BY TABLE_TYPE, TABLE_SCHEMA, TABLE_NAME");
828 OUString
query = buffer.makeStringAndClear();
832 query =
query.replaceFirst(
"?", schemaPattern);
833 query =
query.replaceFirst(
"?", tableNamePattern);
841 const Any& ,
const OUString& ,
842 const OUString& ,
const OUString& )
854 "org.openoffice.comp.helper.DatabaseMetaDataResultSet"),
856 std::vector<std::vector<Any>> rRows;
858 SAL_WARN(
"connectivity.mysqlc",
"method not implemented");
868 "org.openoffice.comp.helper.DatabaseMetaDataResultSet"),
870 std::vector<std::vector<Any>> rRows;
880 "org.openoffice.comp.helper.DatabaseMetaDataResultSet"),
882 std::vector<std::vector<Any>> rRows;
884 SAL_WARN(
"connectivity.mysqlc",
"method not implemented");
890 const OUString& schema,
891 const OUString& table)
894 "org.openoffice.comp.helper.DatabaseMetaDataResultSet"),
897 OUString
query(
"SELECT refi.CONSTRAINT_CATALOG,"
899 " refi.UNIQUE_CONSTRAINT_CATALOG,"
900 " k.REFERENCED_TABLE_SCHEMA,"
901 " refi.REFERENCED_TABLE_NAME,"
902 " k.REFERENCED_COLUMN_NAME,"
903 " refi.UPDATE_RULE, refi.DELETE_RULE,"
904 " refi.CONSTRAINT_NAME, "
906 " refi.CONSTRAINT_SCHEMA "
907 " FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS as refi"
908 " INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE as k ON k.CONSTRAINT_NAME = "
909 "refi.CONSTRAINT_NAME "
910 " and k.TABLE_NAME = refi.TABLE_NAME "
911 " WHERE k.REFERENCED_TABLE_SCHEMA LIKE "
912 "'?' AND refi.TABLE_NAME='?'");
916 std::vector<std::vector<Any>> aRows;
918 Reference<XResultSet> rs = statement->executeQuery(
query);
919 Reference<XRow> xRow(rs, UNO_QUERY_THROW);
923 std::vector<Any> aRow{
Any() };
926 aRow.push_back(
Any(xRow->getString(3)));
928 aRow.push_back(
Any(xRow->getString(4)));
930 aRow.push_back(
Any(xRow->getString(5)));
932 aRow.push_back(
Any(xRow->getString(6)));
935 aRow.push_back(
Any(xRow->getString(1)));
937 aRow.push_back(
Any(xRow->getString(11)));
939 aRow.push_back(
Any(xRow->getString(10)));
941 aRow.push_back(
Any(xRow->getString(2)));
943 aRow.push_back(
Any(sal_Int32{ 0 }));
945 aRow.push_back(
Any(xRow->getShort(7)));
947 aRow.push_back(
Any(xRow->getShort(8)));
949 aRow.push_back(
Any(xRow->getString(9)));
951 aRow.push_back(
Any(OUString{}));
953 aRow.push_back(
Any(Deferrability::NONE));
954 aRows.push_back(aRow);
961 const OUString& schema,
962 const OUString& table)
964 OUString
query(
"SELECT TABLE_CATALOG AS TABLE_CAT, TABLE_SCHEMA "
965 "AS TABLE_SCHEM, TABLE_NAME, "
966 "COLUMN_NAME, SEQ_IN_INDEX AS KEY_SEQ,"
967 "INDEX_NAME AS PK_NAME FROM INFORMATION_SCHEMA.STATISTICS "
968 "WHERE TABLE_SCHEMA LIKE '?' AND TABLE_NAME LIKE '?' AND INDEX_NAME='PRIMARY' "
969 "ORDER BY TABLE_SCHEMA, TABLE_NAME, INDEX_NAME, SEQ_IN_INDEX");
977 Reference<XResultSet> rs = statement->executeQuery(
query);
988 "org.openoffice.comp.helper.DatabaseMetaDataResultSet"),
990 std::vector<std::vector<Any>> rRows;
992 SAL_WARN(
"connectivity.mysqlc",
"method not implemented");
1004 "org.openoffice.comp.helper.DatabaseMetaDataResultSet"),
1006 std::vector<std::vector<Any>> rRows;
1008 SAL_WARN(
"connectivity.mysqlc",
"method not implemented");
1014 const Any& ,
const OUString& ,
const OUString& )
1017 SAL_WARN(
"connectivity.mysqlc",
"method not implemented");
1018 throw SQLException(
"getTablePrivileges method not implemented", *
this,
"IM001", 0,
Any());
1022 const Any& ,
const OUString& ,
1023 const OUString& ,
const Any& ,
1024 const OUString& ,
const OUString& )
1027 "org.openoffice.comp.helper.DatabaseMetaDataResultSet"),
1029 std::vector<std::vector<Any>> rRows;
1031 SAL_WARN(
"connectivity.mysqlc",
"method not implemented");
1039 const Sequence<sal_Int32>& )
HRESULT createInstance(REFIID iid, Ifc **ppIfc)
const ConnectionSettings & getConnectionSettings() const
rtl_TextEncoding getConnectionEncoding() const
css::uno::Reference< css::sdbc::XStatement > SAL_CALL createStatement() override
sal_Int32 getMysqlVersion()
#define SAL_WARN(area, stream)
TypeInfoDef const mysqlc_types[]
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
OUString convert(const ::std::string &_string, const rtl_TextEncoding encoding)
sal_Int32 mysqlStrToOOOType(std::u16string_view sType)
void throwFeatureNotImplementedException(const char *_pAsciiFeatureName, const css::uno::Reference< XInterface > &_rxContext)
sal_Int32 toInt32(std::u16string_view str, sal_Int16 radix=10)
store_handle_type *SAL_CALL query(OStoreObject *pHandle, store_handle_type *)