1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 222: 223: 224: 225: 226: 227: 228: 229: 230: 231: 232: 233: 234: 235: 236: 237: 238: 239: 240: 241: 242: 243: 244: 245: 246: 247: 248: 249: 250: 251: 252: 253: 254: 255: 256: 257: 258: 259: 260: 261: 262: 263: 264: 265: 266: 267: 268: 269: 270: 271: 272: 273: 274: 275: 276: 277: 278: 279: 280: 281: 282: 283: 284: 285: 286: 287: 288: 289: 290: 291: 292: 293: 294: 295: 296: 297: 298: 299: 300: 301: 302: 303: 304: 305: 306: 307: 308: 309: 310: 311: 312: 313: 314: 315: 316: 317: 318: 319: 320: 321: 322: 323: 324: 325: 326: 327: 328: 329: 330: 331: 332: 333: 334: 335: 336: 337: 338: 339: 340: 341: 342: 343: 344: 345: 346: 347: 348: 349: 350: 351: 352: 353: 354: 355: 356: 357: 358: 359: 360: 361: 362: 363: 364: 365: 366: 367: 368: 369: 370: 371: 372: 373: 374: 375: 376: 377: 378: 379: 380: 381: 382: 383: 384: 385: 386: 387: 388: 389: 390: 391: 392: 393: 394: 395: 396: 397: 398: 399: 400: 401: 402: 403: 404: 405: 406: 407: 408: 409: 410: 411: 412: 413: 414: 415: 416: 417: 418: 419: 420: 421: 422: 423: 424: 425: 426: 427: 428: 429: 430: 431: 432: 433: 434: 435: 436: 437: 438: 439: 440: 441: 442: 443: 444: 445: 446: 447: 448: 449: 450: 451: 452: 453: 454: 455: 456: 457: 458: 459: 460: 461: 462: 463: 464: 465: 466: 467: 468: 469: 470: 471: 472: 473: 474: 475: 476: 477: 478: 479: 480: 481: 482: 483: 484: 485: 486: 487: 488: 489: 490: 491: 492: 493: 494: 495: 496: 497: 498: 499: 500: 501: 502: 503: 504: 505: 506: 507: 508: 509: 510: 511: 512: 513: 514: 515: 516: 517: 518: 519: 520: 521: 522: 523: 524: 525: 526: 527: 528: 529: 530: 531: 532: 533: 534: 535: 536: 537: 538: 539: 540: 541: 542: 543: 544: 545: 546: 547: 548: 549: 550: 551: 552: 553: 554: 555: 556: 557: 558: 559: 560: 561: 562: 563: 564: 565: 566: 567: 568: 569: 570: 571: 572: 573: 574: 575: 576: 577: 578: 579: 580: 581: 582: 583: 584: 585: 586: 587: 588: 589: 590: 591: 592: 593: 594: 595: 596: 597: 598: 599: 600: 601: 602: 603: 604: 605: 606: 607: 608: 609: 610: 611: 612: 613: 614: 615: 616: 617: 618: 619: 620: 621: 622: 623: 624: 625: 626: 627: 628: 629: 630: 631: 632: 633: 634: 635: 636: 637: 638: 639: 640: 641: 642: 643: 644: 645: 646: 647: 648: 649: 650: 651: 652: 653: 654: 655: 656: 657: 658: 659: 660: 661: 662: 663: 664: 665: 666: 667: 668: 669: 670: 671: 672: 673: 674: 675: 676: 677: 678: 679: 680: 681: 682: 683: 684: 685: 686: 687: 688: 689: 690: 691: 692: 693: 694: 695: 696: 697: 698: 699: 700: 701: 702: 703: 704: 705: 706: 707: 708: 709: 710: 711: 712: 713: 714: 715: 716: 717: 718: 719: 720: 721: 722: 723: 724: 725: 726: 727: 728: 729: 730: 731: 732: 733: 734: 735: 736: 737: 738: 739: 740: 741: 742: 743: 744: 745: 746: 747: 748: 749: 750: 751: 752: 753: 754: 755: 756: 757: 758: 759: 760: 761: 762: 763: 764: 765: 766: 767: 768: 769: 770: 771: 772: 773: 774: 775: 776: 777: 778: 779: 780: 781: 782: 783: 784: 785: 786: 787: 788: 789: 790: 791: 792: 793: 794: 795: 796: 797: 798: 799: 800: 801: 802: 803: 804: 805: 806: 807: 808: 809: 810: 811: 812: 813: 814: 815: 816: 817: 818: 819: 820: 821: 822: 823: 824: 825: 826: 827: 828: 829: 830: 831: 832: 833: 834: 835: 836: 837: 838: 839: 840: 841: 842: 843: 844: 845: 846: 847: 848: 849: 850: 851: 852: 853: 854: 855: 856: 857: 858: 859: 860: 861: 862: 863: 864: 865: 866: 867: 868: 869: 870: 871: 872: 873: 874: 875: 876: 877: 878: 879: 880: 881: 882: 883: 884: 885: 886: 887: 888: 889: 890: 891: 892: 893: 894: 895: 896: 897: 898: 899: 900: 901: 902: 903: 904: 905: 906: 907: 908: 909: 910: 911: 912: 913: 914: 915: 916: 917: 918: 919: 920: 921: 922: 923: 924: 925: 926: 927: 928: 929: 930: 931: 932: 933: 934: 935: 936: 937: 938: 939: 940: 941: 942: 943: 944: 945: 946: 947: 948: 949: 950: 951: 952: 953: 954: 955: 956: 957: 958: 959: 960: 961: 962: 963: 964: 965: 966: 967: 968: 969: 970: 971: 972: 973: 974: 975: 976: 977: 978: 979: 980: 981: 982: 983: 984: 985: 986: 987: 988: 989: 990: 991: 992: 993: 994: 995: 996: 997: 998: 999: 1000: 1001: 1002: 1003: 1004: 1005: 1006: 1007: 1008: 1009: 1010: 1011: 1012: 1013: 1014: 1015: 1016: 1017: 1018: 1019: 1020: 1021: 1022: 1023: 1024: 1025: 1026: 1027: 1028: 1029: 1030: 1031: 1032: 1033: 1034: 1035: 1036: 1037: 1038: 1039: 1040: 1041: 1042:
<?php
declare(strict_types=1);
/**
* +------------------------------------------------------------+
* | apnscp |
* +------------------------------------------------------------+
* | Copyright (c) Apis Networks |
* +------------------------------------------------------------+
* | Licensed under Artistic License 2.0 |
* +------------------------------------------------------------+
* | Author: Matt Saladna (msaladna@apisnetworks.com) |
* +------------------------------------------------------------+
*/
use Module\Support\Sql;
/**
* MySQL and PostgreSQL operations
*
* @xxx MODULE IS DEPRECATED. SEE MYSQL/PGSQL MODULES
*
* @package core
*/
class Sql_Module extends Sql
{
const MYSQL_USER_FIELD_SIZE = 16;
// maximum length of users - mysql compile-time constant
const PG_TEMP_PASSWORD = '23f!eoj3';
const MYSQL_DATADIR = '/var/lib/mysql';
const PGSQL_DATADIR = '/var/lib/pgsql';
const MIN_PASSWORD_LENGTH = 3;
// maximum number of simultaneous connections to a given DB
// higher increases the risk of monopolization
const PER_DATABASE_CONNECTION_LIMIT = 20;
/**
* @var int minimum db prefix length, to reduce collisions on server xfers
*/
const MIN_PREFIX_LENGTH = 3;
/* @ignore */
const MASTER_USER = 'root';
/**
* a bullshit constant to decide whether to
* up the ulimit fsize or not before exporting a db
*/
const DB_BIN2TXT_MULT = 1.5;
protected const PGSQL_PERMITTED_EXTENSIONS = ['pg_trgm', 'hstore'];
protected $exportedFunctions = [
'*' => PRIVILEGE_SITE,
'get_prefix' => PRIVILEGE_SITE | PRIVILEGE_USER,
'pgsql_version' => PRIVILEGE_ALL,
'mysql_version' => PRIVILEGE_ALL,
'version' => PRIVILEGE_ALL,
'get_mysql_uptime' => PRIVILEGE_ALL,
'assert_mysql_permissions' => PRIVILEGE_SITE | PRIVILEGE_SERVER_EXEC,
'get_pgsql_uptime' => PRIVILEGE_ALL,
'set_mysql_option' => PRIVILEGE_ALL,
'get_mysql_option' => PRIVILEGE_ALL,
'get_pgsql_username' => PRIVILEGE_ALL,
'get_pgsql_password' => PRIVILEGE_ALL,
'set_pgsql_password' => PRIVILEGE_ALL,
'export_mysql_pipe_real' => PRIVILEGE_SITE | PRIVILEGE_SERVER_EXEC,
'export_pgsql_pipe_real' => PRIVILEGE_SITE | PRIVILEGE_SERVER_EXEC,
'enabled' => PRIVILEGE_SITE | PRIVILEGE_USER,
'repair_mysql_database' => PRIVILEGE_SITE | PRIVILEGE_ADMIN,
// necessary for DB backup routines
'get_database_size' => PRIVILEGE_SITE | PRIVILEGE_ADMIN,
'mysql_database_exists' => PRIVILEGE_SITE | PRIVILEGE_ADMIN,
'pgsql_database_exists' => PRIVILEGE_SITE | PRIVILEGE_ADMIN,
'_export_mysql_old' => PRIVILEGE_SITE | PRIVILEGE_SERVER_EXEC,
];
/**
* {{{ void __construct(void)
*
* @ignore
*/
public function __construct()
{
parent::__construct();
if (!AUTH_ALLOW_DATABASE_CHANGE) {
$this->exportedFunctions['change_prefix'] = PRIVILEGE_NONE;
}
}
public function mysql_user_exists($user, $host = 'localhost')
{
return parent::__call('mysql_user_exists', [$user, $host]);
}
/**
* bool delete_mysql_user(string, string[, bool = false])
* Delete a MySQL user
*
* @param string $user username
* @param string $host hostname
* @param string $cascade revoke all privileges from databases
*/
public function delete_mysql_user($user, $host, $cascade = true)
{
return $this->mysql_delete_user($user, $host, $cascade);
}
public function pgsql_user_exists($user)
{
// tricky
return parent::__call('pgsql_user_exists', [$user]);
}
/**
* bool delete_pgsql_user(string[, bool = false])
* Delete a PostgreSQL user
*
* @param string $user username
* @param bool $cascade casecade delete
* @return bool
*/
public function delete_pgsql_user($user, $cascade = false)
{
return $this->pgsql_delete_user($user, $cascade);
}
// {{{ connect_mysql_root()
/**
* bool store_sql_password (string, string)
*
* @param string $sqlpasswd base64 encoded and encrypted password @{see encrypt_sql_password}
* @param string $type password type, where type is either "mysql" or "pgsql"
* @return bool
*/
public function store_sql_password($sqlpasswd, $type)
{
if ($type != 'mysql' && $type != 'postgresql' && $type != 'pgsql') {
return error($type . ': unrecognized type');
}
if ($type === 'postgresql') {
$type = 'pgsql';
}
$fn = "${type}_store_password";
return $this->$fn($sqlpasswd);
}
/**
* Set MySQL client option
*
* Reads from ~/.my.cnf and creates if necessary.
* Specify a value of null to remove an option.
*
* @param string $option
* @param string $value
* @param string $group
* @return bool
*/
public function set_mysql_option($option, $value = null, $group = 'client')
{
return $this->mysql_set_option($option, $value, $group);
}
public function set_pgsql_password($password)
{
return $this->pgsql_set_password($password);
}
public function set_pgsql_username($user)
{
return $this->pgsql_set_username($user);
}
public function get_pgsql_password($user = null)
{
return $this->pgsql_get_password($user);
}
/**
* Get option from MySQL client/server configuration
*
* @param string $option option name
* @param string $group option group
* @return mixed option value, false on failure, null on empty value
*/
public function get_mysql_option($option, $group = 'client')
{
return $this->mysql_get_option($option, $group);
}
public function get_elevated_password_backend()
{
return Opcenter\Database\MySQL::rootPassword();
}
/**
* bool mysql_import(string, string, string, strin)
*/
public function import_mysql($db, $file)
{
return $this->mysql_import($db, $file);
}
/**
* array list_mysql_databases ()
* Queries the db table in the mysql database for applicable grants
*
* @return array list of databases
*/
public function list_mysql_databases()
{
return $this->mysql_list_databases();
}
/**
* Change account database prefix
*
* @todo convert to module-specific
*
* @param string $prefix
* @return bool
*/
public function change_prefix($prefix)
{
if (!IS_CLI) {
return $this->query('sql_change_prefix', $prefix);
}
if ($this->auth_is_demo()) {
return error('cannot change prefix in demo mode');
}
$prefix = strtolower(rtrim($prefix, '_'));
$normalizedPrefix = $prefix . '_';
if (strlen($prefix) < static::MIN_PREFIX_LENGTH) {
return error("minimum acceptable db prefix length is `%d'", static::MIN_PREFIX_LENGTH);
} else if (!preg_match(Regex::compile(Regex::SQL_PREFIX, ['max' => 14]), $normalizedPrefix)) {
return error("invalid db prefix `%s'", $prefix);
}
if (\Opcenter\Map::load('mysql.prefixmap', 'r')->exists($normalizedPrefix)) {
return error("prefix `%s' already in use", $prefix);
}
$editor = new \Util_Account_Editor($this->getAuthContext()->getAccount(), $this->getAuthContext());
$editor->setConfig('mysql', 'dbaseprefix', $normalizedPrefix);
if ($this->pgsql_enabled()) {
$editor->setConfig('pgsql', 'dbaseprefix', $normalizedPrefix);
}
$status = $editor->edit();
if (!$status) {
return error('failed to change database prefix');
}
return $status;
}
public function get_sql_prefix()
{
deprecated('use sql_get_prefix');
return $this->get_prefix();
}
public function get_prefix()
{
return $this->getServiceValue('mysql', 'dbaseprefix');
}
/**
* array list_mysql_users ()
* Lists all created users for MySQL
*/
public function list_mysql_users()
{
return $this->mysql_list_users();
}
/**
* bool add_mysql_user(string, string, string[, int[, int[, int[, string[, string[, string[, string]]]]]]])
*/
public function add_mysql_user(
$user,
$host,
$password,
$maxconn = 5,
$maxupdates = 0,
$maxquery = 0,
$ssl = '',
$cipher = '',
$issuer = '',
$subject = ''
) {
return $this->mysql_add_user($user, $host, $password,
$maxconn, $maxupdates, $maxquery, $ssl, $cipher, $issuer, $subject);
}
public function get_mysql_database_charset($db)
{
return $this->mysql_get_database_charset($db);
}
/**
* Create a new mysql database
*
* @param string $db
* @param string $charset optional default charset
* @param string $collation optional default collation
* @return bool creation succeeded
*/
public function create_mysql_database($db, $charset = 'latin1', $collation = 'latin1_general_ci')
{
return $this->mysql_create_database($db);
}
public function mysql_charset_valid($charset)
{
return parent::__call('mysql_charset_valid', [$charset]);
}
public function get_supported_mysql_charsets()
{
return $this->mysql_get_supported_charsets();
}
/**
* Validate collation name
*
* @param string $collation
* @return bool
*/
public function mysql_collation_valid($collation)
{
return parent::__call('mysql_collation_valid', [$collation]);
}
public function get_supported_mysql_collations()
{
return $this->mysql_get_supported_collations();
}
/**
* Verify collation + charset combination are compatible
*
* @param string $collation
* @param string $charset
*
* @return bool
*/
public function mysql_collation_compatible($collation, $charset)
{
return parent::__call('mysql_collation_compatible', [$collation, $charset]);
}
/**
* Query information_schema for existence of MySQL database
*
* @param string $db database name
* @return bool
*/
public function mysql_database_exists($db)
{
return parent::__call('mysql_database_exists', [$db]);
}
/**
* bool add_mysql_user_permissions (string, string, string, array)
*
* @deprecated
* @see set_mysql_privileges()
*
* @param string $user
* @param string $host
* @param string $db
* @param array $opts
* @return bool
*/
public function add_mysql_user_permissions($user, $host, $db, array $opts)
{
deprecated_func('use set_mysql_privileges()');
return $this->set_mysql_privileges($user, $host, $db, $opts);
}
/**
* Set grants for a MySQL user
*
* @param string $user
* @param string $host
* @param string $db
* @param array $privileges
* @return bool
*/
public function set_mysql_privileges($user, $host, $db, array $privileges)
{
return $this->mysql_set_privileges($user, $host, $db, $privileges);
}
/**
*
* @deprecated
* @see revoke_from_mysql_db()
*/
public function delete_mysql_user_permissions($user, $host, $db)
{
deprecated_func('use revoke_from_mysql_db()');
return $this->revoke_from_mysql_db($user, $host, $db);
}
/**
* Revoke all privileges on a database from a MySQL user
*
* @param string $user
* @param string $host
* @param string $db
* @return bool
*/
public function revoke_from_mysql_db($user, $host, $db)
{
return $this->mysql_revoke_privileges($user, $host, $db);
}
// {{{ enabled()
public function get_mysql_user_permissions($user, $host, $db)
{
deprecated_func('use get_mysql_privileges()');
return $this->get_mysql_privileges($user, $host, $db);
}
// }}}
/**
* Get MySQL grants for a user on a database
*
* @param string $user
* @param string $host
* @param string $db
* @return array
*/
public function get_mysql_privileges($user, $host, $db)
{
return $this->mysql_get_privileges($user, $host, $db);
}
/**
* Returns the version of the MySQL server as an integer
*
* The form of this version number is
* main_version * 10000 + minor_version * 100 + sub_version
* (i.e. version 4.1.0 is 40100)
*
* @param $pretty bool pretty-print version
*
* @return int|string integer representing the server version or string
*/
public function mysql_version($pretty = false)
{
return parent::__call('mysql_version', [$pretty]);
}
/**
* Delete MySQL database from system
*
* @param string $db database
* @return bool
*/
public function delete_mysql_database($db)
{
return $this->mysql_delete_database($db);
}
/**
* Remove MySQL Backup
*
* @param string $db
* @return bool
*/
public function delete_mysql_backup($db)
{
return $this->mysql_delete_backup($db);
}
/**
* Ensure that /var/lib/mysql/ has mysql:<group id> ownership
*/
public function assert_mysql_permissions()
{
return $this->mysql_assert_permissions();
}
/**
* bool edit_mysql_user(string, string, array)
* Note when calling through SOAP, all options must be given, otherwise
* the will default to server preferences.
*
* @param string $user user
* @param string $host hostname
* @param array $opts array of options, valid indexes:
* host
* password
* max_user_connections
* max_updates
* max_questions
* use_ssl
* cipher_type
* ssl_cipher
* x509_subject
* x509_issuer
* @return bool query succeeded
*/
public function edit_mysql_user($user, $host, $opts)
{
return $this->mysql_edit_user($user, $host, $opts);
}
/**
* bool service_enabled (string)
*
* Checks to see if a service is enabled
*
* @deprecated @see enabled()
* @param string $service service name, either "pgsql" or "mysql"
* @return bool
*/
public function service_enabled($service)
{
deprecated('use enabled()');
return $this->enabled($service);
}
/**
* MySQL/PostgreSQL service enabled on account
*
* Checks to see if either MySQL or PostgreSQL is enabled on an account
*
* @param string $svc_name service name to check (mysql, pgsql)
* @return bool
*/
public function enabled($svc_name)
{
if ($svc_name != 'mysql' && $svc_name != 'postgresql' && $svc_name != 'pgsql') {
return error('Invalid service');
}
if ($svc_name == 'postgresql') {
$svc_name = 'pgsql';
}
$fn = "${svc_name}_enabled";
return $this->$fn();
}
/**
* bool add_pgsql_user(string, string[, int])
*/
public function add_pgsql_user($user, $password, $maxconn = 5)
{
return $this->pgsql_add_user($user, $password, $maxconn);
}
/**
* bool create_pgsql_database (string)
*
* @param string $db
* @return bool creation succeeded
*/
public function create_pgsql_database($db)
{
return $this->pgsql_create_database($db);
}
/**
* Query PostgreSQL system table for existence of database
*
* @param string $db database name
* @return bool
*/
public function pgsql_database_exists($db)
{
return parent::__call('pgsql_database_exists', [$db]);
}
/**
* void prep_tablespace ()
* Checks to see if tablespace exists, if not, creates it
*
* @private
*/
public function prep_tablespace()
{
return $this->pgsql_prep_tablespace();
}
public function add_pgsql_extension($db, $extension)
{
return $this->pgsql_add_extension($db, $extension);
}
/**
* array list_mysql_databases ()
* Queries the db table in the mysql database for applicable grants
*
* @return array list of databases
*/
public function list_pgsql_databases()
{
return $this->pgsql_list_databases();
}
/**
* bool add_pgsql_user_permissions (string, string, string, array)
* Add/removes privileges for a user to a table, any value listed as
* false or not supplied as an array key will revoke the privilege
*
* @param string $user
* @param string $db
* @param array $opts
*/
public function add_pgsql_user_permissions($user, $db, array $opts)
{
return error('Function not implemented in PostgreSQL');
}
public function delete_pgsql_user_permissions($user, $db)
{
return error('Function not implemented in PostgreSQL');
}
/**
* void get_pgsql_user_permissions(string, string)
* Function not implemented in PostgreSQL
*
* @return void
*/
public function get_pgsql_user_permissions($user, $db)
{
return error('Function not implemented in PostgreSQL');
}
/**
* bool delete_pgsql_database(string)
* Drops the database and revokes all permssions
*
* @param string $db
* @return bool drop succeeded
*/
public function delete_pgsql_database($db)
{
return $this->pgsql_delete_database($db);
}
/**
* Remove PostgreSQL Backup
*
* @param string $db
* @return bool
*/
public function delete_pgsql_backup($db)
{
return $this->pgsql_delete_backup($db);
}
/**
* Modify use password and connection limit
*
* NOTE: Not implemented with PostgreSQL, owner of database automatically
* receives grants. Varying degrees of grants impact the usability of
* this function, i.e. common grants [SELECT, INSERT, UPDATE, DELETE] exist
* solely on the table level, while [CREATE, TEMP] exist on the database
* level
*
* @param string $user user
* @param string $password
* @param int $maxconn connection limit
* @return bool query succeeded
*/
public function edit_pgsql_user($user, $password, $maxconn = null)
{
return $this->pgsql_edit_user($user, $password, $maxconn);
}
public function get_pgsql_username()
{
return $this->pgsql_get_username();
}
/**
* array list_pgsql_users ()
* Lists all created users for PostgreSQL
*
* @return array
*/
public function list_pgsql_users()
{
return $this->pgsql_list_users();
}
/**
* string pg_vacuum_db (string)
* Vacuums a database
*
* @return string vacuum output
*/
public function pg_vacuum_db($db)
{
return $this->pgsql_vacuum($db);
}
public function truncate_pgsql_database($db)
{
return $this->pgsql_truncate_database($db);
}
public function pgsql_version($pretty = false)
{
return parent::__call('pgsql_version', [$pretty]);
}
public function empty_pgsql_database($db)
{
return $this->pgsql_empty_database($db);
}
/**
* bool pgsql_import(string, string, string, strin)
*/
public function import_pgsql($db, $file)
{
return $this->pgsql_import($db, $file);
}
public function truncate_mysql_database($db)
{
return $this->mysql_truncate_database($db);
}
public function empty_mysql_database($db)
{
return $this->mysql_empty_database($db);
}
/**
* Export a MySQL database
*
* @param string $db
* @param string|null $file optional filename
* @return mixed path of export or false on failure
*/
public function export_mysql($db, $file = null)
{
return $this->mysql_export($db, $file);
}
// {{{ delete_mysql_backup()
/**
* Get disk space occupied by database
*
* @param string $type database type, "mysql" or "pgsql"
* @param string $db database name
* @return int storage in bytes
*/
public function get_database_size($type, $db)
{
$type = strtolower($type);
if ($type != 'mysql' && $type != 'postgresql' && $type != 'pgsql') {
return error($type . ': invalid database type');
}
if ($type === 'postgresql') {
$type = 'pgsql';
}
$fn = "${type}_get_database_size";
return $this->$fn($db);
}
// }}}
// {{{ get_mysql_backup_config()
/**
* Export a db to a named pipe for immediate download
*
* @param $db
* @return bool|void
*/
public function export_mysql_pipe($db)
{
return $this->mysql_export_pipe($db);
}
// }}}
// {{{ get_mysql_backup_config()
/**
* Export a database to a named pipe
*
* Differs from export_mysql_pipe in that it may only be called internally
* or from backend, no API access
*
* @param $db
* @param $user if empty use superuser
* @return bool|string
*/
public function export_mysql_pipe_real($db, $user)
{
return $this->mysql_export_pipe_real($db, $user);
}
// }}}
public function export_pgsql($db, $file = null)
{
return $this->pgsql_export($db, $file);
}
/**
* Export a PGSQL db to a named pipe for immediate download
*
* @param $db
* @return bool|void
*/
public function export_pgsql_pipe($db)
{
return $this->pgsql_export_pipe($db);
}
/**
* int get_pgsql_uptime
*
* @return int time in seconds
*/
public function get_pgsql_uptime()
{
return $this->pgsql_get_uptime();
}
/**
* int get_mysql_uptime
*
* @return int time in seconds
*/
public function get_mysql_uptime()
{
return $this->mysql_get_uptime();
}
// {{{ mysql_database_exists()
public function add_mysql_backup($db, $extension = 'zip', $span = 5, $preserve = '0', $email = '')
{
return $this->mysql_add_backup($db, $extension, $span, $preserve, $email);
}
public function add_pgsql_backup($db, $extension = 'zip', $span = 5, $preserve = '0', $email = '')
{
return $this->pgsql_add_backup($db, $extension, $span, $preserve, $email);
}
public function edit_mysql_backup($db, $extension, $span = '0', $preserve = '0', $email = '')
{
return $this->mysql_edit_backup($db, $extension, $span, $preserve, $email);
}
public function edit_pgsql_backup($db, $extension, $span = '0', $preserve = '0', $email = '')
{
return $this->pgsql_edit_backup($db, $extension, $span, $preserve, $email);
}
public function list_mysql_backups()
{
return $this->mysql_list_backups();
}
public function list_pgsql_backups()
{
return $this->pgsql_list_backups();
}
/**
* Fetch MySQL backup task information
*
* span => (integer) days between backups
* hold => (integer) number of backups to preserve
* next => (integer) unix timestamp of next backup
* ext => (string) extension of backup
* email => (string) notify address after backup
*
* @param string $db database name
* @return array
*/
public function get_mysql_backup_config($db)
{
return $this->mysql_get_backup_config($db);
}
/**
* Fetch backup information
*
* @see get_mysql_backup_config()
*
* @param string $db
* @return array
*/
public function get_pgsql_backup_config($db)
{
return $this->pgsql_get_backup_config($db);
}
public function repair_mysql_database($db)
{
return $this->mysql_repair_database($db);
}
/**
* Kill a mysql connection
*
* @link mysql_processlist
* @param integer $id
* @return bool
*/
public function mysql_kill($id)
{
return parent::__call('mysql_kill', [$id]);
}
/**
* Get active mysql connections
*
* Array
* (
* [0] => Array
* (
* [id] => 11024
* [user] => debug
* [host] => localhost
* [db] => debug
* [command] => Query
* [state] => User sleep
* [info] => select sleep(1000)
* )
* )
*
* @return array
*/
public function mysql_processlist()
{
return parent::__call('mysql_processlist');
}
/**
* Get max length of a column in mysql schema
*
* @param string $field
* @return int
*/
public function mysql_schema_column_maxlen($field)
{
return parent::__call('mysql_schema_column_maxlen', [$field]);
}
public function _delete()
{
// migrated to mysql/pgsql modules
}
public function _create()
{
}
public function _edit_user(string $userold, string $usernew, array $oldpwd)
{
if ($userold === $usernew) {
return;
}
}
public function _edit()
{
$conf = $this->getAuthContext()->getAccount();
// mysql and pgsql must retain the same dbaseadmin/dbaseprefix
$conf_old = $conf->old['mysql'];
$conf_new = $conf->new['mysql'];
if ($conf_new === $conf_old) {
return;
}
$prefixold = $conf_old['dbaseprefix'];
$prefixnew = $conf_new['dbaseprefix'];
$db = MySQL::initialize();
$re = Regex::compile(\Regex::SQL_PREFIX, ['max' => min(\Opcenter\Database\MySQL::fieldLength('db'), Pgsql_Module::IDENTIFIER_MAXLEN)]);
if ($prefixnew && !preg_match($re, $prefixnew)) {
return error("invalid database prefix `%s'", $prefixnew);
}
if ($prefixold !== $prefixnew && $prefixnew && $prefixold) {
$maxlen = self::MYSQL_USER_FIELD_SIZE - 3;
if (strlen($prefixnew) > $maxlen /* prefix + _xy */) {
return error('database prefix max length is %d', $maxlen);
}
$len = strlen($prefixold);
$q = "UPDATE sql_dumps SET db_name = CONCAT('" .
$db->escape_string($prefixnew) . "', SUBSTR(db_name, " . ($len + 1) . ')) WHERE ' .
'SUBSTR(db_name, 1, ' . $len . ") = '" . $db->escape_string($prefixold) . "';";
if (!$db->query($q)) {
$this->add_error('sql backup rename failed');
}
$this->renameDatabasePrefix($prefixold, $prefixnew);
$this->renameUserPrefix($prefixold, $prefixnew);
}
// update grants and db table
// v7.5 does this in dbaseadmin
if (!platform_is('7.5', '>=')) {
if ($conf_new['dbaseadmin'] !== $conf_old['dbaseadmin']) {
$this->renameUser($conf_old['dbaseadmin'], $conf_new['dbaseadmin']);
}
}
}
public function _verify_conf(\Opcenter\Service\ConfigurationContext $ctx): bool
{
return true;
}
public function _create_user(string $user)
{
}
public function _delete_user(string $user)
{
}
}