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

Вниз

Работа с БД в отдельном треде.   Найти похожие ветки 

 
Alex_C   (2012-03-12 09:33) [40]


> динамически расчитывается хоть каждую миниту


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


> он так сложен в расчете


Я описывал выше индекс нужности:

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


 
Anatoly Podgoretsky ©   (2012-03-12 09:53) [41]

Получить одну запись с нужным видом модуляции и диапазоном. Это чрезвычайно сложная и длительная задача, которая к тому же требует несколько запросов.


 
sniknik ©   (2012-03-12 09:55) [42]

> Я описывал выше индекс нужности:
твои слова несут глубокий, НУЛЕВОЙ смысл происходящего, противореча сами себе.

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

и тут же -
>> - индекс достаточно сложный и одним
>> SQL-запросом его получить нельзя
??? что за бред?


 
sniknik ©   (2012-03-12 09:58) [43]

> Это чрезвычайно сложная и длительная задача, которая к тому же требует несколько запросов.
вообще у меня подозрение, что он так и не отказался от "идеи" каждая таблица в своей базе...
а гетерогенные запросы так и не освоил.


 
Anatoly Podgoretsky ©   (2012-03-12 10:04) [44]

Задача придумана, чтобы не работать, на что только человек не пойдет ради данной цели.


 
RWolf ©   (2012-03-12 10:40) [45]

прозреваю, что имеется в виду не тот индекс, что в БД, а просто некий спецтермин из предметной области.


 
Alex_C   (2012-03-12 14:40) [46]

Хорошо. Согласен. Задача достаточно сложна, чтоб понять ее, не зная тем более всех исходных данных.
Ок! разделим ее на простые и понятные части.

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

Часть 1. Получение спотов с интернета и занесение их в таблицу Access, с последующих показом их пользователю.

Справочная информация:
Что такое спот: это текстовые данные, содержащие информацию о работающих сейчас в эфире станциях.
Один спот содержит:
- позывной станции
- частоту
- время занесения спота на сервер спотов
- доп. инфо.
При занесении спотов в таблицу Access программы следует избегать занесения повторных спотов. Спот считается повторным, если позывной и частота в нем совпадают.
Идеология занесения спотов такая:
- если такой спот не существует - заносим его.
- если существует - проверяем время спота. Если оно больше - делаем UPDATE доп. инфо, если оно меньше - спот старый, не заносим его в базу.

Как я делал:
- в отдельном треде получал споты (их может быть от 1 до 1000)
- парсил
- ... теперь вопрос: хотелось бы и в базу заносить споты в отдельном треде, с использованием отдельного ADOConnect. Но при этом возникают проблемы при отображении принятых спотов в основном треде. Проблема заключаются в том, что споты реально на диск в саму Access-базу заносятся через 5 сек (информация взята из интернета.) Майкрософт в принципе написал как обходить это:

 JE := (CreateOleObject("JRO.JetEngine") as JetEngine);
 try
   JE.RefreshCache(FDataBaseConnection.ConnectionObject as ADODB_TLB._Connection);
 finally
   JE := nil;
 end;

Однако по какой то причине у меня это не сработало.

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


 
Inovet ©   (2012-03-12 20:15) [47]

> [40] Alex_C   (12.03.12 09:33)
> Раньше я его динамически расчитывал при отрисовке таблицы.

Скорее всего надо расчитывать раньше отрисовки таблицы и выводить при отрисовке. В твоём случае отрисовка в гуе и получение новых данных из Инеета не связаны. А уж в базе результаты расчёта совсем не нужны, если мстория нужна - храни исходные скачанные с меткой времени, они более информативны, и можешь восстановить в любое время Индекс Нужности на заданный момент, ну если требуется такое.


 
знайка   (2012-03-12 20:35) [48]


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

И напрашивается тут вин-сервис для синхронизации с инетом, раз уж эти споты постоянно идут.


 
Inovet ©   (2012-03-12 20:44) [49]

> [46] Alex_C   (12.03.12 14:40)
> Вот первая часть моей задачи.

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


 
Alex_C   (2012-03-13 09:14) [50]


> при чем тут синхронайзы и т.п...


Меня опять не поняли :)
Я и заношу, где парсю. Но по условиям задачи я МГНОВЕННО должен отобразить занесенный в базу спот!
А это у меня не получается, т.к. при использовании отдельного ADOConnect в отдельном треде, в другом ADOConnect+ADODataSet+DBGrid увидеть внесенные данные я смогу только через 5 сек - это отражено у Майкрософта.
Вот сейчас и пытаюсь обойти это правило 5 сек.
Вроде как у майкрософта это нужно обходить как написано в [46] - но пока это у меня не получилось.


 
sniknik ©   (2012-03-13 09:31) [51]

> Вот сейчас и пытаюсь обойти это правило 5 сек.
херней ты сейчас маешься. хотя, это я уже говорил.
как и про то, что коннект это COM объект, со всеми вытекающими (5 сек)... и то, что то что ты "выносишь в тред" делается тысячную долю секунды, а значит нет смысла во всех твоих "действиях" по, сначала "выносу", а после борьбе с последствиями.
но тебе все пофигу, хоть кол на голове теши... как уперся в свою "борьбу" так и топчешься у стенки.

удачи.

> но пока это у меня не получилось.
да все как обычно, кривые руки, кивание на "рекомендации со стороны", и отсутствие своего кода, того где глюки. а приведен сторонний пример.

и не получится. но все одно, удачи еще раз. она тебе понадобится.


 
RWolf ©   (2012-03-13 09:39) [52]

ну так, может, использовать инструмент пошустрее?
у меня вот в аналогичной задаче используется сервер БД Firebird с его системой оповещений, работает весьма быстро, задержками можно пренебречь.


 
sniknik ©   (2012-03-13 09:44) [53]

> ну так, может, использовать инструмент пошустрее?
в чьих руках?
в начале показывал пример, то что он делает (говорит, т.к. ничего для проверки нет) делается 2 сек, у меня даже не определяется т.к. отображаемая шкала времени кончается на тысячной доле секунды.

или ты имеешь в виду вместо автора взять программиста? под "инструмент пошустрее". тогда 100% за.


 
Anatoly Podgoretsky ©   (2012-03-13 10:32) [54]

> sniknik  (13.03.2012 09:44:53)  [53]

Инструмент называется шустрый программист с прибамбасами


 
Alex_C   (2012-03-13 12:29) [55]


>  "выносишь в тред" делается тысячную долю секунды


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

Привожу ПОЛНЫЙ код примера.
Есть форма, на ней ADOConnection1+ADODataSet1+DBGrid1, ADOConnection2+ADODataSet2+DBGrid2, ADOConnection1+ADOCommand1.


var
 i: integer;

procedure TForm3.Button1Click(Sender: TObject);
begin
 with ADODataSet1 do
 begin
   Active := False;
   CommandText := "SELECT * FROM LogTest";
   Active := True;
 end;
end;

procedure TForm3.Button2Click(Sender: TObject);
begin
 with ADODataSet2 do
 begin
   Active := False;
   CommandText := "SELECT * FROM LogTest";
   Active := True;
 end;
end;

procedure TForm3.Button3Click(Sender: TObject);
var
 V: Variant;
 JE: JetEngine;
begin
 ADOConnection1.BeginTrans;
 {with ADODataSet1 do
 begin
   Append;
   FieldByName("Call").AsString := "RX4HX" + IntToStr(i);
   FieldByName("DateQSO").AsDateTime := Now;
   FieldByName("BandQSO").AsString := IntToStr(i);
   Post;
 end;}

 with ADOCommand1 do
 begin
   CommandText := "INSERT INTO LogTest (Call,DateQSO,BandQSO) " +
     "VALUES(:Call,:DateQSO,:BandQSO)";
   Parameters.Items[0].DataType := ftString;
   Parameters.Items[0].Value := "RX4HX" + IntToStr(i);
   Parameters.Items[1].DataType := ftDateTime;
   Parameters.Items[1].Value := Now;
   Parameters.Items[2].DataType := ftString;
   Parameters.Items[2].Value := IntToStr(i);
   Execute;
 end;
 ADOConnection1.CommitTrans;

 {V := CreateOleObject("JRO.JetEngine");
 try
   V.RefreshCache(ADOConnection1.ConnectionObject);
 finally
   V := 0;
 end;}
 JE := (CreateOleObject("JRO.JetEngine") as JetEngine);
 try
   JE.RefreshCache(ADOConnection1.ConnectionObject as ADODB_TLB._Connection);
 finally
   JE := nil;
 end;
 Button1Click(nil);
 Button2Click(nil);
 Inc(i);
end;

procedure TForm3.Button4Click(Sender: TObject);
begin
 ADOCommand1.CommandText := "DELETE * FROM LogTest";
 ADOCommand1.Execute;
 Button1Click(nil);
 Button2Click(nil);
end;

procedure TForm3.FormCreate(Sender: TObject);
begin
 with ADOConnection1 do
 begin
   ConnectionString := ConnectionStr;
   LoginPrompt := False;
   Mode := cmShareDenyNone;
   Attributes := [];
   Open;
 end;
 with ADOConnection2 do
 begin
   ConnectionString := ConnectionStr;
   LoginPrompt := False;
   Mode := cmShareDenyNone;
   Attributes := [];
   Open;
 end;
 i := 1;
 Button1Click(nil);
 Button2Click(nil);
end;



Нажимаем Button3. Что мы видим - в DBGrid1 - есть новая запись. В DBGrid2 - нет. Ждем 5 сек - жмем Button2 - новая запись появилась и в DBGrid2.

Мой вопрос КОНКРЕТНО по этому ПОЛНОМУ примеру - как сделать , чтоб новая запись появлялась сразу и в DBGrid2?


 
sniknik ©   (2012-03-13 12:40) [56]

ты по моему не слышишь/игнорируешь того чего тебе говорят...
COM  объект, каждый коннект. и т.д. sniknik ©   (11.03.12 16:09) [25] перечитай.

не? не доходит?

> Мой вопрос КОНКРЕТНО по этому ПОЛНОМУ примеру - как сделать , чтоб новая запись появлялась сразу и в DBGrid2?
сделать все через 1 коннект.


 
Alex_C   (2012-03-13 12:43) [57]

Все! Проблема решена!
Все делается как я написал выше только


 JE := (CreateOleObject("JRO.JetEngine") as JetEngine);
 try
   JE.RefreshCache(ADOConnection2.ConnectionObject as ADODB_TLB._Connection);
 finally
   JE := nil;
 end;


RefreshCashe делается на ЧИТАЮЩИЙ  ADOConnect, а я его на пишущей ставил!

Кстати темя эта если ее погуглить весьма широко в инете обсуждается.
Для тех, кто боится быть .... привожу полный работающий код:


const
 ConnectionStr = "Provider=Microsoft.Jet.OLEDB.4.0;Password="";User ID=Admin;"+
   "Data Source=db1.mdb;Mode=Share Deny None;Extended Properties="" ;"+
   "Locale Identifier=1049;Persist Security Info=True;Jet OLEDB:System database="" ;"+
   "Jet OLEDB:Registry Path="" ;Jet OLEDB:Database Password="" ;Jet OLEDB:Engine Type=5;"+
   "Jet OLEDB:Database Locking Mode=1;Jet OLEDB:Global Partial Bulk Ops=2;"+
   "Jet OLEDB:Global Bulk Transactions=1;Jet OLEDB:New Database Password="" ;"+
   "Jet OLEDB:Create System Database=False;Jet OLEDB:Encrypt Database=False;"+
   "Jet OLEDB:Compact Without Replica Repair=False;Jet OLEDB:SFP=False;" +
   "Jet OLEDB:Don""t copy locale on compact=False;";

var
 i: integer;

procedure TForm3.Button1Click(Sender: TObject);
begin
 with ADODataSet1 do
 begin
   Active := False;
   CommandText := "SELECT * FROM LogTest";
   Active := True;
 end;
end;

procedure TForm3.Button2Click(Sender: TObject);
begin
 with ADODataSet2 do
 begin
   Active := False;
   CommandText := "SELECT * FROM LogTest";
   Active := True;
 end;
end;

procedure TForm3.Button3Click(Sender: TObject);
var
 V: Variant;
 JE: JetEngine;
begin
 ADOConnection1.BeginTrans;
 {with ADODataSet1 do
 begin
   Append;
   FieldByName("Call").AsString := "RX4HX" + IntToStr(i);
   FieldByName("DateQSO").AsDateTime := Now;
   FieldByName("BandQSO").AsString := IntToStr(i);
   Post;
 end;}

 with ADOCommand1 do
 begin
   CommandText := "INSERT INTO LogTest (Call,DateQSO,BandQSO) " +
     "VALUES(:Call,:DateQSO,:BandQSO)";
   Parameters.Items[0].DataType := ftString;
   Parameters.Items[0].Value := "RX4HX" + IntToStr(i);
   Parameters.Items[1].DataType := ftDateTime;
   Parameters.Items[1].Value := Now;
   Parameters.Items[2].DataType := ftString;
   Parameters.Items[2].Value := IntToStr(i);
   Execute;
 end;
 ADOConnection1.CommitTrans;

 {V := CreateOleObject("JRO.JetEngine");
 try
   V.RefreshCache(ADOConnection1.ConnectionObject);
 finally
   V := 0;
 end;}
 {JE := (CreateOleObject("JRO.JetEngine") as JetEngine);
 try
   JE.RefreshCache(ADOConnection1.ConnectionObject as ADODB_TLB._Connection);
 finally
   JE := nil;
 end;}
 JE := (CreateOleObject("JRO.JetEngine") as JetEngine);
 try
   JE.RefreshCache(ADOConnection2.ConnectionObject as ADODB_TLB._Connection);
 finally
   JE := nil;
 end;
 Button1Click(nil);
 Button2Click(nil);
 Inc(i);
end;

procedure TForm3.Button4Click(Sender: TObject);
begin
 ADOCommand1.CommandText := "DELETE * FROM LogTest";
 ADOCommand1.Execute;
 Button1Click(nil);
 Button2Click(nil);
end;

procedure TForm3.FormCreate(Sender: TObject);
begin
 with ADOConnection1 do
 begin
   ConnectionString := ConnectionStr;
   LoginPrompt := False;
   Mode := cmShareDenyNone;
   Attributes := [];
   Open;
   Properties.Item["Jet OLEDB:Transaction Commit Mode"].Value := 1;
   Properties.Item["Jet OLEDB:Shared Async Delay"].Value := 0;
   Properties.Item["Jet OLEDB:User Commit Sync"].Value := 1;
   Properties.Item["Jet OLEDB:Implicit Commit Sync"].Value := 1;
   Properties.Item["Jet OLEDB:Flush Transaction Timeout"].Value := 0;
 end;
 with ADOConnection2 do
 begin
   ConnectionString := ConnectionStr;
   LoginPrompt := False;
   Mode := cmShareDenyNone;
   Attributes := [];
   Open;
   Properties.Item["Jet OLEDB:Transaction Commit Mode"].Value := 1;
   Properties.Item["Jet OLEDB:Shared Async Delay"].Value := 0;
   Properties.Item["Jet OLEDB:User Commit Sync"].Value := 1;
   Properties.Item["Jet OLEDB:Implicit Commit Sync"].Value := 1;
   Properties.Item["Jet OLEDB:Flush Transaction Timeout"].Value := 0;
 end;
 i := 1;
 Button1Click(nil);
 Button2Click(nil);
end;

end.



 
sniknik ©   (2012-03-13 12:45) [58]

и кстати
ADOConnection1.BeginTrans; в некоторых случаях не работает, т.к. может быть локальным, а не от движка. пользуйся запросами. (одна из причин почему JRO мог не сработать, вторая в том что RefreshCache делается читающей стороной...)


 
Alex_C   (2012-03-13 12:46) [59]

Да, вот еще информация, на которую следует обратить внимание:


JetEngine object"s RefreshCache Method
There is a separate read-cache for each connection object. Calling the RefreshCache method of the JetEngine object, as exposed by the Microsoft Jet and Replication Objects type library, immediately refreshes the read-cache for the Connection objects passed as a method argument. The read-cache for all other Connection objects in the application are not affected.
Back to the top
"Jet OLEDB:Transaction Commit Mode" Connection Property
In Microsoft Jet 2.x and earlier, all writes were immediately committed. With Win32 and multi-threading, Microsoft Jet introduced a lazy-write mechanism. Setting this property to a value of 1 causes all transaction commits to be written immediately to disk for that Connection object. All other Connection objects are unaffected.

These methods are preferable to modifying registry values to get the same effect because you can precisely control where you need this value and they are more deterministic in operation. Global registry programs will adversely affect engine performance in other areas and in other applications.


 
sniknik ©   (2012-03-13 12:46) [60]

нда, опоздал.
> RefreshCache делается читающей стороной...


 
Anatoly Podgoretsky ©   (2012-03-13 12:46) [61]

> Alex_C  (13.03.2012 12:29:55)  [55]

Что же ты хочешь когда у тебя два соединения.


 
sniknik ©   (2012-03-13 12:47) [62]

> Да, вот еще информация, на которую следует обратить внимание:
тебе бы обратить внимание что проблема решилась только при переходе на конкретику, без "описательных"(бездоказательных)  "мемуаров".


 
sniknik ©   (2012-03-13 12:48) [63]

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


 
Alex_C   (2012-03-13 17:25) [64]


> придуманная из-за кривой логики


Раз проблема решилась, немного не в тему, но думаю для сведения интересно:
- прикольно, но сегодня утром ко мне в аську постучал старый знакомый из другого города. Тоже радиолюбитель и тоже автор лога для радиолюбителей. Только в отличии от меня, он профессиональный программист, специализирующийся на БД (причем очень неплохой программист).
Самое смешное, что он хотел обсудить проблему занесения спотов в базу (то, что я как раз тут и выяснял).
Будучи профессиональным программистом, базу он выбрал себе FireBird.
Так вот - тут как раз с ним обсуждали вопросы логики работы этой базы. Я ему про эту тему рассказал.
Так вот он поугарал и мне сказал: если б я не знал, что ты за программу пишешь, я был бы на стороне  sniknik, но т.к. я знаю всю специфику - молодец что "добил" тему до конца :) Другого тут решения быть не может.
Теперь буду ждать выходных - будут соревнования, проверю свой лог при большом количестве приходящих спотов.


 
sniknik ©   (2012-03-13 17:51) [65]

> я знаю всю специфику ...
и поэтому молодец, что для каждой таблицы отдельную базу держишь! так держать!
и молодец, что расчетные данные, которые в любой момент получить можно, в базу пихаешь, грузишь ее .
молодец, что клиент серверные методы, sql, на клиент серверном базе (движке) игнорируешь, пользуешься навигационными.
молодец, что говоря об ускорении, делаешь все наиболее тормозными способами, не учитывая специфику используемых компонент.

реально М О Л О Д Е Ц !!!

(хотя вообще то все выше сарказм, а то еще поймешь "по своему")

> "добил" тему до конца :)
"добил"... ага, да тебя чуть ли не силком реальный код, а не "рассуждения" о нем, показать заставили. а в реальном, сам наконец то увидел, а не увидел бы через пару минут мое прочитал...

ты сколько это "бил" чтобы "добить"? а мне пару несколько минут понадобилось. но тем не менее другого ты от меня (и других тут тоже) не воспринимаешь... типа ЭТО ВЫ НЕ ПОНИМАЕТЕ.
!!!???
да как хочешь, заблуждайся дальше.


 
Alex_C   (2012-03-14 14:32) [66]

Я вот спросить хочу: может я когда то тебя чем то обидел? Или ты просто обижен жизнью, а на мне пытаешься отыграться? Ты чего тут кричишь?
Я наверное давно должен быть обиженным и уйти. Но я на людей привык не обижаться, по этому тебе отвечу.


> для каждой таблицы отдельную базу держишь


У меня в логе всего 2 БД - в одной сам лог и относящиеся к нему справочные таблицы(диапазоны, модуляция) и вторая БД - там около 15 справочных БД.
Все как и обсуждалось давно.
Ты вот тут чего х.. несешь?


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


Я тебе еще раз говорю - там все только то, что нужно. Как ты вообще можешь судить "о вкусе фуагра", если ты его не ел?


> клиент серверные методы, sql, на клиент серверном базе (движке)
> игнорируешь, пользуешься навигационными.


Предупреждаю: адрес этой темы я дал еще нескольким проф программистам - я у них давно советы спрашиваю.
Ты реально думаешь что АБСОЛЮТНО ВСЕ можно сделать с помощью SQL-запроса? Тем, кто читает эту тему - а они так такого SQL-запроса сделать не смогли (хотя тоже говорили, что смогут - очень интеренсно). Не испугаешься ответить за свои слова - давай мне на мыло. Напишу полностью всю задачу. От меня и от моих знакомых - пару ящиков пива тебе обеспечены, если сделаешь.


> об ускорении, делаешь все наиболее тормозными способами


Ну учитывая, что быстрее, чем у меня лог ни у кого не работает... Наверное я гений! )))


> чуть ли не силком реальный код


Я спросил конкретный вопрос. Я не спрашивал - как делать. Я спросил - как сделать именно так.


> ЭТО ВЫ НЕ ПОНИМАЕТЕ


Чего кричишь? :)


> но тем не менее другого ты от меня


Помнишь ты привел мне пример про качков? Про зеркало? Помнишь?
Так вот: учитывая, что в 20 лет у меня был КМС по атлетическому троеборью скажу тебе так:
у качков самое доброжелательное отношение к тому, кто спрашивает твоего совета. Сильные люди - они добрые. :) Это слабаки пытаются хамя свое сомомнение поднять.
И тем не менее: я даю тебе шанс - миши мне на емайл - дам тебе полную катрину виденья. Поможешь - молодец. А так.... говорить все умеют.

И тем не менее:
Еще раз хочу выразить призательность многим присутствующим тут форумчанам за помощь! Никогда не забуду помощь Сергей М. в организации работе телнета - сколько лет прошло, а лучше чем в моей программе телнет ни у кого не работает))))



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

Форум: "Начинающим";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.63 MB
Время: 0.131 c
2-1331645587
Сергей
2012-03-13 17:33
2013.03.22
Компонент Delphi для Clob Oracle?


2-1333499708
Dron55555555555
2012-04-04 04:35
2013.03.22
Дробные числа 2


2-1343048239
DevilDevil
2012-07-23 16:57
2013.03.22
Очередь потоков


15-1338451685
TUser
2012-05-31 12:08
2013.03.22
Дошкольное программирование


15-1329421469
TUser
2012-02-16 23:44
2013.03.22
Спокойной ночи





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский