powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / нужна блокировка!!!
25 сообщений из 30, страница 1 из 2
нужна блокировка!!!
    #36855034
songv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть сетевая база данных (по гражданам) в VFP9.0. Есть в ней поле, будем называть его порядковый номер и он должен быть распечатан в бланке. Есть таблица ss, расположенная не в базе данных, т.е. отдельно. Из одной записи, в которой указан последний номер по порядку. При добавлении в базу нового человека, система прописывает в поле "порядковый номер" значение+1 из таблицы ss и при нажатии на клавишу "Сохранить" кроме смысловых проверок по всем полям, происходит поиск по всей базе этого значения (на отсутствие дубля) и если дубля нет, то происходит добавление новой записи в БД.
Если несколько операторов добавлябт в БД собственную запсись (разных граждан) , то и у одного и др.оператора в разных карточках людей система показывает в поле "порядковый номер" одно и то же значение (из таблицы ss+1) .Если нажимают на клавишу "Сохранить" не в одну секунду, то система порядковый номер последнему нажавшему меняет автоматически, т.е. может присвоить не только на +1, но и вычислит последний, который прописался в ss (это может быть и +2, +3 - все с разной скоростью работают). Но если нажать на кл."Сохранить" в одну секунду обоим операторам, то получается дубль по порядковому номеру. Сразу скажу, что построить уникальный ключ по этому номеру в БД нельзя по определённым причинам (из-за старых наследуемых данных). Задача - чтобы при многопольз.работе порядковй номер не дублировался.
Думали, что FOX сам отследит... Как грамотно эту проблему решить? Пробовать перед SEEK по БД ставить flock и освободить файл только после сохранения -поставить unlock? Может какие-то др.варианты решения есть? ответ нужен срочно, т.к. в БД уже попали дубли и нужно внести изменения впрогу
...
Рейтинг: 0 / 0
нужна блокировка!!!
    #36855119
Ffffffffffffffff
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Поиск по NewID
...
Рейтинг: 0 / 0
нужна блокировка!!!
    #36855352
igorbik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
songv, таблица СС должна быть заблокирована (вся или одна запись) с момента ее чтения юзером и до тех пор, пока номер клиента не будет записан в таб. клиентов. Если будет работать, то снимите поиск двойников по этому полю.
...
Рейтинг: 0 / 0
нужна блокировка!!!
    #36855540
songv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
igorbik, поиск двойников не могу снять из-за наследуемых данных в БД (такие записи ранее были и они должны, увы, сохраниться в БД)
...
Рейтинг: 0 / 0
нужна блокировка!!!
    #36855716
igorbik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
songvigorbik, поиск двойников не могу снять из-за наследуемых данных в БД (такие записи ранее были и они должны, увы, сохраниться в БД)При таком наследстве, и учитывая, что двойников быть не должно, я бы поступил так:
1) если нет желания отказываться от таблицы SS, то найти максимальный номер клиента на сегодня и продолжить нумерацию с этого номера
2) если без SS (так у меня сделано), то примерно так:
а) блокируем всю таблицу с гражданами. Тогда в это время никто с ней ничего не сделает, разве что прочитать можно.
б) ищем макс. номер и наращиваем его на единицу
в) вставляем новую запись и вписываем туда этот номер
г) разблокируем таблицу.
Теперь любой другой юзер не запишет тот же номер.
В Инете есть много примеров, ищИте.
...
Рейтинг: 0 / 0
нужна блокировка!!!
    #36855898
songv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
igorbik, так всё и делается. если разница по времени несколько секунд между сохранением у разных операторов. Как только одновременно, в одну секунду - хоть тресни, дубль
...
Рейтинг: 0 / 0
нужна блокировка!!!
    #36856097
igorbik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
songv, причин может быть очень много, начиная с того, что все-таки не совсем так все сделано, и заканчивая хромым железом, софтом и сетью.
Попробуйте еще поиграться с параметрами блокировки (посмотрите в хелпе раздел "Блокировка данных", "Программирование многопользовательского доступа" и пр.)
...
Рейтинг: 0 / 0
нужна блокировка!!!
    #36856289
reware
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Имеется некая таблица (у меня MISC,DBF), в ней поле типа LASTNUM (N). Надо добавить запись -
Код: plaintext
1.
2.
3.
4.
5.
IF use_one('misc')
  nextnum=lastnum+ 1 
  APPEND <чего-то куда-то>
  REPLACE misc.lastnum WITH nextnum.
  USE IN misc
ENDIF

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
***************************************************************
Function use_one
***************************************************************
* Попытка открытия одной таблицы в сетевом
* окружении в течение заданного
* времени с дискретностью  0 . 5  сек.
* Отключает буферизацию записей и таблиц.
* Если таблице придан индекс CDX,назначает ведущим тег  1 .
* Делает выбранную область активной в случае успеха.
*!*	Перед открытием проверяется, не открыта ли 
*!*	уже эта таблица.
* Использование - use_one('base1', 0 , 1 ,.F.,'partner')
***************************************************************
param cname, ; && имя таблицы
	  narea, ; && номер области (или  0  для новой).По умолчанию =  0 
      ntime, ; && время (сек). По умолчанию =  3 
      lmode, ; && режим SHARED/EXCLUSIVE. По умолчанию - SHARED
      calias   && алиас. По умолчанию - имя таблицы

lsuccess=.t.
if empty(cname)
	return .f.
ENDIF
if empty(narea)
	narea= 0 
endif
if empty(ntime)
	ntime= 3 
endif
if empty(lmode)
	lmode=.f.
endif
if empty(calias)
	calias=JUSTSTEM(cname)
endif
if ntime< 1 
	ntime= 3 
ENDIF
IF USED(calias)
	RETURN .t.  && таблица уже была открыта до того, как...
endif
on error do TabOpenErr
begtime=seconds()
do while .t.
	tryagain=.f.
	if seconds()-begtime>ntime
		exit
	endif
	if lmode
		use &cname in (narea) exclusive alias &calias	
	else
		use &cname in (narea) shared alias &calias	
	endif
	if !tryagain
		lsuccess=.t.
		exit
	endif	
enddo
on error
if lsuccess
	if !empty(cdx( 1 , calias))
		set order to  1  IN (calias)
	endif
	=CURSORSETPROP('Buffering',  1 , calias)  && buffering off
	GO TOP IN (calias)
	return .t.
ELSE
	return .f.
endif
	

**************************************************
Procedure TabOpenErr
**************************************************
tryagain=.t.
lsuccess=.f.
inkey( 0 . 5 ,'H')  && дискретность выполнения USE
return
...
Рейтинг: 0 / 0
нужна блокировка!!!
    #36856881
songv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
reware,
у нас таблицы уже открыты, ничего открывать не нужно. Подозрение на то, что не успевает индекс обновиться по этому полю в таблице по гражданам, поэтому прога не видит, что этот номер уже записался
...
Рейтинг: 0 / 0
нужна блокировка!!!
    #36857035
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У Вас среди старых данных может существовать значение, которое еще только будет сформировано в таблице SS? Т.е. сам по себе генератор может создавать дубли?

Если такого быть не может, то, очевидно, что дело не в индексе, а в не корректном разрешении конфликтов совместного доступа. Логика примерно такая

- Первый пользователь нашел нужную запись в таблице SS и считал текущее значение
- Второй пользователь в то же самое время нашел эту же самую запись в таблице SS и считал то же самое значение
- Первый пользователь увеличил счетчик
- Второй пользователь "увеличил" счетчик, но по сути, оставил его без изменений

Как разрешить подобный конфликт? Очевидно, что считывать значение счетчика надо не ДО, а ПОСЛЕ установки блокировки. Т.е. логика становится примерно такая

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
* чтобы сгенерить ошибку недопустимого значения, если получить номер не удастся 
* предполагая, что значение NULL недопустимо присвоивать соответствующему полю
local lnID
lnID = null  

select ss
locate for (нужная запись)
if RLOCK()
    * Вот здесь надо считывать значение счетчика и изменять его значение
    * ПОСЛЕ установки блокировки
    lnID = ss.ID
    replace ID with ID +  1 
    UNLOCK
endif

return lnID

Разумеется, это всего-лишь общая схема. Тут еще надо кучу проверок сделать. Все-таки, воспользуйтесь поиском по данному сайту по ключевому слову "NEWID". Как написать этот код корректно много раз обсуждалось.
...
Рейтинг: 0 / 0
нужна блокировка!!!
    #36857082
Рома Б.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Попробуй сойти с записи непосредственно после replace (go recno)
...
Рейтинг: 0 / 0
нужна блокировка!!!
    #36857132
прошелмимо
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
songv Задача - чтобы при многопольз.работе порядковй номер не дублировался.
Думали, что FOX сам отследит...

версия фокспро?

у фокспро есть возможность создать автоинкриментн.счетчик.
чем он Вас не устроил?

Код: plaintext
1.
2.
3.
4.
Create Cursor tt (id i AUTOINC, fio v( 50 ) null)
Insert into tt (fio) values ("Петров")
Insert into tt (fio) values ("Иванов")
Insert into tt (fio) values ("Сидоров")
Select * from tt
...
Рейтинг: 0 / 0
нужна блокировка!!!
    #36857726
songv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ВладимирМ, именно так и делаем.
как думается, дело не в таблице ss (последний выданный номер). А в том, что когда запись с этим номером попадает после работы первого оператора в таблицу с гражданами, повторная проверка на уникальность по этой уже таблице не отрабатывается при сохранении вторым оператором новой записи с др.гражданином - за 1 сек. Как будто система не видит (не успевает увидеть), что уже первый оператор добавил запись с новым номером.
...
Рейтинг: 0 / 0
нужна блокировка!!!
    #36857775
songv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
прошелмимо,

естественно, что id есть и присваивается уникальным. Но этот номер - не есть id. Он в некоторых случаях может корректироваться оператором, поэтому дубль может возникнуть не только по последнему введённому номеру, но и по номеру, существующему в БД, внесённому ранее.
Представьте себе несколько пунктов, которые выдают гражданам определённые бланки, и каждому пункту из центра даётся определённый диапазон номеров. Т.Е. через какой-то временной интервал может следующий бланк быть с номером, не следующим по порядку за предыдущим, а с совершенно новым, и последующие номера на бланках должны распечатываться с +1 от этого нового номера. Да + к этому "старое наследство" записей, закаченных в систему, где дубли по номеру были. поэтому индекс кандидат на этом поле нельзя сделать
...
Рейтинг: 0 / 0
нужна блокировка!!!
    #36857841
прошелмимо
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
songvпрошелмимо,

естественно, что id есть и присваивается уникальным. Но этот номер - не есть id. Он в некоторых случаях может корректироваться оператором, поэтому дубль может возникнуть не только по последнему введённому номеру, но и по номеру, существующему в БД, внесённому ранее.
Представьте себе несколько пунктов, которые выдают гражданам определённые бланки, и каждому пункту из центра даётся определённый диапазон номеров. Т.Е. через какой-то временной интервал может следующий бланк быть с номером, не следующим по порядку за предыдущим, а с совершенно новым, и последующие номера на бланках должны распечатываться с +1 от этого нового номера. Да + к этому "старое наследство" записей, закаченных в систему, где дубли по номеру были. поэтому индекс кандидат на этом поле нельзя сделать

изв., меня учить не нужно - я работаю с САП
и разрабатываю на АБАП.
(а то начну плеваться и матюгаться)
у меня для этого дела есть интегрированные в "словарь"
диапазоны.

в вашем случае - самое простое - это ипользовать
фоксовый автоинкримент.

в противном случае - создать подобный нумератор
посредством создания таблички с полем-запоминателем
последнего номера.
номер вводить не давать, а присваивать в момент сохр-я,
блокируя и передергивая счетчик.

какой-то пример могу сваять.
в принципе такой нумератор при опред-м способе разработки может быть универсальным
и применяться для создяания сложных номеров с аналит.признаками
аля:

01-сент-001
01-сент-002
01-сент-002
...
02-сент-001
...
...
Рейтинг: 0 / 0
нужна блокировка!!!
    #36857844
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
songvВладимирМ, именно так и делаем.
как думается, дело не в таблице ss (последний выданный номер). А в том, что когда запись с этим номером попадает после работы первого оператора в таблицу с гражданами, повторная проверка на уникальность по этой уже таблице не отрабатывается при сохранении вторым оператором новой записи с др.гражданином - за 1 сек. Как будто система не видит (не успевает увидеть), что уже первый оператор добавил запись с новым номером.
Еще раз.

Если сам генератор сконструирован таким образом, что исключает генерацию одинаковых значений разными пользователями (пусть они и "одновременно" обращаются за новым значением), то дополнительная проверка на уникальность - это перестраховка, в общем-то, особо и не нужная.

Проблема-то не в том, что индекс там успевает или не успевает, а в том, что программа сгенерила одинаковые значения. То, что не сумели потом пресечь их использование - это другой разговор (думаю, проще сделать индекс CANDIDATE с for-условием). Это уже следствие, а не причина.

Также мне кажется, что дело не в обновлении индекса, а в том, что на момент проверки никакого дубля и не было. Ну, не успел еще второй пользователь что-то там записать, просто физически нет дубля. Опять возвращаемся к тому, с чего начали - уникальность должен обеспечивать сам генератор значений, а не последующая проверка.

Попробуйте еще такой фокус

Код: plaintext
1.
2.
3.
4.
IF RLOCK()
    go Recno()
    ...
ENDIF

Фиктивный переход на ту же самую запись позволяет обновить буфер этой записи. Возможно, при "одновременной" генерации тот пользователь, который сидит на Reprocess в команде RLOCK() "не видит" изменений, сделанных другим пользователем/
...
Рейтинг: 0 / 0
нужна блокировка!!!
    #36857908
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
songvестественно, что id есть и присваивается уникальным. Но этот номер - не есть id. Он в некоторых случаях может корректироваться оператором, поэтому дубль может возникнуть не только по последнему введённому номеру, но и по номеру, существующему в БД, внесённому ранее.
Вот оно в чем дело. Т.е. генератор значений предлагает некое значение, а затем пользователь может его скорректировать. И рассматриваем ситуацию, когда два пользователя "одновременно" ввели два одинаковых значения.

Ну, в этом случае генератор значений вообще никакого отношения не имеет к обсуждаемой проблеме. Представьте себе, что два пользователя "одновременно" дали команду на вставку

Код: plaintext
insert into MyTab (MyField) values ( 1 )

Никакие внешние проверки ничего не смогут противопоставить возникновению подобного "дубля". Ведь оба пользователя сделали проверки ДО собственно вставки. Когда ни один из них еще ничего физически не вставил. Действительно, не было дубля.

- Первый пользователь проверил - нет дубля
- Второй пользователь проверил - нет дубля, поскольку первый еще ничего не вставил
- Первый пользователь вставил
- Второй пользователь вставил - получили дубль

Подобные дубли можно отловить только на уровне контроля базы данных следующими способами

1. Индекс Candidate/Primary. Возможно, с for-условиями
2. Триггер на вставку (но это если таблица включена в контейнер базы данных)
...
Рейтинг: 0 / 0
нужна блокировка!!!
    #36857973
прошелмимо
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
songv Как будто система не видит (не успевает увидеть), что уже первый оператор добавил запись с новым номером.

ок.
покажите как Вы добавляете записи в табличку.

я бы сделал прибл. так:

1. поднял курсорадаптер с условием фолс
2. добавил в курсорадаптер новую запись
3. автоматом вычислил новый номер (возможен и хитрый алгоритм по возможным диапазонам для какой-то группы пользователей)
4. сохранил изменения в основную таблицу-источник
(возможно применив какой-то алгоритм, который сработает со стороны БД -
если уж так "вкрай" необходимо отсутствие дублей)

и не давал-бы возможности руками править этот номер.
...
Рейтинг: 0 / 0
нужна блокировка!!!
    #36858320
songv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ВладимирМ,
вы всё правильно поняли.
первый предложенный вами вариант (с кандидатом)не подходит. А второй - не очень понятно, что вы имеете ввиду?
Мы сейчас увидели такой сюжет в трейси. Когда сами программно заблокировали таблицу от вставки записи - программа сняла автоматически блокировку (это произошло при генерации primery ключа для главной таблицы базы данных) . Ну и понятно, что дальше понятие блокировки уже отсутствует.
Праймери ключом является guid. Похоже, что формирование ключа сбивает блокировку.
Ничего не получается, блин
...
Рейтинг: 0 / 0
нужна блокировка!!!
    #36858334
ПЗРК0012
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Во нахреначили!
...
Рейтинг: 0 / 0
нужна блокировка!!!
    #36858369
songv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ПЗРК0012, это не мы, это законы такие дурацкие, что под них проги нельзя адеквтные, нормализованные писать
...
Рейтинг: 0 / 0
нужна блокировка!!!
    #36858403
ПЗРК0012
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Не мое, но это то что Вам нужно. Привет Благовещенску.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
Как все у Вас сложно...

Начать можно попроще - написать для каждой открытой таблицы (опять же через цикл) что-то типа:
do chbuf
 
где:

 * check for all table
PROCEDURE chbuf
IF CURSORGETPROP("Buffering")= 5 
  LOCAL llOverwrite,llChanged, lnField,lcField, lnRec
  GO TOP
  lnRec=GETNEXTMODIFIED( 0 )
  DO WHILE lnRec<> 0 
    GOTO lnRec
    llCnanged=.F.
    llOverwrite=.F.
    FOR lnField= 1  TO FCOUNT()
      lcField=FIELD(lnField)
      IF CURVAL(lcField)<>OLDVAL(lcField)
        llCnanged=.T.
        EXIT
      ENDIF
    ENDFOR
    IF llCnanged
      lnResult=MESSAGEBOX("Somebody locked your table. What we have to do?", 4 ,"Try again")
      IF lnResult= 6 
        llOverwrite=.T.
      ENDIF
    ENDIF
    IF llCnanged AND NOT llOverwrite
      =TABLEREVERT()
    ELSE
      IF m.gltransact
        BEGIN TRANSACTION
        =TABLEUPDATE(.F.,.T.)
        END TRANSACTION
      ELSE
        =TABLEUPDATE(.F.,.T.)
      ENDIF
    ENDIF
    lnRec=GETNEXTMODIFIED(lnRec)
  ENDDO
ENDIF
RETURN
 
...
Рейтинг: 0 / 0
нужна блокировка!!!
    #36858861
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
songvВладимирМ,
вы всё правильно поняли.
первый предложенный вами вариант (с кандидатом)не подходит.
Почему? Ведь в FOR-условии можно просто отсечь все "архивные" данные, написав условие, например, больше какого-то значения. Впрочем, Вам виднее

songvА второй - не очень понятно, что вы имеете ввиду?
Если таблица включена в контейнер базы данных, то в режиме дизайнера таблицы будет доступна закладка Table. Там есть группа полей "Triggers", где можно написать вызов функций при возникновении событий вставки/изменения/удаления записи.

Подробнее про триггер здесь Триггер

Тут "фишка" в том, что на момент срабатывания триггера все значения всех полей текущей записи (в FoxPro триггер обрабатывает изменения всегда только одной записи) уже сформированы, запись заблокирована, но пока еще эти изменения не сброшены в таблицу. Вот тут-то и можно запустить проверку уникальности. Если очень надо, могу привести пример подобного триггера.

songvМы сейчас увидели такой сюжет в трейси. Когда сами программно заблокировали таблицу от вставки записи - программа сняла автоматически блокировку (это произошло при генерации primery ключа для главной таблицы базы данных) . Ну и понятно, что дальше понятие блокировки уже отсутствует.
Праймери ключом является guid. Похоже, что формирование ключа сбивает блокировку.
Ничего не получается, блин
Ну, это Вы разбирайтесь со своим кодом, почему у Вас происходит сброс блокировок. Скорее всего, Вы используете UNLOCK без указания записи, с которой надо снять блокировку. В этом случае действительно блокировка сниматся со всех записей.

Это я к тому, что в описанной ситуации - однозначно не корректный код по установке/снятию блокировок. Причем именно код на FoxPro. API-функции генерации GUID тут явно не при чем.
...
Рейтинг: 0 / 0
нужна блокировка!!!
    #36858877
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да, на чем основана уверенность, что "тригер не пропустит".

Если таблица имеет индексный тег по контролируемому полю (любой индекс, достаточно обычного Regular) и все это выполняется внутри транзакции, то на момент выполнения транзакции файл индекса будет блокирован для модификции. Весь файл индекса . Как следствие, пока не будет закрыта или отменена транзакция никто не сможет изменить те поля, по которым построен индекс ни в одной записи.
...
Рейтинг: 0 / 0
нужна блокировка!!!
    #36859313
прошелмимо
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВладимирМНу, это Вы разбирайтесь со своим кодом, почему у Вас происходит сброс блокировок. Скорее всего, Вы используете UNLOCK без указания записи, с которой надо снять блокировку. В этом случае действительно блокировка сниматся со всех записей.


возможно там происходит "топтание" по записи основной таблицы и
куча реплейсов.

в фокспро можно работать с основной таблицей через буфер посредством
курсорадаптера.

в таком буфере можно подготовить новую запись и "топтаться" по ней сколько угодно,
а затем одним махом положить такую новую запись в основную таблицу.

использование КАДа в таком случае облегчает разработку и
оберегает от ряда подобных коллизий.
...
Рейтинг: 0 / 0
25 сообщений из 30, страница 1 из 2
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / нужна блокировка!!!
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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