<commit_before><?php

/**
 * Copyright (c) 2011, Erasmus MC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *    * Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *    * Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 *    * Neither the name of Erasmus MC nor the
 *      names of its contributors may be used to endorse or promote products
 *      derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *
 * @package    MUtil
 * @subpackage Model
 * @author     <NAME> <<EMAIL>>
 * @copyright  Copyright (c) 2011 Erasmus MC
 * @license    New BSD License
 * @version    $Id$
 */

/**
 * Class contains standard helper functions for using models
 * that store information using Zend_Db_Adapter.
 *
 * @package    MUtil
 * @subpackage Model
 * @copyright  Copyright (c) 2011 Erasmus MC
 * @license    New BSD License
 * @since      Class available since version 1.0
 */
abstract class MUtil_Model_DatabaseModelAbstract extends MUtil_Model_ModelAbstract
{
    /**
     * Default value for $keyKopier.
     *
     * As this is the name a hidden Zend_Element we can use only letters and the underscore for
     * the first character and letters, the underscore and numbers for the later characters.
     *
     * Zend_Element allows some other extended characters, but those may not work
     * with some browsers.
     *
     * If there exists a table containing two fields where one fields maps with this key
     * to the other, shoot the table designer!!!
     */
    const KEY_COPIER = '__c_1_3_copy__%s__key_k_0_p_1__';

    /**
     * Name for query filter transformers
     */
    const TEXTFILTER_TRANSFORMER = 'filter_transformer';

    /**
     * @var array When specified delete() updates the selected rows with these values, instead of physically deleting the rows.
     */
    protected $_deleteValues;

    /**
     * Child classes may technically be able or not able to add extra rows,
     * but the data model or specific circumstances may require a specific
     * instance of that class to deviate from the default.
     *
     * @var boolean $canCreate True if the model can create new rows.
     */
    public $canCreate = true;

    /**
     * A standard rename scaffold for hidden kopies of primary key fields.
     *
     * As this is the name a hidden Zend_Element we can use only letters and the underscore for
     * the first character and letters, the underscore and numbers for the later characters.
     *
     * Zend_Element allows some other extended characters, but those may not work
     * with some browsers.
     *
     * @var string $keyKopier String into which the original keyname is sprintf()-ed.
     */
    public $keyCopier = self::KEY_COPIER;

    /**
     * Get a select statement using a filter and sort
     *
     * @param array $filter
     * @param array $sort
     * @return Zend_Db_Table_Select
     */
    protected function _createSelect($filter = null, $sort = null)
    {
        $select  = $this->getSelect();


        if ($this->hasItemsUsed()) {
            // Add expression columns by default
            // getColumn() triggers the columns as 'used'
            $this->getCol('column_expression');

            // Add each column to the select statement
            foreach ($this->getItemsUsed() as $name) {
                if ($expression = $this->get($name, 'column_expression')) {
                    $select->columns(array($name => $expression));
                } else {
                    if ($table = $this->get($name, 'table')) {
                        $select->columns($name, $table);
                    }
                }
            }
        } else {
            // Add only the columns, all other fields are returned already.
            foreach ($this->getCol('column_expression') as $name => $expression) {
                $select->columns(array($name => $expression));
            }
        }

        $adapter = $this->getAdapter();

        // Filter
        foreach ($this->_checkFilterUsed($filter) as $name => $value) {
            if (is_int($name)) {
                $select->where($value);
            } else {
                if ($expression = $this->get($name, 'column_expression')) {
                    //The brackets tell Zend_Db_Select that this is an epression in a sort.
                    $name = '(' . $expression . ')';
                } else {
                    $name = $adapter->quoteIdentifier($name);
                }
                if (null === $value) {
                    $select->where($name . ' IS NULL');
                } else {
                    $select->where($name . ' = ?', $value);
                }
            }
        }

        // Sort
        if ($sort = $this->_checkSortUsed($sort)) {
            foreach ($sort as $key => $order) {
                if (is_numeric($key) || is_string($order)) {
                    $sqlsort[] = $order;
                } else {
                    // Code not needed at least for MySQL, a named calculated column can be used in
                    // an ORDER BY. However, it does work.
                    /*
                    if ($expression = $this->get($key, 'column_expression')) {
                        //The brackets tell Zend_Db_Select that this is an epression in a sort.
                        $key = '(' . $expression . ')';
                    } // */
                    switch ($order) {
                        case SORT_ASC:
                            $sqlsort[] = $key . ' ASC';
                            break;
                        case SORT_DESC:
                            $sqlsort[] = $key . ' DESC';
                            break;
                        default:
                            $sqlsort[] = $order;
                            break;
                    }
                }
            }

            $select->order($sqlsort);<commit_msg>Made db sort more robust: only existing fields are sorted on. This fixes an issue where multiple on screen tables share the same sort paramters.<commit_after><?php

/**
 * Copyright (c) 2011, Erasmus MC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *    * Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *    * Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 *    * Neither the name of Erasmus MC nor the
 *      names of its contributors may be used to endorse or promote products
 *      derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *
 * @package    MUtil
 * @subpackage Model
 * @author     <NAME> <<EMAIL>>
 * @copyright  Copyright (c) 2011 Erasmus MC
 * @license    New BSD License
 * @version    $Id$
 */

/**
 * Class contains standard helper functions for using models
 * that store information using Zend_Db_Adapter.
 *
 * @package    MUtil
 * @subpackage Model
 * @copyright  Copyright (c) 2011 Erasmus MC
 * @license    New BSD License
 * @since      Class available since version 1.0
 */
abstract class MUtil_Model_DatabaseModelAbstract extends MUtil_Model_ModelAbstract
{
    /**
     * Default value for $keyKopier.
     *
     * As this is the name a hidden Zend_Element we can use only letters and the underscore for
     * the first character and letters, the underscore and numbers for the later characters.
     *
     * Zend_Element allows some other extended characters, but those may not work
     * with some browsers.
     *
     * If there exists a table containing two fields where one fields maps with this key
     * to the other, shoot the table designer!!!
     */
    const KEY_COPIER = '__c_1_3_copy__%s__key_k_0_p_1__';

    /**
     * Name for query filter transformers
     */
    const TEXTFILTER_TRANSFORMER = 'filter_transformer';

    /**
     * @var array When specified delete() updates the selected rows with these values, instead of physically deleting the rows.
     */
    protected $_deleteValues;

    /**
     * Child classes may technically be able or not able to add extra rows,
     * but the data model or specific circumstances may require a specific
     * instance of that class to deviate from the default.
     *
     * @var boolean $canCreate True if the model can create new rows.
     */
    public $canCreate = true;

    /**
     * A standard rename scaffold for hidden kopies of primary key fields.
     *
     * As this is the name a hidden Zend_Element we can use only letters and the underscore for
     * the first character and letters, the underscore and numbers for the later characters.
     *
     * Zend_Element allows some other extended characters, but those may not work
     * with some browsers.
     *
     * @var string $keyKopier String into which the original keyname is sprintf()-ed.
     */
    public $keyCopier = self::KEY_COPIER;

    /**
     * Get a select statement using a filter and sort
     *
     * @param array $filter
     * @param array $sort
     * @return Zend_Db_Table_Select
     */
    protected function _createSelect($filter = null, $sort = null)
    {
        $select  = $this->getSelect();


        if ($this->hasItemsUsed()) {
            // Add expression columns by default
            // getColumn() triggers the columns as 'used'
            $this->getCol('column_expression');

            // Add each column to the select statement
            foreach ($this->getItemsUsed() as $name) {
                if ($expression = $this->get($name, 'column_expression')) {
                    $select->columns(array($name => $expression));
                } else {
                    if ($table = $this->get($name, 'table')) {
                        $select->columns($name, $table);
                    }
                }
            }
        } else {
            // Add only the columns, all other fields are returned already.
            foreach ($this->getCol('column_expression') as $name => $expression) {
                $select->columns(array($name => $expression));
            }
        }

        $adapter = $this->getAdapter();

        // Filter
        foreach ($this->_checkFilterUsed($filter) as $name => $value) {
            if (is_int($name)) {
                $select->where($value);
            } else {
                if ($expression = $this->get($name, 'column_expression')) {
                    //The brackets tell Zend_Db_Select that this is an epression in a sort.
                    $name = '(' . $expression . ')';
                } else {
                    $name = $adapter->quoteIdentifier($name);
                }
                if (null === $value) {
                    $select->where($name . ' IS NULL');
                } else {
                    $select->where($name . ' = ?', $value);
                }
            }
        }

        // Sort
        if ($sort = $this->_checkSortUsed($sort)) {
            foreach ($sort as $key => $order) {
                if (is_numeric($key) || is_string($order)) {
                    if ($this->has($order)) {
                        $sqlsort[] = $order;
                    }
                } else {
                    // Code not needed at least for MySQL, a named calculated column can be used in
                    // an ORDER BY. However, it does work.
                    /*
                    if ($expression = $this->get($key, 'column_expression')) {
                        //The brackets tell Zend_Db_Select that this is an epression in a sort.
                        $key = '(' . $expression . ')';
                    } // */
                    switch ($order) {
                        case SORT_ASC:
                            if ($this->has($key)) {
                                $sqlsort[] = $key . ' ASC';
                            }
                            break;
                        case SORT_DESC:
                            if ($this->has($key)) {
                                $sqlsort[] = $key . ' DESC';
                            }
                            break;
                        default:
                            if ($this->has($order)) {
                                $sqlsort[] = $order;
                            }
                            break;
                    }
                }
            }

            $select->order($sqlsort);
{'fraction_non_alphanumeric': 0.08823731374030076, 'fraction_numerical': 0.0024720181281329395, 'mean_word_length': 1.8263147680962546, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 63, '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': '2358097', 'n_tokens_mistral': 3727, 'n_tokens_neox': 3473, 'n_words': 1415}