Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2003.05.29;
Скачать: [xml.tar.bz2];

Вниз

BDE. Ошибка с SQL и уникальным индексом   Найти похожие ветки 

 
-=Guest=-   (2003-05-05 21:24) [0]

Есть таблица Paradox.
Поля ID, ID1, ID2 - все Long Integer
ID - первичный ключ.
По полям ID1 и ID2 есть уникальный индекс.

Добавляю значения 1,1,1
Затем используя TTable пытаюсь добавить 2,1,1 - естественно "Key violuation"

Но беру TQuery и делаю "Insert Into "MyTable.db" Values(2,1,1)"

Добавило !!!

После этого и TTable и TQuery может вводить любые дублирующиеся записи(типа 3,1,1 4,1,1 и т.д.), а если сделать переиндыксацию таблицы - то мой уникальный индекс вообще удаляется, как будто его и не было.

Проверил на трех машинах Win98-D5 и WinXp-D7

Для работы с таблицей использовал Database Explorer(из RxLib Demo) и SQL Explorer из Delphi.
Таблица создавалась в Database Desktop.


 
MsGuns   (2003-05-05 21:45) [1]

Нет никакой ошибки - все АБСОЛЮТНО КОРРЕКТНО с точки зрения лок.БД и парадокс в частности.

>Затем используя TTable пытаюсь добавить 2,1,1 - естественно "Key violuation"

Конечно, естественно - ведь индекс у тебя активный ? Вот BDE ПЕРЕД физ.вставкой сделала поиск по активному индексу, нашла повтор и "вытолкнула" запись

>Но беру TQuery и делаю "Insert Into "MyTable.db" Values(2,1,1)"
Добавило

И тоже естественно. Для запроса BDE не держит кэш активных индексов (ведь у тебя нет RequestLive и вообще выполняется метод ExecSQL, а не Open) и, след-но, не делает проверки ПЕРЕД добавлением. Т.к. PK новой записи уникален, то она спокойно добавляется.

Парадокс - это не Сервер, который в соответствии с заданными в самой БД метаданными правилами НЕЗАВИСИМО ОТ ИСТОЧНИКА И СПОСОБА запроса осуществляет ОБЩИЙ для всех контроль данных во всех таблицах БД.




 
-=Guest=-   (2003-05-05 22:02) [2]

Возможно, но если сделать уникальный индекс по одному полю (напр. ID1), то SQL проверяет дублирование и выдает "key violuation", а если сделать уникальный индекс по двум полям - то происходит описанное выше. Почему так.

Спасибо за ответ,MsGuns ©.
А какой выход. Сейчас проверяю Locate"ом - но это заметно медленнее, чем если бы велась проверка на уровне BDE. Изпользовать TTable невозможно - запрос из нескольких таблиц, результат которого правится в Grid"e как в Excel. Заметны тормоза при переходе со строки на строку. На SQLServer переходить тоже нет смысла - там один пользователь.
Может есть варианты. Подскажите.


 
-=Guest=-   (2003-05-05 22:13) [3]

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


 
MsGuns   (2003-05-05 22:14) [4]

САМЫЙ ЛУЧШИЙ ВАРИАНТ - это кинуть парадокс и взять НОРМАЛЬНЫЙ СЕРВЕР. Например, Firebird (клон IB). Бесплатен, легок, шустр, надежен.
И дело даже не в том, многопользовательская БД или нет. Хотя бы в том, что мнлжество логики можно легко и просто делать в метаданных непосредственно на сервере в БД. Полнофункциональная поддержка транзакций (имеется в виде не операция на ОДНОЙ таблице, а логическая цепочка последовательных изменений во многих таблицах). Забудешь про слеты индексов, "Table is busy", lck и т.д.


 
MsGuns   (2003-05-05 22:23) [5]

Если все же полюбляешь парадокс, то и в нем можно эффективно работать с индексами, помня, однако, ЧТО ИНДЕКСЫ - ЕСТЬ ВСЕГО ЛИШЬ ДОПОЛНИТЕЛЬНОЕ ЛОГИЧЕСКОЕ СРЕДСТВО для повышения эффективности доступа к таблицам и применяются ЛОКАЛЬНО, т.е. в том приложении, которое их активизирует. Из этого следует, что если надо обеспечить уникальность значений совокупности некоторых
НЕКЛЮЧЕВЫХ (PK) полей таблиц, то:
- Не проработана как следует топология БД (структуры таблиц, ключи, связи, разбиение инфы по таблицам - нормализация и т.д.)
- Обеспечить программно защиту от появления в таблице "дублей"
(например перед постом давать запрос "левым" TQuery и смотреть рез-т)
- Перейти на трехзвенку, где можно централизовать всю логику работы с БД и не зависеть от "прихоти" клиентов-приложений.


 
MsGuns   (2003-05-05 22:29) [6]

По поводу Locate.
Одна из славных черт парадокса - быстрота обслуживания курсора (через BDE). Т.е. скачки по НД размером в несколько сот и даже тысяч записей выполняются существенно быстрее (для TTable), чем даже во многих серверных технологиях. "Тормоза" у тебя не от этого, а по-видимому, от того, что при скакании по НД ты не отключаешь отображение. Делай так:

Grid1.DataSource.Enable := false;
Table1.Locate...
все что вздумается, пока не надоест
Grid1.DataSource.Enable := true;

и почувствуй разницу !





 
-=Guest=-   (2003-05-05 22:32) [7]

Жар-птица вне конкуренции, однозначно надежнее, но быстрее ли(как локальная БД). Приложение то уже написано и юзается. С другой стороны стремно если вдруг все полетит и отхватить люлей. Но без опыта работы на FireBird тоже переходить не очень класно.


 
Dred2k   (2003-05-05 22:35) [8]


> MsGuns © (05.05.03 21:45)

Говоришь ты абсолютную лажу. Если б было так, то BDE вообще не вышел бы на рынок - зачем, при такой-то тупорылой несостоятельности...
Никаких аргументов далее не будет - просто возьми и попробуй, тогда можно будет обсудить.
(а то встречаю, порой, от любителей серверов такое, что просто и вдруг ставит жирный крест на всей повседневной рутинной работе систем DBISAM, в т.ч. и парадокса, которую я имею счастье наблюдать ежедневно - работа надежная и полезная, при грамотном использовании, правда).
Короче, не грузи. А то одна реклама "сникерсов" + немного псевдонаучных гаданий...
(у товарища либо индекс слетел во время бурных экспериментов, либо "надо посмотреть"...)


 
-=Guest=-   (2003-05-05 22:52) [9]

тебе "надо посмотреть"


 
Dred2k   (2003-05-05 23:03) [10]


> -=Guest=- (05.05.03 22:52)
> тебе "надо посмотреть"

Это по-любому смотреть надо, и тебе - в первую очередь. Если все так, как тобой описано - случай неадекватный, эт точно. Предположить на ходу сколь-нибудь реальное объяснение не могу - _такой_ ситуации не возникало (были похожие траблы, но все заканчивалось порченной, т.е. упавшей, таблицей - по индексам опять же, но такая нормально не откроется в TTable, TQuery тоже скажет об "index corrupted").
MsGuns кудряво так все описал, что я куплю себе учебник по софистике... Для начинающего.


 
-=Guest=-   (2003-05-05 23:15) [11]

Ты все таки посмотри. Я выходные просидел за перебиранием кода - думал что чето замутил, ведь не должно быть такого. Проверял на трех машинах под разными осями и делфами. Или ты думаешь мы тут в писочнице играем и по каждой мелочи в форум лезем. Все проверено и перепроверено. Иду спать, 14-й час за компом. До завтра.
Будут варианты - пиши.


 
Dred2k   (2003-05-05 23:46) [12]


> -=Guest=- (05.05.03 23:15)

Да нет, вариантов не будет. Вот сейчас тоже спать пойду - только логи забэкаплю от пары сервачков (типа приложений) и агента статистики. Тоже самое: десятки тыщ записей, постоянное обновление, сеть, ключи, уникальные индексы, TQuery (иногда TTable c CachedUpdates) и гвоздь программы - "Paradox - да и только" (ясный перец - недостойный внимания "небольших супермонстров"). И уже больше двух лет пашет в слегка обновляемой версии (для поддержки)...
(сладко зевая) Спокойной ночи! ;)


 
MsGuns   (2003-05-06 00:46) [13]

>Dred2k

Да, крутой орех ! И, главное, ведь такое впечатление, что сам верит в то, что несет !;))


 
Verg   (2003-05-06 08:58) [14]

Не, на самом деле "орех" прав.
Никогда такого не бывало, чтобы уникальные индексы дублировались.
Если id1 и id2 образуют составной уникальный индекс,названный, например, id12, то при выполнении SQL вносящего неуникальные значения в id1,id2 через самый обныкновенный TQuery без всякого там requestLive возникает исключение Key Violation. Index ID12.
Я только что попробовал это на D4 BDE 5.0.1.22 localhare=true

Что-то тут не то. В самом деле, смотреть надо.




 
VAleksey   (2003-05-06 09:01) [15]


> MsGuns © (06.05.03 00:46)

Не так уж он и не прав... Черт, компа нету дома, а то бы я тоже проверил все ваши выкладки.


 
Danilka   (2003-05-06 10:07) [16]

Dred2k © (05.05.03 22:35)
>Никаких аргументов далее не будет

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

>Если б было так, то BDE вообще не вышел бы на рынок
Когда была в нем необходимость - он вышел, сейчас он все больше и больше вытесняется с этого рынка. Какая последняя версия БДЕ? Как давно она вышла?

Хотя, этому место в "потрепаться".


 
-=Guest=-   (2003-05-06 12:21) [17]

Уважаемые Господа, спасибо за Ваши ответы.

У меня ошибка действительно существует, но испавляется это с помощью localhare=true;

После этого все заработало как положенно.
Но если снова установить localhare=false - появляется ошибка, описанная выше

Документацию на BDE почитал.
Возможно, как утверждал MsGuns ©, в этом случае
"Для запроса BDE держит кэш активных индексов " (MsGuns © (05.05.03 21:45)). Это объянение подходит лучше, чем "пары сервачков ... и десятки тыщ записей"(Dred2k © (05.05.03 23:46))

Параметр localhare по-умолчанию установлен в false.

Может у кого-нибудь есть желание поэксперементировать, может у меня BDE каличное.


 
MsGuns   (2003-05-06 12:38) [18]

>Dred2k © (05.05.03 23:03)
>MsGuns кудряво так все описал, что я куплю себе учебник по софистике... Для начинающего.

Для начала ничего покупать не надо, а просто внимательно почитать о BDE и вдуматься в то, а нафига нужны парадоксу (но не самому BDE как таковому) файлы .val и разобраться с понятиями "Индекс" и "Активный индекс"

>Verg © (06.05.03 08:58)
>Никогда такого не бывало, чтобы уникальные индексы дублировались.
Если id1 и id2 образуют составной уникальный индекс,названный, например, id12, то при выполнении SQL вносящего неуникальные значения в id1,id2 через самый обныкновенный TQuery без всякого там requestLive возникает исключение Key Violation. Index ID12.
Я только что попробовал это на D4 BDE 5.0.1.22 localhare=true

Это потому, что данный индекс активен (возможно, указан по умолчанию в DBD - проверь, есть ли файл .val ?). Или узер (приложение) делает всю таблицу "сразу обновляющейся" (LocalShare=true) и тогда все действующие ограничения (в т.ч. и уникальность индекса) становятся актуальными для ЛЮБЫХ запросов к этой таблице.
Еще раз повторю, что индексы в Парадоксе - это не Constraints в SQL-серверах, а лишь их имитация НА КЛИЕНТЕ.





 
MsGuns   (2003-05-06 12:41) [19]

Поправка дабы еще раз не обвинили в софистике ;)
Фраза Еще раз повторю, что индексы в Парадоксе - это не Constraints в SQL-серверах, а лишь их имитация НА КЛИЕНТЕ. относится, ессно не вообще к индексам, а лишь к поддержке их уникальности.





 
Dred2k   (2003-05-06 12:54) [20]


> MsGuns © (06.05.03 12:38)

Поздравляю, маэстро.
Файлы .val - validity checks, понятия "активный/неактивный индекс" в парадоксе нет - индексы бывают maintained (автообновляемые) и не-... Все уникальные (как в вопросе) - maintained. В DBD указать индекс "по умолчанию" просто нельзя за отсутствием такового понятия. К файлам .val вообще какая-то страсть, что ли... ;)
LocalShare нужет для The ability to share access to local data between an active BDE application and an active non-BDE application. Set to TRUE if you need to work with the same files through both a BDE and a non-BDE application at the same time. (It is not necessary to set LOCAL SHARE to TRUE if you do not need to have both applications open at the same time.) Default: FALSE.

> -=Guest=- (06.05.03 12:21)

Насчет квалификаций "объяснений" палку не перегибай - ты тоже тут сотрясал воздух часами за компом, осями, дельфями и проведенными выходными... Мои "сервера" тебе в пику были, чтоб не скучно. ;)


 
MsGuns   (2003-05-06 14:10) [21]

>Dred2k © (06.05.03 12:54)

Вникать с смысл высказанного оппонентом мы не желаем, выдаем кажущееся за действительное, при этом упиваемся собственным умищем, знанищем и опытищем, по ходу дела свысока поплевывая на вертящихся вокруг недотеп, включая автора сабжа ;))

Ну-ну !!


 
Dred2k   (2003-05-06 14:30) [22]


> MsGuns © (06.05.03 14:10)

С файлом .val разберись, прежде чем психоанализом заниматься. Мастер! ;))


 
MsGuns   (2003-05-06 14:40) [23]

>Dred2k © (06.05.03 14:30)
>С файлом .val разберись, прежде чем психоанализом заниматься. Мастер! ;))

Достал пацан 8([]) Где ты увидел хоть раз что я хоть каким нибудь косвенным образом присвоил себе это звание ? Кто тебе вдолбал в твою очень умную (как тебе кажется) голову, что я не знаю с чем едят val ? Когда и кто дал тебе право относиться заносчиво и даже хамски к кому бы-то ни было, в т.ч. и на форуме ? Какой негодяй в какой сволочной школе научил тебя начинать спор со слов "бред", "чушь" и т.д. ? Почему вместо нормального аргументированного опровержения мнения оппонента ты переходишь на издевки и оскорбления ? Кто ты такой ? Гусь хрустальный ? Орел степной ? Или хамло обыкновенное ?

А анкета у тебя соответствующая. Чтоб, тявкнув, можно было свалить в любой момент и концы в воду.

На сем прощаюсь с тобой. Без малейшего уважения.




 
Dred2k   (2003-05-06 15:07) [24]


> MsGuns © (06.05.03 14:40)

Мда... Клоаку прорвало...


 
Verg   (2003-05-06 15:47) [25]


> LocalShare нужет для The ability to share .....


Не только, хоть и написано help-e, но замечено: сам Borland давным-давно давал как "рецепт от многих болезней" - установка LocalShare=true. Помнится впервые этот совет последовал от Борланда при лечении "Blob has been modifyed"...
Ну с тех пор я нераздумывая, всегда это "локалшару" ставлю - как рефлекс : "увидел paradox - поставь локалшару" :)))


 
Dred2k   (2003-05-06 15:58) [26]


> Verg © (06.05.03 15:47)

Да вот, я без нее тоже никуда - аж, порой, забываешь о ее существовании. ;))


 
Mike Kouzmine   (2003-05-06 16:08) [27]

Я сейчас пробовал это описанное, у меня все окейно. Аксес не смог вставить. DBD не смог вставить.
Как мне кажеться, Dred не так уж неправ. И с val и с индексами.


 
Валерий   (2003-05-07 04:25) [28]

>Guest
Но беру TQuery и делаю "Insert Into "MyTable.db" Values(2,1,1)"

Я тоже попробовал этот запрос в SQL Explorer из Delphi
у меня выдало ошибку кеу violation indid2
но после какого-то запроса перестало выдавать ошибку
Налицо глюк!


 
NikB   (2003-05-07 11:33) [29]

Izvinite, chto v etoi vetvi stavliu vopros.
Kak mojno programno (D5) proverit i izmenit "LocalShare" BDE?


 
Verg   (2003-05-07 11:41) [30]

Так проверить (извини, куски кода)

uses Windows,BDE, SysUtils;

const
{ System Initialization Settings... }
bcfgAUTOODBC = "\SYSTEM\INIT\;AUTO ODBC";
bcfgDATAREPOSITORY = "\SYSTEM\INIT\;DATA REPOSITORY";
bcfgDEFAULTDRIVER = "\SYSTEM\INIT\;DEFAULT DRIVER";
bcfgLANGDRIVER = "\SYSTEM\INIT\;LANGDRIVER";
bcfgLOCALSHARE = "\SYSTEM\INIT\;LOCAL SHARE"; bcfgLOWMEMORYUSAGELIMIT = "\SYSTEM\INIT\;LOW MEMORY USAGE LIMIT";
bcfgMAXBUFSIZE = "\SYSTEM\INIT\;MAXBUFSIZE";
bcfgMAXFILEHANDLES = "\SYSTEM\INIT\;MAXFILEHANDLES";
bcfgMEMSIZE = "\SYSTEM\INIT\;MEMSIZE";
bcfgMINBUFSIZE = "\SYSTEM\INIT\;MINBUFSIZE";
bcfgSHAREDMEMLOCATION = "\SYSTEM\INIT\;SHAREDMEMLOCATION";
bcfgSHAREDMEMSIZE = "\SYSTEM\INIT\;SHAREDMEMSIZE";
bcfgSQLQRYMODE = "\SYSTEM\INIT\;SQLQRYMODE";
bcfgSYSFLAGS = "\SYSTEM\INIT\;SYSFLAGS";
bcfgVERSION = "\SYSTEM\INIT\;VERSION";

function GetConfigParameter(Param: string; Count: pword): string;
var
hCur: hDBICur;
rslt: DBIResult;
Config: CFGDesc;
Path, Option: string;
Temp: array[0..255] of char;

begin
Result := ""; hCur := nil;
if Count<>nil then
Count^ := 0;
try
if Pos(";", Param) = 0 then
raise EDatabaseError.Create("Invalid parameter passed to function. There must " +
"be a semi-colon delimited sting passed");
Path := Copy(Param, 0, Pos(";", Param) - 1);
Option := Copy(Param, Pos(";", Param) + 1, Length(Param) - Pos(";", Param));
Check(DbiOpenCfgInfoList(nil, dbiREADONLY, cfgPERSISTENT, StrPCopy(Temp, Path), hCur));
Check(DbiSetToBegin(hCur));
repeat
rslt := DbiGetNextRecord(hCur, dbiNOLOCK, @Config, nil);
if rslt = DBIERR_NONE then
begin
if StrPas(Config.szNodeName) = Option then
Result := Config.szValue;
if Count <> nil then
Inc(Count^);
end
else
if rslt<>DBIERR_EOF then
Check(rslt);
until rslt <> DBIERR_NONE;
finally
if hCur <> nil then
Check(DbiCloseCursor(hCur));
end;
end;


if GetConfigParameter(bcfgLOCALSHARE,nil)<>"TRUE" then <Нет LocalShare>


 
Verg   (2003-05-07 11:46) [31]

Вот процедура установки параметра


procedure SetConfigParameter(Param: string; Value: string);
var
hCfg: hDBICfg;
Config: SYSConfig;
Path, Option: string;
ParamCount, I: word;
pFields, pFld: pFLDDesc;
pRecBuf, pRec: pBYTE;
Found, SelfInitialized: boolean;
rslt: DBIResult;

begin

{$Ifdef WIN32}
hCfg := nil; pFld := nil; pRec := nil; Found := False; SelfInitialized := False;
try
if Pos(";", Param) = 0 then
raise EDatabaseError.Create("Invalid parameter passed to function. There must " +
"be a semi-colon delimited sting passed");
Path := Copy(Param, 0, Pos(";", Param) - 1);
Option := Copy(Param, Pos(";", Param) + 1, Length(Param) - Pos(";", Param));

rslt := DbiGetSysConfig(Config);
if rslt <> DBIERR_NONE then
begin
if rslt = DBIERR_NOTINITIALIZED then // Engine not initialized error...
begin
SelfInitialized := True;
DbiInit(nil);
Check(DbiGetSysConfig(Config));
end
else
Check(rslt);
end;
(* DbiOpenConfigFile is defined as such:
function DbiOpenConfigFile ( { Open/Create configuration }
pszDirPath : PChar; { Directory }
bCreate : Bool; { TRUE to create/overwrite }
var hCfg : hDBICfg { Handle to config }
): DBIResult stdcall; *)
Check(DbiOpenConfigFile(Config.szIniFile, FALSE, hCfg));

(* DbiCfgGetRecord is defined as such:
function DbiCfgGetRecord ( { Get a record }
hCfg : hDBICfg; { Config Handle/NULL }
pszCfgPath : PChar; { Path }
var iFields : Word; { Returned nbr of fields }
pfldDesc : pFLDDesc; { Field descriptors }
pRec : Pointer { Field values }
): DBIResult stdcall; *)
{ Call it without the field and record buffer to get the count... }
Check(DbiCfgGetRecord(hCfg, PChar(Path), ParamCount, nil, nil));

pFields := AllocMem(ParamCount * sizeof(FLDDesc));
pFld := pFields;
pRecBuf := AllocMem(10000);
pRec := pRecBuf;

{ Get the node values... }
Check(DbiCfgGetRecord(hCfg, PChar(Path), ParamCount, pFields, pRecBuf));

for I := 0 to ParamCount - 1 do
begin
if pFields^.szName = Option then
begin
StrPCopy(PChar(pRecBuf), Value);

(* DbiCfgModifyRecord is defines as such:
function DbiCfgModifyRecord ( { Modify a record }
hCfg : hDBICfg; { Config Handle/NULL }
pszCfgPath : PChar; { Path }
iFields : Word; { Nbr of fields }
pfldDesc : pFLDDesc; { Field descriptors }
pRec : Pointer { Data values }
): DBIResult stdcall; *)
Check(DbiCfgModifyRecord(hCfg, PChar(Path), ParamCount, pFld, pRec));

Found := True;
end;
Inc(pFields);
Inc(pRecBuf, 128);
end;
if Found = False then
raise EDatabaseError.Create(Param + " entry was not found in configuration file");

finally
if pFld <> nil then
FreeMem(pFld);
if pRec <> nil then
FreeMem(pRec);
if hCfg <> nil then

(* DbiCloseConfigFile is defined as such:
function DbiCloseConfigFile ( { Close the config file }
var hCfg : hDBICfg; { Handle }
bSave : Bool; { To save the changes }
bDefault : Bool; { To make this file the default }
bSaveAs16 : Bool { To save as a 16-bit config file }
): DBIResult stdcall; *)
{ Close and save the config file... }
Check(DbiCloseConfigFile(hCfg, TRUE, TRUE, FALSE));
if SelfInitialized = True then
DbiExit;
end;
{$Else}
raise EDatabaseError.Create("Non supported function in 16 bit");
{$EndIf}
end;



 
Dred2k   (2003-05-07 11:49) [32]


> NikB (07.05.03 11:33)

DbiOpenCfgInfoList. В bde32.hlp есть подробное описание и примеры. Получить значения для анализа можно также через Session.GetConfigParams.



Страницы: 1 вся ветка

Форум: "Базы";
Текущий архив: 2003.05.29;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.56 MB
Время: 0.007 c
7-95144
Борис_Ш
2003-03-31 18:46
2003.05.29
Как отследить количество свобдной памяти?


1-94860
AlexProdigy
2003-05-19 11:09
2003.05.29
TDateTimePicker + WinXP = глюк


8-94979
real_dimedrol
2003-02-15 12:40
2003.05.29
Помогите разобраться со Scanline


3-94723
AleksandrKu
2003-05-08 14:49
2003.05.29
Как через АДО подключиться к Pervasive серверу?


1-94913
spater
2003-05-17 12:37
2003.05.29
Помогите сложить числа в StringGrid е





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский