Как прочитать полный файл с pg_read_file и missing_ok = true? - PullRequest
0 голосов
/ 07 августа 2020

Все следующие варианты использования pg_read_file () работают нормально:

select pg_read_file('myFile.txt'); -- ok full file
select pg_read_file('myFile-notExists',0,10,true); -- NULL is Ok! 

Но это проблемные c:

select pg_read_file('myFile-notExists.txt'); -- ERROR... It is not what I need
select pg_read_file('myFile.txt',0,10,true); -- ok not null, but need full file!

... Я пытаюсь решить проблему с помощью функции переноса:

CREATE or replace FUNCTION pg_read_file(f text, missing_ok boolean) RETURNS text AS $$
  SELECT pg_read_file(f,0,922337203,missing_ok) 
   -- the max 9223372036854775807 is  too large, also 9223372036854775800, ....
$$ LANGUAGE SQL IMMUTABLE;

Но там написано «ОШИБКА: запрошенная длина слишком велика» для тестов на максимальной длине ... Поэтому я использую случайную константу . Question1 : какое значение "максимальный размер файла"?

select pg_read_file('myFile-notExists.txt',true); -- Ok! NULL is what I need
select pg_read_file('myFile.txt',true); -- Ok! full file.

Вопрос2 : есть ли другой способ решить эту проблему?

По стандарту PostgreSQL v12 \df pg_read_file говорит:

   Schema   |     Name     | Result data type |      Argument data types      | Type
------------+--------------+------------------+-------------------------------+------
 pg_catalog | pg_read_file | text             | text                          | func
 pg_catalog | pg_read_file | text             | text, bigint, bigint          | func
 pg_catalog | pg_read_file | text             | text, bigint, bigint, boolean | func

Почему pg_read_file(text,boolean) отсутствует в pg_catalog? Это приведет к несогласованности с другими модулями или расширениями?

Ответы [ 2 ]

1 голос
/ 07 августа 2020

Как насчет использования pg_stat_file для проверки его существования?

CREATE or replace FUNCTION pg_read_file(f text, missing_ok boolean) RETURNS text AS $$
  SELECT case 
     when pg_stat_file(f,missing_ok) is NULL then NULL 
     else pg_read_file(f) end
$$ LANGUAGE SQL IMMUTABLE;

Здесь есть условие гонки, при котором файл может исчезнуть после pg_stat_file, но до pg_read_file, что приведет к ошибке, а не возврату NULL.

0 голосов
/ 09 августа 2020

Это ошибка pg_read_file() ... И для обходного пути нет действительно хорошего решения без состояния гонки (о чем ранее вспомнил @jjanes). Приложения реального времени требуют осторожности.

Здесь изменение подхода, чтобы получить информацию pg_stat_file, избегая потери ЦП.

Это дело вкуса, я думаю, что ЗАПИСЬ некрасиво работать, я предпочитаю JSONb.

Представьте себе cenario, в котором вы работаете с JSONb, например строите серверную часть с помощью PostgREST ...

Повторное использование pg_stat_file

CREATE or replace FUNCTION jsonb_read_stat_file(
  f text,
  missing_ok boolean DEFAULT false
) RETURNS JSONb AS $f$
  SELECT j || jsonb_build_object( 'file',f,  'content',pg_read_file(f) )
  FROM to_jsonb( pg_stat_file(f,missing_ok) ) t(j)
  WHERE j IS NOT NULL
$f$ LANGUAGE SQL IMMUTABLE;

Чтобы получить только контент, эмулирующий чистый read_file(x,true), вы можете использовать jsonb_read_stat_file('/tmp/text.txt',true)->>'content'.

Пример использования:

echo "Hello world!" > /tmp/text.txt
psql mydb -c "SELECT jsonb_read_stat_file('/tmp/text-ERROR.txt',true) IS NULL" # true
psql mydb -c "SELECT jsonb_read_stat_file('/tmp/text.txt',true)"
 {
   "file": "/tmp/text.txt", 
   "size": 13, 
   "isdir": false, 
   "access": "2020-08-09T14:44:28+00:00",
   "change": "2020-08-09T14:44:28+00:00", 
   "content": "Hello world!\n", 
   "creation": null, 
   "modification": "2020-08-09T14:44:28+00:00"
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...