From e177462c901cd29c3e423640a6f538a930c29536 Mon Sep 17 00:00:00 2001 From: Klaus Weidenbach Date: Sat, 9 Dec 2017 00:31:09 +0100 Subject: :white_check_mark: Unit Test for \DBA factory. --- tests/unit/includes/dba/DBATest.php | 67 +++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 tests/unit/includes/dba/DBATest.php diff --git a/tests/unit/includes/dba/DBATest.php b/tests/unit/includes/dba/DBATest.php new file mode 100644 index 000000000..900d13083 --- /dev/null +++ b/tests/unit/includes/dba/DBATest.php @@ -0,0 +1,67 @@ +assertNull(\DBA::$dba); + + $ret = \DBA::dba_factory('server', 'port', 'user', 'pass', 'db', '0'); + $this->assertInstanceOf('dba_pdo', $ret); + $this->assertFalse($ret->connected); + + $this->assertSame('mysql', \DBA::$scheme); + $this->assertSame('schema_mysql.sql', \DBA::$install_script); + $this->assertSame('0001-01-01 00:00:00', \DBA::$null_date); + $this->assertSame('UTC_TIMESTAMP()', \DBA::$utc_now); + $this->assertSame('`', \DBA::$tquot); + } + + public function testDbaFactoryPostgresql() { + $this->assertNull(\DBA::$dba); + + $ret = \DBA::dba_factory('server', 'port', 'user', 'pass', 'db', '1'); + $this->assertInstanceOf('dba_pdo', $ret); + $this->assertFalse($ret->connected); + + $this->assertSame('pgsql', \DBA::$scheme); + $this->assertSame('schema_postgres.sql', \DBA::$install_script); + $this->assertSame('0001-01-01 00:00:00', \DBA::$null_date); + $this->assertSame("now() at time zone 'UTC'", \DBA::$utc_now); + $this->assertSame('"', \DBA::$tquot); + } + +} -- cgit v1.2.3 From fb111e6d958fdf56352db66e144134241abbacf8 Mon Sep 17 00:00:00 2001 From: Klaus Weidenbach Date: Sun, 10 Dec 2017 01:29:49 +0100 Subject: :white_check_mark: Unit Test for dba_pdo driver class. --- tests/phpunit-pgsql.xml | 10 ++ tests/phpunit.xml.dist | 10 ++ tests/travis/prepare_mysql.sh | 4 +- tests/travis/prepare_pgsql.sh | 9 +- tests/unit/DatabaseTestCase.php | 68 ++++++++++++ tests/unit/includes/dba/_files/account.yml | 9 ++ tests/unit/includes/dba/dba_pdoTest.php | 167 +++++++++++++++++++++++++++++ 7 files changed, 273 insertions(+), 4 deletions(-) create mode 100644 tests/unit/DatabaseTestCase.php create mode 100644 tests/unit/includes/dba/_files/account.yml create mode 100644 tests/unit/includes/dba/dba_pdoTest.php diff --git a/tests/phpunit-pgsql.xml b/tests/phpunit-pgsql.xml index ec4a6fc2d..d95c4897b 100644 --- a/tests/phpunit-pgsql.xml +++ b/tests/phpunit-pgsql.xml @@ -32,4 +32,14 @@ highLowerBound="70"/> + + + + + + + + + diff --git a/tests/phpunit.xml.dist b/tests/phpunit.xml.dist index a22317b08..7b9c1d563 100644 --- a/tests/phpunit.xml.dist +++ b/tests/phpunit.xml.dist @@ -35,4 +35,14 @@ highLowerBound="70"/> + + + + + + + + + diff --git a/tests/travis/prepare_mysql.sh b/tests/travis/prepare_mysql.sh index 095ad7e25..9fd79c1ab 100755 --- a/tests/travis/prepare_mysql.sh +++ b/tests/travis/prepare_mysql.sh @@ -42,8 +42,8 @@ mysql $PROTO -e "SELECT @@sql_mode;" # Create Hubzilla database mysql $PROTO -u root -e "CREATE DATABASE IF NOT EXISTS hubzilla;"; -mysql $PROTO -u root -e "CREATE USER 'hubzilla'@'localhost' IDENTIFIED BY 'hubzilla';" -mysql $PROTO -u root -e "GRANT ALL ON hubzilla.* TO 'hubzilla'@'localhost';" +mysql $PROTO -u root -e "CREATE USER 'hubzilla'@'%' IDENTIFIED BY 'hubzilla';" +mysql $PROTO -u root -e "GRANT ALL ON hubzilla.* TO 'hubzilla'@'%';" # Import table structure mysql $PROTO -u root hubzilla < ./install/schema_mysql.sql diff --git a/tests/travis/prepare_pgsql.sh b/tests/travis/prepare_pgsql.sh index 63c7388cb..3c38ef60c 100755 --- a/tests/travis/prepare_pgsql.sh +++ b/tests/travis/prepare_pgsql.sh @@ -34,10 +34,15 @@ psql -U postgres -c "SELECT VERSION();" # Create Hubzilla database psql -U postgres -c "DROP DATABASE IF EXISTS hubzilla;" -psql -U postgres -c "CREATE DATABASE hubzilla;" +psql -U postgres -v ON_ERROR_STOP=1 <<-EOSQL + CREATE USER hubzilla WITH PASSWORD 'hubzilla'; + CREATE DATABASE hubzilla; + ALTER DATABASE hubzilla OWNER TO hubzilla; + GRANT ALL PRIVILEGES ON DATABASE hubzilla TO hubzilla; +EOSQL # Import table structure -psql -U postgres -v ON_ERROR_STOP=1 hubzilla < ./install/schema_postgres.sql +psql -U hubzilla -v ON_ERROR_STOP=1 hubzilla < ./install/schema_postgres.sql # Show databases and tables psql -U postgres -l diff --git a/tests/unit/DatabaseTestCase.php b/tests/unit/DatabaseTestCase.php new file mode 100644 index 000000000..18c1cfb17 --- /dev/null +++ b/tests/unit/DatabaseTestCase.php @@ -0,0 +1,68 @@ +conn === null) { + if (self::$pdo === null) { + $dsn = \getenv('hz_db_scheme') . ':host=' . \getenv('hz_db_server') + . ';port=' . \getenv('hz_db_port') . ';dbname=' . \getenv('hz_db_database'); + + self::$pdo = new \PDO($dsn, \getenv('hz_db_user'), \getenv('hz_db_pass')); + } + $this->conn = $this->createDefaultDBConnection(self::$pdo, \getenv('hz_db_database')); + } + + return $this->conn; + } +} diff --git a/tests/unit/includes/dba/_files/account.yml b/tests/unit/includes/dba/_files/account.yml new file mode 100644 index 000000000..344bdb799 --- /dev/null +++ b/tests/unit/includes/dba/_files/account.yml @@ -0,0 +1,9 @@ +account: + - + account_id: 42 + account_email: "hubzilla@example.com" + account_language: "no" + - + account_id: 43 + account_email: "hubzilla@example.org" + account_language: "de" diff --git a/tests/unit/includes/dba/dba_pdoTest.php b/tests/unit/includes/dba/dba_pdoTest.php new file mode 100644 index 000000000..ce6e1ffd6 --- /dev/null +++ b/tests/unit/includes/dba/dba_pdoTest.php @@ -0,0 +1,167 @@ +dba = new \dba_pdo( + \getenv('hz_db_server'), + \getenv('hz_db_scheme'), + \getenv('hz_db_port'), + \getenv('hz_db_user'), + \getenv('hz_db_pass'), + \getenv('hz_db_database') + ); + } + protected function assertPreConditions() { + $this->assertSame('pdo', $this->dba->getdriver(), "Driver is expected to be 'pdo'."); + $this->assertInstanceOf('dba_driver', $this->dba); + $this->assertTrue($this->dba->connected, 'Pre condition failed, DB is not connected.'); + $this->assertInstanceOf('PDO', $this->dba->db); + } + protected function tearDown() { + $this->dba = null; + } + + + /** + * @group mysql + */ + public function testQuoteintervalOnMysql() { + $this->assertSame('value', $this->dba->quote_interval('value')); + } + /** + * @group postgresql + */ + public function testQuoteintervalOnPostgresql() { + $this->assertSame("'value'", $this->dba->quote_interval('value')); + } + + /** + * @group mysql + */ + public function testGenerateMysqlConcatSql() { + $this->assertSame('GROUP_CONCAT(DISTINCT field SEPARATOR \';\')', $this->dba->concat('field', ';')); + $this->assertSame('GROUP_CONCAT(DISTINCT field2 SEPARATOR \' \')', $this->dba->concat('field2', ' ')); + } + /** + * @group postgresql + */ + public function testGeneratePostgresqlConcatSql() { + $this->assertSame('string_agg(field,\';\')', $this->dba->concat('field', ';')); + $this->assertSame('string_agg(field2,\' \')', $this->dba->concat('field2', ' ')); + } + + + public function testConnectToSqlServer() { + // connect() is done in dba_pdo constructor which is called in setUp() + $this->assertTrue($this->dba->connected); + } + + /** + * @depends testConnectToSqlServer + */ + public function testCloseSqlServerConnection() { + $this->dba->close(); + + $this->assertNull($this->dba->db); + $this->assertFalse($this->dba->connected); + } + + /** + * @depends testConnectToSqlServer + */ + public function testSelectQueryShouldReturnArray() { + $ret = $this->dba->q('SELECT * FROM account'); + + $this->assertTrue(is_array($ret)); + } + + /** + * @depends testConnectToSqlServer + */ + public function testInsertQueryShouldReturnPdostatement() { + // Fixture account.yml adds two entries to account table + $this->assertEquals(2, $this->getConnection()->getRowCount('account'), 'Pre-Condition'); + + $ret = $this->dba->q('INSERT INTO account + (account_id, account_email, account_language) + VALUES (100, \'insert@example.com\', \'de\') + '); + $this->assertInstanceOf('PDOStatement', $ret); + + $this->assertEquals(3, $this->getConnection()->getRowCount('account'), 'Inserting failed'); + } + + + public function testConnectToWrongSqlServer() { + $nodba = new \dba_pdo('wrongserver', + \getenv('hz_db_scheme'), \getenv('hz_db_port'), + \getenv('hz_db_user'), \getenv('hz_db_pass'), + \getenv('hz_db_database') + ); + + $this->assertSame('pdo', $nodba->getdriver()); + $this->assertInstanceOf('dba_pdo', $nodba); + $this->assertFalse($nodba->connected); + $this->assertNull($nodba->db); + + $this->assertFalse($nodba->q('SELECT * FROM account')); + } + +} -- cgit v1.2.3 From 509844fd7e08ebccec4d924845d0f2a60f5768e5 Mon Sep 17 00:00:00 2001 From: Klaus Weidenbach Date: Fri, 8 Dec 2017 00:26:00 +0100 Subject: :fire: Cleanup old database related files. Remove non used database drivers, remove unused methods. Improve documentation. --- include/dba/dba_driver.php | 82 ++++++++++++------------------ include/dba/dba_mysql.php | 67 ------------------------- include/dba/dba_mysqli.php | 86 ------------------------------- include/dba/dba_pdo.php | 40 ++++++++++----- include/dba/dba_postgres.php | 117 ------------------------------------------- 5 files changed, 60 insertions(+), 332 deletions(-) delete mode 100755 include/dba/dba_mysql.php delete mode 100755 include/dba/dba_mysqli.php delete mode 100644 include/dba/dba_postgres.php diff --git a/include/dba/dba_driver.php b/include/dba/dba_driver.php index deec9adfd..b3298b673 100755 --- a/include/dba/dba_driver.php +++ b/include/dba/dba_driver.php @@ -1,15 +1,20 @@ connected) { - - if(strpbrk($server,':;')) { - $dsn = $server; - } - else { - $dsn = self::$scheme . ':host=' . $server . (intval($port) ? '' : ';port=' . $port); - } - $dsn .= ';dbname=' . $db; - - - self::$dba->pdo_set(array($dsn,$user,$pass)); - } define('NULL_DATE', self::$null_date); define('ACTIVE_DBTYPE', self::$dbtype); define('TQUOT', self::$tquot); + return self::$dba; } } /** - * @brief abstract database driver class. + * @brief Abstract database driver class. * - * This class gets extended by the real database driver classes, e.g. dba_mysql, - * dba_mysqli. + * This class gets extended by the real database driver class. We used to have + * dba_mysql, dba_mysqli or dba_postgres, but we moved to PDO and the only + * implemented driver is dba_pdo. */ abstract class dba_driver { // legacy behavior public $db; - protected $pdo = array(); public $debug = 0; public $connected = false; @@ -111,6 +98,7 @@ abstract class dba_driver { * This abstract function needs to be implemented in the real driver. * * @param string $server DB server name + * @param string $scheme DB scheme * @param string $port DB port * @param string $user DB username * @param string $pass DB password @@ -166,6 +154,7 @@ abstract class dba_driver { $platform_name = \Zotlabs\Lib\System::get_platform_name(); if(file_exists('install/' . $platform_name . '/' . \DBA::$install_script)) return 'install/' . $platform_name . '/' . \DBA::$install_script; + return 'install/' . \DBA::$install_script; } @@ -173,7 +162,6 @@ abstract class dba_driver { return \DBA::$tquot; } - function utcnow() { return \DBA::$utc_now; } @@ -232,19 +220,12 @@ abstract class dba_driver { return $str; } - function pdo_set($x) { - $this->pdo = $x; - } - - function pdo_get() { - return $this->pdo; - } - } // end abstract dba_driver class - +// // Procedural functions +// function printable($s) { $s = preg_replace("~([\x01-\x08\x0E-\x0F\x10-\x1F\x7F-\xFF])~",".", $s); @@ -275,7 +256,7 @@ function dbg($state) { * wrapping with intval(). * * @param string $str A string to pass to a DB query - * @return Return an escaped string of the value to pass to a DB query. + * @return string Return an escaped string of the value to pass to a DB query. */ function dbesc($str) { @@ -298,6 +279,7 @@ function dbunescbin($str) { function dbescdate($date) { if(is_null_date($date)) return \DBA::$dba->escape(NULL_DATE); + return \DBA::$dba->escape($date); } @@ -330,17 +312,17 @@ function db_use_index($str) { * * printf style arguments %s and %d are replaced with variable arguments, which * should each be appropriately dbesc() or intval(). + * * SELECT queries return an array of results or false if SQL or DB error. Other * queries return true if the command was successful or false if it wasn't. * * Example: - * $r = q("SELECT * FROM %s WHERE `uid` = %d", - * 'user', 1); + * @code{.php}$r = q("SELECT * FROM %s WHERE `uid` = %d", + * 'user', 1);@endcode * * @param string $sql The SQL query to execute * @return bool|array */ - function q($sql) { $args = func_get_args(); @@ -359,8 +341,8 @@ function q($sql) { } /* - * This will happen occasionally trying to store the - * session data after abnormal program termination + * This will happen occasionally trying to store the + * session data after abnormal program termination */ db_logger('dba: no database: ' . print_r($args,true),LOGGER_NORMAL,LOG_CRIT); @@ -389,8 +371,8 @@ function dbq($sql) { // Caller is responsible for ensuring that any integer arguments to // dbesc_array are actually integers and not malformed strings containing -// SQL injection vectors. All integer array elements should be specifically -// cast to int to avoid trouble. +// SQL injection vectors. All integer array elements should be specifically +// cast to int to avoid trouble. function dbesc_array_cb(&$item, $key) { if(is_string($item)) { @@ -423,7 +405,7 @@ function dbesc_array(&$arr) { function db_getfunc($f) { $lookup = array( 'rand'=>array( - DBTYPE_MYSQL=>'RAND()', + DBTYPE_MYSQL=>'RAND()', DBTYPE_POSTGRES=>'RANDOM()' ), 'utc_timestamp'=>array( diff --git a/include/dba/dba_mysql.php b/include/dba/dba_mysql.php deleted file mode 100755 index 8b51cf578..000000000 --- a/include/dba/dba_mysql.php +++ /dev/null @@ -1,67 +0,0 @@ -db = mysql_connect($server.":".$port,$user,$pass); - if($this->db && mysql_select_db($db,$this->db)) { - $this->connected = true; - } - if($this->connected) { - return true; - } - return false; - } - - - function q($sql) { - if((! $this->db) || (! $this->connected)) - return false; - - $this->error = ''; - $result = @mysql_query($sql,$this->db); - - - if(mysql_errno($this->db)) - $this->error = mysql_error($this->db); - - if($result === false || $this->error) { - logger('dba_mysql: ' . printable($sql) . ' returned false.' . "\n" . $this->error); - if(file_exists('dbfail.out')) - file_put_contents('dbfail.out', datetime_convert() . "\n" . printable($sql) . ' returned false' . "\n" . $this->error . "\n", FILE_APPEND); - } - - if(($result === true) || ($result === false)) - return $result; - - $r = array(); - if(mysql_num_rows($result)) { - while($x = mysql_fetch_array($result,MYSQL_ASSOC)) - $r[] = $x; - mysql_free_result($result); - if($this->debug) - logger('dba_mysql: ' . printable(print_r($r,true))); - } - return $r; - } - - function escape($str) { - if($this->db && $this->connected) { - return @mysql_real_escape_string($str,$this->db); - } - } - - function close() { - if($this->db) - mysql_close($this->db); - $this->connected = false; - } - - function getdriver() { - return 'mysql'; - } - -} diff --git a/include/dba/dba_mysqli.php b/include/dba/dba_mysqli.php deleted file mode 100755 index 165c8e969..000000000 --- a/include/dba/dba_mysqli.php +++ /dev/null @@ -1,86 +0,0 @@ -db = new mysqli($server,$user,$pass,$db, $port); - else - $this->db = new mysqli($server,$user,$pass,$db); - - if($this->db->connect_error) { - $this->connected = false; - $this->error = $this->db->connect_error; - - if(file_exists('dbfail.out')) { - file_put_contents('dbfail.out', datetime_convert() . "\nConnect: " . $this->error . "\n", FILE_APPEND); - } - - return false; - } - else { - $this->connected = true; - return true; - } - } - - function q($sql) { - if((! $this->db) || (! $this->connected)) - return false; - - $this->error = ''; - $result = $this->db->query($sql); - - if($this->db->errno) - $this->error = $this->db->error; - - - if($this->error) { - db_logger('dba_mysqli: ERROR: ' . printable($sql) . "\n" . $this->error, LOGGER_NORMAL, LOG_ERR); - if(file_exists('dbfail.out')) { - file_put_contents('dbfail.out', datetime_convert() . "\n" . printable($sql) . "\n" . $this->error . "\n", FILE_APPEND); - } - } - - if(($result === true) || ($result === false)) { - if($this->debug) { - db_logger('dba_mysqli: DEBUG: ' . printable($sql) . ' returns ' . (($result) ? 'true' : 'false'), LOGGER_NORMAL,(($result) ? LOG_INFO : LOG_ERR)); - } - return $result; - } - - if($this->debug) { - db_logger('dba_mysqli: DEBUG: ' . printable($sql) . ' returned ' . $result->num_rows . ' results.', LOGGER_NORMAL, LOG_INFO); - } - - $r = array(); - if($result->num_rows) { - while($x = $result->fetch_array(MYSQLI_ASSOC)) - $r[] = $x; - $result->free_result(); - if($this->debug) { - db_logger('dba_mysqli: ' . printable(print_r($r,true)), LOGGER_NORMAL, LOG_INFO); - } - } - return $r; - } - - function escape($str) { - if($this->db && $this->connected) { - return @$this->db->real_escape_string($str); - } - } - - function close() { - if($this->db) - $this->db->close(); - $this->connected = false; - } - - function getdriver() { - return 'mysqli'; - } - -} \ No newline at end of file diff --git a/include/dba/dba_pdo.php b/include/dba/dba_pdo.php index a9d824a50..719f23c4b 100755 --- a/include/dba/dba_pdo.php +++ b/include/dba/dba_pdo.php @@ -1,14 +1,21 @@ -driver_dbtype = $scheme; if(strpbrk($server,':;')) { @@ -17,7 +24,7 @@ class dba_pdo extends dba_driver { else { $dsn = $this->driver_dbtype . ':host=' . $server . (intval($port) ? ';port=' . $port : ''); } - + $dsn .= ';dbname=' . $db; try { @@ -36,10 +43,19 @@ class dba_pdo extends dba_driver { $this->q("SET standard_conforming_strings = 'off'; SET backslash_quote = 'on';"); $this->connected = true; - return true; + return true; } + /** + * {@inheritDoc} + * @see dba_driver::q() + * + * @return bool|array|PDOStatement + * - \b false if not connected or PDOException occured on query + * - \b array with results on a SELECT query + * - \b PDOStatement on a non SELECT SQL query + */ function q($sql) { if((! $this->db) || (! $this->connected)) return false; @@ -57,7 +73,7 @@ class dba_pdo extends dba_driver { $result = $this->db->query($sql, PDO::FETCH_ASSOC); } catch(PDOException $e) { - + $this->error = $e->getMessage(); if($this->error) { db_logger('dba_pdo: ERROR: ' . printable($sql) . "\n" . $this->error, LOGGER_NORMAL, LOG_ERR); @@ -82,11 +98,10 @@ class dba_pdo extends dba_driver { } if($this->debug) { - db_logger('dba_pdo: DEBUG: ' . printable($sql) . ' returned ' . count($r) . ' results.', LOGGER_NORMAL, LOG_INFO); + db_logger('dba_pdo: DEBUG: ' . printable($sql) . ' returned ' . count($r) . ' results.', LOGGER_NORMAL, LOG_INFO); db_logger('dba_pdo: ' . printable(print_r($r,true)), LOGGER_NORMAL, LOG_INFO); } - return (($this->error) ? false : $r); } @@ -99,9 +114,10 @@ class dba_pdo extends dba_driver { function close() { if($this->db) $this->db = null; + $this->connected = false; } - + function concat($fld,$sep) { if($this->driver_dbtype === 'pgsql') { return 'string_agg(' . $fld . ',\'' . $sep . '\')'; @@ -140,7 +156,7 @@ class dba_pdo extends dba_driver { return $this->escape($str); } } - + function unescapebin($str) { if($this->driver_dbtype === 'pgsql' && (! is_null($str))) { $x = ''; diff --git a/include/dba/dba_postgres.php b/include/dba/dba_postgres.php deleted file mode 100644 index 560d8da60..000000000 --- a/include/dba/dba_postgres.php +++ /dev/null @@ -1,117 +0,0 @@ -db = pg_connect($connstr); - if($this->db !== false) { - $this->connected = true; - } else { - $this->connected = false; - } - $this->q("SET standard_conforming_strings = 'off'; SET backslash_quote = 'on';"); // emulate mysql string escaping to prevent massive code-clobber - return $this->connected; - } - - function q($sql) { - if((! $this->db) || (! $this->connected)) - return false; - - if(!strpos($sql, ';')) - $sql .= ';'; - - if(strpos($sql, '`')) // this is a hack. quoted identifiers should be replaced everywhere in the code with dbesc_identifier(), remove this once it is - $sql = str_replace('`', '"', $sql); - - $this->error = ''; - $result = @pg_query($this->db, $sql); - if(file_exists('db-allqueries.out')) { - $bt = debug_backtrace(); - $trace = array(); - foreach($bt as $frame) { - if(!empty($frame['file']) && @strstr($frame['file'], $_SERVER['DOCUMENT_ROOT'])) - $frame['file'] = substr($frame['file'], strlen($_SERVER['DOCUMENT_ROOT'])+1); - - $trace[] = $frame['file'] . ':' . $frame['function'] . '():' . $frame['line'] ; - } - $compact = join(', ', $trace); - file_put_contents('db-allqueries.out', datetime_convert() . ": " . $sql . ' is_resource: '.var_export(is_resource($result), true).', backtrace: '.$compact."\n\n", FILE_APPEND); - } - - if($result === false) - $this->error = pg_last_error($this->db); - - if($result === false || $this->error) { - //db_logger('dba_postgres: ' . printable($sql) . ' returned false.' . "\n" . $this->error); - if(file_exists('dbfail.out')) - file_put_contents('dbfail.out', datetime_convert() . "\n" . printable($sql) . ' returned false' . "\n" . $this->error . "\n", FILE_APPEND); - } - - if(($result === true) || ($result === false)) - return $result; - - if(pg_result_status($result) == PGSQL_COMMAND_OK) - return true; - - $r = array(); - if(pg_num_rows($result)) { - while($x = pg_fetch_array($result, null, PGSQL_ASSOC)) - $r[] = $x; - pg_free_result($result); - if($this->debug) - db_logger('dba_postgres: ' . printable(print_r($r,true))); - } - return $r; - } - - function escape($str) { - if($this->db && $this->connected) { - $x = @pg_escape_string($this->db, $str); - return $x; - } - } - - function escapebin($str) { - return pg_escape_bytea($str); - } - - function unescapebin($str) { - return pg_unescape_bytea($str); - } - - function close() { - if($this->db) - pg_close($this->db); - $this->connected = false; - } - - function quote_interval($txt) { - return "'$txt'"; - } - - function escape_identifier($str) { - return pg_escape_identifier($this->db, $str); - } - - function optimize_table($table) { - // perhaps do some equivalent thing here, vacuum, etc? I think this is the DBA's domain anyway. Applications should not need to muss with this. - // for now do nothing without a compelling reason. function overrides default legacy mysql. - } - - function concat($fld, $sep) { - return 'string_agg(' . $fld . ',\'' . $sep . '\')'; - } - - function getdriver() { - return 'pgsql'; - } -} \ No newline at end of file -- cgit v1.2.3 From 4bf0c9e36a4a89d6b84c6bf8a74124603add9d9e Mon Sep 17 00:00:00 2001 From: Klaus Weidenbach Date: Mon, 22 Jan 2018 22:59:13 +0100 Subject: :white_check_mark: Add tests for non existent tables. Prevent PHP warnings "Undefined variable" in dba_pdo::q(); --- include/dba/dba_pdo.php | 3 ++- tests/unit/includes/dba/dba_pdoTest.php | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/include/dba/dba_pdo.php b/include/dba/dba_pdo.php index 719f23c4b..f24c5381a 100755 --- a/include/dba/dba_pdo.php +++ b/include/dba/dba_pdo.php @@ -66,8 +66,9 @@ class dba_pdo extends dba_driver { } } + $result = null; $this->error = ''; - $select = ((stripos($sql,'select') === 0) ? true : false); + $select = ((stripos($sql, 'select') === 0) ? true : false); try { $result = $this->db->query($sql, PDO::FETCH_ASSOC); diff --git a/tests/unit/includes/dba/dba_pdoTest.php b/tests/unit/includes/dba/dba_pdoTest.php index ce6e1ffd6..12e574d42 100644 --- a/tests/unit/includes/dba/dba_pdoTest.php +++ b/tests/unit/includes/dba/dba_pdoTest.php @@ -164,4 +164,26 @@ class dba_pdoTest extends DatabaseTestCase { $this->assertFalse($nodba->q('SELECT * FROM account')); } + /** + * @depends testConnectToSqlServer + */ + public function testSelectQueryToNonExistentTableShouldReturnFalse() { + $ret = $this->dba->q('SELECT * FROM non_existent_table'); + + $this->assertFalse($ret); + } + + /** + * @depends testConnectToSqlServer + */ + public function testInsertQueryToNonExistentTableShouldReturnEmptyArray() { + $ret = $this->dba->q('INSERT INTO non_existent_table + (account_email, account_language) + VALUES (\'email@example.com\', \'en\') + '); + + $this->assertNotInstanceOf('PDOStatement', $ret); + $this->isEmpty($ret); + } + } -- cgit v1.2.3 From 210c91398da573d3c44bd1ff5bee4c65128c8686 Mon Sep 17 00:00:00 2001 From: Klaus Weidenbach Date: Mon, 29 Jan 2018 21:14:03 +0100 Subject: Make it little bit less likely to erase a real database. Changed the default PHPUnit database environment variables to make it little bit less likely to truncate accidently a real database. --- tests/phpunit-pgsql.xml | 9 +++++---- tests/phpunit.xml.dist | 9 +++++---- tests/travis/prepare_mysql.sh | 12 ++++++------ tests/travis/prepare_pgsql.sh | 14 +++++++------- 4 files changed, 23 insertions(+), 21 deletions(-) diff --git a/tests/phpunit-pgsql.xml b/tests/phpunit-pgsql.xml index d95c4897b..078056d56 100644 --- a/tests/phpunit-pgsql.xml +++ b/tests/phpunit-pgsql.xml @@ -33,13 +33,14 @@ - + - + - + diff --git a/tests/phpunit.xml.dist b/tests/phpunit.xml.dist index 7b9c1d563..97c84fb81 100644 --- a/tests/phpunit.xml.dist +++ b/tests/phpunit.xml.dist @@ -36,13 +36,14 @@ - + - + - + diff --git a/tests/travis/prepare_mysql.sh b/tests/travis/prepare_mysql.sh index 9fd79c1ab..5b1c96d78 100755 --- a/tests/travis/prepare_mysql.sh +++ b/tests/travis/prepare_mysql.sh @@ -25,7 +25,7 @@ # Exit if anything fails set -e -echo "Preparing for MySQL ..." +echo "Preparing for MySQL/MariaDB ..." if [[ "$MYSQL_VERSION" == "5.7" ]]; then echo "Using MySQL 5.7 in Docker container, need to use TCP" @@ -41,13 +41,13 @@ mysql $PROTO -e "SHOW VARIABLES LIKE 'character_set%';" mysql $PROTO -e "SELECT @@sql_mode;" # Create Hubzilla database -mysql $PROTO -u root -e "CREATE DATABASE IF NOT EXISTS hubzilla;"; -mysql $PROTO -u root -e "CREATE USER 'hubzilla'@'%' IDENTIFIED BY 'hubzilla';" -mysql $PROTO -u root -e "GRANT ALL ON hubzilla.* TO 'hubzilla'@'%';" +mysql $PROTO -u root -e "CREATE DATABASE IF NOT EXISTS travis_hubzilla;"; +mysql $PROTO -u root -e "CREATE USER 'travis_hz'@'%' IDENTIFIED BY 'hubzilla';" +mysql $PROTO -u root -e "GRANT ALL ON travis_hubzilla.* TO 'travis_hz'@'%';" # Import table structure -mysql $PROTO -u root hubzilla < ./install/schema_mysql.sql +mysql $PROTO -u root travis_hubzilla < ./install/schema_mysql.sql # Show databases and tables mysql $PROTO -u root -e "SHOW DATABASES;" -mysql $PROTO -u root -e "USE hubzilla; SHOW TABLES;" +mysql $PROTO -u root -e "USE travis_hubzilla; SHOW TABLES;" diff --git a/tests/travis/prepare_pgsql.sh b/tests/travis/prepare_pgsql.sh index 3c38ef60c..0175b9858 100755 --- a/tests/travis/prepare_pgsql.sh +++ b/tests/travis/prepare_pgsql.sh @@ -33,17 +33,17 @@ psql --version psql -U postgres -c "SELECT VERSION();" # Create Hubzilla database -psql -U postgres -c "DROP DATABASE IF EXISTS hubzilla;" +psql -U postgres -c "DROP DATABASE IF EXISTS travis_hubzilla;" psql -U postgres -v ON_ERROR_STOP=1 <<-EOSQL - CREATE USER hubzilla WITH PASSWORD 'hubzilla'; - CREATE DATABASE hubzilla; - ALTER DATABASE hubzilla OWNER TO hubzilla; - GRANT ALL PRIVILEGES ON DATABASE hubzilla TO hubzilla; + CREATE USER travis_hz WITH PASSWORD 'hubzilla'; + CREATE DATABASE travis_hubzilla; + ALTER DATABASE travis_hubzilla OWNER TO travis_hz; + GRANT ALL PRIVILEGES ON DATABASE travis_hubzilla TO travis_hz; EOSQL # Import table structure -psql -U hubzilla -v ON_ERROR_STOP=1 hubzilla < ./install/schema_postgres.sql +psql -U travis_hz -v ON_ERROR_STOP=1 travis_hubzilla < ./install/schema_postgres.sql # Show databases and tables psql -U postgres -l -psql -U postgres -d hubzilla -c "\dt;" +psql -U postgres -d travis_hubzilla -c "\dt;" -- cgit v1.2.3 From b512780e37deb0b9a422ae8b1604e9c3454694a9 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Wed, 7 Feb 2018 10:27:00 +0100 Subject: do not spam the log --- include/feedutils.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/feedutils.php b/include/feedutils.php index 644e205a6..07350a340 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -496,7 +496,7 @@ function get_atom_elements($feed, $item) { $res['item_private'] = 1; } - logger('ostatus_protocol: ' . intval($ostatus_protocol)); + logger('ostatus_protocol: ' . intval($ostatus_protocol), LOGGER_DEBUG); $apps = $item->get_item_tags(NAMESPACE_STATUSNET, 'notice_info'); if($apps && $apps[0]['attribs']['']['source']) { -- cgit v1.2.3 From 661c20e452255754bbccadc3b29dc3c598c07ed0 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Thu, 8 Feb 2018 09:47:49 +0100 Subject: more db and queries finetuning --- Zotlabs/Module/Ping.php | 26 +++++++++++++------------- boot.php | 4 ++-- install/schema_mysql.sql | 4 ++-- install/update.php | 16 +++++++++++++++- 4 files changed, 32 insertions(+), 18 deletions(-) diff --git a/Zotlabs/Module/Ping.php b/Zotlabs/Module/Ping.php index 2e86804ac..96ade22c0 100644 --- a/Zotlabs/Module/Ping.php +++ b/Zotlabs/Module/Ping.php @@ -148,8 +148,8 @@ class Ping extends \Zotlabs\Web\Controller { $pubs = q("SELECT count(id) as total from item WHERE uid = %d - AND author_xchan != '%s' AND item_unseen = 1 + AND author_xchan != '%s' AND created > '" . datetime_convert('UTC','UTC',$_SESSION['static_loadtime']) . "' $item_normal", intval($sys['channel_id']), @@ -166,8 +166,8 @@ class Ping extends \Zotlabs\Web\Controller { $r = q("SELECT * FROM item WHERE uid = %d - AND author_xchan != '%s' AND item_unseen = 1 + AND author_xchan != '%s' AND created > '" . datetime_convert('UTC','UTC',$_SESSION['static_loadtime']) . "' $item_normal ORDER BY created DESC @@ -208,22 +208,22 @@ class Ping extends \Zotlabs\Web\Controller { if(x($_REQUEST, 'markRead') && local_channel()) { switch($_REQUEST['markRead']) { case 'network': - $r = q("update item set item_unseen = 0 where item_unseen = 1 and uid = %d", + $r = q("UPDATE item SET item_unseen = 0 WHERE uid = %d AND item_unseen = 1", intval(local_channel()) ); break; case 'home': - $r = q("update item set item_unseen = 0 where item_unseen = 1 and item_wall = 1 and uid = %d", + $r = q("UPDATE item SET item_unseen = 0 WHERE uid = %d AND item_unseen = 1 AND item_wall = 1", intval(local_channel()) ); break; case 'mail': - $r = q("update mail set mail_seen = 1 where mail_seen = 0 and channel_id = %d ", + $r = q("UPDATE mail SET mail_seen = 1 WHERE channel_id = %d AND mail_seen = 0", intval(local_channel()) ); break; case 'all_events': - $r = q("update event set dismissed = 1 where dismissed = 0 and uid = %d AND dtstart < '%s' AND dtstart > '%s' ", + $r = q("UPDATE event SET dismissed = 1 WHERE uid = %d AND dismissed = 0 AND dtstart < '%s' AND dtstart > '%s' ", intval(local_channel()), dbesc(datetime_convert('UTC', date_default_timezone_get(), 'now + ' . intval($evdays) . ' days')), dbesc(datetime_convert('UTC', date_default_timezone_get(), 'now - 1 days')) @@ -243,9 +243,9 @@ class Ping extends \Zotlabs\Web\Controller { } if(x($_REQUEST, 'markItemRead') && local_channel()) { - $r = q("update item set item_unseen = 0 where parent = %d and uid = %d", - intval($_REQUEST['markItemRead']), - intval(local_channel()) + $r = q("UPDATE item SET item_unseen = 0 WHERE uid = %d AND parent = %d", + intval(local_channel()), + intval($_REQUEST['markItemRead']) ); } @@ -254,7 +254,7 @@ class Ping extends \Zotlabs\Web\Controller { * dropdown menu. */ if(argc() > 1 && argv(1) === 'notify') { - $t = q("select * from notify where uid = %d and seen = 0 order by created desc", + $t = q("SELECT * FROM notify WHERE uid = %d AND seen = 0 ORDER BY CREATED DESC", intval(local_channel()) ); @@ -320,10 +320,10 @@ class Ping extends \Zotlabs\Web\Controller { $r = q("SELECT * FROM item WHERE uid = %d - AND author_xchan != '%s' AND item_unseen = 1 + AND author_xchan != '%s' $item_normal - ORDER BY created DESC, id + ORDER BY created DESC LIMIT 300", intval(local_channel()), dbesc($ob_hash) @@ -495,7 +495,7 @@ class Ping extends \Zotlabs\Web\Controller { if($vnotify & (VNOTIFY_NETWORK|VNOTIFY_CHANNEL)) { $r = q("SELECT id, item_wall FROM item - WHERE item_unseen = 1 and uid = %d + WHERE uid = %d and item_unseen = 1 $item_normal AND author_xchan != '%s'", intval(local_channel()), diff --git a/boot.php b/boot.php index 184ff6ea2..7c6fd090c 100755 --- a/boot.php +++ b/boot.php @@ -50,10 +50,10 @@ require_once('include/attach.php'); require_once('include/bbcode.php'); define ( 'PLATFORM_NAME', 'hubzilla' ); -define ( 'STD_VERSION', '3.1.7' ); +define ( 'STD_VERSION', '3.1.8' ); define ( 'ZOT_REVISION', '1.3' ); -define ( 'DB_UPDATE_VERSION', 1200 ); +define ( 'DB_UPDATE_VERSION', 1201 ); define ( 'PROJECT_BASE', __DIR__ ); diff --git a/install/schema_mysql.sql b/install/schema_mysql.sql index ea13e0de6..aa0ea0178 100644 --- a/install/schema_mysql.sql +++ b/install/schema_mysql.sql @@ -651,6 +651,7 @@ CREATE TABLE IF NOT EXISTS `item` ( KEY `uid_commented` (`uid`, `commented`), KEY `uid_created` (`uid`, `created`), KEY `uid_item_unseen` (`uid`, `item_unseen`), + KEY `uid_item_type` (`uid`, `item_type`), KEY `aid` (`aid`), KEY `owner_xchan` (`owner_xchan`), KEY `author_xchan` (`author_xchan`), @@ -689,8 +690,7 @@ CREATE TABLE IF NOT EXISTS `item` ( KEY `item_verified` (`item_verified`), KEY `item_retained` (`item_retained`), KEY `item_rss` (`item_rss`), - KEY `item_consensus` (`item_consensus`), - KEY `item_type` (`item_type`) + KEY `item_consensus` (`item_consensus`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE IF NOT EXISTS `item_id` ( diff --git a/install/update.php b/install/update.php index ceaccdfa3..d5ad394f4 100644 --- a/install/update.php +++ b/install/update.php @@ -1,6 +1,6 @@ Date: Thu, 8 Feb 2018 10:26:49 +0100 Subject: wrong link --- Zotlabs/Widget/Notifications.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zotlabs/Widget/Notifications.php b/Zotlabs/Widget/Notifications.php index 322a7b60a..d51cb0113 100644 --- a/Zotlabs/Widget/Notifications.php +++ b/Zotlabs/Widget/Notifications.php @@ -67,7 +67,7 @@ class Notifications { 'label' => t('New Events'), 'title' => t('New Events Notifications'), 'viewall' => [ - 'url' => 'mail/combined', + 'url' => 'events', 'label' => t('View events') ], 'markall' => [ -- cgit v1.2.3 From cb70192f36816a0f642af7176932a431982fe376 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Fri, 9 Feb 2018 10:36:43 +0100 Subject: bump version --- boot.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boot.php b/boot.php index 7c6fd090c..7e061e163 100755 --- a/boot.php +++ b/boot.php @@ -50,7 +50,7 @@ require_once('include/attach.php'); require_once('include/bbcode.php'); define ( 'PLATFORM_NAME', 'hubzilla' ); -define ( 'STD_VERSION', '3.1.8' ); +define ( 'STD_VERSION', '3.1.9' ); define ( 'ZOT_REVISION', '1.3' ); define ( 'DB_UPDATE_VERSION', 1201 ); -- cgit v1.2.3 From 5f229d81e9aaac0e0d82091d2d9089f5fb34bfe8 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Fri, 9 Feb 2018 14:06:59 +0100 Subject: use distinct in channel item query and minor notification cache improvement --- Zotlabs/Module/Channel.php | 10 +++++----- view/js/main.js | 2 ++ 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Zotlabs/Module/Channel.php b/Zotlabs/Module/Channel.php index b7e18f954..dddca16b4 100644 --- a/Zotlabs/Module/Channel.php +++ b/Zotlabs/Module/Channel.php @@ -249,13 +249,13 @@ class Channel extends \Zotlabs\Web\Controller { } } else { - $r = q("SELECT id AS item_id FROM item + $r = q("SELECT DISTINCT item.parent AS item_id FROM item left join abook on item.author_xchan = abook.abook_xchan - WHERE uid = %d $item_normal - AND item_wall = 1 and item_thread_top = 1 - AND (abook_blocked = 0 or abook.abook_flags is null) + WHERE true and uid = %d $item_normal + AND (abook.abook_blocked = 0 or abook.abook_flags is null) + AND item.item_wall = 1 AND item.item_thread_top AND item.mid = item.parent_mid $sql_extra $sql_extra2 - ORDER BY created DESC, id $pager_sql ", + ORDER BY created DESC $pager_sql ", intval(\App::$profile['profile_uid']) ); } diff --git a/view/js/main.js b/view/js/main.js index 02b0f125c..4a2bae802 100644 --- a/view/js/main.js +++ b/view/js/main.js @@ -357,6 +357,7 @@ function closeMenu(theID) { function markRead(notifType) { $.get('ping?f=&markRead='+notifType); $('.' + notifType + '-button').hide(); + sessionStorage.removeItem(notifType + '_notifications_cache'); if(timer) clearTimeout(timer); timer = setTimeout(updateInit,2000); } @@ -436,6 +437,7 @@ function handleNotifications(data) { if(item == 0) { $('.' + index + '-button').fadeOut(); + sessionStorage.removeItem(index + '_notifications_cache'); } else { $('.' + index + '-button').fadeIn(); $('.' + index + '-update').html(item); -- cgit v1.2.3 From 6cc32943954124739023751eb377d398a54772d9 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Fri, 9 Feb 2018 20:36:14 +0100 Subject: finally fix channel query --- Zotlabs/Module/Channel.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Zotlabs/Module/Channel.php b/Zotlabs/Module/Channel.php index dddca16b4..3dab85410 100644 --- a/Zotlabs/Module/Channel.php +++ b/Zotlabs/Module/Channel.php @@ -204,7 +204,7 @@ class Channel extends \Zotlabs\Web\Controller { $_SESSION['loadtime'] = datetime_convert(); } else { - $r = q("SELECT distinct parent AS item_id, created from item + $r = q("SELECT distinct parent AS item_id from item left join abook on ( item.owner_xchan = abook.abook_xchan $abook_uids ) WHERE uid = %d $item_normal_update AND item_wall = 1 $simple_update @@ -249,11 +249,11 @@ class Channel extends \Zotlabs\Web\Controller { } } else { - $r = q("SELECT DISTINCT item.parent AS item_id FROM item - left join abook on item.author_xchan = abook.abook_xchan + $r = q("SELECT item.parent AS item_id FROM item + left join abook on ( item.author_xchan = abook.abook_xchan $abook_uids ) WHERE true and uid = %d $item_normal AND (abook.abook_blocked = 0 or abook.abook_flags is null) - AND item.item_wall = 1 AND item.item_thread_top AND item.mid = item.parent_mid + AND item.item_wall = 1 AND item.item_thread_top = 1 $sql_extra $sql_extra2 ORDER BY created DESC $pager_sql ", intval(\App::$profile['profile_uid']) -- cgit v1.2.3 From c6b2652c013b7a331f077f34e222b6d6df6bf042 Mon Sep 17 00:00:00 2001 From: phellmes Date: Sun, 11 Feb 2018 16:08:34 +0100 Subject: add flexibility to prefix/suffix string translations for jquery.timeago In addition to use the defaults or any other translated strings this allows now to force an empty string by setting the translation to NONE. Translators can choose to either use prefixes only, suffixes only, none of them or both of them - whatever sounds best in their language. --- include/js_strings.php | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/include/js_strings.php b/include/js_strings.php index 1b4668061..936594291 100644 --- a/include/js_strings.php +++ b/include/js_strings.php @@ -24,10 +24,16 @@ function js_strings() { '$leavethispage' => t('Unsaved changes. Are you sure you wish to leave this page?'), '$location' => t('Location'), - '$t01' => ((t('timeago.prefixAgo') != 'timeago.prefixAgo') ? t('timeago.prefixAgo') : ''), - '$t02' => ((t('timeago.prefixFromNow') != 'timeago.prefixFromNow') ? t('timeago.prefixFromNow') : ''), - '$t03' => t('ago'), - '$t04' => t('from now'), + // translatable prefix and suffix strings for jquery.timeago - + // using the defaults set below if left untranslated, empty strings if + // translated to "NONE" and the corresponding language strings + // if translated to anything else + '$t01' => ((t('timeago.prefixAgo') == 'timeago.prefixAgo') ? '' : ((t('timeago.prefixAgo') == 'NONE') ? '' : t('timeago.prefixAgo'))), + '$t02' => ((t('timeago.prefixFromNow') == 'timeago.prefixFromNow') ? '' : ((t('timeago.prefixFromNow') == 'NONE') ? '' : t('timeago.prefixFromNow'))), + '$t03' => ((t('timeago.suffixAgo') == 'timeago.suffixAgo') ? 'ago' : ((t('timeago.suffixAgo') == 'NONE') ? '' : t('timeago.suffixAgo'))), + '$t04' => ((t('timeago.suffixFromNow') == 'timeago.suffixFromNow') ? 'from now' : ((t('timeago.suffixFromNow') == 'NONE') ? '' : t('timeago.suffixFromNow'))), + + // translatable main strings for jquery.timeago '$t05' => t('less than a minute'), '$t06' => t('about a minute'), '$t07' => t('%d minutes'), -- cgit v1.2.3 From 1a9c1ecfb16def11e63514abb7264ce4e95dae4f Mon Sep 17 00:00:00 2001 From: phellmes Date: Sun, 11 Feb 2018 17:01:47 +0100 Subject: update DE translation strings for new relative date/time options temporary manual string update in relation to last commit until changes reach Transifex and can be updated there --- view/de-de/hmessages.po | 30 +++++++++++++++--------------- view/de-de/hstrings.php | 30 +++++++++++++++--------------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/view/de-de/hmessages.po b/view/de-de/hmessages.po index e7c962bbd..f68a96c22 100644 --- a/view/de-de/hmessages.po +++ b/view/de-de/hmessages.po @@ -12377,27 +12377,27 @@ msgstr "Ungespeicherte Änderungen. Bist Du sicher, dass Du diese Seite verlasse #: ../../include/js_strings.php:27 msgid "timeago.prefixAgo" -msgstr "timeago.prefixAgo" +msgstr "vor" #: ../../include/js_strings.php:28 msgid "timeago.prefixFromNow" -msgstr " " +msgstr "in" #: ../../include/js_strings.php:29 -msgid "ago" -msgstr "her" +msgid "timeago.suffixAgo" +msgstr "NONE" #: ../../include/js_strings.php:30 -msgid "from now" -msgstr "von jetzt" +msgid "timeago.suffixFromNow" +msgstr "NONE" #: ../../include/js_strings.php:31 msgid "less than a minute" -msgstr "weniger als eine Minute" +msgstr "weniger als einer Minute" #: ../../include/js_strings.php:32 msgid "about a minute" -msgstr "ungefähr eine Minute" +msgstr "ungefähr einer Minute" #: ../../include/js_strings.php:33 #, php-format @@ -12406,7 +12406,7 @@ msgstr "%d Minuten" #: ../../include/js_strings.php:34 msgid "about an hour" -msgstr "ungefähr eine Stunde" +msgstr "ungefähr einer Stunde" #: ../../include/js_strings.php:35 #, php-format @@ -12415,30 +12415,30 @@ msgstr "ungefähr %d Stunden" #: ../../include/js_strings.php:36 msgid "a day" -msgstr "ein Tag" +msgstr "einem Tag" #: ../../include/js_strings.php:37 #, php-format msgid "%d days" -msgstr "%d Tage" +msgstr "%d Tagen" #: ../../include/js_strings.php:38 msgid "about a month" -msgstr "ungefähr einen Monat" +msgstr "ungefähr einem Monat" #: ../../include/js_strings.php:39 #, php-format msgid "%d months" -msgstr "%d Monate" +msgstr "%d Monaten" #: ../../include/js_strings.php:40 msgid "about a year" -msgstr "ungefähr ein Jahr" +msgstr "ungefähr einem Jahr" #: ../../include/js_strings.php:41 #, php-format msgid "%d years" -msgstr "%d Jahre" +msgstr "%d Jahren" #: ../../include/js_strings.php:42 msgid " " diff --git a/view/de-de/hstrings.php b/view/de-de/hstrings.php index 61db3fb5d..e87f660f0 100644 --- a/view/de-de/hstrings.php +++ b/view/de-de/hstrings.php @@ -1,7 +1,7 @@ Date: Sun, 11 Feb 2018 20:53:27 +0100 Subject: this might seem rediculous but it helps mysql to find the better index for this query --- include/items.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/items.php b/include/items.php index c7206458e..8091252d6 100755 --- a/include/items.php +++ b/include/items.php @@ -3467,7 +3467,7 @@ function item_expire($uid,$days) { AND item_thread_top = 1 AND resource_type = '' AND item_starred = 0 - $sql_extra $item_normal LIMIT $expire_limit ", + $sql_extra $item_normal ORDER BY created ASC LIMIT $expire_limit ", intval($uid), db_utcnow(), db_quoteinterval(intval($days).' DAY') -- cgit v1.2.3