Skocz do zawartości

Witamy w Nieoficjalnym polskim support'cie AMX Mod X

Witamy w Nieoficjalnym polskim support'cie AMX Mod X, jak w większości społeczności internetowych musisz się zarejestrować aby móc odpowiadać lub zakładać nowe tematy, ale nie bój się to jest prosty proces w którym wymagamy minimalnych informacji.
  • Rozpoczynaj nowe tematy i odpowiedaj na inne
  • Zapisz się do tematów i for, aby otrzymywać automatyczne uaktualnienia
  • Dodawaj wydarzenia do kalendarza społecznościowego
  • Stwórz swój własny profil i zdobywaj nowych znajomych
  • Zdobywaj nowe doświadczenia

Dołączona grafika Dołączona grafika

Guest Message by DevFuse
 

Zdjęcie

SQLVault - dokumentacja

sql mysql vault sqlvault nvault nfvault dokumentacja cokolwiek

  • Nie możesz napisać tematu
  • Zaloguj się, aby dodać odpowiedź
9 odpowiedzi w tym temacie

#1 fgsfds

    Pomocny

  • Użytkownik

Reputacja: 18
Początkujący

  • Postów:65
Offline

Napisano 14.08.2012 22:34

SQLVault

Wersja 0.0.3

Autor: Exolent

Tłumacz: Maxorq


Wstęp:



SQLVault jest nowym systemem "skrytki" (vault), wykorzystującym SQL do zapisu danych.

Został stworzony dla tych, co potrzebują SQL do zapisywania swoich danych, ale chcą wykorzystać składnię podobną np. do nVault.

Pozwala on na wykorzystanie baz danych zarówno zdalnych (MySQL) jak i lokalnych (SQLite).

W tym tłumaczeniu będę głównie używał sformułowania "vault" zamiast "skrytki", gdyż tak po prostu lepiej brzmi :D


Podstawowe Funkcje:



Te funkcje bazują głównie na pomysłach nVault, NFVault jak i też Exolent'a.


Otwieranie/Zamykanie Vault'a:


/*
* Otwiera vault'a w bazie danych
*
* @param szHost - Serwer, który zostanie wykorzystany do łączenia z bazą danych.
* @param szUser - Nazwa użytkownika, która zostanie wykorzystana do łączenia z bazą danych.
* @param szPass - Hasło, które zostanie wykorzystane do łączenia z bazą danych.
* @param szDb - Nazwa bazy danych, z którą się łączysz.
* @param szVaultName - Nazwa vault'a, którego chcesz otworzyć.
* @param bAutoInit - Jeśli ustawisz 1, sqlv_init() zostanie wykonane razem z tą funkcją, jeśli 0, będziesz musiał wywołać sqlv_init() samemu.
*
* @return Zwraca poprawnego "handle'a" do vault'a, Invalid_SQLVault przy niepowodzeniu.
*
*/
SQLVault:sqlv_open(szHost[], szUser[], szPass[], szDb[], szVaultName[], bool:bAutoInit = true)

/*
* Otwiera vault'a bazując na wartościach zmiennych amx_sql_* w addons/amxmodx/configs/sql.cfg
*
* @param szVaultName - Nazwa vault'a, którego chcesz otworzyć.
* @param bAutoInit - Jeśli ustawisz 1, sqlv_init() zostanie wykonane razem z tą funkcją, jeśli 0, będziesz musiał wywołać sqlv_init() samemu.
*
* @return Zwraca poprawnego "handle'a" do vault'a, Invalid_SQLVault przy niepowodzeniu.
*
*/
SQLVault:sqlv_open_default(szVaultName[], bool:bAutoInit = true)

/*
* Otwiera lokalnego vault'a używając modułu sqlite.
*
* @param szVaultName - Nazwa vault'a, którego chcesz otworzyć.
* @param bAutoInit - Jeśli ustawisz 1, sqlv_init() zostanie wykonane razem z tą funkcją, jeśli 0, będziesz musiał wywołać sqlv_init() samemu.
*
* @return Zwraca poprawnego "handle'a" do vault'a, Invalid_SQLVault przy niepowodzeniu.
*
*/
SQLVault:sqlv_open_local(szVaultName[], bool:bAutoInit = true)

/*
* Zamyka vault'a
*
* @param hVault - Handle vault'a, którego chcesz zamknąć
*
* @return Nie zwraca wartości
*
* @note Handle vault'a zostanie ustawiony do Invalid_SQLVault po zamknięciu.
*
*/
sqlv_close(&SQLVault:hVault)


Inicjalizacja Vault'a:


Po otwarciu vault'a, musisz go inicjalizować.

Jeśli tego nie zrobisz, nie będzie on działać i będziesz miał po prostu masę błędów.

Aby inicjalizować vault'a, możesz ustawić ostatni argument w funkcjach otwierających vault jako 1, albo ustawić go na 0 i użyć tej funkcji:



/*
* Inicjalizuje vault'a
*
* @param hVault - Handle vault'a do inicjalizacji
*
* @return Zwraca 1 przy powodzeniu, 0 przy niepowodzeniu.
*
* @note Musisz tego użyć przed jakimikolwiek innymi operacjami (oprócz otwarcia/zamknięcia vault'a)!
*
*/
sqlv_init(SQLVault:hVault)


Połączenia:


Przy używaniu funkcji tego vault'a, za każdym razem trzeba otwierać i zamykać połączenie z bazą danych.

Spowalnia to tylko procesor gdy masz parę takich funkcji wywoływanych pod rząd.

Technicznie rzecz biorąc, oznacza to, że połączenie jest otwieranie i zamykane parę razy w jednym bloku kodu, co nie ma zbytnio sensu.

Aby to ominąć, możesz bezpośrednio otworzyć i zamknąć połączenie, ratując czas procesora.

Oto funkcje które powinieneś użyć:



/*
* Łączy się z bazą danych vault'a
*
* @param hVault - Handle vault'a z którym chcesz się połączyć
*
* @return Zwraca 1 przy powodzeniu, 0 przy niepowodzeniu.
*
* @note Ta funkcja nie otwiera vault'a!
* Tworzy tylko połączenie z bazą.
*
* @note Ta funkcja pownina być używana tylko gdy używasz paru funkcji pod rząd.
* Zmniejsza to użycie procesora nie wykonując łączenia/rozłączania przy każdej z nich.
*
* @note Po użyciu wszystkich funkcji, powinno się zamknąć połączenie.
*
* @note Niezalecane jest trzymanie połączenia przez cały czas działania pluginu.
*
*/
sqlv_connect(SQLVault:hVault)

/*
* Rozłącza się z bazą danych vault'a
*
* @param hVault - Handle vault'a z którym chcesz się rozłączyć
*
* @return Zwraca 1 przy rozłączeniu, 0 przy błędzie lub nieistniejącym połączeniu.
*
* @note Ta funkcja nie zamyka vault'a!
* Rozłącza tylko połączenie z bazą.
*
*/
sqlv_disconnect(SQLVault:hVault)


Przykład użycia:



sqlv_connect(hVault);

// funkcje takie jak pobierz/ustaw/usuń/itd.

sqlv_disconnect(hVault);


Pobieranie/Ustawianie Danych:

Głównym celem vault'a jest oczywiście przetrzymywanie danych.

Istnieją specyficzne funkcje dla trzech podstawowych typów danych, Integer, Float i String, abyś nie musiał robić dziwnych trików i myków w swoim kodzie.



/*
* Pobiera wartość typu String z vault'a
*
* @param hVault - Handle vault'a z którego chcesz pobrać dane
* @param szKey - Klucz przetrzymujący dane
* @param szData - Bufor, w którym chcesz zapisać dane
* @param iDataLen - Maksymalna długość bufora
* @param iTimeStamp - Zmienna przetrzymująca timestamp (znacznik czasu)
*
* @return Zwraca 1 przy powodzeniu, 0 przy niepowodzeniu.
*
*/
sqlv_get_data(SQLVault:hVault, szKey[], szData[], iDataLen, &iTimeStamp = 0)

/*
* Pobiera wartość typu Integer z vault'a
*
* @param hVault - Handle vault'a z którego chcesz pobrać dane
* @param szKey - Klucz przetrzymujący dane
* @param iTimeStamp - Zmienna przetrzymująca timestamp (znacznik czasu)
*
* @return Zwraca wartość typu Integer przy powodzeniu, 0 przy niepowodzeniu.
*
*/
sqlv_get_num(SQLVault:hVault, szKey[], &iTimeStamp = 0)

/*
* Pobiera wartość typu Float z vault'a
*
* @param hVault - Handle vault'a z którego chcesz pobrać dane
* @param szKey - Klucz przetrzymujący dane
* @param iTimeStamp - Zmienna przetrzymująca timestamp (znacznik czasu)
*
* @return Zwraca wartość typu Float przy powodzeniu, 0 przy niepowodzeniu.
*
*/
Float:sqlv_get_float(SQLVault:hVault, szKey[], &iTimeStamp = 0)

Podobnie wyglądają funkcje stosowane do zapisu danych:

/*
* Zapisuje wartość typu String do vault'a
*
* @param hVault - Handle vault'a w którym chcesz zapisać dane
* @param szKey - Klucz przetrzymujący dane
* @param szData - Wartość typu String, którą chcesz zapisać.
*
* @return Zwraca 1 przy powodzeniu, 0 przy niepowodzeniu.
*
* @note Użyj "*" jako klucza, aby ustawić dane wszystkich wpisów.
* Zaktualizuje to też znaczniki czasu i ustawi wszystkie wpisy jako niepermanentne!
*
*/
sqlv_set_data(SQLVault:hVault, szKey[], szData[])

/*
* Zapisuje wartość typu Integer do vault'a
*
* @param hVault - Handle vault'a w którym chcesz zapisać dane
* @param szKey - Klucz przetrzymujący dane
* @param iData - Wartość typu Integer, którą chcesz zapisać.
*
* @return Zwraca 1 przy powodzeniu, 0 przy niepowodzeniu.
*
* @note Użyj "*" jako klucza, aby ustawić dane wszystkich wpisów.
* Zaktualizuje to też znaczniki czasu i ustawi wszystkie wpisy jako niepermanentne!
*
*/
sqlv_set_num(SQLVault:hVault, szKey[], const iData)

/*
* Zapisuje wartość typu Float do vault'a
*
* @param hVault - Handle vault'a w którym chcesz zapisać dane
* @param szKey - Klucz przetrzymujący dane
* @param flData - Wartość typu Float, którą chcesz zapisać.
*
* @return Zwraca 1 przy powodzeniu, 0 przy niepowodzeniu.
*
* @note Użyj "*" jako klucza, aby ustawić dane wszystkich wpisów.
* Zaktualizuje to też znaczniki czasu i ustawi wszystkie wpisy jako niepermanentne!
*
*/
sqlv_set_float(SQLVault:hVault, szKey[], Float:flData)


Czymś nowym jest tutaj klucz "*".

Jeśli użyjesz "*" jako klucza, wszystkie wpisy zostaną nadpisane twoimi danymi.

Znaczniki czasu zostaną zaktualizowane do bieżącej daty, a wszystkie klucze zostaną ustawione jako niepermanentne [także istniejące klucze które są permanentne (permanentne klucze są opisane trochę dalej)].

Jednak, używając klucza "*", nie zostanie utworzony żaden nowy wpis. Zostaną tylko zaktualizowane te istniejące.


Klucze permanentne to takie, które posiadają znacznik czasu, i są ignorowane przy czyszczeniu vault'a.

Przy czyszczeniu vault'a, wszystkie klucze, które posiadają znacznik czasu w danym zakresie są usuwane.

Klucze permanentne NIGDY nie są usuwane przy czyszczeniu vault'a.


Oto funkcje wykorzystywane do zapisywania permanentnych danych.

Są one łudząco podobne do niepermanentnych odpowiedników tych funkcji:



/*
* Zapisuje permanentną wartość typu String do vault'a
*
* @param hVault - Handle vault'a w którym chcesz zapisać dane
* @param szKey - Klucz przetrzymujący dane
* @param szData - Wartość typu String, którą chcesz zapisać.
*
* @return Zwraca 1 przy powodzeniu, 0 przy niepowodzeniu.
*
* @note "Permanentny" oznacza, że wpis nie może zostać usunięty przez sqlv_prune().
*
* @note Użyj "*" jako klucza, aby ustawić dane wszystkich wpisów.
* Zaktualizuje to też znaczniki czasu i ustawi wszystkie wpisy jako PERMANENTNE!
*
*/
sqlv_pset_data(SQLVault:hVault, szKey[], szData[])

/*
* Zapisuje permanentną wartość typu Integer do vault'a
*
* @param hVault - Handle vault'a w którym chcesz zapisać dane
* @param szKey - Klucz przetrzymujący dane
* @param iData - Wartość typu Integer, którą chcesz zapisać.
*
* @return Zwraca 1 przy powodzeniu, 0 przy niepowodzeniu.
*
* @note "Permanentny" oznacza, że wpis nie może zostać usunięty przez sqlv_prune().
*
* @note Użyj "*" jako klucza, aby ustawić dane wszystkich wpisów.
* Zaktualizuje to też znaczniki czasu i ustawi wszystkie wpisy jako PERMANENTNE!
*
*/
sqlv_pset_num(SQLVault:hVault, szKey[], const iData)

/*
* Zapisuje permanentną wartość typu Float do vault'a
*
* @param hVault - Handle vault'a w którym chcesz zapisać dane
* @param szKey - Klucz przetrzymujący dane
* @param flData - Wartość typu Float, którą chcesz zapisać.
*
* @return Zwraca 1 przy powodzeniu, 0 przy niepowodzeniu.
*
* @note "Permanentny" oznacza, że wpis nie może zostać usunięty przez sqlv_prune().
*
* @note Użyj "*" jako klucza, aby ustawić dane wszystkich wpisów.
* Zaktualizuje to też znaczniki czasu i ustawi wszystkie wpisy jako PERMANENTNE!
*
*/
sqlv_pset_float(SQLVault:hVault, szKey[], Float:flData)


Podobnie jak w niepermanentnych funkcjach, możesz użyć "*" jako klucza.

Jedyną różnicą jest to, że wszystkie klucze zostaną ustawione jako permanentne, nawet te niepermanentne.


Funkcje Kluczy:



Niektóre z funkcji zostały stworzone specjalnie do manipulacji kluczami.

Oto niektóre z nich:



/*
* Sprawdza czy klucz istnieje
*
* @param hVault - Handle vault'a w którym chcesz szukać
* @param szKey - Klucz który chcesz sprawdzić
*
* @return Zwraca 1, jeśli klucz istnieje, 0 jeśli nie.
*
*/
sqlv_key_exists(SQLVault:hVault, szKey[])

/*
* Usuwa klucz z vault'a
*
* @param hVault - Handle vault'a z którego chcesz usuwać
* @param szKey - Klucz który chcesz usunąć
*
* @return Zwraca 1 przy powodzeniu, 0 przy niepowodzeniu.
*
*/
sqlv_remove(SQLVault:hVault, szKey[])

/*
* Aktualizuje ("dotyka") znacznik czasu dla klucza
*
* @param hVault - Handle vault'a w którym chcesz aktualizować
* @param szKey - Klucz który chcesz zaktualizować
* @param iTimeStamp - Znacznik czasu który chcesz zapisąć (opcjonalne, domyślnie -1)
*
* @return Zwraca 1 przy powodzeniu, 0 przy niepowodzeniu.
*
* @note Użyj -1 jako znacznik czasu, aby wpisać aktualny czas.
*
* @note Użyj "*" aby zaktualizować wszystkie wpisy.
*
*/
sqlv_touch(SQLVault:hVault, szKey[], iTimeStamp = -1)


Funkcje Vault'a:

Niektóre z funkcji zostały stworzone do zarządzania całym vault'em.

Oto podstawowe z nich:



/*
* Usuwa wszystkie niepermanentne wpisy ze znacznikiem czasu w określonym zakresie.
*
* @param hVault - Handle vault'a, w którym chcesz usuwać wpisy
* @param iStart - Początkowy znacznik czasu
* @param iEnd - Końcowy znacznik czasu
*
* @return Zwraca ilość usuniętych wpisów (lub 1 jeśli nie usunięto żadnych) przy powodzeniu, 0 przy niepowodzeniu.
*
*/
sqlv_prune(SQLVault:hVault, iStart, iEnd)

/*
* Czyści wszystkie wpisy.
*
* @param hVault - Handle vault'a, którego chcesz wyczyścić.
* @param bSavePermanent - Jeśli 1, usuwa tylko niepermanentne wpisy. Jeśli 0, usuwa wszystkie wpisy. (opcjonalne, domyślnie 0)
*
* @return Zwraca ilość usuniętych wpisów (lub 1 jeśli nie usunięto żadnych) przy powodzeniu, 0 przy niepowodzeniu.
*
*/
sqlv_clear(SQLVault:hVault, bool:bSavePermanent = false)

/*
* Zwraca całkowitą liczbę wpisów
*
* @param hVault - Handle vault'a, którego rozmiar chcesz poznać :D
*
* @return Zwraca całkowitą liczbę wpisów vault'a.
*
*/
sqlv_size(SQLVault:hVault)


Istnieją też pewne nowe funkcje, pomocne dla zaawansowanych programistów.


Pierwszą z nich jest funkcja odczytująca po jednym kluczu:



/*
* Czyta wartość bazując na indeksie kluczy.
*
* @param hVault - Handle vault'a, z którego chcesz czytać.
* @param iKeyIndex - Indeks/numer klucza do przeczytania.
* @param szKey - Wartość String do przetrzymania klucza (opcjonalne)
* @param iKeyLen - Maksymalna długość bufora klucza (opcjonalne)
* @param szData - Wartość String do przetrzymania danych (opcjonalne)
* @param iDataLen - Maksymalna długość bufora danych (opcjonalne)
* @param iTimeStamp - Wartość znacznika czasu (opcjonalne)
* @param szWhere - Warunek "where" dla wybierania specyficznych danych (opcjonalne)
* @param szSort - Metoda sortowania danych (opcjonalne)
*
* @return Zwraca 1 przy powodzeniu, 0 przy niepowodzeniu.
*
* @note Indeksy kluczy zaczynają się od 0 i kończą na 1 przed końcem rozmiaru vault'a (sqlv_size() - 1)
*
* @note Jeśli chcesz przeczytać wszystkie klucze w vault'cie, użyj sqlv_read_all().
*
* @note Przy zmianach takich jak zapisywanie danych, zmiana znaczników czasu, usuwanie, itd. indeksy kluczy mogą się zmienić.
* Z tego powodu, te typy akcji nie powinny być wykonywane, gdy czytasz więcej niż 1 klucz.
*
* @note Warunek "where" jest taki sam jak w MySQL'owym "SELECT".
* Nie podawaj "WHERE" w argumencie.
*
* @note Sortowanie danych może się odbyć na dwa sposoby.
* 1. Podaj "asc" aby sortować rosnąco.
* Podaj "desc" aby sortować malejąco.
* 2. Podaj jakikolwiek inny sposób trawiony przez MySQL'owe "ORDER BY".
* Nie podawaj "ORDER BY" w argumencie.
*
*/
sqlv_read(SQLVault:hVault, iKeyIndex, szKey[] = "", iKeyLen = 0, szData[] = "", iDataLen = 0, &iTimeStamp = 0, const szWhere[] = "", const szSort[] = "")


Ta funkcja czyta każdy wpis vault'a, sprawdzając klucz, dane i znacznik czasu.

Indeks klucza określa który wpis zostanie przeczytany.


Możesz też określić, które dane zostaną przeczytane i jak je sortować.


Przykład:



new iRozmiar = sqlv_size(hVault);

// wygenreruj losowy indeks klucza
new iIndeksKlucza = random(iRozmiar)

new szKlucz[64], szDane[32], iZnacznikCzasu;
sqlv_read(hVault, iZnacznikCzasu, szKlucz, charsmax(szKlucz), szDane, charsmax(szDane), iZnacznikCzasu)

// zamiana znacznika czasu na przyjazny format
new szZnacznikCzasu[32]
format_time(szZnacznikCzasu, charsmax(szZnacznikCzasu), "%d-%m-%Y %H:%M:%S", iZnacznikCzasu)

// wyświetl dane
server_print("Klucz [%s] Dane [%s] ZnacznikCzasu [%s]", szKlucz, szDane, szZnacznikCzasu)



// pobierz statystyki najlepszego gracza
new szKlucz[64], szDane[32], iZnacznikCzasu;
sqlv_read(hVault, 0, szKlucz, charsmax(szKlucz), szDane, charsmax(szDane), iZnacznikCzasu, _, "desc")

// zamiana znacznika czasu na przyjazny format
new szZnacznikCzasu[32]
format_time(szZnacznikCzasu, charsmax(szZnacznikCzasu), "%d-%m-%Y %H:%M:%S", iZnacznikCzasu)

// wyświetl dane
server_print("Klucz [%s] Dane [%s] ZnacznikCzasu [%s]", szKlucz, szDane, szZnacznikCzasu)


Druga z funkcji czyta wszystkie dane vault'a naraz i przetrzymuje je w tablicy dynamicznej



/*
* Czyta wszystkie dane vault'a do tablicy dynamicznej
*
* @param hVault - Handle vault'a z którego chcesz czytać
* @param aVaultData - Tablica dynamiczna do przetrzymania danych
* @param szWhere - Warunek "where" dla wybierania specyficznych danych (opcjonalne)
* @param szSort - Metoda sortowania danych (opcjonalne)
*
* @return Zwraca całkowitą liczbę wpisów
*
* @note Warunek "where" jest taki sam jak w MySQL'owym "SELECT".
* Nie podawaj "WHERE" w argumencie.
*
* @note Sortowanie danych może się odbyć na dwa sposoby.
* 1. Podaj "asc" aby sortować rosnąco.
* Podaj "desc" aby sortować malejąco.
* 2. Podaj jakikolwiek inny sposób trawiony przez MySQL'owe "ORDER BY".
* Nie podawaj "ORDER BY" w argumencie.
*
* @note Tablica dynamiczna zawiera tablice korespondujące enum'owi SQLVaultEntry.
*
* @note Przykład:
*
* new Array:aDaneVaulta;
* new iKluczeVaulta = sqlv_read_all(hVault, aDaneVaulta);
*
* new eDaneVaulta[SQLVaultEntry];
*
* for(new i = 0; i < iKluczeVaulta; i++)
* {
* ArrayGetArray(aDaneVaulta, i, eDaneVaulta);
*
* eDaneVaulta[SQLV_Key] = klucz
* eDaneVaulta[SQLV_Data] = dane
* eDaneVaulta[SQLV_TimeStamp] = znacznikczasu
* }
*
* ArrayDestroy(aDaneVaulta);
*
* @note Nie powinieneś tworzyć tablicy dynamicznej samemu.
* Jest ona tworzona automatycznie przez funkcję.
* Jeśli w tablicy znajduje się już handle, zostaje ona wpierw zniszczona.
*
* @note Tablica dynamiczna musi zostać zniszczona po jej wykorzystaniu.
*
*/
sqlv_read_all(SQLVault:hVault, &Array:aVaultData, const szWhere[] = "", const szSort[] = "")


Jak widać w opisie funkcji, widnieje tam przykład pokazujący dokładnie jak ją użyć.


Możesz także określić które dane ma ona przeczytać, i jak je sortować.



new Array:aDaneVaulta;
new iKluczeVaulta = sqlv_read_all(hVault, aDaneVaulta);

new eDaneVaulta[SQLVaultEntry];
new szZnacznikCzasu[32]

for(new i = 0; i < iKluczeVaulta; i++) {
ArrayGetArray(aDaneVaulta, i eDaneVaulta)
// eDaneVaulta[SQLV_Key] = klucz
// eDaneVaulta[SQLV_Data] = dane
// eDaneVaulta[SQLV_TimeStamp] = znacznikczasu

format_time(szZnacznikCzasu, charsmax(szZnacznikCzasu), "%d-%m-%Y %H:%M:%S", eDaneVaulta[SQLV_TimeStamp]);

server_print("Klucz [%s] Dane [%s] ZnacznikCzasu [%s], eDaneVaulta[SQLV_Key], eDaneVaulta[SQLV_Data], szZnacznikCzasu)
}
ArrayDestroy(aZnacznikCzasu)


Trzecia funkcja czyta cały zestaw danych naraz i zapisuje go w tablicy dynamicznej.



/*
* Czyta zestaw danych do tablicy dynamicznej.
*
* @param hVault - Handle vault'a z którego chcesz czytać
* @param eOutputData - Tablica dynamiczna, która ma przetrzymać cały zestaw.
* @param iOutputSize - Rozmiar zestawu, który czytasz
* @param iStart - Numer od którego chcesz zacząć czytać
* @param szWhere - Warunek "where" dla wybierania specyficznych danych (opcjonalne)
* @param szSort - Metoda sortowania danych (opcjonalne)
*
* @return Zwraca całkowitą liczbę wpisów
*
* @note Warunek "where" jest taki sam jak w MySQL'owym "SELECT".
* Nie podawaj "WHERE" w argumencie.
*
* @note Sortowanie danych może się odbyć na dwa sposoby.
* 1. Podaj "asc" aby sortować rosnąco.
* Podaj "desc" aby sortować malejąco.
* 2. Podaj jakikolwiek inny sposób trawiony przez MySQL'owe "ORDER BY".
* Nie podawaj "ORDER BY" w argumencie.
*
* @note Przykład pobierania wpisów o najwyższych wartościach:
*
* new eDaneVaulta[10][SQLVaultEntry];
* new iKluczeVaulta = sqlv_read_set(hVault, eDaneVaulta, sizeof(eDaneVaulta), _, _, "desc");
*
* for(new i = 0; i < iKluczeVaulta; i++)
* {
* eDaneVaulta[i][SQLV_Key] = klucz
* eDaneVaulta[i][SQLV_Data] = dane
* eDaneVaulta[i][SQLV_TimeStamp] = znacznikczasu
* }
*
*/
sqlv_read_set(SQLVault:hVault, eOutputData[][SQLVaultEntry], iOutputSize, iStart = 0, const szWhere[] = "", const szSort[] = "")


W tej funkcji też widnieje przykład jak jej użyć.


Możesz tu też oczywiście podać które dane chcesz czytać, i jak je sortować.



new eDaneVaulta[10][SQLVaultEntry];
new iKluczeVaulta = sqlv_read_set(hVault, eDaneVaulta, sizeof(eDaneVaulta), _, _, "desc");

new szZnacznikCzasu[32]

for(new i = 0; i < iKluczeVaulta; i++) {
// eDaneVaulta[i][SQLV_Key] = klucz
// eDaneVaulta[i][SQLV_Data] = dane
// eDaneVaulta[i][SQLV_TimeStamp] = znacznikczasu

format_time(szZnacznikCzasu, charsmax(szZnacznikCzasu), "%d-%m-%Y %H:%M:%S, eDaneVaulta[i][SQLV_TimeStamp])

server_print("Klucz [%s] Dane [%s] ZnacznikCzasu [%s]", eDaneVaulta[i][SQLV_Key], eDaneVaulta[i][SQLV_Data], szZnacznikCzasu)
}


Raportowanie Błędów:

Żaden z błędów NIE jest zapisywany do normalnych logów błędów, ani nie zatrzymuje pracy pluginu.

Logi są zapisywane jako normalne logi AMXX'a do addons/amxmodx/logs/LYYYYMMDD.log gdzie YYYY to rok, MM to miesiąc, a DD dzień.


Przypiski:



Te funkcje nie używają wątkowanych zapytań.


Dla tych co nie wiedzą, wątkowane zapytanie to zapytanie, które nie jest wykonywane w czasie jego wysłania.

Wątkowane zapytania są wrzucane na stos i wywoływane na bazie FIFO (first-in-first-out) gdy moduł SQLx ma czas na ich wykonanie.

To oznacza, że zapytanie mogłoby zostać wykonane po upływie 0.001 sekundy lub 5 minut.

Nigdy nie wiadomo kiedy zostaną one na pewno wykonane, czas ich wykonania staje się znany dopiero po właśnie ich wykonaniu.

Ponieważ są one wykonywane wtedy kiedy moduł na to pozwala, nie tworzy się dużego obciążenia każąc serwerowi wykonywać wszystko od razu.


Nie ma wersji SQLVault'a dla wątkowanych zapytań.

Jeśli bardzo takowej potrzebujecie, spamujcie Exolent'owi na forach AlliedModders.


Moduł SQLite jest automatycznie ładowany wraz z includem.

Nawet jeśli nie używasz lokalnych baz danych, i tak jest potrzebny do działania.


Możesz zauważyć, że nazwy kluczy i vault'ów nie są stałymi (constant'ami).

Jest tak ponieważ zmienne muszą zostać "escape'owane" (uszczelnione?) dla pozbycia się niechcianych znaków, które mogłyby zaszkodzić zapytaniom SQL.

Z tego powodu nie da się użyć żadnych stałych zmiennych w tych funkcjach.



// ŹLE
new const g_szNazwaVaulta = "test";
new SQLVault:g_hVault;

public plugin_init() {
g_hVault = sqlv_open_local(g_szNazwaVaulta)
}



// DOBRZE
new g_szNazwaVaulta = "test";
new SQLVault:g_hVault;

public plugin_init() {
g_hVault = sqlv_open_local(g_szNazwaVaulta)
}



// TEŻ DOBRZE
new SQLVault:g_hVault;

public plugin_init() {
g_hVault = sqlv_open_local("test")
}


W załączniku jest też kilka przykładów.

Nie mają one żadnego znaczenia oprócz tego, że mogą zostać wykorzystane do testów (czy się kompiluje, czy działa i nie wywala błędów)

Ich wynik powinien zostać przez ciebie zignorowany bo nie mają one żadnego sensu.


Powiedzcie co myślicie, co poprawić, i co sknociłem w tłumaczeniu :P

Byłoby też miło, gdyby któryś z moderatorów zobaczył czemu nie działa kolorowanie składni :(

Załączone pliki


  • +
  • -
  • 3

#2 Jak się nazwać

    Wszechmogący

  • Power User

Reputacja: 169
Profesjonalista

  • Postów:617
  • Imię:a
  • Lokalizacja:a
Offline

Napisano 15.08.2012 10:44

W 90% przypadków zapisu/odczytu danych nie przyda się bo będą występowały lagi związane z oczekiwaniem na wynik zapytania co jest bardzo dużą wadą.
  • +
  • -
  • 0
Pisze na zamówienie statystyki pod nvault. GG: 15600964

#3 DarkGL

    Nie oddam ciasteczka !

  • Administrator

Reputacja: 6 553
Godlike

  • Postów:11 976
  • GG:
  • Steam:steam
  • Imię:Rafał
  • Lokalizacja:Warszawa
Offline

Napisano 15.08.2012 12:07

W 90% przypadków zapisu/odczytu danych nie przyda się bo będą występowały lagi związane z oczekiwaniem na wynik zapytania co jest bardzo dużą wadą.

^D^
opóźnienie w zapisie / odczycie nie ma znaczenia
tyle modów używa sql i nie ma jakos problemów
  • +
  • -
  • 0

#4 Jak się nazwać

    Wszechmogący

  • Power User

Reputacja: 169
Profesjonalista

  • Postów:617
  • Imię:a
  • Lokalizacja:a
Offline

Napisano 15.08.2012 12:18

DarkGL ale używają metody pośredniej (SQL_ThreadQuery) a w przypadku sqlvault jest metoda bezpośrednia (SQL_Connect+SQL_PrepareQuery+SQL_Execute)

Ta metoda daje natychmiastowy zwrot rezultatu ALE pod warunkiem że bazę danych mamy ulokowaną na tej samej maszynie co serwer. W przeciwnym wypadku na serwerze będą ściny serwera i masakryczne pingi.

Z moich testów sqlvault czyli tej metody przy dużej ilości wpisów też występują lagi nawet na localhoscie/sqlite.
  • +
  • -
  • 0
Pisze na zamówienie statystyki pod nvault. GG: 15600964

#5 DarkGL

    Nie oddam ciasteczka !

  • Administrator

Reputacja: 6 553
Godlike

  • Postów:11 976
  • GG:
  • Steam:steam
  • Imię:Rafał
  • Lokalizacja:Warszawa
Offline

Napisano 15.08.2012 12:22

chodzi o to że threadquery jest asynchroniczne a to drugie synchroniczne dlatego są lagi
ale czy problemem jest przerobić to na threadquery ;)
  • +
  • -
  • 0

#6 Jak się nazwać

    Wszechmogący

  • Power User

Reputacja: 169
Profesjonalista

  • Postów:617
  • Imię:a
  • Lokalizacja:a
Offline

Napisano 15.08.2012 12:26

No niby można przerobić, ja aktualnie piszę moda więc jak skończę to może się tym zajmę. Ja tylko napisałem, że używanie sqlvault w wersji która jest podana w 1 poście będzie powodować zacinki (jak mocne zależy od ilości zapytań itd).
  • +
  • -
  • 0
Pisze na zamówienie statystyki pod nvault. GG: 15600964

#7 fgsfds

    Pomocny

  • Autor tematu
  • Użytkownik

Reputacja: 18
Początkujący

  • Postów:65
Offline

Napisano 16.08.2012 13:00

Ja wywołuję w swoim modzie ok. 100 zapytań dla każdego gracza na koniec rundy i nie widzę żadnych większych problemów.
Może dlatego że baza danych hostowana jest na tym samym kompie co serwer xD
  • +
  • -
  • 0

#8 Jak się nazwać

    Wszechmogący

  • Power User

Reputacja: 169
Profesjonalista

  • Postów:617
  • Imię:a
  • Lokalizacja:a
Offline

Napisano 16.08.2012 15:06

Ja wywołuję w swoim modzie ok. 100 zapytań dla każdego gracza na koniec rundy

Po co aż tyle? Już widzę jak baza danych wyrabia przy 3200 zapytań na raz (32 graczy na serwerze).
  • +
  • -
  • 0
Pisze na zamówienie statystyki pod nvault. GG: 15600964

#9 sebul

    Godlike

  • Przyjaciel

Reputacja: 2 035
Godlike

  • Postów:5 411
  • Steam:steam
  • Imię:Sebastian
  • Lokalizacja:Ostrołęka
Offline

Napisano 16.08.2012 15:22

Jak się dobrze napisze plugin, to spokojnie można wysłać za jednym razem 1k zapytań, bez jakichś większych, widocznych ścin serwera, ale czy więcej, to tego nie wiem.
  • +
  • -
  • 2

Posiadam TBM (inaczej PTB), które działa dużo lepiej niż zwykłe PTB, nawet na modach z lvlami. Zainteresowany? Proszę bardzo


#10 G[o]Q

    I'm G[o]Q

  • Przyjaciel

Reputacja: 1 344
Godlike

  • Postów:3 563
  • Steam:steam
  • Imię:Krzysiek
  • Lokalizacja:C: / program Files / Valve / Cstrike / G[o]Q.dem
Offline

Napisano 16.08.2012 16:02

sebul jak sie dobrze napisze plugin i dobrze baze zaprojektuje to wszystko mozna zrobić 1 zapytaniem dla gracza a nawet 1 zapytaniem dla servera :D
sebul (16.08.2012 16:48):
Jestem ciekaw jak, bo chyba nie da się pomieścić wszystkiego w jednej zmiennej, bo nawet próbowałem czegoś takiego, to przy tablicy z sporo ponad 3k elementami były już problemy, zapytanie nie chciało się wysłać. Zresztą nie chodzi mi tutaj o zapytania wysyłane przez gracza.
sebul (16.08.2012 16:49):
Chyba, że da się w jakiś sposób wysłać plik z zapytaniem, w każdym razie mi z 12k zapytań, udało się zrobić niecałe 300.
G[o]Q (16.08.2012 17:05):
po co ci az tyle zapytań ?

co do organizacji bazy to trzeba sobie dobrze zrobić relacje ale to taki nawyk z access'a ktory raczej malo kto stosuje w mniejszych projektach w mysql'u
sebul (16.08.2012 17:41):
A przerabiałem statystyki sql do gungame, a tam normalnie wysyła tyle zapytań, ile jest graczy w pliku ze statami.
G[o]Q (16.08.2012 17:56):
i chcesz powiedzieć że w ciągu mapy wchodzi i wychodzi 300 osob

przeciez wystarczą 2 zapytania na osobe a na mape prezz server przewija się moze 20-30 osob jak server jest dobry(20 slotów) a dodatkowo jak sie dobrze zaprojektuje interfejs sql to mozna uzyskać sytuacje ze w diablo bedzie mozna grac na serverze i kupować przez www exp'a :D
sebul (16.08.2012 18:08):
Pisałem o 300 zapytaniach w jednym momencie, a nie w ciągu jednej mapy.
Chcąc zrobić to tak jak mam na diablo, czyli podobnie jak piszesz (tylko u mnie są jakieś 3-4 zapytania w ciągu mapy na jednego gracza, bo korzystam z dwóch tabel, jeśli chodzi o same statystyki), to musiałbym chyba przerabiać cały silnik GG. Zresztą zobacz sobie ten plugin od statystyk sql GG, to zobaczysz jak to tam jest zrobione, ja tylko na szybkiego przerobiłem, aby serwer się nie wieszał, bo jednak przy 12k zapytaniach była ostra zamuła.
G[o]Q (16.08.2012 18:10):
2 tabele nie stoją na przeszkodzie zeby uzyć 1 zapytania :D
sebul (16.08.2012 18:21):
Wiem, ale nie zmieniajmy tematu.

  • +
  • -
  • 1
Manual ponad wszystko, konsola ponad manual :D :&

Chcesz wysłać do mnie PW ? użyj nazwy GoQ zamiast G[o]Q
Chcesz Kupić moduł płatności via Pukawka,Tserwery, Gamesol, Zabijaka do mojego sklepu? napisz PW cena to tylko 10 zł/sztuka

GG:6022845 (nie pomagam za free osobom ponizej rangi MoD) :D





Również z jednym lub większą ilością słów kluczowych: sql, mysql, vault, sqlvault, nvault, nfvault, dokumentacja, cokolwiek

Użytkownicy przeglądający ten temat: 0

0 użytkowników, 0 gości, 0 anonimowych