QuickBooks/SQL/Schema.php
static public function mapSchemaToSQLDefinition($xml, &$tables)
	{
		$Parser = new QuickBooks_XML_Parser($xml);
		
		$errnum = 0;
		$errmsg = '';
		$tmp = $Parser->parse($errnum, $errmsg);
		
		$tmp = $tmp->children();
		$base = current($tmp);
		
		$tmp = $base->children();
		$rs = next($tmp);
		
		foreach ($rs->children() as $qbxml)
		{
			QuickBooks_SQL_Schema::_transform('', $qbxml, $tables);
		}
		
		/*
		while (count($subtables) > 0)
		{
			$node = array_shift($subtables);
			
			$subsubtables = array();
			$tables[] = QuickBooks_SQL_Schema::_transform('', $node, $subsubtables);
			
			$subtables = array_merge($subtables, $subsubtables);
		}
		*/
		
		// The code below tries to guess as a good set of indexes to use for 
		//	any database tables we've generated from the schema. The code looks 
		//	at all of the fields in the table and if any of them are *ListID or 
		//	*TxnID it makes them indexes. 
		
		// This is a list of field names that will *always* be assigned 
		//	indexes, regardless of what table they are in
		$always_index_fields = array(
			'qbsql_external_id', 
			'Name', 
			'FullName', 
			'EntityType', 
			'TxnType', 
			'Email', 
			//'Phone', 
			'IsActive', 
			'RefNumber', 
			//'Address_City', 
			//'Address_State', 
			'Address_Country', 
			//'Address_PostalCode', 
			//'BillAddress_City', 
			//'BillAddress_State', 
			'BillAddress_Country', 
			//'BillAddress_PostalCode', 
			//'ShipAddress_City', 
			//'ShipAddress_State', 
			'ShipAddress_Country', 
			//'ShipAddress_PostalCode', 
			'CompanyName', 
			//'FirstName', 
			'LastName', 
			//'Contact', 
			'TxnDate', 
			'IsPaid', 
			'IsPending', 
			'IsManuallyClosed', 
			'IsFullyReceived', 
			'IsToBePrinted', 
			'IsToBeEmailed', 
			'IsFullyInvoiced', 
			//'IsFinanceCharge', 
			);
		
		// This is a list of table.field names that will be assigned indexes 
		$always_index_tablefields = array(
			//'Account.AccountType', 
			);
		
		/*
		'*FullName', 
		'*ListID', 
		'*TxnID', 
		'*EntityType', 
		'*TxnType', 
		'*LineID', 
		*/
		
		foreach ($tables as $table => $tabledef)
		{
			$uniques = array();
			$indexes = array();
			
			foreach ($tabledef[1] as $field => $fielddef)
			{
				if ($field == 'ListID' or 		// Unique keys
					$field == 'TxnID' or 
					$field == 'Name')
				{
					// We can't apply indexes to TEXT columns, so we need to 
					//	check and make sure the column isn't of type TEXT 
					//	before we decide to use this as an index
					
					if ($fielddef[0] != QUICKBOOKS_DRIVER_SQL_TEXT)
					{
						$uniques[] = $field;
					}
				}
				else if (substr($field, -6, 6) == 'ListID' or 		// Other things we should index for performance
					substr($field, -5, 5) == 'TxnID' or 
					substr($field, -6, 6) == 'LineID' or 
					in_array($field, $always_index_fields) or 
					in_array($table . '.' . $field, $always_index_tablefields))
				{
					// We can't apply indexes to TEXT columns, so we need to 
					//	check and make sure the column isn't of type TEXT 
					//	before we decide to use this as an index
					
					if ($fielddef[0] != QUICKBOOKS_DRIVER_SQL_TEXT)
					{
						$indexes[] = $field;
					}
				}
			}
			
			//print_r($indexes);
			//print_r($uniques);
			
			$tables[$table][3] = $indexes;
			$tables[$table][4] = $uniques;
		}
		
		return true;
	}
static public function mapSchemaToSQLDefinition($xml, &$tables)
	{
		$Parser = new QuickBooks_XML_Parser($xml);
		
		$errnum = 0;
		$errmsg = '';
		$tmp = $Parser->parse($errnum, $errmsg);
		
		$tmp = $tmp->children();
		$base = current($tmp);
		
		$tmp = $base->children();
		$rs = next($tmp);
		
		foreach ($rs->children() as $qbxml)
		{
			QuickBooks_SQL_Schema::_transform('', $qbxml, $tables);
		}
		
		/*
		while (count($subtables) > 0)
		{
			$node = array_shift($subtables);
			
			$subsubtables = array();
			$tables[] = QuickBooks_SQL_Schema::_transform('', $node, $subsubtables);
			
			$subtables = array_merge($subtables, $subsubtables);
		}
		*/
		
		// The code below tries to guess as a good set of indexes to use for 
		//	any database tables we've generated from the schema. The code looks 
		//	at all of the fields in the table and if any of them are *ListID or 
		//	*TxnID it makes them indexes. 
		
		// This is a list of field names that will *always* be assigned 
		//	indexes, regardless of what table they are in
		$always_index_fields = array(
			'qbsql_external_id', 
			'Name', 
			'FullName', 
			'EntityType', 
			'TxnType', 
			'Email', 
			//'Phone', 
			'IsActive', 
			'RefNumber', 
			//'Address_City', 
			//'Address_State', 
			'Address_Country', 
			//'Address_PostalCode', 
			//'BillAddress_City', 
			//'BillAddress_State', 
			'BillAddress_Country', 
			//'BillAddress_PostalCode', 
			//'ShipAddress_City', 
			//'ShipAddress_State', 
			'ShipAddress_Country', 
			//'ShipAddress_PostalCode', 
			'CompanyName', 
			//'FirstName', 
			'LastName', 
			//'Contact', 
			'TxnDate', 
			'IsPaid', 
			'IsPending', 
			'IsManuallyClosed', 
			'IsFullyReceived', 
			'IsToBePrinted', 
			'IsToBeEmailed', 
			'IsFullyInvoiced', 
			//'IsFinanceCharge', 
			);
		
		// This is a list of table.field names that will be assigned indexes 
		$always_index_tablefields = array(
			//'Account.AccountType', 
			);
		
		/*
		'*FullName', 
		'*ListID', 
		'*TxnID', 
		'*EntityType', 
		'*TxnType', 
		'*LineID', 
		*/
		
		foreach ($tables as $table => $tabledef)
		{
			$uniques = array();
			$indexes = array();
			
			foreach ($tabledef[1] as $field => $fielddef)
			{
				if ($field == 'ListID' or 		// Unique keys
					$field == 'TxnID' or 
					$field == 'Name')
				{
					// We can't apply indexes to TEXT columns, so we need to 
					//	check and make sure the column isn't of type TEXT 
					//	before we decide to use this as an index
					
					if ($fielddef[0] != QUICKBOOKS_DRIVER_SQL_TEXT)
					{
						$uniques[] = $field;
					}
				}
				else if (substr($field, -6, 6) == 'ListID' or 		// Other things we should index for performance
					substr($field, -5, 5) == 'TxnID' or 
					substr($field, -6, 6) == 'LineID' or 
					in_array($field, $always_index_fields) or 
					in_array($table . '.' . $field, $always_index_tablefields))
				{
					// We can't apply indexes to TEXT columns, so we need to 
					//	check and make sure the column isn't of type TEXT 
					//	before we decide to use this as an index
					
					if ($fielddef[0] != QUICKBOOKS_DRIVER_SQL_TEXT)
					{
						$indexes[] = $field;
					}
				}
			}
			
			//print_r($indexes);
			//print_r($uniques);
			
			$tables[$table][3] = $indexes;
			$tables[$table][4] = $uniques;
		}
		
		return true;
	}
Take a qbXML schema and transform that schema to an SQL schema definition

@param string $xml			The XML string to transform
@param array $tables			An array of... erm... something?
@return boolean