Pg lo truncate: примеры (PHP)
pg_lo_truncate(PgSql\Lob $lob, int $size): boolФункция pg_lo_truncate в PHP предназначена для изменения размера большого объекта (Large Object) в базе данных PostgreSQL. Эта функция обрезает существующий большой объект до указанной длины в байтах.
Использование pg_lo_truncate актуально при работе с бинарными данными, хранимыми в виде больших объектов PostgreSQL, когда требуется уменьшить их размер без полной перезаписи. Типичные сценарии включают редактирование файлов изображений, документов или медиаконтента непосредственно в базе данных.
Первый аргумент (resource $large_object) - идентификатор большого объекта, полученный с помощью pg_lo_open. Этот ресурс должен быть открыт в режиме записи.
Второй аргумент (int $size) - новый размер объекта в байтах. Если указанное значение меньше текущего размера объекта, данные обрезаются с конца. При значении больше текущего размера объект расширяется нулевыми байтами.
Сокращение большого объекта до 500 байт:
<?
$connection = pg_connect("dbname=test user=postgres");
$oid = 12345; // Идентификатор существующего большого объекта
$largeObject = pg_lo_open($connection, $oid, "w");
if (pg_lo_truncate($largeObject, 500)) {
echo "Объект успешно обрезан";
} else {
echo "Ошибка при обрезке объекта";
}
pg_lo_close($largeObject);
pg_close($connection);
?>Объект успешно обрезан
Увеличение размера большого объекта до 2000 байт:
<?
$connection = pg_connect("dbname=test user=postgres");
$oid = 12346;
$largeObject = pg_lo_open($connection, $oid, "w");
$result = pg_lo_truncate($largeObject, 2000);
var_dump($result);
pg_lo_close($largeObject);
pg_close($connection);
?>bool(true)
Функция pg_lo_write позволяет записывать данные в большой объект с текущей позиции. В отличие от pg_lo_truncate, которая изменяет размер объекта, pg_lo_write добавляет или перезаписывает содержимое.
Функция для чтения содержимого большого объекта. Часто используется вместе с pg_lo_truncate для обработки данных после изменения размера.
Полное удаление большого объекта из базы данных. Применяется когда данные больше не нужны, вместо частичной обрезки.
pg_lo_truncate предпочтительнее при необходимости изменить размер объекта без полной перезаписи содержимого. pg_lo_write используется для добавления или модификации данных, а pg_lo_unlink - для полного удаления.
В Python используется метод truncate() объекта LargeObject:
import psycopg2
conn = psycopg2.connect("dbname=test user=postgres")
conn.autocommit = True
# Открытие большого объекта
lobj = conn.lobject(12345, 'w')
# Обрезка до 500 байт
lobj.truncate(500)
lobj.close()
conn.close()# Метод не возвращает значение, вызывает исключение при ошибке
В Node.js для работы с большими объектами требуется использование потоков:
// Прямого аналога pg_lo_truncate в популярных библиотеках Node.js нет
// Обычно используют запросы SQL напрямую:
const { Client } = require('pg');
const client = new Client();
async function truncateLo() {
await client.connect();
await client.query('BEGIN');
await client.query('SELECT lo_truncate($1, $2)', [12345, 500]);
await client.query('COMMIT');
await client.end();
}Непосредственный вызов функции базы данных:
-- Обрезка большого объекта с OID 12345 до 500 байт
SELECT lo_truncate(12345, 500); lo_truncate
-------------
1
(1 row)Попытка обрезки объекта, открытого в режиме 'r':
<?
$connection = pg_connect("dbname=test user=postgres");
$oid = 12345;
$largeObject = pg_lo_open($connection, $oid, "r"); // Ошибка: режим чтения
$result = pg_lo_truncate($largeObject, 500);
var_dump($result);
?>bool(false)
Использование несуществующего OID:
<?
$connection = pg_connect("dbname=test user=postgres");
$largeObject = pg_lo_open($connection, 999999, "w"); // Несуществующий OID
if ($largeObject === false) {
echo "Не удалось открыть объект";
} else {
$result = pg_lo_truncate($largeObject, 500);
var_dump($result);
}
?>Не удалось открыть объект
Указание отрицательного значения размера:
<?
$connection = pg_connect("dbname=test user=postgres");
$oid = 12345;
$largeObject = pg_lo_open($connection, $oid, "w");
$result = pg_lo_truncate($largeObject, -100); // Отрицательное значение
var_dump($result);
?>bool(false)
Функция pg lo truncate была добавлена в PHP 5.6.0. В PHP 7.0.0 функция начала возвращать boolean значение вместо ресурса. В PHP 8.0.0 существенных изменений в работе функции не произошло, но усилилась строгость типизации аргументов.
В ранних версиях PHP ошибки работы с большими объектами часто оставались незамеченными. Начиная с PHP 7.0, улучшена диагностика проблем при выполнении операций с большими объектами.
Обрезка нескольких объектов до определенного размера:
<?
function truncateMultipleObjects($connection, $oids, $newSize) {
$results = [];
foreach ($oids as $oid) {
$lo = pg_lo_open($connection, $oid, "w");
if ($lo) {
$results[$oid] = pg_lo_truncate($lo, $newSize);
pg_lo_close($lo);
} else {
$results[$oid] = false;
}
}
return $results;
}
$connection = pg_connect("dbname=test user=postgres");
$oids = [12345, 12346, 12347];
$truncationResults = truncateMultipleObjects($connection, $oids, 1024);
print_r($truncationResults);
pg_close($connection);
?>Array
(
[12345] => 1
[12346] => 1
[12347] => 1
)Проверка текущего размера перед обрезкой:
<?
function safeTruncate($connection, $oid, $maxSize) {
$lo = pg_lo_open($connection, $oid, "w");
if (!$lo) return false;
// Определяем текущий размер
$currentSize = pg_lo_lseek($lo, 0, SEEK_END);
if ($currentSize > $maxSize) {
$result = pg_lo_truncate($lo, $maxSize);
} else {
$result = true; // Обрезка не требуется
}
pg_lo_close($lo);
return $result;
}
$connection = pg_connect("dbname=test user=postgres");
$result = safeTruncate($connection, 12345, 5000);
var_dump($result);
?>bool(true)
Обрезка объекта с откатом изменений при ошибке:
<?
$connection = pg_connect("dbname=test user=postgres");
pg_query($connection, "BEGIN");
try {
$oid = 12345;
$largeObject = pg_lo_open($connection, $oid, "w");
if (!pg_lo_truncate($largeObject, 1000)) {
throw new Exception("Ошибка обрезки объекта");
}
// Другие операции с базой данных
pg_query($connection, "UPDATE documents SET modified = NOW() WHERE oid = $oid");
pg_lo_close($largeObject);
pg_query($connection, "COMMIT");
echo "Транзакция успешно завершена";
} catch (Exception $e) {
pg_query($connection, "ROLLBACK");
echo "Ошибка: " . $e->getMessage();
}
pg_close($connection);
?>Транзакция успешно завершена