Return to Snippet

Revision: 6108
at April 28, 2008 19:07 by donkawechico


Updated Code
#!/usr/bin/python

import re, sys, getopt, os

args = sys.argv
ROOT_DIR = '/home/whatever'
VO_DIR = ROOT_DIR + '/vo'
VIEW_DIR = ROOT_DIR + '/views'
dbAttr = []
dbMap = {}

files = []
finishedVOs = []

def usage():
	print "./voGenerator [-s single vo filename] [-a all views in vo dir] [-h show usage]"

def getAllViews():
	files = os.listdir(VO_DIR)
	filenames = []
	for f in files:
		filenames.append(os.path.splitext(f)[0])
	return filenames

try:

	opts, args = getopt.getopt(sys.argv[1:], "has:", ["help", "update all", "vo="])

	for o,a in opts:
		if o == "-a":
			files = getAllViews()
		elif o == "-s":
			files.append(a)
			print "Don't use single right now, it'll screw up the AllViews file"
		elif o in ("-h", "--help"):
			usage()
			sys.exit()
		else:
			assert(False, "Unhandled Option")

	for fname in files:
		print "Updating %s" % (fname)
		#Parse .vo mapping
		for line in open( '%s/%s.vo' % (VO_DIR, fname)):
			entry = line.split(':')
			dbAttr.append(entry[0])
			dbMap[entry[0]] = entry[1].rstrip()					

		f = open('%s/%sVO.php' % (VIEW_DIR, fname.title()), 'w')
	
		#php start tag	
		f.write('<?php\n\n')
	
		#class declaration
		f.write('\nclass %sVO {\n\n' % (fname.title()))
	
		#private variables
		for attr in dbAttr:
			f.write('\tprivate $%s;\n' % (attr))
	
		f.write('\n')
	
		#getter functions
		for attr in dbAttr:
			f.write('\tpublic function get%s() { return $this->%s; }\n' % (dbMap[attr], attr))
		f.write('\n')	
	
		#setter functions
		for attr in dbAttr:
			f.write('\tpublic function set%s($val) { $this->%s = $val; }\n' % (dbMap[attr], attr))
		f.write('\n')	
	
		#dump out contents of the VO to stdout
		f.write('\tpublic function dump() {\n')
		for attr in dbAttr:
			f.write('\t\techo "%s: ".$this->get%s()."\\n";\n' % (dbMap[attr], dbMap[attr]))
		f.write('\t}\n')
		f.write('\n')
	
		#populate function which takes a tuple from the db, and populates class
		f.write('\tpublic function populate($result_hash) {\n')
		for attr in dbAttr:
			f.write('\t\t$_%s = $result_hash["%s"];\n' % (attr, attr))
		for attr in dbAttr:
			f.write('\t\tif (isset($_%s)) $this->set%s($_%s);\n' % (attr, dbMap[attr], attr))
		f.write('\t}\n')
	
		#end of class, closing php tag
		f.write('}\n\n?>\n')
		
		f.close()
		
		dbAttr = []
		dbMap = {}
		finishedVOs.append(fname.title()+'VO.php')

	#Create the all-inclusive php include file
	f = open('%s/AllViews.php' % (VIEW_DIR), 'w')	
	f.write('<?php\n')
	for voname in finishedVOs:
		f.write('require_once("%s");\n' % (voname))
	f.write('?>')
	f.close()


except IOError:
	print 'file does not exist'
except getopt.GetoptError, err:
	print str(err)
	usage()
	sys.exit(2)

Revision: 6107
at April 28, 2008 18:54 by donkawechico


Initial Code
#!/usr/bin/python

import re, sys, getopt, os

args = sys.argv
ROOT_DIR = '/'
VO_DIR = ROOT_DIR + '/vo'
VIEW_DIR = ROOT_DIR + '/views'
dbAttr = []
dbMap = {}

files = []
finishedVOs = []

def usage():
	print "./voGenerator [-s single vo filename] [-a all views in vo dir] [-h show usage]"

def getAllViews():
	files = os.listdir(VO_DIR)
	filenames = []
	for f in files:
		filenames.append(os.path.splitext(f)[0])
	return filenames

try:

	opts, args = getopt.getopt(sys.argv[1:], "has:", ["help", "update all", "vo="])

	for o,a in opts:
		if o == "-a":
			files = getAllViews()
		elif o == "-s":
			files.append(a)
			print "Don't use single right now, it'll screw up the AllViews file"
		elif o in ("-h", "--help"):
			usage()
			sys.exit()
		else:
			assert(False, "Unhandled Option")

	for fname in files:
		print "Updating %s" % (fname)
		#Parse .vo mapping
		for line in open( '%s/%s.vo' % (VO_DIR, fname)):
			entry = line.split(':')
			dbAttr.append(entry[0])
			dbMap[entry[0]] = entry[1].rstrip()					

		f = open('%s/%sVO.php' % (VIEW_DIR, fname.title()), 'w')
	
		#php start tag	
		f.write('<?php\n\n')
	
		#class declaration
		f.write('\nclass %sVO {\n\n' % (fname.title()))
	
		#private variables
		for attr in dbAttr:
			f.write('\tprivate $%s;\n' % (attr))
	
		f.write('\n')
	
		#getter functions
		for attr in dbAttr:
			f.write('\tpublic function get%s() { return $this->%s; }\n' % (dbMap[attr], attr))
		f.write('\n')	
	
		#setter functions
		for attr in dbAttr:
			f.write('\tpublic function set%s($val) { $this->%s = $val; }\n' % (dbMap[attr], attr))
		f.write('\n')	
	
		#dump out contents of the VO to stdout
		f.write('\tpublic function dump() {\n')
		for attr in dbAttr:
			f.write('\t\techo "%s: ".$this->get%s()."\\n";\n' % (dbMap[attr], dbMap[attr]))
		f.write('\t}\n')
		f.write('\n')
	
		#populate function which takes a tuple from the db, and populates class
		f.write('\tpublic function populate($result_hash) {\n')
		for attr in dbAttr:
			f.write('\t\t$_%s = $result_hash["%s"];\n' % (attr, attr))
		for attr in dbAttr:
			f.write('\t\tif (isset($_%s)) $this->set%s($_%s);\n' % (attr, dbMap[attr], attr))
		f.write('\t}\n')
	
		#end of class, closing php tag
		f.write('}\n\n?>\n')
		
		f.close()
		
		dbAttr = []
		dbMap = {}
		finishedVOs.append(fname.title()+'VO.php')

	#Create the all-inclusive php include file
	f = open('%s/AllViews.php' % (VIEW_DIR), 'w')	
	f.write('<?php\n')
	for voname in finishedVOs:
		f.write('require_once("%s");\n' % (voname))
	f.write('?>')
	f.close()


except IOError:
	print 'file does not exist'
except getopt.GetoptError, err:
	print str(err)
	usage()
	sys.exit(2)

Initial URL


Initial Description
Any time I make PHP applications that interact with a database, I use this script. It generates one or more self-populating "View Objects" (a class that represents a single record from a DB). For example, rather than access a MySQL record-set by array indices (e.g. $row[1]), you can populate an object with the record's values, and reference them like properties in an object (e.g. $productVO->price).

To use:
1. Create a ".vo" file. For example, if you have a Products table, make "products.vo". 
2. In this file, you will map column names to some string of your choice. This string will be used to name the getter/setter functions in the generated class. "get" and "set" will be pre-pended to these mapped names automatically, so don't include them. Like so:
[column 1 name]:[desired function name]
[column 2 name]:[desired function name] ...
e.g. 

file "product.vo":

id:Id
price:Price
desc:Description

This will generate a class with functions "getId()", "getPrice()", and "getDescription()", returning the appropriate attribute.
3. Edit the folder names in the python source below to match your setup
4. Run ./voGenerator.py -a

This will generate views for all ".vo" files in the directory specified in the python script as well as an "AllViews.php" file which, when included in your PHP code, imports all view files. View files take the form [filename]VO.php as in ProductVO.php

To populate these objects, use the following snippit:

function getAllProducts() {
		$products = array();
		$row = array();
		$result = query("SELECT * FROM products");

		while ($row = mysql_fetch_assoc($result)) {
			$pVO = new ProductsVO;
			$pVO->populate($row);
			array_push($products, $pVO);
		}

		return $products;
}

Initial Title
Simple PHP ViewObject generator

Initial Tags
database, php, python

Initial Language
PHP