<commit_before><?php

class BaseDataAccess
{
    protected $table;
    protected $primary_key;

    /**
     * find
     * @return array of objects
     */
    public static function find()
    {
        $object = new static;

        $sql = 'select '.$object->getPropertiesString().' '.
            'from '.$object->table.';';

        return $object->fetch($sql, array());
    }

    /**
     * findById
     * @param mixed $id
     * @return object
     */
    public static function findById($id)
    {
        $object = new static;

        $sql = 'select ' . $object->getPropertiesString() . ' ' .
            'from ' . $object->table . ' ' .
            'where ' . $object->primary_key . ' = ?;';

        return $object->fetchSingle($sql, array($id));
    }

    /**
     * findByProperties
     * @param array $properties
     * @return array of objects
     */
    public static function findByProperties(array $properties)
    {
        $object = new static;
        $filters = array();
        $values = array();

        $sql = 'select ' . $object->getPropertiesString() . ' ' .
            'from ' . $object->table . ' ' .
            'where ';

        foreach($properties as $key => $value)
        {
            $filters[] = $key . ' = ?';
            $values[] = $value;
        }

        $sql .= join(' and ', $filters) . ';';

        return $object->fetch($sql, $values);
    }

    /**
     * existById
     * @param $id
     * @return mixed
     */
    public static function existById($id)
    {
        $object = new static;

        $sql = 'select count(*) as count ' .
            'from ' . $object->table . ' ' .
            'where ' . $object->primary_key . ' = ?;';

        $result = $object->fetchSingle($sql, array($id));

        return $result->count > 0;
    }

    /**
     * existByProperties
     * @param array $properties
     * @return bool
     */
    public static function existByProperties(array $properties)
    {
        $object = new static;
        $filters = array();
        $values = array();

        $sql = 'select count(*) as count ' .
            'from ' . $object->table . ' ' .
            'where ';

        foreach($properties as $key => $value)
        {
            $filters[] = $key . ' = ?';
            $values[] = $value;
        }

        $sql .= join(' and ', $filters) . ';';

        $result = $object->fetchSingle($sql, $values);

        return $result->count > 0;
    }

    /**
     * insert
     * @return bool
     */
    public function insert()
    {
        $properties = $this->getProperties();
        $tokens = array();
        $values = array();

        foreach($properties as $property) {
            $name = $property->name;

            if($name != 'table' && $name != 'primary_key' && $name != $this->primary_key) {
                $tokens[] = $name;
                $values[] = '?';
            }
        }

        $sql = 'insert into ' . $this->table . '(' . join(', ', $tokens) . ') '.
            'values(' . join(', ', $values) . ');';

        $db = db::getInstance();
        $stmt = $db->prepare($sql);
        $stmt->execute($this->bindProperties());
        $this->id = $db->lastInsertId();

        $error = $stmt->errorInfo();
        return ($error[0] === '00000');
    }

    /**
     * update
     * @return bool
     */
    public function update() {
        $properties = $this->getProperties();
        $tokens = array();

        foreach($properties as $property) {
            $name = $property->name;

            if($name != 'table' && $name != 'primary_key' && $name != $this->primary_key) {
                $tokens[] = $name.' = ?';
            }
        }

        $sql = 'update ' . $this->table . ' ' .
            'set ' . join(', ', $tokens) . ' ' .
            'where ' . $this->primary_key . ' = ?;';

        $db = db::getInstance();
        $stmt = $db->prepare($sql);
        $stmt->execute($this->bindProperties(true));

        $error = $stmt->errorInfo();
        return ($error[0] === '00000');
    }

    /**
     * delete
     * @return bool
     */
    public function delete() {
        $sql = 'delete from ' . $this->table . ' ' .
            'where ' . $this->primary_key . ' = ?;';

        $db = db::getInstance();
        $stmt = $db->prepare($sql);
        $properties_array = $this->bindProperties(true);
        $primary_key = array_pop($properties_array);
        $stmt->execute(array($primary_key));

        $error = $stmt->errorInfo();
        return ($error[0] === '00000');
    }

    /**
     * bindProperties
     * @param bool $with_id
     * @return array
     */
    protected function bindProperties($with_id = false)
    {
        $properties = $this->getProperties();
        $primary = null;
        $pairs = array();

        foreach($properties as $property) {
            $name = $property->name;

            if($name != 'table' && $name != 'primary_key') {
                if($name === $this->primary_key) {
                    $primary = $property->getValue($this);
                }
                else {
                    $pairs[] = $property->getValue($this);
                }
            }
        }

        if($with_id) {
            $pairs[] = $primary;
        }

        return $pairs;
    }

    /**
     * getPropertiesString
     * @return string
     */
    protected function getPropertiesString()
    {
        $properties = $this->getProperties();
        $columns = array();

        foreach($properties as $property) {
            $name = $property->name;

            if($name != 'table' && $name != 'primary_key') {
                $columns[] = $name;
            }
        }

        return join(', ', $columns);
    }

    protected function getProperties() {
        $object = new static;
        $reflector = new ReflectionClass($object);
        return $reflector->getProperties();
    }

    /**
     * fetch
     * @param string $sql
     * @param array $params
     * @return array of objects
     */
    protected function fetch($sql, array $params)
    {
        $db = db::getInstance();
        $stmt = $db->prepare($sql);
        $stmt->execute($params);
        $objects = array();

        while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
            $objects[] = self::mapProperties($row);
        }

        return $objects;
    }

    /**
     * fetchSingle
     * @param string $sql
     * @param array $params
     * @return object
     */
    protected function fetchSingle($sql, array $params) {
        $db = db::getInstance();
        $stmt = $db->prepare($sql);
        $stmt->execute($params);
        $result = $stmt->fetch(PDO::FETCH_ASSOC);
        return ($result)
            ? self::mapProperties($result)
            : null;
    }

    /**
     * mapProperties
     * @param array $properties
     * @return object
     */
    protected function mapProperties(array $properties)
    {
        $object = new static;

        foreach($properties as $key => $value) {
            $object->$key = $value;
        }

        return $object;
    }
}<commit_msg>remove enforcement on primary key being 'id' only<commit_after><?php

class BaseDataAccess
{
    protected $table;
    protected $primary_key;

    /**
     * find
     * @return array of objects
     */
    public static function find()
    {
        $object = new static;

        $sql = 'select '.$object->getPropertiesString().' '.
            'from '.$object->table.';';

        return $object->fetch($sql, array());
    }

    /**
     * findById
     * @param mixed $id
     * @return object
     */
    public static function findById($id)
    {
        $object = new static;

        $sql = 'select ' . $object->getPropertiesString() . ' ' .
            'from ' . $object->table . ' ' .
            'where ' . $object->primary_key . ' = ?;';

        return $object->fetchSingle($sql, array($id));
    }

    /**
     * findByProperties
     * @param array $properties
     * @return array of objects
     */
    public static function findByProperties(array $properties)
    {
        $object = new static;
        $filters = array();
        $values = array();

        $sql = 'select ' . $object->getPropertiesString() . ' ' .
            'from ' . $object->table . ' ' .
            'where ';

        foreach($properties as $key => $value)
        {
            $filters[] = $key . ' = ?';
            $values[] = $value;
        }

        $sql .= join(' and ', $filters) . ';';

        return $object->fetch($sql, $values);
    }

    /**
     * existById
     * @param $id
     * @return mixed
     */
    public static function existById($id)
    {
        $object = new static;

        $sql = 'select count(*) as count ' .
            'from ' . $object->table . ' ' .
            'where ' . $object->primary_key . ' = ?;';

        $result = $object->fetchSingle($sql, array($id));

        return $result->count > 0;
    }

    /**
     * existByProperties
     * @param array $properties
     * @return bool
     */
    public static function existByProperties(array $properties)
    {
        $object = new static;
        $filters = array();
        $values = array();

        $sql = 'select count(*) as count ' .
            'from ' . $object->table . ' ' .
            'where ';

        foreach($properties as $key => $value)
        {
            $filters[] = $key . ' = ?';
            $values[] = $value;
        }

        $sql .= join(' and ', $filters) . ';';

        $result = $object->fetchSingle($sql, $values);

        return $result->count > 0;
    }

    /**
     * insert
     * @return bool
     */
    public function insert()
    {
        $properties = $this->getProperties();
        $tokens = array();
        $values = array();

        foreach($properties as $property) {
            $name = $property->name;

            if($name != 'table' && $name != 'primary_key' && $name != $this->primary_key) {
                $tokens[] = $name;
                $values[] = '?';
            }
        }

        $sql = 'insert into ' . $this->table . '(' . join(', ', $tokens) . ') '.
            'values(' . join(', ', $values) . ');';

        $db = db::getInstance();
        $stmt = $db->prepare($sql);
        $stmt->execute($this->bindProperties());
        $this->{$this->primary_key} = $db->lastInsertId();

        $error = $stmt->errorInfo();
        return ($error[0] === '00000');
    }

    /**
     * update
     * @return bool
     */
    public function update() {
        $properties = $this->getProperties();
        $tokens = array();

        foreach($properties as $property) {
            $name = $property->name;

            if($name != 'table' && $name != 'primary_key' && $name != $this->primary_key) {
                $tokens[] = $name.' = ?';
            }
        }

        $sql = 'update ' . $this->table . ' ' .
            'set ' . join(', ', $tokens) . ' ' .
            'where ' . $this->primary_key . ' = ?;';

        $db = db::getInstance();
        $stmt = $db->prepare($sql);
        $stmt->execute($this->bindProperties(true));

        $error = $stmt->errorInfo();
        return ($error[0] === '00000');
    }

    /**
     * delete
     * @return bool
     */
    public function delete() {
        $sql = 'delete from ' . $this->table . ' ' .
            'where ' . $this->primary_key . ' = ?;';

        $db = db::getInstance();
        $stmt = $db->prepare($sql);
        $properties_array = $this->bindProperties(true);
        $primary_key = array_pop($properties_array);
        $stmt->execute(array($primary_key));

        $error = $stmt->errorInfo();
        return ($error[0] === '00000');
    }

    /**
     * bindProperties
     * @param bool $with_id
     * @return array
     */
    protected function bindProperties($with_id = false)
    {
        $properties = $this->getProperties();
        $primary = null;
        $pairs = array();

        foreach($properties as $property) {
            $name = $property->name;

            if($name != 'table' && $name != 'primary_key') {
                if($name === $this->primary_key) {
                    $primary = $property->getValue($this);
                }
                else {
                    $pairs[] = $property->getValue($this);
                }
            }
        }

        if($with_id) {
            $pairs[] = $primary;
        }

        return $pairs;
    }

    /**
     * getPropertiesString
     * @return string
     */
    protected function getPropertiesString()
    {
        $properties = $this->getProperties();
        $columns = array();

        foreach($properties as $property) {
            $name = $property->name;

            if($name != 'table' && $name != 'primary_key') {
                $columns[] = $name;
            }
        }

        return join(', ', $columns);
    }

    protected function getProperties() {
        $object = new static;
        $reflector = new ReflectionClass($object);
        return $reflector->getProperties();
    }

    /**
     * fetch
     * @param string $sql
     * @param array $params
     * @return array of objects
     */
    protected function fetch($sql, array $params)
    {
        $db = db::getInstance();
        $stmt = $db->prepare($sql);
        $stmt->execute($params);
        $objects = array();

        while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
            $objects[] = self::mapProperties($row);
        }

        return $objects;
    }

    /**
     * fetchSingle
     * @param string $sql
     * @param array $params
     * @return object
     */
    protected function fetchSingle($sql, array $params) {
        $db = db::getInstance();
        $stmt = $db->prepare($sql);
        $stmt->execute($params);
        $result = $stmt->fetch(PDO::FETCH_ASSOC);
        return ($result)
            ? self::mapProperties($result)
            : null;
    }

    /**
     * mapProperties
     * @param array $properties
     * @return object
     */
    protected function mapProperties(array $properties)
    {
        $object = new static;

        foreach($properties as $key => $value) {
            $object->$key = $value;
        }

        return $object;
    }
}
{'fraction_non_alphanumeric': 0.1703761093111706, 'fraction_numerical': 0.002817298211015636, 'mean_word_length': 1.6125114995400185, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 128, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7366072', 'n_tokens_mistral': 4196, 'n_tokens_neox': 4038, 'n_words': 853}