Database: Difference between revisions

No edit summary
(Added a few examples of various database functions, and clarified some of the database function arguments.)
Line 54: Line 54:
|-
|-
| [[GetDBEntryRank]]
| [[GetDBEntryRank]]
| string ''namespace'', string ''key'', bool ''order''
| string ''namespace'', string ''key'', bool ''descending''
| int ''position''
| int ''position''
| Sort a namespace by value and return the position of the given key in that namespace.
| Sort a namespace by value and return the position of the given key in that namespace.
Line 64: Line 64:
|-
|-
| [[SortDBEntries]]
| [[SortDBEntries]]
| string ''namespace'', int ''limit'', int ''offset'', bool ''order''
| string ''namespace'', int ''limit'', int ''offset'', bool ''descending''
| resource ''results''
| resource ''results''
| Return a resource that contains a pointer to rows in the namespace sorted by value.
| Return a resource that contains a pointer to rows in the namespace sorted by value. <br>''Limit'' is the maximum number of rows to return.<br>''Offset'' is the starting position to return in the sorted table (a value of 1 will cause the returned database to start at the second highest value).
|-
|-
| [[CountDBResults]]
| [[CountDBResults]]
Line 128: Line 128:


== Examples ==
== Examples ==
{{Noexamples}}
Lets say we want to make a script that keeps track of player deaths.
 
The following script increments (or if it doesn't exist, creates) a namespace with the player's authentication account name and initializes a section called "Deaths". Whenever a player dies, if they are logged in, their death will be recorded.
One namespace can store multiple sections, so you could use the same player name to store "Deaths" and "Frags". The namespace does not need to be the player's authentication name, you could use their ingame name instead. This is a little bit unsafe, however, as it might cause problems when players share the same names.
 
<syntaxhighlight lang="c" line="1">
script "IncrementPlayerDeaths" DEATH
{
    if (PlayerIsLoggedIn(PlayerNumber()))
        IncrementDBEntry(GetPlayerAccountName(PlayerNumber()), "Deaths", 1);
}
</syntaxhighlight>
 
However, instead of incrementing this value every time a player dies, you can do this before the map changes with a transaction. This is benefitial for performance on large databases with many players. Be aware that if a player leaves the game before the map change, their data will not be saved!
 
<syntaxhighlight lang="c" line="1">
#define MAXPLAYERS 64
 
int global_playerdeaths[MAXPLAYERS];
 
script "IncrementPlayerDeaths" DEATH
{
    global_playerdeaths[PlayerNumber()]++;
}
 
script "StorePlayerDeaths" UNLOADING
{
    BeginDBTransaction();
    for (int i=0; i<MAXPLAYERS; i++)
        if (PlayerIsLoggedIn(i))
            IncrementDBEntry(GetPlayerAccountName(i)), "Deaths", global_playerdeaths[i]);
    EndDBTransaction();
}
</syntaxhighlight>
 
And the following script sorts the database and prints the name of the player with the most deaths, as well as how many times they died
 
<syntaxhighlight lang="c" line="1">
script "ShowMostDeaths" (void)
{
int result = GetDBEntries("Deaths");
    int count = CountDBResults(result);
   
    // Make sure the database has values
    if (count != 0)
{
        // Free the memory allocated by the first GetDBEntries call
        FreeDBResults(result);
       
        // Get the list of deaths, sort it, and then print who died the most
        result = SortDBEntries("Deaths", count, 0, true);
        PrintBold(s:"Player ", s:GetDBResultKeyString(result, 0), s:" has the most deaths, having died ", d:GetDBResultValue(result, 0), " time(s).");
    }
   
    // Free the memory allocated by SortDBEntries, or by CountDBResults if it returned zero.
    FreeDBResults(result);
}
</syntaxhighlight>


== See also ==
== See also ==