MongoDB Plugin Design: Support Functions

 

UniServer 6-Carbo
MongoDB plugin design.

Support Functions

Currently we have all our main functions in place allowing server to be started, stopped and administered using the client.

Starting and stopping MongoDB takes a finite time a method is required to determine when either action is complete. Similarly we need to know if a client is already running.

With server running Admin requires an easy way to create new users and update exciting user passwords.

This page covers support functions that address the above.

Is MongoDB running?

Uniform Server has a small utility pskill.exe returning true if a named process is running.

This utility is command-line driven making it ideal for scripting.

We require a function that returns true if MongoDB is running.

Initial setup

Copy UniServer\unicon\program\pskill.exe to folder UniServer\usr\local\mongo\bin

Our script needs to find this file add the following constant to file UniServer\usr\local\mongo\a_test\mongo_db_inc.php

define("MON_PSKILL_EXE",  "$mongo_base_f/usr/local/mongo_tutorial/bin/pskill.exe");

New batch file

Create a new batch file z_mongo_running.bat in folder a_test with the following content

TITLE UNIFORM SERVER - Mongo Running
COLOR B0
@echo off
cls
cd ..\..\php
php.exe -c mongo_tutorial_cli.ini ..\mongo_tutorial\a_test\mongo_running.php
pause
EXIT
|}

=== New test script ===
Create a new test script '''''mongo_running.php''''' with the following content
{|
|-valign="top"
|
<pre>
<?php
chdir(dirname(__FILE__)); // Change wd to this files location
include_once "mongo_db_inc.php";

if(mongodb_running()){
 print "\n Mongo Running \n";
}
else{
 print "\n Mongo Not Running \n";
}

//=== Is MongoDB running ======================================================
function mongodb_running(){
  $mongo_exe = "mongod.exe";   

  $cmd = MON_PSKILL_EXE." $mongo_exe";  // command line to be run  
  exec($cmd,$dummy,$return);            // 0=running 1=not-running 

  if($return == 0){                     // Check return value
   return true;                         // MongoDB is running
  }
  else{
   return false;                        // MongoDB not running
 }
}
//================================================= END Is MongoDB running ====
?>

Run Test

  • Start MongoDB double click Run_mongo_no_auth.bat
  • Start test script double click z_mongo_running.bat
  • If statement runs function mongodb_running()
  • If returned value is true prints “Mongo Running”
  • Otherwise prints “Mongo Not Running”

Function

  • The executable (mongod.exe) to be tested is assigned to a variable. This is not strictly required however function may be converted at a later date to be more generic by passing executable as a parameter to the function.
  • A command-line ($cmd) is contracted it defines path to utility pskill and passes a paramter ($mongo_exe) to it.
  • This command line is executed returned value from pskill is tested using an if statement.
  • 0 returned that executable is running hence function returns true.
  • 1 returned executable not running hence function returns false

Cut and copy above function save to file mongo_db_inc.php

Top

Is MongoDB Client running?

Similar to above differences are function and executable name changes.

New batch file

Create a new batch file z_client_running.bat in folder a_test with the following content

TITLE UNIFORM SERVER - Mongo Client running
COLOR B0
@echo off
cls
cd ..\..\php
php.exe -c mongo_tutorial_cli.ini ..\mongo_tutorial\a_test\client_running.php
pause
EXIT

New test script

Create a new test script client_running.php with the following content

<?php
chdir(dirname(__FILE__)); // Change wd to this files location
include_once "mongo_db_inc.php";

if(mongo_client_running()){
 print "\n Mogo Client Running \n";
}
else{
 print "\n Mogo Client Not Running \n";
}

//=== Is Mongo client running =================================================
function mongo_client_running(){
  $mongo_exe = "mongo.exe";   

  $cmd = MON_PSKILL_EXE." $mongo_exe";  // command line to be run  
  exec($cmd,$dummy,$return);            // 0=running 1=not-running 

  if($return == 0){                     // Check return value
   return true;                         // Mongo cient is running
  }
  else{
   return false;                        // Mongo client not running
 }
}
//============================================ END Is Mongo client running ====
?>

Run Test

  • Start MongoDB double click Run_mongo_no_auth.bat
  • Start MongoDB-Client double click Run_client_no_auth.bat
  • Start test script double click z_client_running.bat
  • If statement runs function client_running()
  • If returned value is true prints “Mongo Client Running”
  • Otherwise prints “Mongo Client Not Running”

After testing cut and copy function, save to file mongo_db_inc.php

Note:

Coding is one of personal choice this is a classic example. Do you create a generic function and pass the executable as a parameter or use two separate functions. My preference is two functions; duplicated code is small and not an issue. They are slightly easier to use, you do not have to remember to pass a parameter.

Top

Databases and users

Creating a database requires it to be first selected by name and some write action performed on it. A database will not be created until it is written to hence adding a useris a good way to create a database.

MongoDB is essentially a command-line driven device and certain commands specific to database control are not reflected in the PHP extension these can only be run from the command-line client. We wish to run client in the background although the client supports parameter --eval it cannot run a series of commands.

Solution is to run commands we require from an external file. This file is piped to Mongo it contains a list of commands and executed as if they were typed at the keyboard.

Command-line format

mongo.exe --port 27017 --username root --password root admin < cmd.txt

cmd.txt examples

The following selects a database and creates a new user:

use books                                - select db
db.addUser('fred', 'secret123')          - Create new user fred password secret123

The following selects a database and deletes user fred

use books                                - select db
db.system.users.remove ({user: “fred”})

Having above commands limited to client only is logical; no user other than Admin should have the power to create or delete users.

List of client and PHP driver commands

Client PHP driver Comments
use dbname $db = $connection->selectDB("dbname") Select database to use. If database does not exist prepare to create it
show dbs $dbs = $connection->listDBs() Lists all available databases
  $db->drop() Drop (delete) currently selected database
db.addUser("username", "password")   Create new user to access currently selected database
db.system.users.remove( { user: "fred123" } )   Remove user from currently selected database
db.system.users.find()   Show users for currently selected database

listDBs()

Create a new batch file z_list_dbs.bat with the following content:

TITLE UNIFORM SERVER - Mongo List DBS
COLOR B0
@echo off
cls
cd ..\..\php
php.exe -c mongo_tutorial_cli.ini ..\mongo_tutorial\a_test\z_list_dbs.php
pause
EXIT

Create a new test script z_list_dbs.php with the following content:

<?php
chdir(dirname(__FILE__)); // Change wd to this files location
include_once "mongo_db_inc.php";

$dbs_array = list_dbs_no_auth();
print_r($dbs_array);

//$dbs_array = list_dbs_auth();
//print_r($dbs_array);

//=== List DBS NO Auth ========================================================
// List all DBS on server.  
function list_dbs_no_auth(){
  $port = get_mongo_port_no_auth();    // Get port from config

  $connection = new Mongo('mongodb://'.'localhost:'.$port); // connect

  $dbs = $connection->listDBs();                      //get array of list of dbs
  $connection->close();                               // disconnect
  //print_r($dbs);                                    // Test code

  foreach ($dbs["databases"] as $property=>$value) {  // Scan array
    $names[] = $value["name"];                        // Create aray of names
    //print_r($names);                                // Test code
  }
  return  $names; // Return array of dbs
}
//==================================================== END List DBS NO Auth ===

//=== List DBS Auth ===========================================================
// List all DBS on server.  
function list_dbs_auth(){
  $port = get_mongo_port_no_auth();    // Get port from config
  $a_pwd_array = get_name_pwd_array(); // Get Admin name and password from file
  $name = $a_pwd_array[0];             // Set name 
  $password =  $a_pwd_array[1];        // Set password

  // connect
  $connection = new Mongo('mongodb://'.$name.':'.$password.'@localhost:'.$port);

  $dbs = $connection->listDBs();                      //get array of list of dbs
  $connection->close();                               // disconnect
  //print_r($dbs);                                    // Test code

  foreach ($dbs["databases"] as $property=>$value) {  // Scan array
    $names[] = $value["name"];                        // Create aray of names
    //print_r($names);                                // Test code
  }
  return  $names; // Return array of dbs
}
//======================================================= END List DBS Auth ===
?>

Overview

There are two functions each return an array of all databases on the server.

First function requires no authentication while the second does. Parameters that are changeable by a user are read directly from appropriate configuration file.

Script is currently enabled to run the no authentication function.

Hence the code that runs the authentication function is commented out.

Test 1:

  • Run - Run_mongo_no_auth.bat
  • Run - z_list_dbs.bat
  • Run - Run_stop_mongo_no_auth.bat

Test 2:

Comment no authentication and un-Comment authentication as shown:

//$dbs_array = list_dbs_no_auth();
//print_r($dbs_array);

$dbs_array = list_dbs_auth();
print_r($dbs_array);
  • Run - Run_mongo_auth.bat
  • Run - z_list_dbs.bat
  • Run - Run_stop_mongo_auth.bat

Results:

Minimum of two databases as shown:

Array
(
    [0] => admin
    [1] => local
)
Press any key to continue . . .

Note:

Cut the two functions and paste in file mongo_db_inc.php

drop()

Drop (Delete) a currently selected database.

Create a new batch file z_drop_db.bat with the following content:

TITLE UNIFORM SERVER - Mongo Drop DB
COLOR B0
@echo off
cls
cd ..\..\php
php.exe -c mongo_tutorial_cli.ini ..\mongo_tutorial\a_test\z_drop_db.php

pause
EXIT

Create a new test script z_drop_db.php with the following content:

<?php
chdir(dirname(__FILE__)); // Change wd to this files location
include_once "mongo_db_inc.php";

$dbs_array = drop_db_no_auth("fred1234");
print_r($dbs_array);

//$dbs_array = drop_db_auth("mpg456");
//print_r($dbs_array);

//=== DROP DB NO Auth =========================================================
// Drop (delete) a db  
function  drop_db_no_auth($db_name){
  $port = get_mongo_port_no_auth();    // Get port from config

  $connection = new Mongo('mongodb://'.'localhost:'.$port); // connect

  $db = $connection->selectDB($db_name);  // select (create) a database
  $response = $db->drop();                // Delete db
  //print_r($response);                   // test code
  $connection->close();                   // disconnect
}
//===================================================== END DROP DB NO Auth ===

//=== DROP DB Auth ============================================================
// Drop (delete) a db   
function  drop_db_auth($db_name){
  $port = get_mongo_port_no_auth();    // Get port from config
  $a_pwd_array = get_name_pwd_array(); // Get Admin name and password from file
  $name = $a_pwd_array[0];             // Set name 
  $password =  $a_pwd_array[1];        // Set password

  $connection = new Mongo('mongodb://'.$name.':'.$password.'@localhost:'.$port); // connect

  $db = $connection->selectDB($db_name);  // select (create) a database
  $response = $db->drop();                // Delete db
  //print_r($response);                   // test code
  $connection->close();                   // disconnect
}
//======================================================== END DROP DB Auth ===
?>





Overview

There are two functions each drops (deltes) a database db_name passed as parameter on the server.

First function requires no authentication while the second does. Parameters that are changeable by a user are read directly from appropriate configuration file.

Script is currently enabled to run the no authentication function.

Hence the code that runs the authentication function is commented out.

Test 1:

  • Run - Run_mongo_no_auth.bat
  • Run - z_drop_db.bat
  • Run - z_list_dbs.bat
  • Run - Run_stop_mongo_no_auth.bat

Result: Database name fred1234 deleted from list.

Test 2:

Comment no authentication and un-Comment authentication as shown:

//$dbs_array = drop_db_no_auth("fred1234");
//print_r($dbs_array);

$dbs_array = drop_db_auth("mpg456");
print_r($dbs_array);
  • Run - Run_mongo_auth.bat
  • Run - z_drop_db.bat
  • Run - z_list_dbs.bat
  • Run - Run_stop_mongo_auth.bat

Result: Database name mpg456 deleted from list.

Note:

Cut the two functions and paste in file mongo_db_inc.php

Top

Summary

That covers most of the functions required for our applications.

Next page covers some additional functions that may be required to offer more advanced features.

These are implemented using a command pipe.


Top