powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Зависание Prepare
43 сообщений из 43, показаны все 2 страниц
Зависание Prepare
    #39284983
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У нас в базе, в BLOB полях, хрянятся SQL (DML) запросы. Соответственно, когда в процессе разработки, начинают меняться метаданные, эти запросы могут перестать выполняться. Поэтому был придуман такой финт: перед выкладыванием базы в тестирование, для всех этих запросов делается prepare и, если возникает ошибка, то идет останов всего процесса, с уведомлением, где именно ошибка.

Все это реализовано в виде UDF, на вход которой, подается имя базы. Она внутри открывает свой коннект к указанной базе, вытягивает все запросы и делает им prepare. Код, примерно, такой
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
function Test(const ADBName: string): string;
begin
  db.DatabaseName := ADBName;
  db.Open;
  try
    qrySQLs.ExecQuery;
    while not qrySQLs.Eof do begin
      qryPrepare.SQL.Text := qrySQLs.FieldByName('SQL').AsString;
      try
        qryPrepare.Prepare;
        qryPrepare.UnPrepare;
      except
        on E: Exception do begin
          Result := E.Message;
          Exit;
        end;
      end;
      qrySQLs.Next;
    end;   
  finally
    db.Close;
  end;
end;


Все отлично работало до сегодняшнего дня. Сегодня эта UDF зависла. Разбирательство показало, что зависание происходит на первом вызове qryPrepare.Prepare, точнее при вызове функции isc_dsql_execute(). Call stack показывал кучу вызовов gds32.dll, потом вызов mswsock.dll и ожидание на WaitFor функции.

Я менял сортировку в qrySQLs. Все равно на первом запросе (уже другом) - зависание. Также было замечено, что если до вызова UDF сделать, в том же коннекте, prepare какого-нибудь запроса, то зависания нет.

Все вылечилось после Backup/Restore базы, но хотелось бы понять, что это вообще было?

С уважением, Vasilisk
...
Рейтинг: 0 / 0
Зависание Prepare
    #39285003
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

и какой только ерунды не выдумают...
Почему это обязательно должно делаться в UDF?
...
Рейтинг: 0 / 0
Зависание Prepare
    #39285013
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов ДенисПочему это обязательно должно делаться в UDF?В этом обсуждении сказано почему
...
Рейтинг: 0 / 0
Зависание Prepare
    #39285433
fb user
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Симонов Дениси какой только ерунды не выдумают...
Почему это обязательно должно делаться в UDF?
hvladТы не трынди о чём не знаешь.hvlad похоже хотел это вам написать, но что-то его отвлекло и он написал это мне: 19489421 .
...
Рейтинг: 0 / 0
Зависание Prepare
    #39285437
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fb user,

нет он написал это тому кому хотел.

Вот он ещё один любитель внутри UDF коннекты делать. Да ещё с помощью Delphi компонент.
...
Рейтинг: 0 / 0
Зависание Prepare
    #39285465
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_В этом обсуждении сказано почему
ничего внятного про UDF в том обсуждении не нашел. IBEScript - сколько угодно. а UDF - это через ж.
...
Рейтинг: 0 / 0
Зависание Prepare
    #39285481
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kdvничего внятного про UDF в том обсуждении не нашел. IBEScript - сколько угодно. а UDF - это через ж.В IBEScript нет Prepare. Только Execute
...
Рейтинг: 0 / 0
Зависание Prepare
    #39285489
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_ В IBEScript нет Prepare. Только Execute

и что? Написать свою утилиту для проверки запросов не так уж сложно. Зачем это в UDF пихать?
...
Рейтинг: 0 / 0
Зависание Prepare
    #39285491
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

программа, которой дают БД, выбирают таблицу, и столбец для prepare (хоть варчар, хоть блоб), которая делает prepare и пишет лог по успеху неуспеху - пишется не более чем за 30-60 минут.

кроме того, я не понимаю, почему вместо ответа в 15-20 слов "udf сделана потому что", или вместо ссылки на конкретное сообщение, где дается такой же ответ, надо давать ссылку на всю эту переписку. Где лично я сразу спросил почему нельзя приложение написать, и сказал то же самое про "зад" и "udf" ?
...
Рейтинг: 0 / 0
Зависание Prepare
    #39285494
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов ДенисЗачем это в UDF пихать?Чтобы все это вставить в один скрипт по очистке базы
...
Рейтинг: 0 / 0
Зависание Prepare
    #39285500
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

это не ответ. Скрипт тоже может делать приложение. В чём сокральный смысл пихать невпихуемое делать это именно в UDF?
...
Рейтинг: 0 / 0
Зависание Prepare
    #39285517
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денисэто не ответ.
- У меня не заводится машина, что делать?
- А зачем Вы купили машину?
- Чтобы быстро попадать из точки А в точку Б
- Это не ответ. Пешком тоже можно легко попадать куда угодно. И бензин покупать не нужно
...
Рейтинг: 0 / 0
Зависание Prepare
    #39285537
fb user
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Симонов ДенисВот он ещё один любитель внутри UDF коннекты делать. Да ещё с помощью Delphi компонент.
Расскажите поподробней, почему по-вашему в виндовой dll нельзя делать вызовы к другой виндовой dll? А особенно с помощью Delphi компонент. Давайте чисто технически, почему нельзя, какой конкретно код в FB накладывает такие ограничения на разработчиков UDF? Я наивно полагал что могу взять и из UDF или UDR присоединиться например к FB4 и мне за это ничего не будет. Верней я полагал что разработчики FB сделают юзерам правильно, и оно просто будет работать. Не будет: CORE-5123 . Юзерам придётся наступить, прийти в трекер, увидеть что тикет уже висит, задаться вопросом "а какого хрена эта банальщина не исправлена", дальше возможно прийти на sql.ru и увидеть как некто Симонов Денис глумится над такими же "недалёкими" разработчиками. А когда они узнают что глумящийся - это человек из команды FB, которая собственно и создала багу, то что они сделают? Покрутят у виска.
...
Рейтинг: 0 / 0
Зависание Prepare
    #39285547
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fb user,

Ничего - кроме того что любые непредсказыемые баги и задержки в UDF могут обрушить весь сервер и/или испортить БД

а вот отдельное приложение этого не может

Особенно будет красиво если UDF вытащит скрипт, который ее дропнет :-)

PS. почему это нельзя сделать просто на SP + Execute Statement ?
...
Рейтинг: 0 / 0
Зависание Prepare
    #39285552
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fb user,

из UDR делать коннект к другой БД (может даже и не Firebird) вполне нормально, из UDF нет.

Тем более посмотри на то как он это делает. Ладно бы ещё через Firebird API, так нет засунем в UDF половину VCL библиотеки.

И дело даже не в том возможно это принципиально или нет. А в том что это проктостоматологическое решение.

С чего ты взял что CORE-5123 к костылям автора имеет хоть какое-то отношение?

fb userА когда они узнают что глумящийся - это человек из команды FB, которая собственно и создала багу, то что они сделают?

Я не имею никакого отношение к разработке FB. Да документирую SQL, обсуждаю некоторые фичи, но не более того.
...
Рейтинг: 0 / 0
Зависание Prepare
    #39285561
fb user
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
AriochPS. почему это нельзя сделать просто на SP + Execute Statement ?
Есть табличка:
Код: sql
1.
 CREATE TABLE SQLS (ID INTEGER, SQL BLOB SUB_TYPE TEXT)


Человек как я понимаю хочет чего-то такого:
Код: sql
1.
2.
3.
4.
5.
6.
7.
EXECUTE BLOCK RETURNS (ID INTEGER) AS
  DECLARE SQL BLOB SUB_TYPE TEXT;
BEGIN
  FOR SELECT ID, SQL FROM SQLS INTO :ID, :SQL DO
    IF (PREPARE_SQL(:SQL) <> 1) THEN
      SUSPEND;
END


Какой код предлагаете вы?
...
Рейтинг: 0 / 0
Зависание Prepare
    #39285564
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fb userЧеловек как я понимаю хочет чего-то такого:Именно! Причем, меня вполне устроит если PREPARE_SQL() будет кидать исключение, а не возвращать код ошибки. Но это не важно
...
Рейтинг: 0 / 0
Зависание Prepare
    #39285567
Andrey_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ariochлюбые непредсказыемые баги и задержки в UDF могут обрушить весь сервер и/или испортить БДЭто в концепции UDF присутствует изначально. И не важно, сделано это с помощью делфи и фибов или с помощю udf написанной на обероне и вызывающей ShellExecute или еще как посмешнее.
Архитектурно, да, хочется плакать кровью от такого подхода. Но формально разницы между пустой UDF и UDF выполняющей коннект к какой-то базе нет.
...
Рейтинг: 0 / 0
Зависание Prepare
    #39285568
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fb user,

предположим что UDF написана без бага.

Код: sql
1.
2.
3.
4.
5.
6.
7.
EXECUTE BLOCK RETURNS (ID INTEGER) AS
  DECLARE SQL BLOB SUB_TYPE TEXT;
BEGIN
  FOR SELECT ID, SQL FROM SQLS INTO :ID, :SQL DO
    IF (PREPARE_SQL(:SQL) <> 1) THEN
      SUSPEND;
END



сколько раз произойдёт CONNECT/DISCONNECT пока будет выполняться сей блок?
...
Рейтинг: 0 / 0
Зависание Prepare
    #39285576
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Дениссколько раз произойдёт CONNECT/DISCONNECT пока будет выполняться сей блок?
_Vasilisk_Все это реализовано в виде UDF, на вход которой, подается имя базы. Она внутри открывает свой коннект к указанной базе, вытягивает все запросы и делает им prepareОтвет: один. Сейчас у меня в UDF передается не SQL, а только путь к базе.

Как сделать prepare штатными средствами БД или IBExpert - мне так никто и не сказал
...
Рейтинг: 0 / 0
Зависание Prepare
    #39285579
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

один? А мне казалось столько у тебя записей вернёт запрос SELECT ID, SQL FROM SQLS. Ты проверял что один? Трейсом например.
...
Рейтинг: 0 / 0
Зависание Prepare
    #39285581
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денис,

извиняюсь, запрос то не твой, а fb_user
...
Рейтинг: 0 / 0
Зависание Prepare
    #39285583
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

в любом случае этому не место в UDF.

_Vasilisk_Как сделать prepare штатными средствами БД

с помощью SQL или PSQL никак.
...
Рейтинг: 0 / 0
Зависание Prepare
    #39285593
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fb userAriochPS. почему это нельзя сделать просто на SP + Execute Statement ?
Есть табличка:
Код: sql
1.
 CREATE TABLE SQLS (ID INTEGER, SQL BLOB SUB_TYPE TEXT)



Человек как я понимаю хочет чего-то такого:
Код: sql
1.
2.
3.
4.
5.
6.
7.
EXECUTE BLOCK RETURNS (ID INTEGER) AS
  DECLARE SQL BLOB SUB_TYPE TEXT;
BEGIN
  FOR SELECT ID, SQL FROM SQLS INTO :ID, :SQL DO
    IF (PREPARE_SQL(:SQL) <> 1) THEN
      SUSPEND;
END



Какой код предлагаете вы?

Код: sql
1.
2.
FOR SELECT ID, SQL FROM SQLS INTO :ID, :SQL DO
  EXECUTE STATEMENT :SQL



По вкусу - логгирование, перехват исключений, autonomous transaction и т.д.
...
Рейтинг: 0 / 0
Зависание Prepare
    #39285596
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arioch,

это будет работать ужасно. Даже если транзакции с модифицирующими запросами будут откачены, то сами запросы могут быть довольно тяжёлыми. Предлагаешь их выполнять?
...
Рейтинг: 0 / 0
Зависание Prepare
    #39285599
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arioch
Код: sql
1.
2.
FOR SELECT ID, SQL FROM SQLS INTO :ID, :SQL DO
  EXECUTE STATEMENT :SQL

12874261 , 12874351
...
Рейтинг: 0 / 0
Зависание Prepare
    #39285601
fb user
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Симонов Денисfb user,

предположим что UDF написана без бага.

Код: sql
1.
2.
3.
4.
5.
6.
7.
EXECUTE BLOCK RETURNS (ID INTEGER) AS
  DECLARE SQL BLOB SUB_TYPE TEXT;
BEGIN
  FOR SELECT ID, SQL FROM SQLS INTO :ID, :SQL DO
    IF (PREPARE_SQL(:SQL) <> 1) THEN
      SUSPEND;
END



сколько раз произойдёт CONNECT/DISCONNECT пока будет выполняться сей блок?
Столько сколько закодит разработчик.

А вот такое вообще не понятно взлетит или нет, потому как код FB будет путать свои и чужие dll ( CORE-5123 ). Плюс ещё возможно и потому что не умеет выгружаться полностью ( CORE-5299 )
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
CREATE TABLE SERVERS (ID INTEGER, LIB VARCHAR(100), CONNSTRING VARCHAR(200))

INSERT INTO SERVERS (ID, LIB, CONNSTRING) (1, 'fb\2.5.6\fbembed.dll', 'db\2.5.6\data.fdb');
INSERT INTO SERVERS (ID, LIB, CONNSTRING) (2, 'fb\3.0.0\fbclient.dll', 'db\3.0.0\data.fdb');
INSERT INTO SERVERS (ID, LIB, CONNSTRING) (3, 'fb\3.0.1\fbclient.dll', 'db\3.0.1\data.fdb');
INSERT INTO SERVERS (ID, LIB, CONNSTRING) (4, 'fb\4.0.0.snapshot\fbclient.dll', 'db\4.0.0.snapshot\data.fdb');

EXECUTE BLOCK RETURNS (ID INTEGER, SERVERID INTEGER) AS
  DECLARE SQL BLOB SUB_TYPE TEXT;
  DECLARE LIB VARCHAR(100);
  DECLARE CONNSTRING VARCHAR(200);
BEGIN
  FOR SELECT ID, SQL FROM SQLS INTO :ID, :SQL DO
    FOR SELECT ID, LIB, CONNSTRING FROM SERVERS INTO :SERVERID, :LIB, :CONNSTRING DO
      IF (PREPARE_SQL2(:LIB, :CONNSTRING, 'SYSDBA', 'masterkey', :SQL) <> 1) THEN
        SUSPEND;
END
...
Рейтинг: 0 / 0
Зависание Prepare
    #39285603
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

да что ты всё к UDF привязываешься. Сделать консольное приложение которое будет подключаться 1 раз, считывать все твои запросы, препарировать их и выкидываю лог неудач дело одного дня максимум.
А с UDF ты ещё долго будешь гадать на кофейной гуще.
...
Рейтинг: 0 / 0
Зависание Prepare
    #39285609
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

а что толку тебе препарировать вызов процедуры без её реального выполнения ?
проверить что совпадает количество параметров - и всё.
...
Рейтинг: 0 / 0
Зависание Prepare
    #39285610
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денис,

Вы очень резки сегодня. Давайте всё же подумаем о компромиссах!

Сделаем таки UDF, которая запустит консольное приложение...
...
Рейтинг: 0 / 0
Зависание Prepare
    #39285621
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arioch,

я сама доброта. Вот если бы тут появился Dimitry Sibiryakov или МП...
...
Рейтинг: 0 / 0
Зависание Prepare
    #39285638
fb user
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Симонов ДенисВот если бы тут появился Dimitry Sibiryakov или МП...
Да они бы сразу показали разработчикам FB где у них не правильно. Это вы всё стесняетесь видеть ясно :)
...
Рейтинг: 0 / 0
Зависание Prepare
    #39285643
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денисда что ты всё к UDF привязываешьсяУже писал_Vasilisk_Чтобы все это вставить в один скрипт по очистке базы
Симонов ДенисА с UDF ты ещё долго будешь гадать на кофейной гуще.UDF после Backup/Restore отлично заработала. Повторюсь - это была единственная проблема, за все пять лет использования механизма. Проблема решена. Мне было интересно, подскажет ли кто в чем была причина. Вот и все
Ariochа что толку тебе препарировать вызов процедуры без её реального выполнения ?
проверить что совпадает количество параметров - и всё.Вот именно! Проверить количество параметров в процедурах, проверить имена полей в SELECT/UPDATE запросах...
...
Рейтинг: 0 / 0
Зависание Prepare
    #39285717
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fb userДавайте чисто технически, почему нельзя, какой конкретно код в FB накладывает такие ограничения на разработчиков UDF?
Да все можно. Понятно - udf написана чтобы можно было ее вызывать в sql из каких-то других скриптовых языков. Но раз она написана на Дельфи, то зачем нужен вот этот анус - можно же этот кусок кода udf использовать прямо из программы на Дельфи, и не иметь проблем ни с разрядностью udf, ни с будущей совместимостью, ни с какими-то потенциальными багами сервера, и т.д.
...
Рейтинг: 0 / 0
Зависание Prepare
    #39285719
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_Чтобы все это вставить в один скрипт по очистке базы
в смысле - не сделать список запросов для исправления в соответствии с новыми метаданными, а тупо этот список грохнуть, что-ли?
Мне казалось, что описываемая проблема имеет только один тип решения - ручное исправление.
...
Рейтинг: 0 / 0
Зависание Prepare
    #39285742
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kdv_Vasilisk_Чтобы все это вставить в один скрипт по очистке базы
в смысле - не сделать список запросов для исправления в соответствии с новыми метаданными, а тупо этот список грохнуть, что-ли?
Мне казалось, что описываемая проблема имеет только один тип решения - ручное исправление.в смысле есть скрипт, который прогоняется на девелоперской базе перед выкладыванием ее на тестирование. Этот скрипт оччищает таблицы, сбрасывает значения генераторов, заносит дефолтные данные и т.д. В этом же скрипте воткнута проверка таблицы запросов. При обнаружении ошибки скрипт сообщает о ней и останавливается
...
Рейтинг: 0 / 0
Зависание Prepare
    #39285747
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_есть скрипт
А интерпретатор этого скрипта команду SHELL сосем не понимает?..
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Зависание Prepare
    #39285752
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fb user,

кстати твои ссылки на тикеты в трекере здесь совсем не в тему. У ТС вообще Interbase. Он не имеет ничего общего с плагинной архитектурой тройки, линковкой fbclient и т.д.
...
Рейтинг: 0 / 0
Зависание Prepare
    #39285755
fb user
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Симонов ДенисУ ТС вообще Interbase.
Да не, ТС бы нас давно поправил.
...
Рейтинг: 0 / 0
Зависание Prepare
    #39285758
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovА интерпретатор этого скрипта команду SHELL сосем не понимает?..Это мысль. Есть ibec_Exec и, вроде, он позволяет парсить выхлоп
...
Рейтинг: 0 / 0
Зависание Prepare
    #39285759
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fb userТС бы нас давно поправил.IB. Но в чем поправлять? Не было предложено ни одного решения. Вот Сибиряков натолкнул на мысль
...
Рейтинг: 0 / 0
Зависание Prepare
    #39285760
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fb user,

почитай тот топик

_Vasilisk_Симонов ДенисПочему это обязательно должно делаться в UDF?В этом обсуждении сказано почему
...
Рейтинг: 0 / 0
Зависание Prepare
    #39285762
fb user
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Vasilisk_fb userТС бы нас давно поправил.IB. Но в чем поправлять?
Перечитал. Увидел. Кое-кому нужно быть внимательней (не буду показывать на себя пальцем).
...
Рейтинг: 0 / 0
43 сообщений из 43, показаны все 2 страниц
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Зависание Prepare
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]