QuickBooks/SQL/Schema.php
static public function mapFieldToSQLDefinition($object_type, $field, $qb_type)
	{
		// array( type, length, default )
		
		static $overrides = array(
			'billpaymentcheck' => array(
				'istobeprinted' => array( null, null, 'null' ), 
				), 
			'check' => array(
				'istobeprinted' => array( null, null, 'null' ), 
				),
			'creditmemo' => array(
				'ispending' => array( null, null, 'null' ), 
				),
			'creditmemo_creditmemoline' => array(
				'creditcardtxninputinfo_expirationmonth' => array( null, null, 'null' ),
				'creditcardtxninputinfo_expirationyear' => array( null, null, 'null' ),
				'creditcardtxnresultinfo_resultcode' => array( null, null, 'null' ),
				'creditcardtxnresultinfo_paymentgroupingcode' => array( null, null, 'null' ),
				'creditcardtxnresultinfo_txnauthorizationstamp' => array( null, null, 'null' ),
				), 
			'creditmemo_creditmemolinegroup_creditmemoline' => array(
				'creditcardtxninfo_creditcardtxninputinfo_expirationmonth' => array( null, null, 'null' ),
				'creditcardtxninfo_creditcardtxninputinfo_expirationyear' => array( null, null, 'null' ),
				'creditcardtxninfo_creditcardtxnresultinfo_resultcode' => array( null, null, 'null' ),
				'creditcardtxninfo_creditcardtxnresultinfo_paymentgroupingcode' => array( null, null, 'null' ),
				'creditcardtxninfo_creditcardtxnresultinfo_txnauthorizationstamp' => array( null, null, 'null' ),			
				), 
			'customer' => array(
				'creditcardinfo_expirationmonth' => array( null, null, 'null' ),
				'creditcardinfo_expirationyear' => array( null, null, 'null' )
				),
			'employee' => array(
				'employeepayrollinfo_clearearnings' => array( null, null, 'null' ),
				'employeepayrollinfo_isusingtimedatatocreatepaychecks' => array( null, null, 'null' ), 
				'employeepayrollinfo_sickhours_isresettinghourseachnewyear' => array( null, null, 'null' ),
				'employeepayrollinfo_vacationhours_isresettinghourseachnewyear' => array( null, null, 'null' ),
				), 
			'estimate' => array(
				'istobeemailed' => array( null, null, 'null' ), 
				),
			'estimate_estimateline' => array(
				'quantity' => array( null, null, 'null' ),
				),
			'itemnoninventory' => array(
				'salesorpurchase_price' => array( null, null, 'null' ),
				'salesorpurchase_pricepercent' => array( null, null, 'null' ),
				'salesorpurchase_salesprice' => array( null, null, 'null' ),
				'salesorpurchase_purchasecost' => array( null, null, 'null' )
				),
			'itemdiscount' => array(
				'discountrate' => array( null, null, 'null' ),
				'discountratepercent' => array( null, null, 'null' )
				),
			'inventoryadjustment_inventoryadjustmentline' => array(
				'quantityadjustment_newquantity' => array( null, null, 'null' ),
				'quantityadjustment_quantitydifference' => array( null, null, 'null' ),
				'valueadjustment_newquantity' => array( null, null, 'null' ),
				'valueadjustment_quantitydifference' => array( null, null, 'null' ),
				'valueadjustment_newvalue' => array( null, null, 'null' ),
				'valueadjustment_valuedifference' => array( null, null, 'null' ),
				),
			'invoice' => array(
				'ispending' => array( null, null, 'null' ),
				'isfinancecharge' => array( null, null, 'null' ),
				'ispaid' => array( null, null, 'null' ),
				'istobeprinted' => array( null, null, 'null' ), 
				'istobeemailed' => array( null, null, 'null' ), 			
				), 
			'invoice_invoiceline' => array(
				'quantity' => array( null, null, 'null' )
				),
			'purchaseorder' => array(
				'ismanuallyclosed' => array( null, null, 'null' ),
				'isfullyreceived' => array( null, null, 'null' ),
				'istobeprinted' => array( null, null, 'null' ), 
				'istobeemailed' => array( null, null, 'null' ), 
				), 
			'purchaseorder_purchaseorderline' => array(
				'ismanuallyclosed' => array( null, null, 'null' ),
				'receivedquantity' => array( null, null, 'null' ),
				'quantity' => array( null, null, 'null' )
				),
			'receivepayment' => array(
				'creditcardtxninfo_creditcardtxninputinfo_expirationmonth' => array( null, null, 'null' ), 
				'creditcardtxninfo_creditcardtxninputinfo_expirationyear' => array( null, null, 'null' ), 
				'creditcardtxninfo_creditcardtxnresultinfo_resultcode' => array( null, null, 'null' ), 
				'creditcardtxninfo_creditcardtxnresultinfo_paymentgroupingcode' => array( null, null, 'null' ), 
				'creditcardtxninfo_creditcardtxnresultinfo_txnauthorizationstamp' => array( null, null, 'null' ), 
				), 
			'salesorder' => array(
				'ismanuallyclosed' => array( null, null, 'null' ),
				'isfullyinvoiced' => array( null, null, 'null' ),
				'istobeprinted' => array( null, null, 'null' ), 
				'istobeemailed' => array( null, null, 'null' ), 
				), 
			'salesorder_salesorderline' => array(
				'quantity' => array( null, null, 'null' ),
				'invoiced' => array( null, null, 'null' ),
				'ismanuallyclosed' => array( null, null, 'null' ),
				),
			'salesreceipt' => array(
				'ispending' => array( null, null, 'null' ), 
				'istobeprinted' => array( null, null, 'null' ), 
				'istobeemailed' => array( null, null, 'null' ), 
				'creditcardtxninfo_creditcardtxninputinfo_expirationmonth' => array( null, null, 'null' ), 
				'creditcardtxninfo_creditcardtxninputinfo_expirationyear' => array( null, null, 'null' ), 
				'creditcardtxninfo_creditcardtxnresultinfo_resultcode' => array( null, null, 'null' ), 
				'creditcardtxninfo_creditcardtxnresultinfo_paymentgroupingcode' => array( null, null, 'null' ), 
				'creditcardtxninfo_creditcardtxnresultinfo_txnauthorizationstamp' => array( null, null, 'null' ), 
				),
			'salesreceipt_salesreceiptline' => array(
				'quantity' => array( null, null, 'null' ),
				'creditcardtxninfo_creditcardtxninputinfo_expirationmonth' => array( null, null, 'null' ), 
				'creditcardtxninfo_creditcardtxninputinfo_expirationyear' => array( null, null, 'null' ), 
				'creditcardtxninfo_creditcardtxnresultinfo_resultcode' => array( null, null, 'null' ), 
				'creditcardtxninfo_creditcardtxnresultinfo_paymentgroupingcode' => array( null, null, 'null' ), 
				'creditcardtxninfo_creditcardtxnresultinfo_txnauthorizationstamp' => array( null, null, 'null' ), 				
				), 	 
			);
			
		$object_type = strtolower($object_type);
		$field = strtolower($field);
			
		$type = QUICKBOOKS_DRIVER_SQL_VARCHAR;
		$length = 32;
		$default = null;
			
		// Default mappings for types
		switch ($qb_type)
		{
			case 'AMTTYPE':
				
				$type = QUICKBOOKS_DRIVER_SQL_DECIMAL;
				$length = '10,2';
				$default = 'null';
				
				break;
			case 'PRICETYPE':
				
				$type = QUICKBOOKS_DRIVER_SQL_DECIMAL;
				$length = '13,5';
				$default = 'null';
				
				break;
			case 'PERCENTTYPE':
				
				$type = QUICKBOOKS_DRIVER_SQL_DECIMAL;
				$length = '12,5';
				$default = 'null';
				
				break;
			case 'DATETYPE':
				
				$type = QUICKBOOKS_DRIVER_SQL_DATE;
				$length = null;
				$default = 'null';
				
				break;
			case 'DATETIMETYPE':
				
				$type = QUICKBOOKS_DRIVER_SQL_DATETIME;
				$length = null;
				$default = 'null';
				
				break;
			case 'BOOLTYPE':
				
				$type = QUICKBOOKS_DRIVER_SQL_BOOLEAN;
				$length = null;
				$default = false;
				
				break;
			case 'INTTYPE':
				
				$type = QUICKBOOKS_DRIVER_SQL_INTEGER;
				$length = null;
				$default = 0;
				
				break;
			case 'QUANTYPE':
			
				$type = QUICKBOOKS_DRIVER_SQL_DECIMAL;
				$length = '12,5';
				$default = 0;
			
				break;
			case 'IDTYPE':
				
				$type = QUICKBOOKS_DRIVER_SQL_VARCHAR;
				$length = 40;
				$default = 'null';
				
				break;
			case 'ENUMTYPE':
				
				$type = QUICKBOOKS_DRIVER_SQL_VARCHAR;
				$length = 40;
				$default = 'null';
				
				break;
			case 'STRTYPE':
			default:
				
				//print('casting: ' . $object_type . "\n");
				//print('field: ' . $field . "\n");
				
				$x = str_repeat('x', 10000);
				$length = strlen(QuickBooks_Cast::cast($object_type, $field, $x));
				
				// All FullName and *_FullName fields should be VARCHAR(255) so we can add INDEXes to them
				if ($length > 255 and 
					strtolower(substr($field, -8)) == 'fullname')
				{
					$length = 255;
				}
				
				// If the length is really long, put it in a TEXT field instead of a VARCHAR
				if ($length > 255)
				{
					$type = QUICKBOOKS_DRIVER_SQL_TEXT;
				}
				else
				{
					$type = QUICKBOOKS_DRIVER_SQL_VARCHAR;
				}
				
				$default = 'null';
				
				if ($field == 'EditSequence')
				{
					$length = 16;
				}
				else if (isset($overrides[$object_type][$field]))
				{
					// 
					
					if (!is_null($overrides[$object_type][$field][2]))
					{
						$default = $overrides[$object_type][$field][2];
					}
				}
				
				break;
		}
			
		// Overrides for mappings that couldn't be done automatically 
		/*switch ($object_type)
		{
			case 'invoice':
				switch ($field)
				{
					default:
						break;
				}
			default:
				
				switch ($field)
				{
					case 'isactive':
						$default = true;
						break;
					default:
						
						break;
				}
				
				break;
		}*/
		
		// @TODO -- Keith, is this a good way to accomplish converting all txnid/listid fields to varchar? ~Garrett
		if (stripos($field, 'listid') !== false or stripos($field, 'txnid') !== false)
		{
			$type = QUICKBOOKS_DRIVER_SQL_VARCHAR;
			$length = 40;
			$default = 'null';
		}
		else if (strtolower($field) == 'sortorder')
		{
			$type = QUICKBOOKS_DRIVER_SQL_INTEGER;
			$length = null;
			$default = 0;
		}
		
		if (isset($overrides[$object_type][$field]))
		{
			if (!is_null($overrides[$object_type][$field][0]))
			{
				$type = $overrides[$object_type][$field][0];
			}
			
			if (!is_null($overrides[$object_type][$field][1]))
			{
				$length = $overrides[$object_type][$field][1];
			}
			
			if (!is_null($overrides[$object_type][$field][2]))
			{
				$default = $overrides[$object_type][$field][2];
			}
		}
			
		return array( $type, $length, $default );
	}
static public function mapFieldToSQLDefinition($object_type, $field, $qb_type)
	{
		// array( type, length, default )
		
		static $overrides = array(
			'billpaymentcheck' => array(
				'istobeprinted' => array( null, null, 'null' ), 
				), 
			'check' => array(
				'istobeprinted' => array( null, null, 'null' ), 
				),
			'creditmemo' => array(
				'ispending' => array( null, null, 'null' ), 
				),
			'creditmemo_creditmemoline' => array(
				'creditcardtxninputinfo_expirationmonth' => array( null, null, 'null' ),
				'creditcardtxninputinfo_expirationyear' => array( null, null, 'null' ),
				'creditcardtxnresultinfo_resultcode' => array( null, null, 'null' ),
				'creditcardtxnresultinfo_paymentgroupingcode' => array( null, null, 'null' ),
				'creditcardtxnresultinfo_txnauthorizationstamp' => array( null, null, 'null' ),
				), 
			'creditmemo_creditmemolinegroup_creditmemoline' => array(
				'creditcardtxninfo_creditcardtxninputinfo_expirationmonth' => array( null, null, 'null' ),
				'creditcardtxninfo_creditcardtxninputinfo_expirationyear' => array( null, null, 'null' ),
				'creditcardtxninfo_creditcardtxnresultinfo_resultcode' => array( null, null, 'null' ),
				'creditcardtxninfo_creditcardtxnresultinfo_paymentgroupingcode' => array( null, null, 'null' ),
				'creditcardtxninfo_creditcardtxnresultinfo_txnauthorizationstamp' => array( null, null, 'null' ),			
				), 
			'customer' => array(
				'creditcardinfo_expirationmonth' => array( null, null, 'null' ),
				'creditcardinfo_expirationyear' => array( null, null, 'null' )
				),
			'employee' => array(
				'employeepayrollinfo_clearearnings' => array( null, null, 'null' ),
				'employeepayrollinfo_isusingtimedatatocreatepaychecks' => array( null, null, 'null' ), 
				'employeepayrollinfo_sickhours_isresettinghourseachnewyear' => array( null, null, 'null' ),
				'employeepayrollinfo_vacationhours_isresettinghourseachnewyear' => array( null, null, 'null' ),
				), 
			'estimate' => array(
				'istobeemailed' => array( null, null, 'null' ), 
				),
			'estimate_estimateline' => array(
				'quantity' => array( null, null, 'null' ),
				),
			'itemnoninventory' => array(
				'salesorpurchase_price' => array( null, null, 'null' ),
				'salesorpurchase_pricepercent' => array( null, null, 'null' ),
				'salesorpurchase_salesprice' => array( null, null, 'null' ),
				'salesorpurchase_purchasecost' => array( null, null, 'null' )
				),
			'itemdiscount' => array(
				'discountrate' => array( null, null, 'null' ),
				'discountratepercent' => array( null, null, 'null' )
				),
			'inventoryadjustment_inventoryadjustmentline' => array(
				'quantityadjustment_newquantity' => array( null, null, 'null' ),
				'quantityadjustment_quantitydifference' => array( null, null, 'null' ),
				'valueadjustment_newquantity' => array( null, null, 'null' ),
				'valueadjustment_quantitydifference' => array( null, null, 'null' ),
				'valueadjustment_newvalue' => array( null, null, 'null' ),
				'valueadjustment_valuedifference' => array( null, null, 'null' ),
				),
			'invoice' => array(
				'ispending' => array( null, null, 'null' ),
				'isfinancecharge' => array( null, null, 'null' ),
				'ispaid' => array( null, null, 'null' ),
				'istobeprinted' => array( null, null, 'null' ), 
				'istobeemailed' => array( null, null, 'null' ), 			
				), 
			'invoice_invoiceline' => array(
				'quantity' => array( null, null, 'null' )
				),
			'purchaseorder' => array(
				'ismanuallyclosed' => array( null, null, 'null' ),
				'isfullyreceived' => array( null, null, 'null' ),
				'istobeprinted' => array( null, null, 'null' ), 
				'istobeemailed' => array( null, null, 'null' ), 
				), 
			'purchaseorder_purchaseorderline' => array(
				'ismanuallyclosed' => array( null, null, 'null' ),
				'receivedquantity' => array( null, null, 'null' ),
				'quantity' => array( null, null, 'null' )
				),
			'receivepayment' => array(
				'creditcardtxninfo_creditcardtxninputinfo_expirationmonth' => array( null, null, 'null' ), 
				'creditcardtxninfo_creditcardtxninputinfo_expirationyear' => array( null, null, 'null' ), 
				'creditcardtxninfo_creditcardtxnresultinfo_resultcode' => array( null, null, 'null' ), 
				'creditcardtxninfo_creditcardtxnresultinfo_paymentgroupingcode' => array( null, null, 'null' ), 
				'creditcardtxninfo_creditcardtxnresultinfo_txnauthorizationstamp' => array( null, null, 'null' ), 
				), 
			'salesorder' => array(
				'ismanuallyclosed' => array( null, null, 'null' ),
				'isfullyinvoiced' => array( null, null, 'null' ),
				'istobeprinted' => array( null, null, 'null' ), 
				'istobeemailed' => array( null, null, 'null' ), 
				), 
			'salesorder_salesorderline' => array(
				'quantity' => array( null, null, 'null' ),
				'invoiced' => array( null, null, 'null' ),
				'ismanuallyclosed' => array( null, null, 'null' ),
				),
			'salesreceipt' => array(
				'ispending' => array( null, null, 'null' ), 
				'istobeprinted' => array( null, null, 'null' ), 
				'istobeemailed' => array( null, null, 'null' ), 
				'creditcardtxninfo_creditcardtxninputinfo_expirationmonth' => array( null, null, 'null' ), 
				'creditcardtxninfo_creditcardtxninputinfo_expirationyear' => array( null, null, 'null' ), 
				'creditcardtxninfo_creditcardtxnresultinfo_resultcode' => array( null, null, 'null' ), 
				'creditcardtxninfo_creditcardtxnresultinfo_paymentgroupingcode' => array( null, null, 'null' ), 
				'creditcardtxninfo_creditcardtxnresultinfo_txnauthorizationstamp' => array( null, null, 'null' ), 
				),
			'salesreceipt_salesreceiptline' => array(
				'quantity' => array( null, null, 'null' ),
				'creditcardtxninfo_creditcardtxninputinfo_expirationmonth' => array( null, null, 'null' ), 
				'creditcardtxninfo_creditcardtxninputinfo_expirationyear' => array( null, null, 'null' ), 
				'creditcardtxninfo_creditcardtxnresultinfo_resultcode' => array( null, null, 'null' ), 
				'creditcardtxninfo_creditcardtxnresultinfo_paymentgroupingcode' => array( null, null, 'null' ), 
				'creditcardtxninfo_creditcardtxnresultinfo_txnauthorizationstamp' => array( null, null, 'null' ), 				
				), 	 
			);
			
		$object_type = strtolower($object_type);
		$field = strtolower($field);
			
		$type = QUICKBOOKS_DRIVER_SQL_VARCHAR;
		$length = 32;
		$default = null;
			
		// Default mappings for types
		switch ($qb_type)
		{
			case 'AMTTYPE':
				
				$type = QUICKBOOKS_DRIVER_SQL_DECIMAL;
				$length = '10,2';
				$default = 'null';
				
				break;
			case 'PRICETYPE':
				
				$type = QUICKBOOKS_DRIVER_SQL_DECIMAL;
				$length = '13,5';
				$default = 'null';
				
				break;
			case 'PERCENTTYPE':
				
				$type = QUICKBOOKS_DRIVER_SQL_DECIMAL;
				$length = '12,5';
				$default = 'null';
				
				break;
			case 'DATETYPE':
				
				$type = QUICKBOOKS_DRIVER_SQL_DATE;
				$length = null;
				$default = 'null';
				
				break;
			case 'DATETIMETYPE':
				
				$type = QUICKBOOKS_DRIVER_SQL_DATETIME;
				$length = null;
				$default = 'null';
				
				break;
			case 'BOOLTYPE':
				
				$type = QUICKBOOKS_DRIVER_SQL_BOOLEAN;
				$length = null;
				$default = false;
				
				break;
			case 'INTTYPE':
				
				$type = QUICKBOOKS_DRIVER_SQL_INTEGER;
				$length = null;
				$default = 0;
				
				break;
			case 'QUANTYPE':
			
				$type = QUICKBOOKS_DRIVER_SQL_DECIMAL;
				$length = '12,5';
				$default = 0;
			
				break;
			case 'IDTYPE':
				
				$type = QUICKBOOKS_DRIVER_SQL_VARCHAR;
				$length = 40;
				$default = 'null';
				
				break;
			case 'ENUMTYPE':
				
				$type = QUICKBOOKS_DRIVER_SQL_VARCHAR;
				$length = 40;
				$default = 'null';
				
				break;
			case 'STRTYPE':
			default:
				
				//print('casting: ' . $object_type . "\n");
				//print('field: ' . $field . "\n");
				
				$x = str_repeat('x', 10000);
				$length = strlen(QuickBooks_Cast::cast($object_type, $field, $x));
				
				// All FullName and *_FullName fields should be VARCHAR(255) so we can add INDEXes to them
				if ($length > 255 and 
					strtolower(substr($field, -8)) == 'fullname')
				{
					$length = 255;
				}
				
				// If the length is really long, put it in a TEXT field instead of a VARCHAR
				if ($length > 255)
				{
					$type = QUICKBOOKS_DRIVER_SQL_TEXT;
				}
				else
				{
					$type = QUICKBOOKS_DRIVER_SQL_VARCHAR;
				}
				
				$default = 'null';
				
				if ($field == 'EditSequence')
				{
					$length = 16;
				}
				else if (isset($overrides[$object_type][$field]))
				{
					// 
					
					if (!is_null($overrides[$object_type][$field][2]))
					{
						$default = $overrides[$object_type][$field][2];
					}
				}
				
				break;
		}
			
		// Overrides for mappings that couldn't be done automatically 
		/*switch ($object_type)
		{
			case 'invoice':
				switch ($field)
				{
					default:
						break;
				}
			default:
				
				switch ($field)
				{
					case 'isactive':
						$default = true;
						break;
					default:
						
						break;
				}
				
				break;
		}*/
		
		// @TODO -- Keith, is this a good way to accomplish converting all txnid/listid fields to varchar? ~Garrett
		if (stripos($field, 'listid') !== false or stripos($field, 'txnid') !== false)
		{
			$type = QUICKBOOKS_DRIVER_SQL_VARCHAR;
			$length = 40;
			$default = 'null';
		}
		else if (strtolower($field) == 'sortorder')
		{
			$type = QUICKBOOKS_DRIVER_SQL_INTEGER;
			$length = null;
			$default = 0;
		}
		
		if (isset($overrides[$object_type][$field]))
		{
			if (!is_null($overrides[$object_type][$field][0]))
			{
				$type = $overrides[$object_type][$field][0];
			}
			
			if (!is_null($overrides[$object_type][$field][1]))
			{
				$length = $overrides[$object_type][$field][1];
			}
			
			if (!is_null($overrides[$object_type][$field][2]))
			{
				$default = $overrides[$object_type][$field][2];
			}
		}
			
		return array( $type, $length, $default );
	}
Map a qbXML XML field type to it's SQL type definition

@param string $object_type
@param string $field
@param string $qb_type
@return array
@TODO We case the input to lowercase, and so the array has to be in lowercase. Is there a better way to do this?