<commit_before><?php

	/**
	 * PostgresDb Class
	 * by @DJDavid98 | https://github.com/DJDavid98/PHP-PostgreSQL-Database-Class
	 *
	 * Heavily based on MysqliDB version 2.4 as made by
	 *   <NAME> <<EMAIL>>
	 *   <NAME> <<EMAIL>>
	 *   <NAME> <<EMAIL>>
	 * and licensed under GNU Public License v3
	 * (http://opensource.org/licenses/gpl-3.0.html)
	 * http://github.com/joshcam/PHP-MySQLi-Database-Class
	 **/
	class PostgresDb {
		protected
			/**
			 * PDO connection
			 *
			 * @var PDO
			 */
				$_conn,
			/**
			 * The SQL query to be prepared and executed
			 *
			 * @var string
			 */
				$_query,
			/**
			 * The previously executed SQL query
			 *
			 * @var string
			 */
				$_lastQuery,
			/**
			 * An array that holds where joins
			 *
			 * @var array
			 */
				$_join = array(),
			/**
			 * An array that holds where conditions 'fieldname' => 'value'
			 *
			 * @var array
			 */
				$_where = array(),
			/**
			 * Dynamic type list for order by condition value
			 */
				$_orderBy = array(),
			/**
			 * Dynamic type list for group by condition value
			 */
				$_groupBy = array(),
			/**
			 * Dynamic array that holds a combination of where condition/table data value types and parameter references
			 *
			 * @var array|null
			 */
				$_bindParams = null,
			/**
			 * Name of the auto increment column
			 *
			 */
				$_lastInsertId = null,
			/**
			 * Variable which holds last statement error
			 *
			 * @var string
			 */
				$_stmtError = null;

		public
			/**
			 * Variable which holds an amount of returned rows during get/getOne/select queries
			 *
			 * @var string
			 */
				$count = 0;

		private
			/**
			 * Used for connecting to the database
			 *
			 * @var string
			 */
				$_connstr;

		public function __construct($db, $host = DB_HOST, $user = DB_USER, $pass = DB_PASS){
			$this->_connstr = "pgsql:host=$host user=$user password=$pass dbname=$db options='--client_encoding=UTF8'";
		}

		protected function _connect(){
			try {
				$this->_conn = new PDO($this->_connstr);
				$this->_conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
			}
			catch (PDOException $e){
				throw new Exception("Database connection error: ".$e->getMessage());
			}
		}

		public function pdo(){
			if (!$this->_conn){
				$this->_connect();
			}

			return $this->_conn;
		}

		/**
		 * Method attempts to prepare the SQL query
		 * and throws an error if there was a problem.
		 *
		 * @return mysqli_stmt
		 */
		protected function _prepareQuery(){
			try {
				$stmt = $this->pdo()->prepare($this->_query);
			}
			catch (PDOException $e){
				throw new Exception ("Problem preparing query ($this->_query) ".$e->getMessage());
			}

			return $stmt;
		}

		/**
		 * Function to replace ? with variables from bind variable
		 *
		 * @param string $str
		 * @param Array  $vals
		 *
		 * @return string
		 */
		protected function _replacePlaceHolders($str, $vals){
			$i = 0;
			$valcount = count($vals);

			while (strpos($str, "?") !== false && $i < $valcount){
				$val = $vals[$i++];
				if (is_object($val)){
					$val = '[object]';
				}
				else if ($val === null){
					$val = 'NULL';
				}
				if (is_string($val)){
					$val = "'$val'";
				}

				$str = preg_replace('/\?/', $val, $str, 1);
			}

			return $str;
		}

		/**
		 * Helper function to add variables into bind parameters array
		 *
		 * @param string Variable value
		 */
		protected function _bindParam($value){
			$this->_bindParams[] = $value;
		}

		/**
		 * Helper function to add variables into bind parameters array in bulk
		 *
		 * @param Array Variable with values
		 */
		protected function _bindParams($values){
			foreach ($values as $value){
				$this->_bindParam($value);
			}
		}

		/**
		 * Helper function to add variables into bind parameters array and will return
		 * its SQL part of the query according to operator in ' $operator ?'
		 *
		 * @param array $operator Variable with values
		 * @param       $value
		 *
		 * @return string
		 */
		protected function _buildPair($operator, $value){
			$this->_bindParam($value);

			return ' '.$operator.' ? ';
		}

		/**
		 * Abstraction method that will build an JOIN part of the query
		 */
		protected function _buildJoin(){
			if (empty ($this->_join)){
				return;
			}

			foreach ($this->_join as $data){
				list ($joinType, $joinTable, $joinCondition) = $data;

				$this->_query .= " $joinType JOIN ".$this->_escapeTableName($joinTable)." on $joinCondition";
			}
		}

		/**
		 * Abstraction method that will build the part of the WHERE conditions
		 */
		protected function _buildWhere(){
			if (empty ($this->_where)){
				return;
			}

			//Prepare the where portion of the query
			$this->_query .= ' WHERE';

			foreach ($this->_where as $cond){
				list ($concat, $varName, $operator, $val) = $cond;
				if (preg_match('~^[a-z_\-\d]+$~', $varName)){
					$varName = "\"$varName\"";
				}
				$this->_query .= ' '.trim("$concat $varName");

				switch (strtolower($operator)) {
					case 'not in':
					case 'in':
						$comparison = ' '.$operator.' (';
						if (is_object($val)){
							$comparison .= $this->_buildPair("", $val);
						}
						else {
							foreach ($val as $v){
								$comparison .= ' ?,';
								$this->_bindParam($v);
							}
						}
						$this->_query .= rtrim($comparison, ',').' ) ';
						break;
					case 'not between':
					case 'between':
						$this->_query .= " $operator ? AND ? ";
						$this->_bindParams($val);
						break;
					case 'not exists':
					case 'exists':
						$this->_query .= $operator.$this->_buildPair("", $val);
						break;
					default:
						if (is_array($val)){
							$this->_bindParams($val);
						}
						else if ($val === null){
							$this->_query .= $operator." NULL";
						}
						else if ($val != 'DBNULL' || $val == '0'){
							$this->_query .= $this->_buildPair($operator, $val);
						}
				}
			}
			$this->_query = rtrim($this->_query);
		}

		public function _buildDataPairs($tableData, $tableColumns, $isInsert){
			foreach ($tableColumns as $column){
				$value = $tableData[$column];
				if (!$isInsert){
					$this->_query .= "\"$column\" = ";
				}

				// Simple value
				if (!is_array($value)){
					if (is_bool($value))
						$value = $value ? 'true' : 'false';
					$this->_bindParam($value);
					$this->_query .= '?, ';
					continue;
				}
			}
			$this->_query = rtrim($this->_query, ', ');
		}

		/**
		 * Abstraction method that will build an INSERT or UPDATE part of the query
		 *
		 * @param array $tableData
		 */
		protected function _buildInsertQuery($tableData){
			if (!is_array($tableData)){
				return;
			}

			$isInsert = preg_match('/^[INSERT|REPLACE]/', $this->_query);
			$dataColumns = array_keys($tableData);
			if ($isInsert){
				$this->_query .= ' ("'.implode($dataColumns, '", "').'")  VALUES (';
			}
			else $this->_query .= " SET ";

			$this->_buildDataPairs($tableData, $dataColumns, $isInsert);

			if ($isInsert){
				$this->_query .= ')';
			}
		}

		/**
		 * Abstraction method that will build the GROUP BY part of the WHERE statement
		 *
		 */
		protected function _buildGroupBy(){
			if (empty ($this->_groupBy)){
				return;
			}

			$this->_query .= " GROUP BY ";
			foreach ($this->_groupBy as $value){
				$this->_query .= "$value, ";
			}

			$this->_query = rtrim($this->_query, ', ').' ';
		}

		/**
		 * Abstraction method that will build the LIMIT part of the WHERE statement
		 *
		 */
		protected function _buildOrderBy(){
			if (empty($this->_orderBy)){
				return;
			}

			$this->_query .= " ORDER BY ";
			foreach ($this->_orderBy as $prop => $value){
				if (strtolower(str_replace(' ', '', $prop)) == 'rand()'){
					$this->_query .= 'rand(), ';
				}
				else $this->_query .= "$prop $value, ";
			}

			$this->_query = rtrim($this->_query, ', ');
		}

		/**
		 * Internal function to build and execute INSERT/REPLACE calls
		 *
		 * @param <string $tableName The name of the table.
		 * @param array       $insertData   Data containing information for inserting into the DB.
		 * @param             $operation
		 * @param string|null $returnColumn What column to return after insert
		 *
		 * @return boolean Boolean indicating whether the insert query was completed succesfully.
		 */
		private function _buildInsert($tableName, $insertData, $operation, $returnColumn = null){
			$this->_query = "$operation INTO ".$this->_escapeTableName($tableName);
			if (!empty($returnColumn)){
				$returnColumn = trim($returnColumn);
			}
			$stmt = $this->_buildQuery(null, $insertData, $returnColumn);

			$res = $this->_execStatement($stmt);

			if ($res === false || $this->count < 1){
				return false;
			}

			if (!empty($res[0][$returnColumn])){
				return $res[0][$returnColumn];
			}

			return true;
		}

		/**
		 * Abstraction method that will build the LIMIT part of the WHERE statement
		 *
		 * @param integer|array $numRows Array to define SQL limit in format Array ($count, $offset)
		 *                               or only $count
		 */
		protected function _buildLimit($numRows){
			if (!isset($numRows)){
				return;
			}

			$this->_query .= ' LIMIT '.(
					is_array($numRows)
							? (int) $numRows[1].' OFFSET '.(int) $numRows[0]
							: (int) $numRows
					);
		}

		/**
		 * Abstraction method that will compile the WHERE statement,
		 * any passed update data, and the desired rows.
		 * It then builds the SQL query.
		 *
		 * @param integer|array $numRows   Array to define SQL limit in format Array ($count, $offset)
		 *                                 or only $count
		 * @param array         $tableData Should contain an array of data for updating the database.
		 * @param string|null   $returning What column to return after inserting
		 *
		 * @return mysqli_stmt Returns the $stmt object.
		 */
		protected function _buildQuery($numRows = null, $tableData = null, $returning = null){
			$this->_buildJoin();
			$this->_buildInsertQuery($tableData);
			if (!empty($returning)){
				$this->_query .= " RETURNING \"$returning\"";
			}
			$this->_buildWhere();
			$this->_buildGroupBy();
			$this->_buildOrderBy();
			$this->_buildLimit($numRows);
			$this->_alterQuery();

			$this->_lastQuery = $this->_replacePlaceHolders($this->_query, $this->_bindParams);

			// Prepare query
			$stmt = $this->_prepareQuery();

			return $stmt;
		}

		/**
		 * Execute raw SQL query.
		 *
		 * @param string $query      User-provided query to execute.
		 * @param array  $bindParams Variables array to bind to the SQL statement.
		 *
		 * @return array Contains the returned rows from the query.
		 */
		public function rawQuery($query, $bindParams = null){
			$params = array(null); // Create the empty 0 index
			$this->_query = $query;
			$this->_alterQuery();

			$stmt = $this->_prepareQuery();
			$this->_bindParams = is_array($bindParams) ? $bindParams : null;
<commit_msg>Update PostgresDb to latest version<commit_after><?php

	/**
	 * PostgresDb Class
	 * by @DJDavid98 | https://github.com/DJDavid98/PHP-PostgreSQL-Database-Class
	 *
	 * Heavily based on MysqliDB version 2.4 as made by
	 *   <NAME> <<EMAIL>>
	 *   <NAME> <<EMAIL>>
	 *   <NAME> <<EMAIL>>
	 * and licensed under GNU Public License v3
	 * (http://opensource.org/licenses/gpl-3.0.html)
	 * http://github.com/joshcam/PHP-MySQLi-Database-Class
	 **/
	class PostgresDb {
		protected
			/**
			 * PDO connection
			 *
			 * @var PDO
			 */
				$_conn,
			/**
			 * The SQL query to be prepared and executed
			 *
			 * @var string
			 */
				$_query,
			/**
			 * The previously executed SQL query
			 *
			 * @var string
			 */
				$_lastQuery,
			/**
			 * An array that holds where joins
			 *
			 * @var array
			 */
				$_join = array(),
			/**
			 * An array that holds where conditions 'fieldname' => 'value'
			 *
			 * @var array
			 */
				$_where = array(),
			/**
			 * Dynamic type list for order by condition value
			 */
				$_orderBy = array(),
			/**
			 * Dynamic type list for group by condition value
			 */
				$_groupBy = array(),
			/**
			 * Dynamic array that holds a combination of where condition/table data value types and parameter references
			 *
			 * @var array|null
			 */
				$_bindParams = null,
			/**
			 * Name of the auto increment column
			 *
			 */
				$_lastInsertId = null,
			/**
			 * Variable which holds last statement error
			 *
			 * @var string
			 */
				$_stmtError = null;

		public
			/**
			 * Variable which holds an amount of returned rows during get/getOne/select queries
			 *
			 * @var string
			 */
				$count = 0;

		private
			/**
			 * Used for connecting to the database
			 *
			 * @var string
			 */
				$_connstr;

		public function __construct($db, $host = DB_HOST, $user = DB_USER, $pass = DB_PASS){
			$this->_connstr = "pgsql:host=$host user=$user password=$<PASSWORD> dbname=$db options='--client_encoding=UTF8'";
		}

		protected function _connect(){
			try {
				$this->_conn = new PDO($this->_connstr);
				$this->_conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
			}
			catch (PDOException $e){
				throw new Exception("Database connection error: ".$e->getMessage());
			}
		}

		public function pdo(){
			if (!$this->_conn){
				$this->_connect();
			}

			return $this->_conn;
		}

		/**
		 * Method attempts to prepare the SQL query
		 * and throws an error if there was a problem.
		 *
		 * @return mysqli_stmt
		 */
		protected function _prepareQuery(){
			try {
				$stmt = $this->pdo()->prepare($this->_query);
			}
			catch (PDOException $e){
				throw new Exception ("Problem preparing query ($this->_query) ".$e->getMessage());
			}

			return $stmt;
		}

		/**
		 * Function to replace ? with variables from bind variable
		 *
		 * @param string $str
		 * @param Array  $vals
		 *
		 * @return string
		 */
		protected function _replacePlaceHolders($str, $vals){
			$i = 0;
			$valcount = count($vals);

			while (strpos($str, "?") !== false && $i < $valcount){
				$val = $vals[$i++];
				if (is_object($val)){
					$val = '[object]';
				}
				else if ($val === null){
					$val = 'NULL';
				}
				if (is_string($val)){
					$val = "'$val'";
				}

				$str = preg_replace('/\?/', $val, $str, 1);
			}

			return $str;
		}

		/**
		 * Helper function to add variables into bind parameters array
		 *
		 * @param string Variable value
		 */
		protected function _bindParam($value){
			$this->_bindParams[] = $value;
		}

		/**
		 * Helper function to add variables into bind parameters array in bulk
		 *
		 * @param Array Variable with values
		 */
		protected function _bindParams($values){
			foreach ($values as $value){
				$this->_bindParam($value);
			}
		}

		/**
		 * Helper function to add variables into bind parameters array and will return
		 * its SQL part of the query according to operator in ' $operator ?'
		 *
		 * @param array $operator Variable with values
		 * @param       $value
		 *
		 * @return string
		 */
		protected function _buildPair($operator, $value){
			$this->_bindParam($value);

			return ' '.$operator.' ? ';
		}

		/**
		 * Abstraction method that will build an JOIN part of the query
		 */
		protected function _buildJoin(){
			if (empty ($this->_join)){
				return;
			}

			foreach ($this->_join as $data){
				list ($joinType, $joinTable, $joinCondition) = $data;

				$this->_query .= " $joinType JOIN ".$this->_escapeTableName($joinTable)." on $joinCondition";
			}
		}

		/**
		 * Abstraction method that will build the part of the WHERE conditions
		 */
		protected function _buildWhere(){
			if (empty ($this->_where)){
				return;
			}

			//Prepare the where portion of the query
			$this->_query .= ' WHERE';

			foreach ($this->_where as $cond){
				list ($concat, $varName, $operator, $val) = $cond;
				if (preg_match('~^[a-z_\-\d]+$~', $varName)){
					$varName = "\"$varName\"";
				}
				$this->_query .= ' '.trim("$concat $varName");

				switch (strtolower($operator)) {
					case 'not in':
					case 'in':
						$comparison = ' '.$operator.' (';
						if (is_object($val)){
							$comparison .= $this->_buildPair("", $val);
						}
						else {
							foreach ($val as $v){
								$comparison .= ' ?,';
								$this->_bindParam($v);
							}
						}
						$this->_query .= rtrim($comparison, ',').' ) ';
						break;
					case 'not between':
					case 'between':
						$this->_query .= " $operator ? AND ? ";
						$this->_bindParams($val);
						break;
					case 'not exists':
					case 'exists':
						$this->_query .= $operator.$this->_buildPair("", $val);
						break;
					default:
						if (is_array($val)){
							$this->_bindParams($val);
						}
						else if ($val === null){
							$this->_query .= $operator." NULL";
						}
						else if ($val != 'DBNULL' || $val == '0'){
							$this->_query .= $this->_buildPair($operator, $val);
						}
				}
			}
			$this->_query = rtrim($this->_query);
		}

		public function _buildDataPairs($tableData, $tableColumns, $isInsert){
			foreach ($tableColumns as $column){
				$value = $tableData[$column];
				if (!$isInsert){
					$this->_query .= "\"$column\" = ";
				}

				// Simple value
				if (!is_array($value)){
					if (is_bool($value))
						$value = $value ? 'true' : 'false';
					$this->_bindParam($value);
					$this->_query .= '?, ';
					continue;
				}
			}
			$this->_query = rtrim($this->_query, ', ');
		}

		/**
		 * Abstraction method that will build an INSERT or UPDATE part of the query
		 *
		 * @param array $tableData
		 */
		protected function _buildInsertQuery($tableData){
			if (!is_array($tableData)){
				return;
			}

			$isInsert = preg_match('/^[INSERT|REPLACE]/', $this->_query);
			$dataColumns = array_keys($tableData);
			if ($isInsert){
				$this->_query .= ' ("'.implode($dataColumns, '", "').'")  VALUES (';
			}
			else $this->_query .= " SET ";

			$this->_buildDataPairs($tableData, $dataColumns, $isInsert);

			if ($isInsert){
				$this->_query .= ')';
			}
		}

		/**
		 * Abstraction method that will build the GROUP BY part of the WHERE statement
		 *
		 */
		protected function _buildGroupBy(){
			if (empty ($this->_groupBy)){
				return;
			}

			$this->_query .= " GROUP BY ";
			foreach ($this->_groupBy as $value){
				$this->_query .= "$value, ";
			}

			$this->_query = rtrim($this->_query, ', ').' ';
		}

		/**
		 * Abstraction method that will build the LIMIT part of the WHERE statement
		 *
		 */
		protected function _buildOrderBy(){
			if (empty($this->_orderBy)){
				return;
			}

			$this->_query .= " ORDER BY ";
			foreach ($this->_orderBy as $prop => $value){
				if (strtolower(str_replace(' ', '', $prop)) == 'rand()'){
					$this->_query .= 'rand(), ';
				}
				else $this->_query .= "$prop $value, ";
			}

			$this->_query = rtrim($this->_query, ', ');
		}

		/**
		 * Internal function to build and execute INSERT/REPLACE calls
		 *
		 * @param <string $tableName The name of the table.
		 * @param array       $insertData   Data containing information for inserting into the DB.
		 * @param             $operation
		 * @param string|null $returnColumn What column to return after insert
		 *
		 * @return boolean Boolean indicating whether the insert query was completed succesfully.
		 */
		private function _buildInsert($tableName, $insertData, $operation, $returnColumn = null){
			$this->_query = "$operation INTO ".$this->_escapeTableName($tableName);
			if (!empty($returnColumn)){
				$returnColumn = trim($returnColumn);
			}
			$stmt = $this->_buildQuery(null, $insertData, $returnColumn);

			$res = $this->_execStatement($stmt);

			if ($res === false || $this->count < 1){
				return false;
			}

			if (!empty($res[0][$returnColumn])){
				return $res[0][$returnColumn];
			}

			return true;
		}

		/**
		 * Abstraction method that will build the LIMIT part of the WHERE statement
		 *
		 * @param integer|array $numRows Array to define SQL limit in format Array ($count, $offset)
		 *                               or only $count
		 */
		protected function _buildLimit($numRows){
			if (!isset($numRows)){
				return;
			}

			$this->_query .= ' LIMIT '.(
					is_array($numRows)
							? (int) $numRows[1].' OFFSET '.(int) $numRows[0]
							: (int) $numRows
					);
		}

		/**
		 * Abstraction method that will compile the WHERE statement,
		 * any passed update data, and the desired rows.
		 * It then builds the SQL query.
		 *
		 * @param integer|array $numRows   Array to define SQL limit in format Array ($count, $offset)
		 *                                 or only $count
		 * @param array         $tableData Should contain an array of data for updating the database.
		 * @param string|null   $returning What column to return after inserting
		 *
		 * @return mysqli_stmt Returns the $stmt object.
		 */
		protected function _buildQuery($numRows = null, $tableData = null, $returning = null){
			$this->_buildJoin();
			$this->_buildInsertQuery($tableData);
			if (!empty($returning)){
				$this->_query .= " RETURNING \"$returning\"";
			}
			$this->_buildWhere();
			$this->_buildGroupBy();
			$this->_buildOrderBy();
			$this->_buildLimit($numRows);
			$this->_alterQuery();

			$this->_lastQuery = $this->_replacePlaceHolders($this->_query, $this->_bindParams);

			// Prepare query
			$stmt = $this->_prepareQuery();

			return $stmt;
		}

		/**
		 * Execute raw SQL query.
		 *
		 * @param string $query      User-provided query to execute.
		 * @param array  $bindParams Variables array to bind to the SQL statement.
		 *
		 * @return array Contains the returned rows from the query.
		 */
		public function rawQuery($query, $bindParams = null){
			$params = array(null); // Create the empty 0 index
			$this->_query = $query;
			$this->_alterQuery();

			$stmt = $this->_prepareQuery();
			if (empty($bindParams))
				$this->_bindParams = null;
			else if (!is_array($bindParams))
				throw new Exception('$bindParams must be an array');
			else {
				$this->_bindParams =  $bindParams;
			}

{'fraction_non_alphanumeric': 0.15881358256021205, 'fraction_numerical': 0.0018280700150815777, 'mean_word_length': 2.5754901960784315, 'pattern_counts': {'":': 0, '<': 30, '<?xml version=': 0, '>': 195, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6409794', 'n_tokens_mistral': 8680, 'n_tokens_neox': 6590, 'n_words': 1879}