6.4 Client program 3-Generate Connection code module
For our third client program, client program 3, by encapsulating it into functions do_connect () and Do_disconnect (), it will make the connection and disconnect code more modular so that it can be easily used by multiple client programs. This provides a choice to embed the connection code precisely in the main () function. In any case, it's a good idea to have any code that is stereotyped in the application process. Place it in a function that can be accessed through multiple programs, rather than writing it in every program. If you fix an error in this function or make some improvements to the function, you can change it only once, and all programs that can use the function as a recompile are modified or take advantage of this improvement. Also, write some client programs so that you can connect and disconnect several times during their execution. Writing such a client is easier if you place the installation and uninstall methods in a connected and disconnected function. The encapsulation strategy looks like this:
1 separate the common code into a wrapper function of a separate source file (COMMON.C).
2 provides a header file, Common.h, which includes the prototype of the common routine.
3 includes common.h in client source files that use common routines.
4 Compile the common source file into the target file.
5 Connect the common target file to your client program.
With these strategies, let's construct Do_connect () and do _ Disconnect ().
Do_connect () replaces the call to Mysql_init () and Mysql_real_connect (), replacing the incorrectly printed code. In addition to not passing any connection handlers, you can call it like Mysql_real_connect (). Do_connect () assigns and initializes the handler, and then returns a pointer to it after the connection. If Do_ connect () fails, after printing an error message, returns Null (that is, any program that calls Do_connect () and gets the return value NULL can simply exit without worrying about printing the message itself). Do_ Disconnect () produces a pointer to the connection handler and calls Mysql_close (). Here is the code for COMMON.C:
Common.h declares the prototypes of these routines in COMMON.C:
To access a common routine, include common.h in the source file. Please note that COMMON.C also includes Common.h. That is to say, if the function definition in COMMON.C does not match the declaration in the header file, a compiler warning is immediately obtained. Similarly, if you change the order of calls in COMMON.C without changing common.h Accordingly, the compiler will issue a warning when the COMMON.C is recompiled.
One would ask why the wrapper function do _ disconnect () was invented, and it was used so little. Do _ Disconnect () and mysql_close () are equivalent. However, assume that when you disconnect, there are some additional cleanup to perform. By invoking a wrapper function that is already fully controlled, you can modify the wrapper function to do what is needed, and the change will take effect for any disconnected operation. If you call Mysql_ close () directly, you cannot do this. In the preceding, I claim that it is advantageous to encapsulate code into modular code in functions that are used in multiple programs or within a single program. For a reason, there are several reasons to see the following two examples.
Sample 1 in the previous version of MySQL3 22, the Mysql_real_connect () call is slightly different from what it is now: there is no database name parameter. If you want to use the old MySQL client library using do _ Connect (), it will not work. However, you can modify do _ Connect () so that it can be run on versions prior to version 3.22. It's
means that by modifying do _ Connect (), you can increase the portability of all programs that use it. If you embed these connection codes directly into each client, you must modify each of them independently.
To modify do _ Connect () so that it can handle the old format of Mysql_real_connect (), you can use the MYSQL_VERSION_ID macro that includes the current MySQL version. The changed Do_connect () tests the mysql_version_id value and uses the correct format for Mysql_real_connect ():
In addition to the following two points, this modified version of Do_connect () is identical in appearance to the previous version:
It does not pass the Db_name parameter to the earlier format of Mysql_real_connect (), because that version has no such parameters.
If the database name is Non-null, Do_connect () invokes mysql_select_db () to make the specified database the current database (this is similar to the effect without db_name parameters). If this database is not selected, Do_connect () prints an error message, closes the connection, and returns null to indicate failure.
Sample 2 is based on a change to the Do_connect () of the first sample. Those changes result in calls to the three group of error functions Mysql_errno () and Mysql_error (). It's annoying to write the code that reports the problem every time. In addition, the error printed out the code looks uncomfortable, read
Come also difficult. And it's easier to read the following code:
PRINT_ERROR (Conn, "Mysql_real_connect () failed"); So let's encapsulate error printing in the Print_error () function. Even if Conn is null, it can be written to do some sensible things. In other words, if the mysql_init () call fails, you can use the print _error (). And no mixed calls (some for fprintf (), some for print _ Error ()). I heard some objections: "In order to report an error without having to call two error functions each time, the code is deliberately written hard to read to illustrate that the farce case is better." You don't actually have to write all the wrong print code: write it once, and then use copy and paste when you need it again. "This view is correct, but I oppose it for the following reasons:
Even with the use of copy and paste, it is easier to do it in a shorter piece of code.
Every time you report an error, whether you are willing to call two functions at a time, writing all the error reporting code very long can produce inconsistencies. By placing the code of the error report in an easily callable wrapper function, you can reduce the idea and increase the consistency of the encoding.
If you decide to modify the format of the error message, you need to make changes in one place instead of the entire program, which is much easier. Alternatively, if you decide to write the error message to a log file instead of (or otherwise) written to stderr, you will need to change the print _ error () to make it easier. This approach can make fewer mistakes, and once again reduces the likelihood of work and inconsistency.
When testing a program, if you use a debugger to place a breakpoint in a function that is reported incorrectly, the debugger is a convenient way to break a program when it detects an error condition. The following is an example of the use of the error reporting function Print _ Error ():
The primary source file client3.c is the same as client2.c, but all embedded connections and disconnected code are removed and replaced by invoking the wrapper function. As shown below: