<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class MY_Model extends CI_Model{
	//Global Variables---
	var $record_sql_action = TRUE;	//Records every single SQL commands
	var $record_delete = TRUE;	//Records JSON value of Deleted Data
	var $filter_data = TRUE;	//Filter data before Insert/Update
	var $can_fetch_next_only = FALSE;	//For MSSQL 2012 or above
	var $identity_insert = FALSE;
	
	var $table;
	var $pk = "";
	var $is_identity = NULL;
	var $field_array = array();
	var $created_by = "CREATED_BY";
	var $date_created = "DATE_CREATED";
	var $modified_by = "MODIFIED_BY";
	var $date_modified = "DATE_MODIFIED";
	var $join = "";
	var $ticketno_table = "TICKETNO";
	//-------------------
	
	function __construct(){
	}
	
	function get_data($params=array()){
		if(! isset($params['select']) || $params['select'] == "") $params['select'] = "<T>.*";
		$sql = $this->sql_select($params);
		$query = $this->db->query($sql);
		return $query->result();
	}
	
	function data_count($params=array()){
		$params['select'] = "COUNT(1) as number_of_rows ";
		$params['sort'] = " ";
		$sql = $this->sql_select($params);
		$query = $this->db->query($sql);
		$data_array = $query->result();
		
		return count($data_array) > 0? $data_array[0]->number_of_rows:0;
	}
	
	function save($post){
		$this->load->model("ticketno_model");
		
		$return = array(
			'error' => "",
			'pk' => "",
		);
		
		$pk = $this->sql_get_pk();
		$field_array = $this->sql_get_field();
		
		$is_identity = $this->sql_is_identity();
		
		$pk_value = isset($post[$pk])? $post[$pk]:NULL;
		
		unset($save_mode);
		if($is_identity){
			if(isset($pk_value) && $pk_value != ""){
				$save_mode = "UPDATE";
			}
			else{
				$save_mode = "INSERT";
			}
		}
		else{
			//Auto-generate for int field---
			if(isset($field_array[$pk])){
				if($field_array[$pk]->TYPE == "int" && ! isset($pk_value)){
					$save_mode = "INSERT";
					
					$post[$pk] = $this->ticketno_model->get_next_no($this->table, $pk);
					
					if($post[$pk] == ""){
						$last_array = $this->get_data(array(
							'select' => "<T>.<PK>",
							'sort' => "<T>.<PK> DESC",
							'limit' => "1",
							'' => "",
						));
						
						$post[$pk] = count($last_array) > 0? (int)$last_array[0]->$pk + 1:1;
					}
					
					$pk_value = $post[$pk];
				}
			}
			//------------------------------
			
			if(! isset($save_mode)){
				if(isset($pk_value)){
					$existing_array = $this->get_data(array(
						'condition' => "<T>.<PK> = '".$pk_value."'",
						'' => "",
					));
					
					$save_mode = (count($existing_array) > 0)? "UPDATE":"INSERT";
				}
				else{
					$save_mode = "INSERT";
				}
			}
		}
		
		$post = $this->save_before($post, $save_mode);
		
		//Set to NULL if empty value---
		foreach($post as $field=>$value){
			if(strlen($value) == 0){
				$post[$field] = NULL;
			}
		}
		//-----------------------------
		
		switch($save_mode){
			case "INSERT":
				// if($is_identity) unset($post[$pk]);
				
				if($this->identity_insert){
					switch($this->db->dbdriver){
						case "sqlsrv":
							$sql = "SET IDENTITY_INSERT ".$this->table." ON ";
							$this->db->query($sql);
							break;
					}
				}
				
				$insert_return = $this->sql_insert($post);
				$return['pk'] = $insert_return['pk'];
				if(! $insert_return['success']){
					$return['error'] = "Create Failed!";
				}
				break;
			case "UPDATE":
				if($is_identity) unset($post[$pk]);
				
				$update_return = $this->sql_update($post, $pk_value);
				if($update_return['success']){
					$return['pk'] = $pk_value;
				}
				else{
					$return['error'] = "Update Failed!";
				}
				break;
		}
		
		$this->save_after($post, $return);
		
		return $return;
	}
	
	
	function save_before($post){
		return $post;
	}
	
	function save_after($return){
	}
	
	function remove($pk_value){
		return $this->sql_delete($pk_value);
	}
	
	//SQL---
	function sql_select($params=array()){
		$pk = $this->sql_get_pk();
		
		//Default---
		if((! isset($params['sort']) || $params['sort'] == "") && $pk != "") $params['sort'] = "<T>.<PK>";
		if(! isset($params['select']) || $params['select'] == "") $params['select'] = "<T>.*";
		//----------
		
		if(isset($params['additional_select']) && $params['additional_select'] != ""){
			if($params['select'] != "") $params['select'] .= ", ";
			$params['select'] .= $params['additional_select']." ";
		}
		
		if(! $this->can_fetch_next_only && $this->db->dbdriver == "sqlsrv" && isset($params['sort']) && trim($params['sort']) != ""){
			if($params['select'] != "") $params['select'] .= ", ";
			$params['select'] .= "ROW_NUMBER() OVER( ";
			$params['select'] .= 	"ORDER BY ".$params['sort']." ";
			$params['select'] .= ") AS R_NO ";
		}
		
		$sql = "";
		$sql .= "SELECT ".$params['select']." ";
		$sql .= "FROM <T> ";
		$sql .= (isset($params['join']) && $params['join'] != "")? $params['join']." ":$this->join." ";
		if(isset($params['additional_join']) && $params['additional_join'] != "") $sql .= $params['additional_join']." ";
		if(isset($params['condition']) && $params['condition'] != "") $sql .= "WHERE ".$params['condition']." ";
		if(! $this->can_fetch_next_only && $this->db->dbdriver == "sqlsrv" && isset($params['limit'])){
			$params['offset'] = isset($params['offset'])? (int)$params['offset'] + 1:1;
			
			$sql = "SELECT * FROM (".$sql." ";
			$sql .= ") AS A ";
			$sql .= "WHERE R_NO BETWEEN ".$params['offset']." AND ".((int)$params['offset'] + (int)$params['limit'] - 1)." ";
		}
		if(isset($params['group_by']) && $params['group_by'] != "") $sql .= "GROUP BY ".$params['group_by']." ";
		if(isset($params['having']) && $params['having'] != "") $sql .= "HAVING ".$params['having']." ";
		if($this->can_fetch_next_only || in_array($this->db->dbdriver, array("mysql", "mysqli"))){
			if(isset($params['sort']) && trim($params['sort']) != "") $sql .= "ORDER BY ".$params['sort']." ";
			if(isset($params['limit'])){
				if($this->db->dbdriver == "sqlsrv"){
					$sql .= "OFFSET ".(isset($params['offset'])? (int)$params['offset']:0)." ROWS ";
					$sql .= "FETCH NEXT ".(int)$params['limit']." ROWS ONLY ";
				}
				else if(in_array($this->db->dbdriver, array("mysql", "mysqli"))){
					$sql .= "LIMIT ".(int)$params['limit']." OFFSET ".(isset($params['offset'])? (int)$params['offset']:0)." ";
				}
			}
		}
		
		$sql = str_replace("<T>", $this->table, $sql);
		$sql = str_replace("<PK>", $pk, $sql);
		return $sql;
	}
	
	function sql_insert($data, $audit_trail=TRUE){
		$return = array(
			'success' => FALSE,
			'pk' => "",
		);
		
		$date_created = date("Y-m-d H:i:s");
		
		if($this->created_by != "" && ! isset($data[$this->created_by])) $data[$this->created_by] = $this->session->userdata('user_id');
		if($this->date_created != "" && ! isset($data[$this->date_created])) $data[$this->date_created] = $date_created;
		
		$field_array = $this->sql_get_field();
		if(isset($field_array[$this->created_by])){
			if($field_array[$this->created_by]->TYPE != "int"){
				$this->load->model("user_model");
				
				$user_array = $this->user_model->get_data(array(
					'condition' => "<T>.PKKEY = '".$this->session->userdata('user_id')."'",
				));
				if(count($user_array) > 0) $user = $user_array[0];
				$data[$this->created_by] = $user->CODE;
			}
		}
		
		$data = $this->filter_data(array($data));
		
		$data = $this->format_index($data);
		
		$pk = $this->sql_get_pk();
		
		$is_identity = $this->sql_is_identity();
		
		if($this->db->insert($this->table, $data)){
			$last_query = $this->db->last_query();
			
			if($is_identity){
				$pk_value = $this->db->insert_id();
			}
			else{
				$pk_index_array = array($pk, '`'.$pk.'`', '['.$pk.']');
				foreach($pk_index_array as $v){
					if(isset($data[$v])){
						$pk_index = $v;
						break;
					}
				}
				
				if(isset($pk_index)) $pk_value = $data[$pk_index];
			}
			
			$return['query'] = $last_query;
			
			if($this->record_sql_action){
				$sql_data['TBL'] = $this->table;
				$sql_data['SQL'] = $last_query;
				if(isset($pk_value)) $sql_data['PK'] = $pk_value;
				
				$this->sql_model->sql_insert($sql_data);
			}
			
			//Audit Trail---
			$audit_trail_table = "WFC_".$this->table;
			if($audit_trail && $this->db->table_exists($audit_trail_table)){
				$key = method_exists($this, "get_key")? $this->get_key($pk_value):$pk_value;
				
				unset($audit_trail_data);
				$audit_trail_data['DATE'] = $date_created;
				$audit_trail_data['USER_ID'] = $this->session->userdata('user_id');
				if(in_array($this->db->dbdriver, array("mysql", "mysqli"))){
					$audit_trail_data['KEY'] = $key;
				}
				elseif($this->db->dbdriver == "sqlsrv"){
					$audit_trail_data['[KEY]'] = $key;
				}
				$audit_trail_data['NEW_DATA'] = "Create Data";
				
				$this->db->insert($audit_trail_table, $audit_trail_data);
			}
			//--------------
			
			$return['pk'] = isset($pk_value)? $pk_value:"";

			//SYNC---
			if($this->db->table_exists($this->ticketno_table)){
				$sql = "
					SELECT * FROM ".$this->ticketno_table."
					WHERE RecordSet = '".$this->table."'
				";
				$query = $this->db->query($sql);
				$ticketno_array = $query->result();
				
				if(count($ticketno_array) > 0){
					$ticketno = $ticketno_array[0];
					
					//Sync To Branches---
					if(isset($ticketno->ToBranch) && $ticketno->ToBranch == "1"){
						$this->load->model("log_underscore_model");
						
						$this->log_underscore_model->sync(array(
							'QUERY' => $last_query,
							'TABLE' => $this->table,
							'FKEY' => $return['pk'],
							'' => "",
						));
					}
					//-------------------
				}
			}
			//-------
			
			$return['success'] = TRUE;
		}
		
		return $return;
	}
	
	function sql_insert_batch($data_array){
		//Rules: Only in MySQL
		$data_array = $this->filter_data($data_array, TRUE);
		
		if(count($data_array) > 0){
			foreach($data_array as $x=>$data){
				if($this->created_by != "" && ! isset($data[$this->created_by])) $data_array[$x][$this->created_by] = $this->session->userdata('user_id');
				if($this->date_created != "" && ! isset($data[$this->date_created])) $data_array[$x][$this->date_created] = date("Y-m-d H:i:s");
				
				$field_array = $this->sql_get_field();
				if(isset($field_array[$this->created_by])){
					if($field_array[$this->created_by]->TYPE != "int"){
						$this->load->model("user_model");
						
						$user_array = $this->user_model->get_data(array(
							'condition' => "<T>.PKKEY = '".$this->session->userdata('user_id')."'",
						));
						if(count($user_array) > 0) $user = $user_array[0];
						$data[$this->created_by] = $user->CODE;
					}
				}
		
				$data = $this->format_index($data);
			}
			
			if($this->db->insert_batch($this->table, $data_array)){
				if($this->record_sql_action){
					$sql_data['TBL'] = $this->table;
					$sql_data['SQL'] = $this->db->last_query();
//					$sql_data['PK'] = $pk;
					
					$this->sql_model->sql_insert($sql_data);
				}
			
				return TRUE;
			}
			else{
				return FALSE;
			}
		}
		else{
			return TRUE;
		}
	}
	
	function sql_update($data, $pk_value, $audit_trail=TRUE){
		$return = array(
			'success' => FALSE,
		);
		
		$ci = get_instance();
		
		$date_modified = date("Y-m-d H:i:s");
		
		if($this->modified_by != "" && ! isset($data[$this->modified_by])) $data[$this->modified_by] = $this->session->userdata('user_id');
		if($this->date_modified != "" && ! isset($data[$this->date_modified])) $data[$this->date_modified] = $date_modified;
		
		$field_array = $this->sql_get_field();
		if(isset($field_array[$this->modified_by])){
			if($field_array[$this->modified_by]->TYPE != "int"){
				$this->load->model("user_model");
				
				$user_array = $this->user_model->get_data(array(
					'condition' => "<T>.PKKEY = '".$this->session->userdata('user_id')."'",
				));
				if(count($user_array) > 0) $user = $user_array[0];
				$data[$this->modified_by] = $user->CODE;
			}
		}
				
		$data = $this->filter_data(array($data));
		
		$pk = $this->sql_get_pk();
		
		//Audit Trail---
		$audit_trail_table = "WFC_".$this->table;
		if(! $this->db->table_exists($audit_trail_table)) $audit_trail = FALSE;
		if($audit_trail){
			$old_data_array = $this->get_data(array(
				'condition' => "<T>.<PK> = '".$pk_value."'",
				'' => "",
			));
			if(count($old_data_array) > 0) $old_data = $old_data_array[0];
			
			$field_array = $this->fm->index_array($this->db->field_data($audit_trail_table), "name");
			$new_data_len = (int)$field_array['NEW_DATA']->max_length;
			$old_data_len = (int)$field_array['OLD_DATA']->max_length;
		}
		//--------------
		
		$data = $this->format_index($data);
		
		$key = method_exists($this, "get_key")? $this->get_key($pk_value):$pk_value;
		
		$this->db->where($pk, $pk_value);
		if($this->db->update($this->table, $data)){
			$last_query = $this->db->last_query();
			
			$return['query'] = $last_query;
			
			if($this->record_sql_action){
				$sql_data['TBL'] = $this->table;
				$sql_data['SQL'] = $last_query;
				$sql_data['PK'] = $pk_value;
				
				$this->sql_model->sql_insert($sql_data);
			}
			
			//Audit Trail---
			if($audit_trail && isset($old_data)){
				$bypass_field = $ci->audit_trail_field_bypass;
				
				$query = $this->db->get_where($this->table, $pk." = '".$pk_value."'");
				$new_data_array = $query->result();
				$new_data = count($new_data_array) > 0? $new_data_array[0]:$data;
				
				foreach($new_data as $field=>$value){
					if($old_data->$field != $value && ! in_array($field, $bypass_field)){
						unset($audit_trail_data);
						$audit_trail_data['DATE'] = $date_modified;
						$audit_trail_data['USER_ID'] = $this->session->userdata('user_id');
						if(in_array($this->db->dbdriver, array("mysql", "mysqli"))){
							$audit_trail_data['KEY'] = $key;
						}
						elseif($this->db->dbdriver == "sqlsrv"){
							$audit_trail_data['[KEY]'] = $key;
						}
						$audit_trail_data['FIELD'] = $field;
						$audit_trail_data['NEW_DATA'] = strlen($value) > $new_data_len? substr($value, 0, $new_data_len):$value;
						$audit_trail_data['OLD_DATA'] = strlen($old_data->$field) > $old_data_len? substr($old_data->$field, 0, $old_data_len):$old_data->$field;
						
						$this->db->insert($audit_trail_table, $audit_trail_data);
					}
				}
			}
			//--------------

			//SYNC---
			if($this->db->table_exists($this->ticketno_table)){
				$sql = "
					SELECT * FROM ".$this->ticketno_table."
					WHERE RecordSet = '".$this->table."'
				";
				$query = $this->db->query($sql);
				$ticketno_array = $query->result();
				
				if(count($ticketno_array) > 0){
					$ticketno = $ticketno_array[0];
					
					//Sync To Branches---
					if(isset($ticketno->ToBranch) && $ticketno->ToBranch == "1"){
						$this->load->model("log_underscore_model");
						
						$this->log_underscore_model->sync(array(
							'QUERY' => $last_query,
							'TABLE' => $this->table,
							'FKEY' => $pk,
							'' => "",
						));
					}
					//-------------------
				}
			}
			//-------
			
			$return['success'] = TRUE;
		}
		
		return $return;
	}
	
	function sql_update_condition($data, $condition=""){
		$date_modified = date("Y-m-d H:i:s");
		
		if($this->modified_by != "" && ! isset($data[$this->modified_by])) $data[$this->modified_by] = $this->session->userdata('user_id');
		if($this->date_modified != "" && ! isset($data[$this->date_modified])) $data[$this->date_modified] = $date_modified;
		
		$field_array = $this->sql_get_field();
		if(isset($field_array[$this->modified_by])){
			if($field_array[$this->modified_by]->TYPE != "int"){
				$this->load->model("user_model");
				
				$user_array = $this->user_model->get_data(array(
					'condition' => "<T>.PKKEY = '".$this->session->userdata('user_id')."'",
				));
				if(count($user_array) > 0) $user = $user_array[0];
				$data[$this->modified_by] = $user->CODE;
			}
		}
		
		$data = $this->filter_data(array($data));
		
		$data = $this->format_index($data);
		
		$pk = $this->sql_get_pk();
		
		if($condition == "") $condition = $pk." IS NOT NULL";
		$this->db->where($condition);
		if($this->db->update($this->table, $data)){
			if($this->record_sql_action){
				$sql_data['TBL'] = $this->table;
				$sql_data['SQL'] = $this->db->last_query();
				//$sql_data['PK'] = $id;
				
				$this->sql_model->sql_insert($sql_data);
			}
			
			return TRUE;
		}
		else{
			return FALSE;
		}
	}
	
	function sql_update_batch($data_array){
		//Rules: Only in MySQL
		$date_modified = date("Y-m-d H:i:s");
		
		foreach($data_array as $x=>$data){
			if($this->modified_by != "" && ! isset($data[$this->modified_by])) $data_array[$x][$this->modified_by] = $this->session->userdata('user_id');
			if($this->date_modified != "" && ! isset($data[$this->date_modified])) $data_array[$x][$this->date_modified] = $date_modified;
			
			$field_array = $this->sql_get_field();
			if(isset($field_array[$this->modified_by])){
				if($field_array[$this->modified_by]->TYPE != "int"){
					$this->load->model("user_model");
					
					$user_array = $this->user_model->get_data(array(
						'condition' => "<T>.PKKEY = '".$this->session->userdata('user_id')."'",
					));
					if(count($user_array) > 0) $user = $user_array[0];
					$data[$this->modified_by] = $user->CODE;
				}
			}
		
			$data = $this->format_index($data);
		}
		
		$data_array = $this->filter_data($data_array, TRUE);
		
		$pk = $this->sql_get_pk();
		
		$this->db->update_batch($this->table, $data_array, $pk);	//update_batch return NULL
		if($this->record_sql_action){
			$sql_data['TBL'] = $this->table;
			$sql_data['SQL'] = $this->db->last_query();
//			$sql_data['PK'] = $pk;
			
			$this->sql_model->sql_insert($sql_data);
		}
	
		return TRUE;
	}
	
	function sql_delete($pk_value, $audit_trail=TRUE){
		$key = method_exists($this, "get_key")? $this->get_key($pk_value):$pk_value;
		
		$pk = $this->sql_get_pk();
		
		$this->db->where($pk, $pk_value);
		if($this->db->delete($this->table)){
			$last_query = $this->db->last_query();

			if($this->record_sql_action){
				$sql_data['TBL'] = $this->table;
				$sql_data['SQL'] = $this->db->last_query();
				$sql_data['PK'] = $pk_value;
				
				$this->sql_model->sql_insert($sql_data);
			}
			
			$date_delete = date("Y-m-d H:i:s");
			
			//Audit Trail---
			$audit_trail_table = "WFC_".$this->table;
			if($audit_trail && $this->db->table_exists($audit_trail_table)){
				unset($audit_trail_data);
				$audit_trail_data['DATE'] = $date_delete;
				$audit_trail_data['USER_ID'] = $this->session->userdata('user_id');
				if(in_array($this->db->dbdriver, array("mysql", "mysqli"))){
					$audit_trail_data['KEY'] = $key;
				}
				elseif($this->db->dbdriver == "sqlsrv"){
					$audit_trail_data['[KEY]'] = $key;
				}
				$audit_trail_data['NEW_DATA'] = "Delete Data";
				
				$this->db->insert($audit_trail_table, $audit_trail_data);
			}
			//--------------

			//SYNC---
			if($this->db->table_exists($this->ticketno_table)){
				$sql = "
					SELECT * FROM ".$this->ticketno_table."
					WHERE RecordSet = '".$this->table."'
				";
				$query = $this->db->query($sql);
				$ticketno_array = $query->result();
				
				if(count($ticketno_array) > 0){
					$ticketno = $ticketno_array[0];
					
					//Sync To Branches---
					if(isset($ticketno->ToBranch) && $ticketno->ToBranch == "1"){
						$this->load->model("log_underscore_model");
						
						$this->log_underscore_model->sync(array(
							'QUERY' => $last_query,
							'TABLE' => $this->table,
							'FKEY' => $pk_value,
							'' => "",
						));
					}
					//-------------------
				}
			}
			//-------
			
			return TRUE;
		}
		else{
			return FALSE;
		}
	}
	
	function sql_delete_condition($condition){
		$this->db->where($condition);
		if($this->db->delete($this->table)){
			if($this->record_sql_action){
				$sql_data['TBL'] = $this->table;
				$sql_data['SQL'] = $this->db->last_query();
				//$sql_data['PK'] = $id;
				
				$this->sql_model->sql_insert($sql_data);
			}
			
			return TRUE;
		}
		else{
			return FALSE;
		}
	}
	
	function sql_truncate(){
		$sql = "TRUNCATE TABLE ".$this->table;
		if($this->db->query($sql)){
			if($this->record_sql_action){
				$sql_data['TBL'] = $this->table;
				$sql_data['SQL'] = $this->db->last_query();
				//$sql_data['PK'] = $id;
				
				$this->sql_model->sql_insert($sql_data);
			}
			
			return TRUE;
		}
		else{
			return FALSE;
		}
	}
	
	function filter_data($data_array, $return_array=FALSE){
		/*
		 * Function:
		 * 	- Substring to max length
		 * 	- Remove un-existing data
		 */
		if($this->filter_data){
			//Case Insensitive---
			$field_array = $this->db->field_data($this->table);
			foreach($field_array as $x=>$field){
				if(isset($field->name)) $field_array[$x]->name = strtoupper($field->name);
			}
			$field_array = $this->fm->index_array($field_array, "name");
			//-------------------
			
			foreach($data_array as $x=>$data){
				foreach($data as $name=>$v){
					$name = str_replace("[", "", $name);
					$name = str_replace("]", "", $name);
					if(isset($field_array[strtoupper($name)])){
						$field = $field_array[strtoupper($name)];
					
						if(isset($field->max_length) && (int)$field->max_length > 0 && strlen($v) > (int)$field->max_length){
							$data[$name] = substr($v, 0, (int)$field->max_length);	//Substring to max length
						}
					}
					else{
						unset($data[$name]);	//Remove un-existing data
					}
				}
				
				$data_array[$x] = $data;
			}
		}
		
		if($return_array){
			return $data_array;
		}
		else{
			return isset($data_array[0])? $data_array[0]:array();
		}
	}
	
	function format_index($data){
		if($this->db->dbdriver == "sqlsrv"){
			foreach($data as $index=>$v){
				if(substr($index, 0, 1) != "["){
					$data['['.$index.']'] = $v;
					unset($data[$index]);
				}
			}
		}
		elseif(in_array($this->db->dbdriver, array("mysql", "mysqli"))){
			foreach($data as $index=>$v){
				if(substr($index, 0, 1) != "`"){
					$data['`'.$index.'`'] = $v;
					unset($data[$index]);
				}
			}
		}
		
		return $data;
	}
	
	function sql_get_pk(){
		if($this->pk == ""){
			switch($this->db->dbdriver){
				case "mysql":
				case "mysqli":
					$field_array = $this->db->field_data($this->table);
					foreach($field_array as $v){
						if(isset($v->primary_key, $v->name) && $v->primary_key == "1"){
							$this->pk = $v->name;
							break;
						}
					}
					break;
				case "sqlsrv":
//					$field_array = $this->sql_get_field();
//					foreach($field_array as $field_name=>$v){
//						if($v->PRIMARY == "1"){
//							$this->pk = $field_name;
//							break;
//						}
//					}

					/*
					 * Rules:
					 * 	PK = Last Field if Last Field = ID/PKKEY/PRIMARY
					 * 	Otherwise, PK = first field
					 */
					
					$field_array = $this->db->field_data($this->table);
					
					$first_field = TRUE;
					$last_field = "";
					foreach($field_array as $v){
						if($first_field) $this->pk = $v->name;
						
						$last_field = $v->name;
						
						$first_field = FALSE;
					}
					
					if(in_array($last_field, array("ID", "PKKEY", "PRIMARY"))){
						$this->pk = $last_field;
					}
					break;
			}
		}
		
		return $this->pk;
	}
	
	function sql_get_field(){
		if(count($this->field_array) == 0){
			switch($this->db->dbdriver){
				case "mysql":
				case "mysqli":
					$table = str_replace("`", "", $this->table);
					
					$sql = "
						SELECT *
						FROM INFORMATION_SCHEMA.COLUMNS
						WHERE TABLE_SCHEMA = '".$this->db->database."' AND TABLE_NAME = '".$table."'
					";
					$query = $this->db->query($sql);
					$column_array = $this->fm->index_array($query->result(), "COLUMN_NAME");
					
					$field_array = $this->db->field_data($table);
					foreach($field_array as $v){
						$obj = new stdClass();
						$obj->TYPE = $v->type;
						$obj->MAX_LEN = $v->max_length;
						$obj->PRIMARY = $v->primary_key;
						$obj->DEFAULT = $v->default;
						$obj->IDENTITY = (isset($column_array[$v->name]) && strpos($column_array[$v->name]->EXTRA, "auto_increment") !== FALSE)? 1:0;
						
						$this->field_array[$v->name] = $obj;
					}
					break;
				case "sqlsrv":
					$table = str_replace(array("[", "]"), "", $this->table);
					
					$this->db->where("TABLE_NAME", $table);
					$query = $this->db->get("INFORMATION_SCHEMA.TABLES");
					$table_array = $query->result();
					
					//VIEW---
					if(count($table_array) > 0 && $table_array[0]->TABLE_TYPE == "VIEW"){
						$this->db->where("TABLE_NAME", $table);
						$query = $this->db->get("INFORMATION_SCHEMA.VIEWS");
						$view_array = $query->result();
						
						if(count($view_array) > 0){
							$view_def = str_replace(array("\r\n", "\r", "\n", "\t"), " ", $view_array[0]->VIEW_DEFINITION);
							$view_def = preg_replace("/\s+/", " ", $view_def);	//Replace multiple spacings into 1 spacing
							
							$string_array = explode(" ", $view_def);
							foreach($string_array as $x=>$v){
								if($v == "FROM" && isset($string_array[$x + 1])){
									$table = str_replace(array("dbo.", "[", "]"), "", $string_array[$x + 1]);
									break;
								}
							}
						}
					}
					//-------
					
					$sql = "
						SELECT Col.Column_Name FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE Col
						INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS Tab ON Col.Constraint_Name = Tab.Constraint_Name
						AND Col.Table_Name = Tab.Table_Name
						AND Constraint_Type = 'PRIMARY KEY'
						AND Col.Table_Name = '".$table."'
					";
					$query = $this->db->query($sql);
					$pk_data_array = $query->result();
					$pk_array = array();
					foreach($pk_data_array as $v){
						array_push($pk_array, $v->Column_Name);
					}
					
					$sql = "
						SELECT *, COLUMNPROPERTY(object_id(TABLE_SCHEMA+'.'+TABLE_NAME), COLUMN_NAME, 'IsIdentity') AS [IDENTITY]
						FROM INFORMATION_SCHEMA.COLUMNS
						WHERE TABLE_NAME = '".$table."'
					";
					$query = $this->db->query($sql);
					$field_data_array = $query->result();
					foreach($field_data_array as $v){
						$obj = new stdClass();
						$obj->TYPE = $v->DATA_TYPE;
						$obj->MAX_LEN = $v->CHARACTER_MAXIMUM_LENGTH;
						$obj->PRIMARY = in_array($v->COLUMN_NAME, $pk_array)? 1:0;
						$obj->DEFAULT = $v->COLUMN_DEFAULT;
						$obj->IDENTITY = $v->IDENTITY;
						
						if(substr($obj->DEFAULT, 0, 2) == "('" && substr($obj->DEFAULT, -2) == "')"){
							$obj->DEFAULT = substr($obj->DEFAULT, 2, strlen($obj->DEFAULT) - strlen("('')"));
						}
						
						$this->field_array[$v->COLUMN_NAME] = $obj;
					}
					break;
			}
		}
		
		return $this->field_array;
	}
	
	function sql_is_identity(){
		if(! isset($this->is_identity)){
//			$this->is_identity = FALSE;
			
			$pk = $this->sql_get_pk();
//			$field_array = $this->sql_get_field();
//			if(isset($field_array[$pk])){
//				if($field_array[$pk]->IDENTITY == "1"){
//					$this->is_identity = TRUE;
//				}
//			}

			$this->is_identity = in_array($pk, array("ID", "PKKEY", "PRIMARY"));
		}
		
		return $this->is_identity;
	}
	//------
}