/** * @covers PsUtil::fileUniqueTime */ function testFileUniqueTime() { $files = array(); for ($i = 0; $i < 1000; $i++) { $files[] = PsUtil::fileUniqueTime(); } self::log('Generated file names: {}', print_r($files, true)); $count = count($files); $CountUq = count(array_unique($files)); $this->assertEquals($count, $CountUq, "Files: {$count}, Unique: {$CountUq}"); }
/** * Метод сохраняет ошибку выполнения в файл * * @param Exception $exception */ public static function dumpError(Exception $exception, $additionalInfo = '') { if (ConfigIni::exceptionsMaxDumpCount() <= 0) { return; //--- } $additionalInfo = trim("{$additionalInfo}"); //Поставим защиту от двойного дампинга ошибки $SafePropName = 'ps_ex_dumped'; if (property_exists($exception, $SafePropName)) { return; //--- } $exception->{$SafePropName} = true; try { $INFO[] = 'SERVER: ' . (isset($_SERVER) ? print_r($_SERVER, true) : ''); $INFO[] = 'REQUEST: ' . (isset($_REQUEST) ? print_r($_REQUEST, true) : ''); $INFO[] = 'SESSION: ' . (isset($_SESSION) ? print_r($_SESSION, true) : ''); $INFO[] = 'FILES: ' . (isset($_FILES) ? print_r($_FILES, true) : ''); if ($additionalInfo) { $INFO[] = "ADDITIONAL:\n{$additionalInfo}\n"; } $INFO[] = 'STACK:'; $INFO[] = ExceptionHelper::formatStackFile($exception); $original = ExceptionHelper::extractOriginal($exception); $fname = get_file_name($original->getFile()); $fline = $original->getLine(); $DM = DirManager::autogen('exceptions'); if ($DM->getDirContentCnt() >= ConfigIni::exceptionsMaxDumpCount()) { $DM->clearDir(); } $DM->getDirItem(null, PsUtil::fileUniqueTime() . " [{$fname} {$fline}]", 'err')->putToFile(implode("\n", $INFO)); } catch (Exception $ex) { //Если в методе дампа эксепшена ошибка - прекращаем выполнение. die("Exception [{$exception->getMessage()}] dump error: [{$ex->getMessage()}]"); } }
/** * Метод сохраняет последний удачно отправленный email */ private function dumpEmail() { $DM = DirManager::autogen('emails'); if ($DM->getDirContentCnt() >= EMAILS_MAX_FILES_COUNT) { $DM->clearDir(); } $DM->getDirItem(null, PsUtil::fileUniqueTime(), 'mail')->putToFile($this); }
/** * Метод выполняет дамп таблицы */ public static function dumpTable($idColumn, $table, array $where = array(), $order = null) { //Стартуем секундомер $secundomer = Secundomer::startedInst("Снятие дампа {$table}"); //Отключим ограничение по времени PsUtil::startUnlimitedMode(); //Получим экземпляр логгера $LOGGER = PsLogger::inst(__CLASS__); //Текущий пользователь $userId = AuthManager::getUserIdOrNull(); //Для логов, запросов и все остального $table = strtoupper(PsCheck::tableName($table)); //Макс кол-во записей $limit = PsDefines::getTableDumpPortion(); //Проверим наличие id $idColumn = PsCheck::tableColName($idColumn); $LOGGER->info('Dumping table {}. Id column: {}, limit: {}. User id: {}.', $table, $idColumn, $limit, $userId); //Получаем лок (без ожидания) $lockName = "DUMP table {$table}"; $locked = PsLock::lock($lockName, false); $LOGGER->info('Lock name: {}, locked ? {}.', $lockName, var_export($locked, true)); if (!$locked) { return false; //Не удалось получить лок } $zipDi = false; try { //ЗПРОСЫ: //1. Запрос на извлечение колва записей, подлежащих дампированию $queryCnt = Query::select("count({$idColumn}) as cnt", $table, $where); //2. Запрос на извлечение данных, подлежащих дампированию $queryDump = Query::select('*', $table, $where, null, $order, $limit); //3. Запрос на извлечение кодов дампируемых записей $selectIds = Query::select($idColumn, $table, $where, null, $order, $limit); //4. Запрос на удаление дампированных данных $queryDel = Query::delete($table, Query::plainParam("{$idColumn} in (select {$idColumn} from (" . $selectIds->build($delParams) . ') t )', $delParams)); //Выполним запрос для получения кол-ва записей, подлежащих дампу $cnt = PsCheck::int(array_get_value('cnt', PSDB::getRec($queryCnt, null, true))); $LOGGER->info('Dump recs count allowed: {}.', $cnt); if ($cnt < $limit) { $LOGGER->info('SKIP dumping table, count allowed ({}) < limit ({})...', $cnt, $limit); $LOGGER->info("Query for extract dump records count: {$queryCnt}"); PsLock::unlock($lockName); return false; } //Время дампа $date = PsUtil::fileUniqueTime(false); $time = time(); //Название файлов $zipName = $date . ' ' . $table; //Элемент, указывающий на zip архив $zipDi = DirManager::stuff(null, array(self::DUMPS_TABLE, $table))->getDirItem(null, $zipName, PsConst::EXT_ZIP); $LOGGER->info('Dump to: [{}].', $zipDi->getAbsPath()); if ($zipDi->isFile()) { $LOGGER->info('Dump file exists, skip dumping table...'); PsLock::unlock($lockName); return false; } //Комментарий к таблице $commentToken[] = "Date: {$date}"; $commentToken[] = "Time: {$time}"; $commentToken[] = "Table: {$table}"; $commentToken[] = "Manager: {$userId}"; $commentToken[] = "Recs dumped: {$limit}"; $commentToken[] = "Total allowed: {$cnt}"; $commentToken[] = "Query dump cnt: {$queryCnt}"; $commentToken[] = "Query dump data: {$queryDump}"; $commentToken[] = "Query dump ids: {$selectIds}"; $commentToken[] = "Query del dumped: {$queryDel}"; $comment = implode("\n", $commentToken); //Начинаем zip и сохраняем в него данные $zip = $zipDi->startZip(); $zip->addFromString($zipName, serialize(PSDB::getArray($queryDump))); $zip->setArchiveComment($comment); $zip->close(); $LOGGER->info('Data successfully dumped, zip comment:'); $LOGGER->info("[\n{$comment}\n]"); //Удалим те записи, дамп которых был снят $LOGGER->info('Clearing dumped table records...'); $affected = PSDB::update($queryDel); $LOGGER->info('Rows deleted: {}.', $affected); $LOGGER->info('Dumping is SUCCESSFULLY finished. Total time: {} sec.', $secundomer->stop()->getAverage()); } catch (Exception $ex) { PsLock::unlock($lockName); ExceptionHandler::dumpError($ex); $LOGGER->info('Error occured: {}', $ex->getMessage()); throw $ex; } return $zipDi; }
/** * Метод сохраняет последний удачно отправленный email */ private function dumpEmail() { if (ConfigIni::emailsMaxDumpCount() > 0) { $DM = DirManager::autogen('emails'); if ($DM->getDirContentCnt() >= ConfigIni::emailsMaxDumpCount()) { $DM->clearDir(); } $DM->getDirItem(null, PsUtil::fileUniqueTime(), 'mail')->putToFile($this); } }