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

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

MyDC.ru _ Kорзина _ Web Статистика С Использованием Единой Базы Данных Sqlite

Автор: Jaska 23.9.2008, 9:16

Пришла задумка сделать такую статистику:

Хаб создает базу данных SQLite в которую я записываю онлайн, шару и прочую необходимую инфу. Эту базу данных использует сайт для вставки инфы "куда надо"

Работа ступорится из-за SQLite, вернее из-за моего незнания ..

CODE
sMainPath = "HubStat\\"

dofile("libs\\sqlite3.lua")

local init, error = package.loadlib("PXSQLite3", "luaopen_pxsqlite3")
local db = sqlite3.open_memory()

function OnStartup()
if not loadfile(sMainPath) then
os.execute("mkdir \""..sMainPath.."\"")
end
TmrMan.AddTimer(1000)
local stmt = db:prepare("SELECT * FROM Report")
if not stmt then
db:exec("CREATE TABLE HubStat (id STRING PRIMARY KEY, count)") -- не знаю правильно ли так делать, но я хочу чтоб id был строкой типо "Онлай", "Шара" .. в принципе повроторений быть не должно.
end
end

function OnTimer()
GetHubStat()
end

function GetHubStat()
local sUpTime = Core.GetUpTime()
db:exec("INSERT INTO HubStat VALUES ('UpTime', '"..sUpTime.."');") -- заносим в бд .. опять таки не уверен в правильности своих действий
for row in db:rows("SELECT * FROM HubStat") do
if row.id == id then
Core.SendToAll(row.count) -- это я для проверки что все правильно записалось ..
end
end
end

function OnExit()
db:close()
end


скулайт дается тяжело .. скорее всего у меня где-то грубые ошибки.

Автор: Setuper 23.9.2008, 14:25

Да уж... хрен знает что делаешь))))))

1. Если подключаешь файл

Код
dofile("libs\\sqlite3.lua")
, то строчка
Код
local init, error = package.loadlib("PXSQLite3", "luaopen_pxsqlite3")
не нужна!

2. Функция open_memory() создаёт временную базу данных. Если ты хочешь считывать из бд, то надо знать откуда считывать, поэтому надо создавать постоянную бд. open("путь".."имя_файла.db3")

3. Функция
Код
loadfile(sMainPath)
вообще непонятно что делает. По ходу дела она пытается загрузить вместо файла всего лишь путь))))

4. В части кода:
Код
local stmt = db:prepare("SELECT * FROM Report")
if not stmt then
db:exec("CREATE TABLE HubStat (id STRING PRIMARY KEY, count)") -- не знаю правильно ли так делать, но я хочу чтоб id был строкой типо "Онлай", "Шара" .. в принципе повроторений быть не должно.
end
также написан бред! Ты ваобще понимаешь что делается, или просто так наобум пишешь? Ты написал следующее: Если не существует таблицы Report, то создаём таблицу HubStat. Чета вообще чтото несвязанное такое получилось. Спрашивается нафига при отсутствии таблицы Report создавать совершенно другую таблицу, с другим именем, тем более что действие по созданию таблицы не выполняется если таковая таблица уже существует. Должно быть просто вот так:
Код
db:exec("CREATE TABLE HubStat (id STRING PRIMARY KEY, count)")


5. Тут тоже неверно:
Цитата
-- не знаю правильно ли так делать, но я хочу чтоб id был строкой типо "Онлай", "Шара" .. в принципе повроторений быть не должно.
Слова PRIMARY KEY - означают первичный ключ. Свойства первичного ключа таковы, что по нему идет связь нескольких таблиц и кроме этого первичный ключ уникальный, то есть не повторяется никогда (какие бы 2 строки таблицы ты не взял - первичный ключ должен быть разным). Зачем спрашивается тебе брать для параметра онлайн или оффлайн первичный ключ? Заведи под эти нужды новый параметр, который не будет первичным ключом, а первичный ключ лучше оставить целого типа, т.е. INTEGER, тем более, что sqlite автоматически выставляет такого типа ключи, поэтому не надо об них заботится, все сделается автоматически в порядке возрастания натуральных чисел))))

6. Спрашивается нафига делать такую таблицу:
Код
HubStat:
id = "Onlain", count=10
id = "UpTime", count=100

Когда гараздо эффективнее сразу все продумать и сделать так:
Код
HubStat:
id = 1, Onlain=10, UpTime=100


И к таму же у тебя получатся всеравно повторения в твоем случае (потому что ты не обновляешь данные, а записываешь новые!!!):
Код
HubStat:
id = "Onlain", count=10
id = "UpTime", count=100
id = "Onlain", count=11
id = "UpTime", count=100
id = "Onlain", count=12
id = "UpTime", count=100
видишь первичный ключ повторяется! это не верно!!! я даже не знаю, что на это тебе скажет sqlite - наверное просто зависнет)))))

7. Для обновления данных служит команда UPDATE.
То есть вот как должен выглядеть твой код:
Код
dofile("libs\\sqlite3.lua")

function OnStartup()
    db = sqlite3.open("путь\\имя_файла.db3")
    TmrMan.AddTimer(1000)
    db:exec("CREATE TABLE HubStat (id INTEGER PRIMARY KEY, online INTEGER, share INTEGER)")
end

function OnTimer()
    GetHubStat()
end

function GetHubStat()
    local stmt=db:prepare("SELECT * FROM HubStat")
    if stmt and stmt:first_row() then
        db:exec("UPDATE HubStat SET online='"..Core.GetUpTime().."', share='"..Core.GetCurrentSharedSize().."'")
    else
        db:exec("INSERT INTO HubStat (online,share) VALUES ('"..Core.GetUpTime().."', '"..Core.GetCurrentSharedSize().."')")
    end

    -- это для проверки
    local stmt=db:prepare("SELECT * FROM HubStat")
    if stmt and stmt:first_row() then
        local tTbl=stmt:first_row()
        Core.SendToAll("Хаб онлайн "..tTbl.online.." секунд.\tОбщая шара хаба "..tTbl.share.." байт.")
    end -- конец проверки
end

function OnExit()
    db:close()
end