<?

class SQLValue {

	var $muValue;
	var $msType;

	function SQLValue( $value, $type = 'N'){

		if ( is_a( $value, 'SQLValue' ) ) {
			$this->copyFrom( $value );

		} else {
			$this->setValue( $value );
			$this->setType( $type );
		}
	}

	function &Value( $value = NULL ){
		if ( !is_null( $value ) ) {
			$this->muValue = $value;
		}
		return $this->muValue;
	}

	function &Type( $type = NULL) {
		if( !is_null( $type ) ) {
			$this->setType( $type );
		}
		return $this->msType;
	}

	function setValue( $luValue ){
		$this->muValue = $luValue;
		return $this->muValue;
	}

	function setType( $lcType ){
		switch( $lcType ){
		case 'N':
		case 'n':
			$this->msType = 'N';
			break;
		case 'U':
		case 'u':
			$this->msType = 'U';
			break;
		case 'P':
		case 'p':
			$this->msType = 'P';
			break;
		default:
			$this->msType = 'C';
		}
		return $this->msType;
	}

	function getSQLValue() {

		switch($this->msType){
		case 'N':
			if ( is_numeric( $this->muValue ) ) {
				return $this->muValue;

			} else {
				return 0;
			}

		case 'C':
			return "'".addslashes( $this->muValue )."'";

		case 'P':
			return "PASSWORD('".addslashes( $this->muValue )."')";

		case 'U':
			return  $this->muValue;

		default:
			return addslashes( $this->muValue );
		}
	}

	function copyFrom( $src ){
		if ( is_a( $src, 'SQLValue' ) ) {
			$this->setValue( $src->Value() );
			$this->setType( $src->Type() );
		}
	}

	function &getClone(){
		return new SQLValue( $this );
	}

}

#
#
#===========================================================
#
#

class SQLField extends SQLValue {

	var $msName;

	function SQLField( $name, $value = 0, $type = 'N' ) {

		if( is_a($name,'SQLField') ) {
			$this->copyFrom( $name ); // copy constructor

		} else {
			SQLValue::SQLValue( $value, $type );
			$this->setName( $name );
		}
	}


	function &Name( $name = NULL ){
		if( $name ) {
			$this->setName( $name );
		}
		return $this->msName;
	}

	function setName( $lcName ){
		$this->msName = $lcName;
	}


	function getSQLUpdate(){
		return $this->msName.'='.$this->getSQLValue();
	}

	function copyFrom( &$poSrc ) {
		if( is_a( $poSrc, 'SQLField' ) ){
			$this->setName( $poSrc->Name() );
		}
		parent::copyFrom( $poSrc );
	}

	function &getClone(){
		return new SQLField( $this );
	}
}

#
#
#============================================================
#
#

class SQLFieldSet {

	var $maFields;

	function SQLFieldSet( $fields = NULL ) {

		global $DEBUG;

		$this->maFields = array();

		if( is_a( $fields, 'SQLFieldSet' ) ) { // copy constructor
			$this->copyFrom( $fields );
			
		} else {
			if ( !is_array( $fields ) ) {
				$fields = func_get_args();
			}
			foreach ( $fields as $name => $value ) {

				if ( is_array( $value ) ) {
					list( $val, $type) = $value;
					$this->maFields[] = new SQLField( $name, $val, $type );

				} elseif( is_a( $value, 'SQLField' ) ) {
					$this->maFields[] = new SQLField( $value );
					
				} else {
					$this->maFields[] = new SQLField( $name, $value );
				}
			}
		}
	}


	function &getFields(){
		return $this->maFields;
	}

	function &Field( $index, $newField = NULL, $newValue = NULL, $newType = 'N' ) {
		
		if ( is_numeric($index) ) {
			if ( ( $index >= 0 ) && ( $index < count( $this->maFields ) ) ) {

				if ( !is_null( $newField ) ) {
					$this->maFields[$index] = new SQLField( $newField, $newValue, $newType );
				}

				$fieldFound =& $this->maFields[$index];

			} elseif ( $index == -1 && !is_null( $newField ) ){
				$this->maFields[] = new SQLField( $newField, $newValue, $newType );
			}
			
		} else {
			$cnt = count($this->maFields);
			for( $i=0; $i<$cnt; $i++ ) {
				if ( $this->maFields[$i]->Name() == $index ) {
					if ( is_object( $newField ) ) {
						$this->maFields[$i] = $newField;
					}
					$fieldFound =& $this->maFields[$i];
					break;
				}
			}
			if ( !( is_null( $newField ) || is_object($fieldFound) ) ) {
				$this->maFields[] = new SQLField( $newField, $newValue, $newType );
			}
		}
		return $fieldFound;
	}

	function updateField ( $index, $value, $type = 'N'){

		if ( is_numeric($index) ) {
			if ( ( $index >= 0 ) && ( $index < count( $this->maFields ) ) ) {
				$fieldFound =& $this->maFields[ $index ];
			} elseif ( $index == -1 && is_object( $value ) ) {
				$fieldFound = new SQLField( $value );
				$this->maFields[] =& $fieldFound;
			}

		} else {
			$cnt = count($this->maFields);
			for( $i=0; $i<$cnt; $i++ ) {
				if ( $this->maFields[$i]->Name() == $index ) {
					$fieldFound =& $this->maFields[$i];
					break;
				}
			}
			if ( !is_object( $fieldFound ) ) {
				$fieldFound = new SQLField( $value );
				$this->maFields[] =& $fieldFound;
			}
		}
		if ( is_object( $fieldFound ) ) {
			if ( is_object( $value ) ) {
				$fieldFound->copyFrom( $value );
			} else {
				$fieldFound->setValue( $value );
				$fieldFound->setType( $type );
			}
		}
	}

	function &addField ( $firstArg, $value = NULL, $type = 'N' ) {

		if (is_array( $firstArg ) ) {
			foreach ( $firstArg as $name => $value ) {
				if ( is_array( $value ) ) {
					list( $val, $tp) = $value;
					$this->maFields[] = new SQLField( $name, $val, $tp );

				} elseif( is_a( $value, 'SQLField' ) ) {
					$this->maFields[] =& $value->getClone();

				} else {
					$this->maFields[] = new SQLField( $name, $value );
				}
			}

		} else {
			$this->maFields[] = new SQLField( $firstArg, $value, $type );
		}
		return $this->maFields[count($this->maFields)-1];
	}

	function &pushField( $firstArg, $value = NULL, $type = 'N'){
		return $this->addField( $firstArg, $value, $type );
	}

	function &popField(){
		return array_pop( $this->maFields );
	}

	function &shiftField(){
		return array_shift( $this->maFields );
	}

	function &unshiftField( $firstArg, $value = NULL, $type = 'N' ){
		
		if (is_array( $firstArg ) ) {
			foreach ( $firstArg as $name => $value ) {
				if ( is_array( $value ) ) {
					list( $val, $tp) = $value;
					$loItem = new SQLField( $name, $val, $tp );

				} elseif( is_a( $value, 'SQLField' ) ) {
					$loItem =& $value->getClone();

				} else {
					$loItem = new SQLField( $name, $value );
				}
				array_unshift( $this->maFields, $loItem );
			}

		} else {
			$loItem = new SQLField( $firstArg, $value, $type );
			array_unshift( $this->maFields, $loItem );
		}

		return $this->maFields[0];
	}
	
	

  function appendFromLimits( $poLimits, $psTable ){
		if( is_a( $poLimits, 'AllLimits' ) ) {
			$poLimits->FirstService();
			while( $loServ =& $poLimits->NextService() ) {
				$lcName = $loServ->GetNameForTable( $psTable );
				if ( $lcName ) {
					$this->addField( $lcName, $loServ->GetValue() );
				}
			}
		}
	}

	function getSQLNames() {
		$arr = array();
		foreach( $this->getFields() as $field ) {
			$arr[] = $field->Name();
		}
		return implode( ', ', $arr);
	}

	function getSQLValues() {
		$arr = array();
		foreach( $this->getFields() as $field ) {
			$arr[] = $field->getSQLValue();
		}
		return implode( ', ', $arr);
	}

	function getSQLInsert() {
		$fld = array();
		$val = array();
		foreach( $this->getFields() as $field ) {
			$fld[] = $field->Name();
			$val[] = $field->getSQLValue();
		}
		return array( implode( ', ', $fld), implode( ', ', $val) );
	}

	function getSQLUpdate() {
		$arr = array();
		foreach( $this->getFields() as $field ) {
			$arr[] = $field->getSQLUpdate();
		}
		return implode( ', ', $arr);
	}

	function getSQLWhere( $lcOp = ' AND ' ){
		$laChunks = array();
		foreach( $this->getFields() as $loField ) {
			$laChunks[] = $loField->getSQLUpdate();
		}
		if( count( $laChunks ) ) {
			return '('.implode( $lcOp, $laChunks).')';
		} else {
			return '';
		}
	}

	function clean(){
		$this->maFields = array();
	}

	function getCount() {
		return count($this->maFields);
	}

	function copyFrom( &$loSrc ){
		$this->clean();
		$this->addField( $loSrc->getFields() );
	}

}

?>