Ошибка соединения SQL с PHP после многих операций

В настоящее время я зацикливаюсь на создании карты MBTiles и каждый раз добавляю информацию в свою базу данных.
Вот как я настроил свое соединение и выполняю действия во время цикла:

if ($pdo_mbtiles == null) {
echo "Opening new database connection".PHP_EOL;
$pdo_mbtiles = new PDO('sqlite:'.$filename,
'',
'',
array(
PDO::ATTR_PERSISTENT => true
)
);
$pdo_mbtiles->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
$pdo_mbtiles->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}


$q = $pdo_mbtiles->prepare("INSERT INTO tiles (zoom_level, tile_column, tile_row,tile_data) VALUES (:zoom_level, :tile_column, :tile_rowTMS, :tile_data)");
$q->bindParam(':zoom_level', $zoom_level);
$q->bindParam(':tile_column', $tile_column);
$q->bindParam(':tile_rowTMS', $tile_rowTMS);
$q->bindParam(':tile_data', $tile_data, PDO::PARAM_LOB);
$q->execute();

После 1018 циклов (это число не меняется независимо от того, сколько раз я пытаюсь), я получаю это сообщение об ошибке:

SQLSTATE[HY000]: General error: 14 unable to open database file

Я проверил решение, написанное здесь:
Как предотвратить SQLITE SQLSTATE [HY000] [14]?
но эхо-сообщение появляется только в первый раз цикла, поэтому я предполагаю, что соединение PDO не закрыто.

Я не нашел другой документации, относящейся к этому коду ошибки.

Что здесь может пойти не так?

Я попытался переместить команды prepare и bind в следующее состояние. Исключение не возникает, но сохраняется только первая плитка (или каждая плитка сохраняется поверх первой, не уверен):

if ($pdo_mbtiles == null) {
echo "Opening new database connection".PHP_EOL;
$pdo_mbtiles = new PDO('sqlite:'.$filename,
'',
'',
array(
PDO::ATTR_PERSISTENT => true
)
);
$pdo_mbtiles->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
$pdo_mbtiles->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}

if ($q == null) {
$q = $pdo_mbtiles->prepare("INSERT INTO tiles (zoom_level, tile_column, tile_row,tile_data) VALUES (:zoom_level, :tile_column, :tile_rowTMS, :tile_data)");
$q->bindParam(':zoom_level', $zoom_level);
$q->bindParam(':tile_column', $tile_column);
$q->bindParam(':tile_rowTMS', $tile_rowTMS);
$q->bindParam(':tile_data', $tile_data, PDO::PARAM_LOB);
}
$q->execute();

Вот файлы во время генерации:
files_during_process

И тут после исключения возбуждается:
files_after_process

Кроме того, когда возникает исключение, я делаю var_dump из моего $ pdo_mbtiles, и вот результат (точно такой же, как когда я делаю это с успехом):

object(PDO)#116 (0) {
}

Редактировать: Все еще пытаясь решить эту проблему, я упростил код для создания файла MBTiles. Пока безуспешно, но вот пример, если кто-то хочет воспроизвести проблему. Вы можете скачать его с https://www.dropbox.com/s/33vqamc9tn4c3ux/sample_PHP_MBTiles_generation_bug.zip?dl=0

1

Решение

Я предлагаю вам повторно использовать соединение, если оно открыто.

Создать свойство: private $pdo;

И проверьте, является ли он нулевым, прежде чем создавать новый объект:

function opendatabase(){
try{
if($this->pdo==null){
$this->pdo =new PDO("sqlite:database/database.db","","",array(
PDO::ATTR_PERSISTENT => true
));
}
return $this->pdo;
}catch(PDOException $e){
logerror($e->getMessage(), "opendatabase");
print "Error in openhrsedb ".$e->getMessage();
}
}
0

Другие решения

Сообщение об ошибке вводило в заблуждение. После многих часов отладки я обнаружил, что это совершенно не связано с подключением к моей базе данных.
Это правда, что я использовал fopen () для получения данных тайлов, и не зарегистрировал fclose (), таким образом, достигнув предела 1024.

1024 — потому что я использовал шесть операторов require или require_once, поэтому 1018 запросов плиток + 6 require = 1024 открытых соединения.

0

По вопросам рекламы [email protected]