LoadArrayByXXX($intSomeValue, ...) with array support for $intSomeValue

thread: 19 messages  |  last: about 5 years ago  |  started: monday, july 3, 2006, 11:04 am pdt


#1  |  Alec de Zegher (Brussels, Belgium) Belgium
Monday, July 3, 2006, 11:04 AM PDT

Hi,

I made a small script that allows loading for multiple id-strings.
For exemple you have $intSomeValue = array('23', '24', '56');
And then you call LoadArrayByXXX($intSomeValue,...);

This should be easy to implement in the code generator. I tried, but still got errors. So I was wondering if someone of the great QCodo team couldn't implement this. It's quite easy and it has backwards compability.
Here is an exemple.

Best Regards
Alec

        public static function LoadArrayByTestId($intTestId, $strOrderBy = null, $strLimit = null, $objExpansionMap = null) {
            // Call to ArrayQueryHelper to Get Database Object and Get SQL Clauses
            Scores::ArrayQueryHelper($strOrderBy, $strLimit, $strLimitPrefix, $strLimitSuffix, $strExpandSelect, $strExpandFrom, $objExpansionMap, $objDatabase);

            // Properly Escape All Input Parameters using Database->SqlVariable()
            
            //EDITED by Alec de Zegher
            foreach($intTestId as $TestId)
            {
                $TestId = $objDatabase->SqlVariable($TestId);
            }
            $intTestId = implode("' OR `scores`.`test_id`='", $intTestId);
            // END EDITED

            // Setup the SQL Query
            $strQuery = sprintf('
                SELECT
                %s
                    `scores`.`id` AS `id`,
                    `scores`.`score` AS `score`,
                    `scores`.`comment` AS `comment`,
                    `scores`.`test_id` AS `test_id`,
                    `scores`.`person_id` AS `person_id`,
                    `scores`.`update` AS `update`
                    %s
                FROM
                    `scores` AS `scores`
                    %s
                WHERE
                    `scores`.`test_id`=\'%s\'  --> ALSO EDITED
                %s
                %s', $strLimitPrefix, $strExpandSelect, $strExpandFrom,
                $intTestId,
                $strOrderBy, $strLimitSuffix);
            // Perform the Query and Instantiate the Result
            $objDbResult = $objDatabase->Query($strQuery);
            return Scores::InstantiateDbResult($objDbResult);
        }
.bc
#2  |  Martin Kronstad (Mjoendalen) Norway Qcodo Core Contributor
Monday, July 3, 2006, 1:23 PM PDT

I think this is a pretty nice idea, but maybe we want to add some sort of more dynamic and flexible solution.

I would like to see the ability to set each values operator (AND or OR)

So I could add something like this:

$intTestId = array('AND' => array('OR' => 12,'OR' => 13),'AND' => 14);

This should generate:

SELECT
Bla.blabla_id
Bla.blabla
FROM tblBla bla
WHERE
( blabla_id = 12 OR blabla_id = 13)
AND blabla_id = 14

This way we could define operator to use.

Actually the first key index is not used, but should be defined as something.

$intTestId = array('NOT_IN_USE' => 12,'AND' => 13,'AND' => 14,'OR' => 15);
This would generate this:
SELECT
Bla.blabla_id
Bla.blabla
FROM tblBla bla
WHERE
blabla_id = 12
AND blabla_id = 13
AND blabla_id = 14
OR blabla_id = 15

Also I think someone was working on creating a solution where you could define what field you wanted to add also.

Anyway I think everyone wants a easy way to load dataarrays with some sort of customized sql with more than one field in the where clause.

The optimal solution would be where we could pass some sort of array with information about the data we want.

maybe something like this:

$arrWhereClause = array(
           array('clause_operator' => null,
               'fieldname' => 'test_id',
               'operator' => '=',
               'value' => 12
               ),
           array('clause_operator' => 'AND',
               'fieldname' => 'name',
               'operator' => 'LIKE',
               'value' => 'somestring'
               )
           array('clause_operator' => 'OR',
               'fieldname' => 'color',
               'operator' => 'LIKE',
               'value' => 'blue'
               )
           );

This sould generate:
SELECT
somefieldshere
FROM sometable
WHERE
test_id = 12
AND name LIKE 'somestring'
OR color LIKE 'blue'

The next step would be to group several fields to create something like this:

SELECT
somefieldshere
FROM sometable
WHERE
(
test_id = 12
AND name LIKE 'somestring'
)
OR color LIKE 'blue'

What do you think?

#3  |  Alec de Zegher (Brussels, Belgium) Belgium
Monday, July 3, 2006, 11:54 PM PDT

It's even better then mine ;-) Last exemple is best because you can easily implement search features (with operator choice)

An easy implementation could be (for your last exemple):

           [some code ]
           
           //EDITED by Alec de Zegher
           $strWhereClause = "";
           foreach($intSomeString as $SomeString)
            {
                $SomeString->Value = $objDatabase->SqlVariable($SomeString->Value);
                $strWhereClause .=" ".$SomeString->ClauseOperator." `name_of_table`.".$SomeString->FieldName.$SomeString->Operator.$SomeString->Value;

            }
            // END EDITED

            [some code]

                                %s
                WHERE
                    %s  --> ALSO EDITED
                %s
                %s', $strLimitPrefix, $strExpandSelect, $strExpandFrom,
                $strWhereClause,
                $strOrderBy, $strLimitSuffix)


                [some code]

I didn't try the code, but that should work. I don't know how I should implement a template for it. Any suggestions?

#4  |  Martin Kronstad (Mjoendalen) Norway Qcodo Core Contributor
Tuesday, July 4, 2006, 8:04 AM PDT

Yes, thats just what I was thinking about.

I'll try do do some testing with something like this tomorrow, or maybe tonight.

#5  |  Martin Kronstad (Mjoendalen) Norway Qcodo Core Contributor
Wednesday, July 5, 2006, 2:46 AM PDT

I added this feature to a subtemplate, you may download the templates here :http://www.qcodo.com/downloads/category.php/3

This will generate the LoadArrayByArray and CountByArray functions you need.

#6  |  Alec de Zegher (Brussels, Belgium) Belgium
Wednesday, July 5, 2006, 9:37 AM PDT

Thanks Martin!

It works great! (and it makes my application faster;-))

#7  |  Martin Kronstad (Mjoendalen) Norway Qcodo Core Contributor
Wednesday, July 5, 2006, 12:17 PM PDT

Glad to hear that :)

#8  |  Alec de Zegher (Brussels, Belgium) Belgium
Wednesday, July 5, 2006, 2:18 PM PDT

I just found one small improvement: You could add <%= $strEscapeIdentifierBegin %> and <%= $strEscapeIdentifierEnd %>. This because sometimes MySQL interprets the name of the field incorrectly.
Exemple: If you have a field 'group' and you don't use `` then MySQL will give an error.

line 20 of load_array_by_array.tpl:

? '<%= $strEscapeIdentifierBegin %><%= $objTable->Name %><%= $strEscapeIdentifierEnd %>.<%= $strEscapeIdentifierBegin %>' . $arrField['fieldname'] . '<%= $strEscapeIdentifierEnd %> ' . $arrField['operator'] . ' ' . $arrField['value']
: $strWhereClause . "\n" . $arrField['clause_operator'] . ' <%= $strEscapeIdentifierBegin %><%= $objTable->Name %><%= $strEscapeIdentifierEnd %>.<%= $strEscapeIdentifierBegin %>' . $arrField['fieldname'] . '<%= $strEscapeIdentifierEnd %> ' . $arrField['operator'] . ' ' . $arrField['value'];
.bc
#9  |  Martin Kronstad (Mjoendalen) Norway Qcodo Core Contributor
Thursday, July 6, 2006, 1:38 AM PDT

I did a quick update on the downloadpage with this added. I just missed it when I did the mod :)


Anyway, I could also see that someone had made the mod before, without the clause_operator. I think he actually had a better name for it too, LoadArrayByFilter. So If this gets into the core, I suggest that Mike changes the name from LoadArrayByArray to LoadArrayByFilters to avoid problems for people already using that mod.

#10  |  Alec de Zegher (Brussels, Belgium) Belgium
Wednesday, July 19, 2006, 1:06 AM PDT

Hi!

I did some changes to this mod. It was impossible to make querys like:

<? $arrWhere[] = array("fieldname"=>"score", operator=>"IS NOT NULL");
$arrWhere[] = array("clause_operator"=>"AND(");
$arrWhere[] = array("fieldname"=>"comment", operator=>"IS NULL");
$arrWhere[] = array("caluse_operator"=>"OR", "fieldname"=>"group_name", operator=>"=", "value"=>"student");
$arrWhere[] = array("clause_operator=>")"); ?>

With this code it is possible. And at least you don't neede to rewrite a whole function. (I'am to lazy for it :p)

        /**
         * Load an array of <%= $objTable->ClassName %> objects,
         * by an array of fields
         * @param integer $arrFields
         * @param string $strOrderBy
         * @param string $strLimit
         * @param array $objExpansionMap map of referenced columns to be immediately expanded via early-binding
         * @return <%= $objTable->ClassName %>[]
        */
        public static function LoadArrayByArray($arrFields, $strOrderBy = null, $strLimit = null, $objExpansionMap = null) {
            // Call to ArrayQueryHelper to Get Database Object and Get SQL Clauses
            <%= $objTable->ClassName %>::ArrayQueryHelper($strOrderBy, $strLimit, $strLimitPrefix, $strLimitSuffix, $strExpandSelect, $strExpandFrom, $objExpansionMap, $objDatabase);

            $strWhereClause = "";
            foreach ($arrFields as $arrField){
                // Properly Escape All Input Parameters using Database->SqlVariable()
                if(isset($arrField['value']))
                    $arrField['value'] = $objDatabase->SqlVariable($arrField['value'], false);
                
                // Build the whereclause
                if(isset($arrField['clause_operator']))
                {
                    $strWhereClause .= "\n" . $arrField['clause_operator'];
                }
                if(isset($arrField['fieldname']))
                {
                    $strWhereClause .= ' <%= $strEscapeIdentifierBegin %><%= $objTable->Name %><%= $strEscapeIdentifierEnd %>.<%= $strEscapeIdentifierBegin %>' . $arrField['fieldname'] . '<%= $strEscapeIdentifierEnd %>';
                }
                if(isset($arrField['operator']))
                {
                    $strWhereClause .= " ".$arrField['operator'];
                }
                if(isset($arrField['value']))
                {
                    $strWhereClause .= " ".$arrField['value'];
                }                
            }

            // Setup the SQL Query
            $strQuery = sprintf('
                SELECT
                %s
<% foreach ($objTable->ColumnArray as $objColumn) { %>
                    <%= $strEscapeIdentifierBegin %><%= $objTable->Name %><%= $strEscapeIdentifierEnd %>.<%= $strEscapeIdentifierBegin %><%= $objColumn->Name %><%= $strEscapeIdentifierEnd %> AS <%= $strEscapeIdentifierBegin %><%= $objColumn->Name %><%= $strEscapeIdentifierEnd %>,
<% } %><%--%>
                    %s
                FROM
                    <%= $strEscapeIdentifierBegin %><%= $objTable->Name %><%= $strEscapeIdentifierEnd %> AS <%= $strEscapeIdentifierBegin %><%= $objTable->Name %><%= $strEscapeIdentifierEnd %>
                    %s
                WHERE
                %s
                <%-----%>
                %s
                %s', $strLimitPrefix, $strExpandSelect, $strExpandFrom,
                $strWhereClause,
                $strOrderBy, $strLimitSuffix);

            // Perform the Query and Instantiate the Result
            $objDbResult = $objDatabase->Query($strQuery);
            return <%= $objTable->ClassName %>::InstantiateDbResult($objDbResult);
        }


        /**
         * Count <%= $objTable->ClassNamePlural %>
         * by array of fields
<% foreach ($objTable->ColumnArray as $objColumn) { %>
         * @param <%= $objColumn->VariableType %> $<%= $objColumn->VariableName %>
<% } %>
         * @return int
        */
        public static function CountByArray($arrFields) {
            // Call to ArrayQueryHelper to Get Database Object and Get SQL Clauses
            <%= $objTable->ClassName %>::QueryHelper($objDatabase);


            $strWhereClause = "";
            foreach ($arrFields as $arrField){
                // Properly Escape All Input Parameters using Database->SqlVariable()
                if(isset($arrField['value']))
                    $arrField['value'] = $objDatabase->SqlVariable($arrField['value'], false);
                
                // Build the whereclause
                if(isset($arrField['clause_operator']))
                {
                    $strWhereClause .= "\n" . $arrField['clause_operator'];
                }
                if(isset($arrField['fieldname']))
                {
                    $strWhereClause .= ' <%= $strEscapeIdentifierBegin %><%= $objTable->Name %><%= $strEscapeIdentifierEnd %>.<%= $strEscapeIdentifierBegin %>' . $arrField['fieldname'] . '<%= $strEscapeIdentifierEnd %>';
                }
                if(isset($arrField['operator']))
                {
                    $strWhereClause .= " ".$arrField['operator'];
                }
                if(isset($arrField['value']))
                {
                    $strWhereClause .= " ".$arrField['value'];
                }                
            }

            // Setup the SQL Query
            $strQuery = sprintf('
                SELECT
                    COUNT(*) AS row_count
                FROM
                    <%= $strEscapeIdentifierBegin %><%= $objTable->Name %><%= $strEscapeIdentifierEnd %>
                WHERE
%s', $strWhereClause);

            // Perform the Query and Return the Count
            $objDbResult = $objDatabase->Query($strQuery);
            $strDbRow = $objDbResult->FetchRow();
            return QType::Cast($strDbRow[0], QType::Integer);
        }
.bc


Copyright © 2005 - 2012, Quasidea Development, LLC
This open-source framework for PHP is released under the terms of The MIT License.