151 lines
6.3 KiB
Plaintext
151 lines
6.3 KiB
Plaintext
|
|
dbquery.c / dbquery.h
|
|
|
|
Retrieve information from the database & displays it.
|
|
|
|
Overview
|
|
|
|
This component uses colors.c / colors.h.
|
|
|
|
Every function that allocates memory also frees it.
|
|
|
|
Advanced string manipulation such as concatenation is avoided. Instead
|
|
strings are printed in parts.
|
|
|
|
Exo File Dependencies
|
|
|
|
SQL commands are stored in an outside file (.sql) and executed. The
|
|
functions in this file are largely adaptable until
|
|
void qresult(void * const, const char *);
|
|
which prints the results of the query. This is specific to the query. All
|
|
functions in this file could be considered non-modular because the
|
|
specialized functions like 'qresult' are eventually called by the more
|
|
adaptable functions. This may later be solved by calling function pointers
|
|
to display table data, but currently many of the tables are similar enough
|
|
that one function to print all tables suffices.
|
|
|
|
Adding or Removing New Queries
|
|
|
|
To add new queries the program may handle the following functions need to
|
|
be adjusted.
|
|
|
|
inline void print_tblheader(const char *);
|
|
|
|
inline char *get_filename(const char *) ;
|
|
|
|
void qresult(void * const, const char *);
|
|
|
|
The file name of the query file should be added to the switch statement of
|
|
function 'get_filename'. The starting html tags and labels should also be
|
|
added to the switch statement of function 'print_tblheader'. For both
|
|
forementioned functions, the switch statement operates on a variable 'c'
|
|
which represents the first character of the query string. Currently, the
|
|
case is that the different queries, '?map=' and '?player=', begin with
|
|
different letters.
|
|
|
|
The function 'qresult'- extra formatting and corresponding conditions
|
|
should be added to the series of if/else-if statements. 'qresult's most
|
|
applicable conditionals are player names and formatted times- if a new
|
|
query will involve those, the conditionals should be added.
|
|
|
|
Function Walkthrough
|
|
Sorted by caller to callee.
|
|
|
|
void getquery(char * const);
|
|
Parameter 'char * const' is the query string retrieved from the
|
|
environment. NULL is an acceptable parameter. Only the first character
|
|
of the string pointed at by the pointer will be changed.
|
|
|
|
A file name is then retrieved from 'get_filename', depending on the
|
|
first character of the query string. Then the contents of the query
|
|
file is read in to be later to query the database.
|
|
|
|
Currently, this function determines the size of the file by using
|
|
'fseek' and 'ftell'. Often recommended against however:
|
|
1. The files to open are restricted to a specific set.
|
|
2. The files are plain text files.
|
|
3. The file sizes, in bytes, are very unlikely to exceed the
|
|
maximum value representable by integers.
|
|
|
|
'ftell' returns a long int. It can determine the file size of a ~2 GB
|
|
file.
|
|
|
|
int executequery(const char *, const char *);
|
|
Parameter #1 is the string containing the query for the database. NULL
|
|
is not acceptable. If a null value is given, the program will output
|
|
the following string to stderr:
|
|
Could not prepare SQL statement: not an error
|
|
|
|
(null)
|
|
Parameter #2 is the query string. NULL is acceptable.
|
|
|
|
This function opens and closes the connection to the database. Also
|
|
prepares and finalizes the sql statement. However itself, it does not
|
|
actually query the database.
|
|
|
|
void qresult(void * const, const char *);
|
|
Parameter #1 is the prepared sql statement.
|
|
Parameter #2 is the first character of the query string- in use to
|
|
identify the query.
|
|
|
|
This function both executes the query and displays the data.
|
|
The for loop iterates for each field of the row returned.
|
|
|
|
Conditionals explained:
|
|
|
|
The fields are hardcoded from the sql query files.
|
|
|
|
mranks.sql - (*c = QOVERVIEW)
|
|
select mapid, max(trank), min(tvalue), alias
|
|
i = 0 1 2 3
|
|
|
|
rplayers.sql - (*c = QRPLAYER)
|
|
select alias, mapid, idrank
|
|
i = 0 1 2
|
|
|
|
mleaderboard.sql - (*c = QMLEADERBOARD)
|
|
select trank, alias, tvalue
|
|
i = 0 1 2
|
|
|
|
if ((*c == QMLEADERBOARD && i == 1)
|
|
|| (*c == QOVERVIEW && i == 3)
|
|
|| (*c == QRPLAYER && i == 0))
|
|
If the field is for map leaderboards and column 1, or the overview
|
|
and column 3, or player ranks and column 0, then it is a player
|
|
name; which should have the in-game color codes translated to html.
|
|
|
|
if ((i == 0 && *c == QOVERVIEW) || (i == 1 && *c == QRPLAYER))
|
|
If the field is for overview and column 0 or is player ranks column
|
|
1, then it is a map name, and it should have html tags linking it
|
|
to the map leaderboards.
|
|
|
|
if (i == 2 && (*c == QMLEADERBOARD || *c == QOVERVIEW))
|
|
If the field is column 2 of either the overview or the map
|
|
leaderboards, then it is a time which should be formatted as such.
|
|
|
|
If none of the conditionals are met, then the field is printed as usual.
|
|
|
|
void print_time(const unsigned char *);
|
|
Parameter 'const unsigned char *' is the string that represents a
|
|
number- quantity of centiseconds.
|
|
|
|
The time as a string is converted to a number by 'strtoul'. Thus, the
|
|
maximum value that is returned by 'strtoul' given a string is
|
|
21,474,836.47 seconds. This is by far, more than enough for a game mode
|
|
focused on the lowest possible times.
|
|
|
|
This function performs the conversion and prints the value.
|
|
|
|
inline void print_tblheader(const char *);
|
|
Parameter 'const char *' is a pointer to a string. However, only the
|
|
first character is of interest because C can not switch on strings.
|
|
|
|
This function prints the starting tag of the html table.
|
|
|
|
inline char *get_filename(const char *) ;
|
|
Parameter 'const char *' is a pointer to a string. However, only the
|
|
first character is of interest because C can not switch on strings.
|
|
|
|
This function returns the file name of a sql query file.
|
|
|