MongoDB Plugin Design: Basic Components
MongoDB : Introduction | Download | Basic Components | Start | Stop | Client | Support Functions | Command pipe | Mongo-Start
|
|
UniServer 6-Carbo MongoDB plugin design. |
MongoDB
Basic Components
An application requires several components (functions and scripts) these need to tested before integration. Our Windows application for MogoDB is no exception.
This tutorial assume you have downloaded Uniform Server 6-Carbo and the MongoDB tutorial see previous page for details.
General
Single point references
Our final application will use single point references. A changeable parameter will have a unique location. It is changeable by any user (manually or script) when using this parameter it is assumed to have changed hence before using always read it afresh.
For example MongoDB configuration file is a single point of reference. It contains a parameter defining port to use. A user or script can change its value. Any script performing some action that uses the port will read its value directly from the configuration file before use.
Similarly another point of reference will be the Admin name/password file. Bear the above in mind even if the examples hard code parameters.
Batch file Command-line
Using a command line interface becomes very tedious. Most of what you enter for testing is reparations and prone to typing errors. My preference is to create a batch file containing the command-line to run. This also avoids creating shortcuts on the desktop.
:mode con:cols=65 lines=20 TITLE UNIFORM SERVER - Option COLOR B0 @echo off cls ===== command-line to run ===== :pause EXIT |
Basic batch file
|
Preparation
Create a new folder named a_test in folder UniServer\usr\local\mongo_tutorial
This will contain our test batch files and scripts.
Command prompt
Lets start with a small script that opens a command prompt where Mongo binaries are located.
A user would typically create a short cut to this folder! Not very portable, an alternative is to open a command prompt manually at this location as follows:
- Click start
- Click run. Type in cmd to open a command window
- Type cd (change directory) enter full path to the bin folder
We what to perform the same using a php script create a new file named run_cmd.php in folder a_test.
With the following content:
run_cmd.php:
<?php print "Test\n"; ?>
Double clicking on file run_cmd.php you will find it does not run! I have assumed PHP has not been installed on the PC hence there is no file association.
Note: If it does run you have PHP installed however that is not the version or configuration file we want to run.
All test scripts require PHP version and configuration file installed with Uniform Server 6-Carbo.
For testing we use a batch file to run PHP test scripts. Create a new file Run_cmd.bat in folder a_test with the following content:
Run_cmd.bat: TITLE UNIFORM SERVER - Run cmd COLOR B0 @echo off cls cd ..\..\php php.exe -c mongo_tutorial_cli.ini ..\mongo_tutorial\a_test\run_cmd.php pause EXIT |
Note: This batch file is generic and will be renamed along with minor modification to run other test scripts. |
Test:
Run run_cmd.php by double clicking on Run_cmd.bat you will see “Test” is printed in the window.
CLI Script
We want to create a function that opens a command prompt window. This window must remain open however our main application does not want to wait for it to be closed hence it must be detached from the main process.
Function needs to force current working directory to Mongo bin folder however it must reinstate original working. For flexibility we want to use absolute paths that are relative to folder UniServer. A slight contradiction path to folder UniServer is variable and dependent where a user located Uniform Server. All paths from folder UniServer are definable.
Start a second command window
At this point we can’t script anything! How do you start a second command window?
Add the following line as show to our test batch file:
:mode con:cols=65 lines=20 TITLE UNIFORM SERVER - Run cmd COLOR B0 @echo off cls cd ..\..\php php.exe -c mongo_tutorial_cli.ini ..\mongo_tutorial\a_test\run_cmd.php start "UNIFORM SERVER Mongo Command Line" cmd.exe /k "COLOR B0 && cls &&dir" pause EXIT |
|
Test:
Double click on Run_cmd.bat
You may have to drag top window away to reveal the first command window. Note the message “Press any key to continue” this indicates our new window is detached from the first.
You can delete that line from the batch file its no longer required. We are going to code it as a command string in the function.
Tip
I personally hate long lines in scripts. First thing I would perform is to add a back slash to all quotes as shown:
start \"UNIFORM SERVER Mongo Command Line\" cmd.exe /k \"COLOR B0 && cls &&dir\"
Slit that line into smaller manageable parts:
start \"UNIFORM SERVER Mongo Command Line\" cmd.exe /k \"COLOR B0 && cls &&dir\"
Them rebuild the command line string as follows:
$cmd1 = "start "; $cmd2 = "\"UNIFORM SERVER Mongo Command Line\" "; $cmd3 = "cmd.exe /k \"COLOR B0 && cls &&dir\""; $cmd = $cmd1.$cmd2.$cmd3;
It involves a little extra work however when it comes to debugging it is well worth the effort.
Detached process
If the above command line is run using something like PHP exe format of function shown below
string exec (string $command [, array &$output [,int &$return_var ]])
For example
exec($cmd):
The script will hang until the second window is closed. This is because processes open are child processes of the script.
To run a detached process use the following:
pclose(popen($cmd,'r'));
For a detailed explanation see PHP CLI: Detached Processes
Finished test script
<?php chdir(dirname(__FILE__)); // Change wd to this files location $path_array = explode("\\usr",getcwd()); // Split $mongo_base = $path_array[0]; // Path to UniServer $mongo_base_f = preg_replace('/\\\/','/', $mongo_base); // Replace \ with / //=== FOLDERS === define("MONGO_START", "$mongo_base_f/unicon/tray_menu_2"); // Mongo start define("MONGO_BIN", "$mongo_base_f/usr/local/mongo_tutorial/bin");// Binaries open_cmd_window(); // Run our test function //=== Open a command window =================================================== // Opem a cmd window in bin folder function open_cmd_window(){ $return_wd = getcwd(); // Save current wd chdir(MONGO_BIN); // Change wd to Mongo Bin $base = preg_replace('/\//','\\', MONGO_BIN); // Replace / with \ $cmd1 = "start "; $cmd2 = "\"UNIFORM SERVER Mongo Command Line\" "; $cmd3 = "cmd.exe /k \"COLOR B0 && cls &&dir\""; $cmd = $cmd1.$cmd2.$cmd3; pclose(popen($cmd,'r')); // Start a new process ignore output chdir($return_wd); // Restore original wd } //=============================================== END Open a command window === ?> |
|
Testing finished script
Comment out the pause in batch file to look like this:
TITLE UNIFORM SERVER - Run cmd COLOR B0 @echo off cls cd ..\..\php php.exe -c mongo_tutorial_cli.ini ..\mongo_tutorial\a_test\run_cmd.php :pause EXIT
Run this modified batch file.
After a short time batch file closes leaving a command window that can be used to run Mongo’s command-line tools.
Summary
That completes one component (function) of our main application. Detail included was not intended to be patronising it was aimed at users new to CLI and DOS (cmd) batch file scripting.
Our main application will be click and run the above function with minor modification will run Mongo,s client interface directly covered in next section.
Add structure
Looking at our first test script you will notice there is a structure already evolving. Defining paths will be a common task for all test scripts. Having access to common functions will also be a requirement. We don’t want to keep typing the same ting over and over again.
Include file
Solution to the above repetition is to place common elements and functions into an included file. After completing each test script we transfer appropriate elements to this file.
Create a new file mongo_db_inc.php with the following content:
<?php $path_array = explode("\\usr",getcwd()); // Split at folder usr $mongo_base = $path_array[0]; // find drive letter and any sub-folders $mongo_base_f = preg_replace('/\\\/','/', $mongo_base); // Replace \ with / //=== FOLDERS === define("MONGO_BIN", "$mongo_base_f/usr/local/mongo_tutorial/bin"); // Binaries for MongoDB //=== FILES === //=== Open a command window =================================================== // Opem a cmd window in bin folder function open_cmd_window(){ $return_wd = getcwd(); // Save current wd chdir(MONGO_BIN); // Change wd to Mongo Bin $base = preg_replace('/\//','\\', MONGO_BIN); // Replace / with \ $cmd1 = "start "; $cmd2 = "\"UNIFORM SERVER Mongo Command Line\" "; $cmd3 = "cmd.exe /k \"COLOR B0 && cls &&dir\""; $cmd = $cmd1.$cmd2.$cmd3; pclose(popen($cmd,'r')); // Start a new process ignore output chdir($return_wd); // Restore original wd } //=============================================== END Open a command window === ?>
Our test script requires modification delete lines moved into the include file. Add an include line to read the file content into our test script. Modified file shown below:
<?php chdir(dirname(__FILE__)); // Change wd to this files location include_once "mongo_db_inc.php"; open_cmd_window(); // Run our test function ?>
Add configuration files
From the previous page we know two configuration files are required create these in folder bin with the following content:
No-authentication: config_no_auth.ini |
Authentication config_auth.ini |
dbpath = ../data/mongodb # Path to db bind_ip = 127.0.0.1 # Localhost port = 27017 # Port to use noauth = true # use 'true' verbose = true |
dbpath = ../data/mongodb # Path to db bind_ip = 127.0.0.1 # Localhost port = 27017 # Port to use verbose = true # to disable, comment out. auth = true # |
We need to locate these files hence two constants are defined. Add the following two lines to the include file:
//=== FILES === define("CONFIG_NO_AUTH_F", "$mongo_base_f/usr/local/mongo_tutorial/bin/config_no_auth.ini"); define("CONFIG_AUTH_F", "$mongo_base_f/usr/local/mongo_tutorial/bin/config_auth.ini");
Add name password file
For scripting we require access to the Admin name and password these are stored in file mongo_name_password create this file in folder bin with the following content
mongo_name_password root:root |
We need to locate this file hence a constant is defined. Add the following line to the include file:
define("NAME_PWD_F", "$mongo_base_f/usr/local/mongo_tutorial/bin/mongo_name_password");
Get and Set Mongo Port
Mongo port is a changeable parameter. Before using we need to read its value from a configuration file. In our final application we will provide a user with the option of changing it.
Four functions are required a pair (set-port and get-port) for no authentications and a matching pair for authentication.
Create a new batch file Run_port.bat with following content:
TITLE UNIFORM SERVER - Run cmd COLOR B0 @echo off cls cd ..\..\php php.exe -c mongo_tutorial_cli.ini ..\mongo_tutorial\a_test\run_port.php pause EXIT |
|
New test script
Create a new test script run_port.php wth the following content:
<?php chdir(dirname(__FILE__)); // Change wd to this files location include_once "mongo_db_inc.php"; set_mongo_port_no_auth("12345"); $port = get_mongo_port_no_auth(); print "\n###$port####\n"; set_mongo_port_auth("56789"); $port = get_mongo_port_auth(); print "\n###$port####\n"; === Delete this and replace with four functions shown below ===== ?> |
|
set_mongo_port_no_auth($new_port)
// === Set Mongo port No Auth ================================================= function set_mongo_port_no_auth($new_port){ $new_line = "port = ".$new_port." # Port to use\r\n"; if ($filearray=file(CONFIG_NO_AUTH_F)) { // read file into array foreach ($filearray as $txt) { // scan array for port if(preg_match("/^\s*port\s*=\s*(\d+)/", $txt)){ // test for match $new_array[] = $new_line; // found add new line } else{ // No match $new_array[] = $txt; // Save original line } } } $str = implode($new_array); // Convert array to string file_put_contents(CONFIG_NO_AUTH_F,$str); // Save to file } // ============================================ END Set Mongo port No Auth ==== |
|
get_mongo_port_no_auth()
// === Get Mongo port No Auth ================================================= function get_mongo_port_no_auth(){ if ($filearray=file(CONFIG_NO_AUTH_F)) { // read file into array foreach ($filearray as $txt) { // scan array for port if(preg_match("/^\s*port\s*=\s*(\d+)/", $txt,$match)){ // test save $match $mongo_port = $match[1]; // match found save port number break; // give up nothing else to do } } } else { // failed to read file echo "Cannot read the file"; } return $mongo_port; } // ============================================ END Get Mongo port No Auth ==== |
|
set_mongo_port_auth($new_port)
// === Set Mongo port Auth ==================================================== function set_mongo_port_auth($new_port){ $new_line = "port = ".$new_port." # Port to use\r\n"; if ($filearray=file(CONFIG_AUTH_F)) { // read file into array foreach ($filearray as $txt) { // scan array for port if(preg_match("/^\s*port\s*=\s*(\d+)/", $txt)){ // test for match $new_array[] = $new_line; // found add new line } else{ // No match $new_array[] = $txt; // Save original line } } } $str = implode($new_array); // Convert array to string file_put_contents(CONFIG_AUTH_F,$str); // Save to file } // ================================================ END Set Mongo portAuth ==== |
|
get_mongo_port_auth()
// === Get Mongo port Auth ==================================================== function get_mongo_port_auth(){ if ($filearray=file(CONFIG_AUTH_F)) { // read file into array foreach ($filearray as $txt) { // scan array for port if(preg_match("/^\s*port\s*=\s*(\d+)/", $txt,$match)){ // test save $match $mongo_port = $match[1]; // match found save port number break; // give up nothing else to do } } } else { // failed to read file echo "Cannot read the file"; } return $mongo_port; } // =============================================== END Get Mongo port Auth ==== |
|
Test
Give the test script a workout, ensure it correctly updates the configuration files and does not blow them apart.
When you have finished copy the four functions to the include file. You can delete the batch file (Run_port.bat) and test script (run_port.php).
Remember to restore port to 27017 in both configuration files.
Get and set Admin name password file
Admin nameand password are changeable parameter. Before using we need to read their values from a file.
In our final application we will provide a user with the option of changing these.
Two functions are required (set-name-password and get-name-password) these are specific to authentications.
Create a new batch file Run_pwd.bat with following content:
TITLE UNIFORM SERVER - Run cmd COLOR B0 @echo off cls cd ..\..\php php.exe -c mongo_tutorial_cli.ini ..\mongo_tutorial\a_test\run_pwd.php pause EXIT |
|
New test script
Create a new test script run_pwd.php with the following content:
<?php chdir(dirname(__FILE__)); // Change wd to this files location include_once "mongo_db_inc.php"; set_name_pwd("fred","123456"); $npwd_array = get_name_pwd_array(); print_r($npwd_array); === Delete this and replace with two functions shown below ===== ?> |
|
get_name_pwd_array()
//=== Get name password array ================================================= function get_name_pwd_array(){ $str = file_get_contents(NAME_PWD_F); // Read file into string $str = trim( $str); // Clean $name_pwd__array = explode(":",$str); // Split at Separator ":" $new_array[] = $name_pwd__array[0]; // name $new_array[] = $name_pwd__array[1]; // password return $new_array; // return namd and password } //============================================ END Get name password array ==== |
|
set_name_pwd($name,$password)
//=== Set name password ======================================================= function set_name_pwd($name,$password){ file_put_contents(NAME_PWD_F,$name.":".$password); // Save string to file } //======================================================= Set name password === |
|
Test
Give the test script a workout, ensure it correctly updates name and password.
When you have finished copy the two functions to the include file. You can delete the batch file (Run_pwd.bat) and test script (run_pwd.php).
Remember to restore name and password to root:root in file mongo_name_password file
Summary
That was a long session I trust it has sparked a few ideas and inspired you to follow a bit more of this tutorial.
If I have lost that, its not an issue may be a little snippet of code has caught your eye. Hey! May be it has encouraged you to look a little deeper into PHP CLI scripting.
With the foundations (components/functions) in place we can start the fun stuff.
Next part of this tutorial looks at starting MongoDB