Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

MyDC.ru _ Дополнительные библиотеки для PtokaX _ Sqlite

Автор: Nickolya 29.5.2008, 12:18

Библиотека для работы с базой данных SQLite.

Для API 1:  PXLua_Sqlite3_0.4.1_Lua_5.1.1_SQLite_3.2.7_API1.7z ( 290.41 килобайт ) : 28


Для API 2 (большое спасибо alex82 за сборку, однако либа по-прежнему глючная):  PXLua_SQLite_0.4.1_Lua_5.1.3_SQLite_3.2.7_API2.7z ( 579.51 килобайт ) : 73


Исходники SQLite v3.2.7:  PXSqlite3_SQLite_3.2.7_src.7z ( 350.06 килобайт ) : 14

Автор: BIMMER71 5.6.2008, 8:43

А какие возможности даёт эта библеотека=)?

Автор: Nickolya 5.6.2008, 23:02

Димон, если не понимаешь сути базы данных, зачем спрашивать? big_smile.gif

Эта библиотека позволяет работать с базами данных SQLite. Подробнее - или в инете, или позже тут. Сам я пока пробовал сделать скрипт с использованием этой библиотеки, но, видимо, попытка неудачна, при тесте на рабочем хабе, скрипт выдает ошибку, хотя на тестовом всё нормально... Видимо беда в каких-то символах или еще в чем-то, будем разбираться, ибо база данных - очень удобная вещь. big_smile.gif

Автор: Nickolya 20.6.2008, 17:30

Цитата(Setuper @ 20.6.2008, 16:22) *
Это для нового апи 0.4 ???

Если да, то не пашет она!
С какого сайта взята эта библиотека?

Да. С The PtokaX Portal'а взята, а именно отсюда: http://mydc.ru/r/?http://board.ptokax.ch/index.php?board=38.0

Автор: Jaska 20.6.2008, 21:06

Ооо) дождались. А дебаг криптография и прочая бурда тоже есть? =) Кста ты еще не надумал юзеринфо переводить под 0.4 ?

Автор: Nickolya 21.6.2008, 11:15

Цитата(Jaska @ 20.6.2008, 22:06) *
Ооо) дождались. А дебаг криптография и прочая бурда тоже есть? =) Кста ты еще не надумал юзеринфо переводить под 0.4 ?

Надумал... Легко сказать! big_smile.gif Надо еще полностью разрулить этого зверя, ведь и под 1 апи скрипт не работает... big_smile.gif Х3 почему никто не отписывает что не пашет это чудо-творение.
А библиотеки я сюда пока выкладываю по мере необходимости для некоторых скриптов.

Автор: Nickolya 21.6.2008, 16:59

Сейчас пробовал еще работать с библиотечкой.
Прикол в том, что на 0.4.0.0 всё как часы, данные заносятся и извлекаются из бд простеньким тестовым скриптом, он есть в архиве с библиотекой, выглядит вот так:

Код
require "SQLite3"

local db = sqlite3.open_memory()

db:exec[[
  CREATE TABLE test (id INTEGER PRIMARY KEY, content);

  INSERT INTO test VALUES (NULL, 'Hello World');
  INSERT INTO test VALUES (NULL, 'Hello Lua');
  INSERT INTO test VALUES (NULL, 'Hello Sqlite3')
]]

for row in db:rows("SELECT * FROM test") do
  Core.SendToAll("row.id = "..row.id.."\t\trow.content = "..row.content)
end

Но на 0.4.1.0 вот такая ошибка:

Цитата
Синтаксис C:\0.4.1.0\libs\SQLite3.lua:165: attempt to index upvalue 'api' (a nil value)

При инициализации библиотеки, если вывести ошибку в чат получаем вот это: "Не найден указанный модуль."

В SQLite3.lua инициализация выглядит так:

Код
local init, error = package.loadlib("pxsqlite3", "luaopen_pxsqlite3")

local api, ERR, TYPE, AUTH

if init then
  api, ERR, TYPE, AUTH = init()
end

В библиотеке либо изменена функция, теперь она не luaopen_pxsqlite3, а какая-то еще, либо в PXLua.dll опять что-то изменили. :\

Автор: Nickolya 23.6.2008, 10:25

Цитата(Setuper @ 23.6.2008, 10:43) *
Ура Наконецто можно перейти на новый апи. У меня все работает.

Setuper, а ты свои библиотеки никогда не компилировал??? А то хотелось бы, но в этом я просто ноль. Как-то на форуме птоки нашел я вот это, но ничего так и не вышло...

Цитата
A guide on howto create a extension for PXLua ?

Actually its rather easy

C++ lib for Lua 5.1:

Код
#pragma comment(lib, "PXLua.lib")

extern "C" { // we dont need all of them in this sample, but does not hurt to include all
#  include "lua.h"
#  include "lualib.h"
#  include "lauxlib.h"
};

// The HelloWorld lua function
int lua_helloworld (lua_State *L) {
  if (lua_gettop(L) != 0) { // check no of arguments - we expect none (we dont need to do this in this case, but its just to show how)
    luaL_where(L,1); // at witch line did the error happen in the script
    lua_pushliteral(L, "Function should be called without arguments!"); // push the message
    lua_concat(L, 2); // concat; merge the where-message and the error-message
    lua_error(L); // halt the script and display the message
  }

  lua_pushstring(L, "Hello World!");
  return 1; // the number of objects we pushed onto the stack
}

// table of methods to register
static const luaL_reg our_methods[] = {
  {"FunctionName", lua_helloworld},
  {0,0}
};

// Lua entry point when loading
int __declspec(dllexport) libinit (lua_State* L) {
  luaL_register(L, "TableName", our_methods);
  return 0;
}


-- EOF --

The script:

Код
libinit = package.loadlib("px_helloworld.dll", "_libinit") // the existance of "_" in the entrypoint depends on you compiler options.
libinit()

retval = TableName.FunctionName()
SendToAll(retval)

-- EOF --

Ну и может расскажешь, что за SBot, уже даже 7.0RC1?!
И ну очень был бы тебе благодарен если бы ты поделился опытом работы с SQLite, может даже мануал в этом разделе бы создал? big_smile.gif

Автор: Setuper 23.6.2008, 10:36

Сам пытался писать библиотеки, точнее пытался править код уже написанных - потом компилил исправленный код, но в итоге после того, как компилятором была выброшена длл, подключал её к PtokaX но ничего не работало. Хотя "простейшие" длл библиотеки могу писать - работают.

Автор: Nickolya 23.6.2008, 12:22

Цитата(Setuper @ 23.6.2008, 10:36) *
Сам пытался писать библиотеки, точнее пытался править код уже написанных - потом компилил исправленный код, но в итоге после того, как компилятором была выброшена длл, подключал её к PtokaX но ничего не работало. Хотя "простейшие" длл библиотеки могу писать - работают.

Вот можно такой авторский мануальчик по "простейшим" DLL? Типа того HelloWorld, что я постил.

И если не трудно, еще как работает эта вот связка: прикладная программа - скрипт?! А то робокопа ни разу не включал...

Автор: Setuper 23.6.2008, 17:03

Цитата(Nickolya @ 23.6.2008, 13:22) *
Вот можно такой авторский мануальчик по "простейшим" DLL? Типа того HelloWorld, что я постил.

И если не трудно, еще как работает эта вот связка: прикладная программа - скрипт?! А то робокопа ни разу не включал...

а какие проблемы в том что ты запостил? там все работает. длл скомпилить у меня получилось. Или ты хочешь чтобы я подробно рассказал что там делается?

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

Автор: Nickolya 23.6.2008, 17:16

Просто в этом я нуп, пробовал я долго и усердно, но не вышло...
Реально интересуют пошаговые инструкции для компилирования, какой компилятор (я себе поставил Microsoft Visual Studio 2008), и прочее, что может к этому относиться.

Цитата
И если не трудно, еще как работает эта вот связка: прикладная программа - скрипт?! А то робокопа ни разу не включал...

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

И, Setuper, огромное спасибо тебе за готовность помогать, делиться своими знаниями и опытом! ;)

Автор: NikseR 21.12.2008, 3:23

Народ, подскажите, файлы и папки из распакованного архива PXLua-SQLite-0.4.1-SQLite-3.5.6.7z пихать в папку libs или в заглавную папку с птокой?

Автор: KauH 21.12.2008, 3:33

будут работать и там и там

Автор: sphinx 2.2.2009, 1:22

PPK выложил обновление библиотек

http://mydc.ru/r/?http://www.czdc.org/PtokaX/Libs-0.4.0.0/PXLua-SQLite-0.4.1-SQLite-3.6.10.7z
http://mydc.ru/r/?http://www.czdc.org/PtokaX/Libs-0.4.0.0/PXLua-SQLite-0.4.1-SQLite-3.6.10-src.7z

Автор: mariner 2.2.2009, 1:25

ну да... таки выложил big_smile.gif А я на линуксе уже 4 месяца без них живу и скулайт работает... странно, оторвался от сообщества.

Автор: Wariner 3.2.2009, 11:44

Рано я обрадовался... В целом для виндовой птоки, по моему, ничего не изменилось! Как не мог создать две таблицы так и сейчас токо одна создаётся!!!
PS: 2Setuper: Илюх, что ты думаешь по этому поводу? Ощущаю резкую потребность в БД но ставить MySQL тоже как то не очень хочется((( Будет ли решение этой проблемы?

Автор: mariner 3.2.2009, 12:14

да, оно зовется линукс (с)

в нем вся коровья суперсила!

Автор: sphinx 5.2.2009, 4:40

Код
--[[

    SQLite3 Example script by Mutor

]]

-- Admins nick for status / error messages
local OpNick = "Mutor"
-- Subdir of scripts folder ["" = scripts folder]
local path = "sql/"
-- Database file name ["" = hubname.db"]
local file = ""
-- Database timeout, in seconds
local to = 3
-- Delete file on script exit? true/false
local DelFile = true

require "sqlite3"

OnStartup = function()
    local root = Core.GetPtokaXPath().."scripts/"
    if #path > 0 then path = root..path else path = root end
    if #file == 0 then file = path..SetMan.GetString(0):gsub(" ","_")..".db" else file = path..file end
    if Update() then OnError(file.." has been updated.") else OnError(file.." failed to update.") end
end

OnError = function(msg)
    if msg and #msg > o then
        local user,bot = Core.GetUser(OpNick),SetMan.GetString(21)
        if user and bot then
            Core.SendToUser(user,"<"..bot.."> "..msg.."|")
        end
    end
end

OnExit = function()
    if DelFile then
        assert(os.remove(file))
    end
end

Update = function()
    db = sqlite3.open(file)
    db:set_busy_timeout(to)
    db:exec("CREATE TABLE HubUsers (Nick TEXT, IP TEXT, Profile NUMERIC);")
    local t = {"Nick","IP","Profile"}
    for x,user in ipairs(Core.GetOnlineUsers()) do
        db:exec("INSERT INTO HubUsers ( Nick, IP, Profile ) VALUES ('"..user.sNick.."', '"..user.iProfile.."', '"..user.sIP.."');");
    end
    db:exec('commit')
    ReadDb(db)
    db:close()
    return true
end

ReadDb = function(db)
    for _, nick,profile,ip in db:cols("SELECT 1, * FROM HubUsers") do
        OnError("[ "..nick.." ] "..profile.." "..ip.."|")
    end
end

------ End of Code ------

Автор: Wariner 5.2.2009, 10:39

2sphinx: а ты не мог бы передать мутору чтоб он написал пример скрипта с созданием двух таблиц в одной БД и запросами типо АПДЕЙТ, или СЕЛЕКТ с параметром WHERE?

Автор: sphinx 6.2.2009, 17:35

Код
--[[

    SQLite3 Example script by Mutor v2

]]

-- Admins nick for status / error messages
local OpNick = "Mutor"
-- Status in PM? true/false [false = main chat]
local PmOnly = true
-- Subdir of scripts folder ["" = scripts folder]
local path = "sql/"
-- Database file name ["" = hubname.db"]
local file = ""
-- Database timeout, in seconds
local to = 3
-- Delete file on script exit? true/false
local DelFile = true

require "sqlite3"

OnStartup = function()
    local root = Core.GetPtokaXPath().."scripts/"
    if #path > 0 then path = root..path else path = root end
    if #file == 0 then file = path..SetMan.GetString(0):gsub(" ","_")..".db" else file = path..file end
    db = sqlite3.open(file)
    assert(db,"Failed to open "..file..", check files.")
    assert(db:set_busy_timeout(to))
    assert(db:exec("CREATE TABLE HubUsers (Nick TEXT, IP TEXT, Profile NUMERIC, Connected TEXT, Time NUMERIC)"))
    local r = "Ї"
    if DoOnline() then
        OnError("\t\t\t"..file.." has been updated.")
        OnError(" ")
        OnError(r:rep(100))
    else
        OnError("\t\t\t"..file.." failed to update.")
        OnError(" ")
        OnError(r:rep(100))
    end
end

OnError = function(msg)
    if msg and #msg > 0 then
        local user,bot = Core.GetUser(OpNick),SetMan.GetString(21)
        if user and bot then
            if PmOnly then
                Core.SendPmToUser(user,bot,msg.."|")
            else
                Core.SendToUser(user,"<"..bot.."> "..msg.."|")
            end
        end
    end
end

OnExit = function()
    db:close()
    if DelFile then
        assert(os.remove(file))
    end
end

UserConnected = function(user,data)
    if not ChkNick(user.sNick:lower()) then
        assert(db:exec("INSERT INTO HubUsers ( Nick, IP, Profile, Connected, Time) VALUES ('"..
        user.sNick.."', '"..user.iProfile.."', '"..user.sIP.."', 'Online', '"..os.time().."');"))
        db:exec('commit')
        ReadDb()
    end
end
OpConnected,RegConnected = UserConnected,UserConnected

UserDisconnected = function(user)
    if ChkNick(user.sNick:lower()) then
        --assert(db:exec("DELETE FROM HubUsers WHERE Nick = '"..user.sNick.."' and IP = '"..user.sIP.."'"))
        assert(db:exec("UPDATE HubUsers SET Time = '"..os.time().."', Connected = "..
        "'Offline' WHERE Nick = '"..user.sNick.."' and IP = '"..user.sIP.."'"))
    end
    db:exec('commit')
    ReadDb()
end
RegDisconnected,OpDisconnected = UserDisconnected,UserDisconnected

ChkNick = function(nick)
    local t = {"Nick","IP","Profile"}
    for row in db:irows("SELECT "..t[1].." FROM HubUsers") do
        if row[1]:lower() == nick then return true end
    end

end

DoOnline = function()
    for x,user in ipairs(Core.GetOnlineUsers()) do
        if ChkNick(user.sNick:lower()) then
            assert(db:exec("UPDATE HubUsers SET Nick = '"..user.sNick.."', IP = '"..user.sIP..
            "', Profile = '"..user.iProfile.."', Connected = 'Offline', Time = '"..
            os.time().."' WHERE Nick = '"..user.sNick.."'"))
        else
            assert(db:exec("INSERT INTO HubUsers ( Nick, IP, Profile, Connected, Time ) VALUES ('"..
            user.sNick.."', '"..user.iProfile.."', '"..user.sIP.."', 'Online', '"..os.time().."');"))
        end
    end
    db:exec('commit')
    ReadDb()
    return true
end

ReadDb = function()
    GetProf = function(n)
        local Prof = "Unregistered"
        if n ~= -1 then Prof = ProfMan.GetProfile(n).sProfileName end
        return Prof
    end
    if db:exec("SELECT * FROM HubUsers LIMIT 1") then
        local r = "Ї"
        OnError("NickName\t\t\tProfile\t\tIP Address\t\tConnected\tDate/Time")
        OnError(r:rep(100))
        for _,nick,profile,ip,status,time in db:cols("SELECT 1, * FROM HubUsers") do
            OnError(string.format("%-40.30s",nick)..
            "\t"..string.format("%-20.13s",GetProf(tonumber(profile)))..
            "\t"..string.format("%-24.15s",ip)..
            "\t"..string.format("%-15.10s",status)..
            "\t"..os.date(nil,tonumber(time))
            )
        end
        OnError(" ")
        OnError(r:rep(100))
    end
end

Автор: Setuper 6.2.2009, 18:51

И что это? Просили же 2 таблицы, а тут я что-то не вижу 2 таблиц!

Автор: sphinx 7.2.2009, 0:43

Цитата(Setuper @ 6.2.2009, 18:51) *
И что это? Просили же 2 таблицы, а тут я что-то не вижу 2 таблиц!

Ну значит ничего не изменилось в новой библиотеке big_smile.gif
Я конечно спрошу еще раз, но...
И еще, я в принципе чайник по базам данных, но почему надо обязательно создавать несколько таблиц в одной базе? Несколько баз создать религия не позволяет?

В общем, он ответил примерно то, что сказал я:

Цитата
[00:35:51] <Mutor> There does seem to be a problem adding multiple tables with sqilte
[00:36:38] <Mutor> Until it's sorted suggest you add field to existing table or use a second db/file


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

Автор: Setuper 7.2.2009, 11:55

Так может говорить только человек, который далёк от принципа построения баз данных, видимо Мутор далёк от этого.

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

Сначала строится так называемая ER-модель базы данных, после этого эта модель проектируется на реляционную базу данных и уже потом всё переносится на конкретный язык бд. Таблица на первом этапе построения бд - это основной элемент.

Автор: Wariner 7.2.2009, 12:14

меня интересует почему он подключает вот это:

Код
require "sqlite3"


А так же меня интересует как он это делает. При попытке это сделать мой хаб запросил ещё две библиотеки lua5.1.dll и msvcr80.dll После чего птока выдала ошибку подключения библиотеки

Автор: alex82 7.2.2009, 13:54

Цитата(Wariner @ 7.2.2009, 11:14) *
меня интересует почему он подключает вот это:
Код
require "sqlite3"

http://mydc.ru/ipb.html?s=&showtopic=142&view=findpost&p=8895

Автор: Setuper 7.2.2009, 17:12

Можно подключать любым из способов, однако более расширенный способ подключения, который автоматически ищет точку входа в длл, является require "sqlite3"

Автор: Wariner 7.2.2009, 20:34

я запутался.... В этой теме обсуждалась библиотека PXSQLite3.dll. Щас идёт разговор про неё?

Если да то результат:

Цитата
[20:28] Синтаксис test.lua:20: module 'sqlite3' not found:
no field package.preload['sqlite3']
no file 'C:\Documents and Settings\...\Рабочий стол\Хаб SQLite\sqlite3.lua'
no file 'C:\Documents and Settings\...\Рабочий стол\Хаб SQLite\libs\sqlite3.lua'
no file 'C:\Documents and Settings\...\Рабочий стол\Хаб SQLite\scripts\libs\sqlite3.lua'
no file 'C:\Documents and Settings\...\Рабочий стол\Хаб SQLite\sqlite3.dll'
no file 'C:\Documents and Settings\...\Рабочий стол\Хаб SQLite\libs\sqlite3.dll'
no file 'C:\Documents and Settings\...\Рабочий стол\Хаб SQLite\scripts\libs\sqlite3.dll'



Если же всё таки речь идёт о sqlite3.dll то результат я писал ранее!

Объясните мне beat_brick.gif

Автор: Setuper 7.2.2009, 20:43

Операция:

Код
require "sqlite3"
подключает модуль sqlite3. Модуль подключается из файла sqlite3.lua. В ошибках интерпретатор написал где он ищет этот файл, а он наверняка у тебя лежит в папке scripts.

Автор: Wariner 7.2.2009, 21:20

не пашет этот скрипт мутора.....

Автор: Setuper 24.2.2009, 21:20

Ура! alex82 получил рабочую библиотеку под API2.

Прикладываю эту библиотеку:  PXSqlite3.rar ( 159.33 килобайт ) : 7


Также перезалил библиотеку в первом посту.

Автор: Wariner 24.2.2009, 22:27

2Setuper: раз уж так всё хорошо, можно ли услышать пару слов о БД. Ты где то обмолвился о структуре. Можешь рассказать что к чему? К примеру будет ли смысл в переходе с одной таблицы в текстовом файле к одной таблицы в БД? Стоит ли хранить в БД маленькие таблицы которые моно и в текстовый файл запхнуть?

PS: alex82 поздравляю и огромное спасибо!!!

Автор: Setuper 24.2.2009, 22:34

Нет. Не совсем так. Таблицы нужно создавать из расчёта разнородности данных в них. В нашем случае связи между таблицами надо делать непосредственно в скриптах. Если бы мы использовали mysql, а не sqlite, то связывать таблицы можно было бы непосредственно при помощи mysql.
Покачай из инета какие-нибудь книжки по общему языку SQL. Посмотри как правильно надо составлять таблицы для повышения оптимизации выполнения запросов. База данных строится в несколько этапов: 1) составление ER диаграммы, 2) переход к реляционной бд, 3) переход к непосредственным запросам. Это основные 3 этапа при построении оптимизированной базы данных.

Автор: Wariner 24.2.2009, 22:37

а можно какой нибудь примерчик в двух словах?

Автор: Setuper 24.2.2009, 22:44

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

В двух словах это не опишешь. Хорошие примеры написаны в книжках по SQL. Я просто изучал базы данных в институте и сдавал по ним экзамен, в качестве курсового проекта по базам данных мною была разработана и представлена как раз таки база данных для моего SBot'а.

Автор: Wariner 24.2.2009, 23:09

Жаль(((( Просто с сегодняшними моими познаниями я бы создал в БД одну таблицу где была бы вся информация о пользователях. Возможно я так и сделаю ибо времени катастрофически не хватает на изучение(((

upd: думается связь осуществляется с помощью поля идентификатора(id)? при заходе пользователя в каждой таблице БД создаётся запись с одинаковым ид что в дальнейшем служит связью этих таблиц, так?

Автор: Setuper 24.2.2009, 23:46

Связи бывают разными, и осуществляться они могут разными способами. Ты привёл один из способов, который осуществим в sqlite только по средствам триггеров.

Автор: Wariner 25.2.2009, 18:11

а какие ещё могут быть связи именно в SQLite?


2Setuper: можешь на примере моего бота объяснить мне зачем нужны несколько таблиц? Вот часть главной таблицы:

Код
    ["xx.xx.xx.xx"] = {
        ["Punish"] = {
            [1] = "15.02.2009 в 18:33    Юзер    забанен    Наказал: -=Wariner=-    Причина: Реклама хаба+ФЛУД",
        },
        ["OffData"] = "15.02.2009 в 18:33",
        ["Shara"] = 193955841117,
        ["Msg"] = 187,
        ["Ban"] = {
            ["Punished"] = "-=Wariner=-",
            ["Time"] = 1235575980,
            ["Reason"] = "Реклама хаба+ФЛУД",
        },
        ["Time"] = 148020,
        ["IP"] = "xx.xx.xx.xx",
        ["Nick"] = "yyyyyy",
        ["BanTop"] = 2,
    },

полная таблица юзера конечно больше но она немного уменьшена в следствии использования большого количества памяти!

Автор: dmvn 27.2.2009, 10:41

Цитата(Setuper @ 24.2.2009, 21:20) *
Ура! alex82 получил рабочую библиотеку под API2.


А может быть, он обнародует способ, как он ее получил? big_smile.gif
Понятно что не без бубна, но всё-таки... что надо подхачить в исходной либе, чтобы она завелась на API2?
хочу diff видеть.

Автор: Setuper 27.2.2009, 13:35

Обсуждения этого велись тут: http://mydc.ru/ipb.html?s=&showtopic=142&view=findpost&p=10185