#!/usr/bin/python

__version__ = "$Revision: 1.3 $"[11:-2]

# This version mangled by Andy Dustman <adustman@comstar.net>.
# Original credits follow. This is a nice introduction in general,
# but I felt there were a few bits and pieces that needs to be cleaned up.

# TITLE:        dbtrainer1
# WRITTEN BY:	Bradley Stec, July 1999
# 		RuleSpace, Inc.
# SUPPORTS:     WebOps Database Interface Trainer Script
# PURPOSE:      This script is a code and output example of how to use the
#		MySQLdb API to communicate to a database and perform basic
#		SQL command language requests.
# FUNCTION:     Both by executing the script and by reading the source code,
#		a programmer should be able to get a grasp on how the interface
#		works and may borrow code for their own script projects.
# REQUIREMENTS: This script requires the access to the webops module, and that a
#		database named "TEST" be installed in the webops specified 
#		database server.  
#
# CHANGES:	7/99	Initial Version

import sys
#import webops
import traceback
sys.stderr = sys.stdout

# Set Up Page Layout
print "content-type: text/html"
print
print "<HTML>\n"
print "<BODY BGCOLOR=\"#FFFFFF\">\n"
print "<FONT FACE=\"arial\" SIZE=\"3\"><B>RuleSpace, Inc. WebOps Database Interface Trainer -- Part 1</B><BR><HR>"
print "The purpose of this page is to present sample code for interfacing with the databases within the Web Operations server farm.  The display below illustrates real database queries as well as how the information is handled and presented.<P>"
print "By viewing the CGI script which presents the information below you'll be able to see how the database interface and API works within the WebOps scripting environment.<P>"
print "<HR>"

# Loading The API Support
# The API MySQLdb is a thin wrapper around a C program which is also in the site-packages directory called _mysqlmodule.so
# The API follows the Python Database API Spec version 2.0 which basically sets standards for what kind of methods will be
# used to access databases within the Python environment.  The _mysqlmodule.so and MySQLdb.py programs allow a programmer
# to pass SQL commands/queries through to a database.  The database server may be remote or local.  The MySQL database server
# software doesn't provide an interactive cursor, so the API programs create a "cursor" in local memory.  Read the Python
# Database API Spec version 2.0 for details.

# This command loads the support files
import MySQLdb

# PREPARE TO CONNECT TO DATABASE 
# This command forms a connection through the support files to the target database server and database name.
try:
	#WebOpsDB = MySQLdb.Connection(host=webops.dbserver,user=webops.dbuser,passwd=webops.dbpass,db='test',port=3306,unix_socket="")
	WebOpsDB = MySQLdb.Connect(db='test')
except:
        print "\n\n<PRE>"
        traceback.print_exc()
        sys.exit()

# A LITTLE BONUS INFORMATION FROM THE API
# The API can provide some information about the connection and server.  
# These methods are not portable to other databases.
print "<B>CONNECTED TO</B><BR>"
print "&nbsp;&nbsp;&nbsp;&nbsp;server <B> ", WebOpsDB.get_host_info(), "</B><BR>"
print "&nbsp;&nbsp;&nbsp;&nbsp;running <B>mySQL server v", WebOpsDB.get_server_info(), "</B><BR>"
print "&nbsp;&nbsp;&nbsp;&nbsp;current status: ",WebOpsDB.stat(), "<P>"
print "<HR>"

# CREATE YOUR PERSONAL CONNECTION TO THE "RESULTS" WITHIN THE CONNECTION OBJECT
# We haven't actually queried anything yet, so don't get confused, we're just preparing for it.
try:
	cursor = WebOpsDB.cursor()
except:
        print "\n\n<PRE>"
        traceback.print_exc()
        sys.exit()

# EXAMPLE: INSERTING A NEW RECORD
# This example uses a query command to INSERT a new record into the table.  The format of the data must exactly match 
# the table structure requirements or it will be rejected.  Note that we are using single quotes around strings within
# the SQL command.

# GOTCHA #1: The MySQLdb API doesn't respond well to zero value datatime fields.  Make sure that you populate your datetime
# fields with positive values.  You'll notice I used the built-in mySQL function NOW() to make sure that there was a valid
# date in the created field.  The modified field is auto-updated because it is the first timestamp data type in the data table.

# GOTCHA #2: INSERT or REPLACE?  Both function in a very similar method, with one minor difference.  The INSERT command 
# simply creates a new record/row and places the fields/columns into the table.  The REPLACE command will INSERT a new record
# into the table, then it compares the Primary Key values of the new record to any pre-existing matches in the table.  Any
# older records/rows in the table with a matching Primary Key (which is supposed to be unique) will be deleted in favor of
# the new record.  You might consider using REPLACE even when you want to INSERT just to make sure you don't end up with 
# duplicate data in your tables.

print "<B>EXAMPLES USING THE <U>INSERT</U> AND <U>REPLACE</U> SQL COMMANDS.</B><P>"

# REPLACE
try:
	cursor.execute("REPLACE INTO TEAM (MEMBER_ID,FIRST_NAME,LAST_NAME,REMARK,FAV_COLOR,OPEN_DATE) VALUES ('6','Frederick','Clueless','Clueless Fred','blue',NOW());")
except:
        print "\n\n<PRE>"
        traceback.print_exc()
        sys.exit()

# INSERT -- Note that since the Primary Key for the TEAM table is not specified in our insert command and member_id is an
# autoincrement data type, a new member_id is assigned to this inserted record.  Try reloading this web page in your browser
# a few times to observe the results.
try:
	cursor.execute("INSERT INTO TEAM (FIRST_NAME,LAST_NAME,REMARK,FAV_COLOR,OPEN_DATE) VALUES ('Ruprecht','Lionheart','Lost Rupe','cyan',NOW());")
except:
        print "\n\n<PRE>"
        traceback.print_exc()
        sys.exit()

# INSERT -- This example will cause an INTEGRITY ERROR, because the MEMBER_ID will conflict with an existing MEMBER_ID.
try:
	cursor.execute("INSERT INTO TEAM (MEMBER_ID,FIRST_NAME,LAST_NAME,REMARK,FAV_COLOR,OPEN_DATE) VALUES ('4','Fuzzy','Illogic','Evil Twin of Fuzzy Logic','red',NOW());")
except:
	print "<FONT SIZE=\"1\">SAMPLE INTEGRITY ERROR</FONT><BR>"
        print "<PRE>"
        traceback.print_exc()
	print "</PRE><P>"

# REQUERY TO SEE RESULTS
try:
	cursor.execute("SELECT * FROM TEAM")
except:
        print "\n\n<PRE>"
        traceback.print_exc()
        sys.exit()
resultSet = cursor.fetchall()
print "<B>ADDING NEW TEAM MEMBERS</B><BR>"
print "<FONT SIZE=\"1\">results of query:<BR>"
print "<TABLE BORDER=\"1\"><TR>"
for cursorFieldname in cursor.description:
        print "<TD><CENTER><FONT FACE=\"arial\" SIZE=\"2\">" +cursorFieldname[0]+ "</FONT></CENTER></TD>"
print "</TR>"
for cursorRecord in resultSet:
        print "<TR>"
        for cursorField in cursorRecord:
                print "<TD><FONT FACE=\"arial\" SIZE=\"1\">"
                print cursorField
                print "</FONT></TD>"
        print "</TR>"
print "</TABLE>"
print "</CENTER>"
print "&nbsp;<P></FONT><P><HR><P>"

# CLOSING THE DATABASE OBJECT
try:
	WebOpsDB.close()
except:
        print "\n\n<PRE>"
        traceback.print_exc()
        sys.exit()

# CONTINUED IN DBTRAINER2
# To learn more about replacing and updating records, and performing other SQL functions review
# dbtrainer2.

# END YOUR HTML PAGE
print "</FONT></BODY>\n"
print "</HTML>\n"
