Димон, если не понимаешь сути базы данных, зачем спрашивать?
Эта библиотека позволяет работать с базами данных SQLite. Подробнее - или в инете, или позже тут. Сам я пока пробовал сделать скрипт с использованием этой библиотеки, но, видимо, попытка неудачна, при тесте на рабочем хабе, скрипт выдает ошибку, хотя на тестовом всё нормально... Видимо беда в каких-то символах или еще в чем-то, будем разбираться, ибо база данных - очень удобная вещь.
Автор: 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 ?
Надумал... Легко сказать! Надо еще полностью разрулить этого зверя, ведь и под 1 апи скрипт не работает... Х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()
Ну и может расскажешь, что за SBot, уже даже 7.0RC1?! И ну очень был бы тебе благодарен если бы ты поделился опытом работы с SQLite, может даже мануал в этом разделе бы создал?
Автор: 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 или в заглавную папку с птокой?
ну да... таки выложил А я на линуксе уже 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 таблиц!
Ну значит ничего не изменилось в новой библиотеке Я конечно спрошу еще раз, но... И еще, я в принципе чайник по базам данных, но почему надо обязательно создавать несколько таблиц в одной базе? Несколько баз создать религия не позволяет?
В общем, он ответил примерно то, что сказал я:
Цитата
[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 После чего птока выдала ошибку подключения библиотеки
Можно подключать любым из способов, однако более расширенный способ подключения, который автоматически ищет точку входа в длл, является 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 то результат я писал ранее!
Объясните мне
Автор: 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: можешь на примере моего бота объяснить мне зачем нужны несколько таблиц? Вот часть главной таблицы:
полная таблица юзера конечно больше но она немного уменьшена в следствии использования большого количества памяти!
Автор: dmvn 27.2.2009, 10:41
Цитата(Setuper @ 24.2.2009, 21:20)
Ура! alex82 получил рабочую библиотеку под API2.
А может быть, он обнародует способ, как он ее получил? Понятно что не без бубна, но всё-таки... что надо подхачить в исходной либе, чтобы она завелась на API2? хочу diff видеть.
Автор: Setuper 27.2.2009, 13:35
Обсуждения этого велись тут: http://mydc.ru/ipb.html?s=&showtopic=142&view=findpost&p=10185