From 8c209a7a61b1988ca4a827bdf25ef29c4b15c60f Mon Sep 17 00:00:00 2001 From: Taylor Otwell Date: Sat, 17 Mar 2012 15:42:01 -0500 Subject: [PATCH] Just cleaning up some code. Signed-off-by: Taylor Otwell --- laravel/database/query.php | 59 +++++++------- laravel/database/query/grammars/grammar.php | 81 ++++++++----------- laravel/database/query/grammars/sqlserver.php | 42 ++++------ 3 files changed, 80 insertions(+), 102 deletions(-) diff --git a/laravel/database/query.php b/laravel/database/query.php index ae8581d9..e19708ae 100644 --- a/laravel/database/query.php +++ b/laravel/database/query.php @@ -237,7 +237,7 @@ public function raw_or_where($where, $bindings = array()) */ public function where($column, $operator = null, $value = null, $connector = 'AND') { - // If a CLosure is passed into the method, it means a nested where + // If a Closure is passed into the method, it means a nested where // clause is being initiated, so we will take a different course // of action than when the statement is just a simple where. if ($column instanceof Closure) @@ -397,16 +397,16 @@ public function where_nested($callback, $connector = 'AND') { $type = 'where_nested'; - // To handle a nested where statement, we will actually instantiate a - // new Query instance and run the callback over that instance, which - // will allow the developer to have a fresh query. + // To handle a nested where statement, we will actually instantiate a new + // Query instance and run the callback over that instance, which will + // allow the developer to have a fresh query instance $query = new Query($this->connection, $this->grammar, $this->from); call_user_func($callback, $query); - // Once the callback has been run on the query, we will store the - // nested query instance on the where clause array so that it's - // passed to the query's query grammar instance. + // Once the callback has been run on the query, we will store the nested + // query instance on the where clause array so that it's passed to the + // query's query grammar instance when building. $this->wheres[] = compact('type', 'query', 'connector'); $this->bindings = array_merge($this->bindings, $query->bindings); @@ -429,32 +429,31 @@ private function dynamic_where($method, $parameters) $segments = preg_split('/(_and_|_or_)/i', $finder, -1, $flags); - // The connector variable will determine which connector will be - // used for the condition. We'll change it as we come across new + // The connector variable will determine which connector will be used + // for the condition. We'll change it as we come across new boolean // connectors in the dynamic method string. // - // The index variable helps us get the correct parameter value - // for the where condition. We increment it each time we add - // a condition to the query's where. + // The index variable helps us get the correct parameter value for + // the where condition. We increment it each time we add another + // condition to the query's where clause. $connector = 'AND'; $index = 0; foreach ($segments as $segment) { - // If the segment is not a boolean connector, we can assume it - // it is a column name, and we'll add it to the query as a new - // where clause. - // - // Otherwise, we'll store the connector so that we know how to - // connection the next where clause we find to the query, as - // all connectors should precede a new where clause. + // If the segment is not a boolean connector, we can assume it it is + // a column name, and we'll add it to the query as a new constraint + // of the query's where clause and keep iterating the segments. if ($segment != '_and_' and $segment != '_or_') { $this->where($segment, '=', $parameters[$index], $connector); $index++; } + // Otherwise, we will store the connector so we know how the next + // where clause we find in the query should be connected to the + // previous one and will add it when we find the next one. else { $connector = trim(strtoupper($segment), '_'); @@ -777,9 +776,9 @@ protected function adjust($column, $amount, $operator) { $wrapped = $this->grammar->wrap($column); - // To make the adjustment to the column, we'll wrap the expression in - // an Expression instance, which forces the adjustment to be injected - // into the query as a string instead of bound. + // To make the adjustment to the column, we'll wrap the expression in an + // Expression instance, which forces the adjustment to be injected into + // the query as a string instead of bound. $value = Database::raw($wrapped.$operator.$amount); return $this->update(array($column => $value)); @@ -793,10 +792,9 @@ protected function adjust($column, $amount, $operator) */ public function update($values) { - // For update statements, we need to merge the bindings such that - // the update values occur before the where bindings in the array - // since the set statements will precede any of the where clauses - // in the SQL syntax that is generated. + // For update statements, we need to merge the bindings such that the update + // values occur before the where bindings in the array since the sets will + // precede any of the where clauses in the SQL syntax that is generated. $bindings = array_merge(array_values($values), $this->bindings); $sql = $this->grammar->update($this, $values); @@ -814,9 +812,9 @@ public function update($values) */ public function delete($id = null) { - // If an ID is given to the method, we'll set the where clause - // to match on the value of the ID. This allows the developer - // to quickly delete a row by its primary key value. + // If an ID is given to the method, we'll set the where clause to + // match on the value of the ID. This allows the developer to + // quickly delete a row by its primary key value. if ( ! is_null($id)) { $this->where('id', '=', $id); @@ -839,6 +837,9 @@ public function __call($method, $parameters) return $this->dynamic_where($method, $parameters, $this); } + // All of the aggregate methods are handled by a single method, so we'll + // catch them all here and then pass them off to the agregate method + // instead of creating methods for each one of them. if (in_array($method, array('count', 'min', 'max', 'avg', 'sum'))) { if (count($parameters) == 0) $parameters[0] = '*'; diff --git a/laravel/database/query/grammars/grammar.php b/laravel/database/query/grammars/grammar.php index d21fe435..b0c06824 100644 --- a/laravel/database/query/grammars/grammar.php +++ b/laravel/database/query/grammars/grammar.php @@ -37,10 +37,6 @@ final protected function components($query) // Each portion of the statement is compiled by a function corresponding // to an item in the components array. This lets us to keep the creation // of the query very granular and very flexible. - // - // Note that each component also connects to a public property on the - // query instance, allowing us to pass the correct data into each - // of the compiler functions. foreach ($this->components as $component) { if ( ! is_null($query->$component)) @@ -91,7 +87,13 @@ protected function aggregate(Query $query) { $column = $this->columnize($query->aggregate['columns']); - if ($query->distinct and $column !== '*') $column = 'DISTINCT '.$column; + // If the "distinct" flag is set and we're not aggregating everything + // we'll set the distinct clause on the query, since this is used + // to count all of the distinct values in a column, etc. + if ($query->distinct and $column !== '*') + { + $column = 'DISTINCT '.$column; + } return 'SELECT '.$query->aggregate['aggregator'].'('.$column.') AS '.$this->wrap('aggregate'); } @@ -118,19 +120,15 @@ protected function joins(Query $query) // We need to iterate through each JOIN clause that is attached to the // query an translate it into SQL. The table and the columns will be // wrapped in identifiers to avoid naming collisions. - // - // Once all of the JOINs have been compiled, we can concatenate them - // together using a single space, which should give us the complete - // set of joins in valid SQL that can appended to the query. foreach ($query->joins as $join) { $table = $this->wrap_table($join->table); $clauses = array(); - // Each JOIN statement may have multiple clauses, so we will - // iterate through each clause creating the conditions then - // we will concatenate them all together. + // Each JOIN statement may have multiple clauses, so we will iterate + // through each clause creating the conditions then we'll join all + // of the together at the end to build the clause. foreach ($join->clauses as $clause) { extract($clause); @@ -142,10 +140,9 @@ protected function joins(Query $query) $clauses[] = "{$connector} {$column1} {$operator} {$column2}"; } - // The first clause will have a connector on the front, - // but it is not needed on the first condition, so we - // will strip it off of the condition before adding - // it to the array of joins. + // The first clause will have a connector on the front, but it is + // not needed on the first condition, so we will strip it off of + // the condition before adding it to the arrya of joins. $search = array('AND ', 'OR '); $clauses[0] = str_replace($search, '', $clauses[0]); @@ -155,9 +152,9 @@ protected function joins(Query $query) $sql[] = "{$join->type} JOIN {$table} ON {$clauses}"; } - // Finally, we should have an array of JOIN clauses - // that we can implode together and return as the - // complete SQL for the JOIN of the query. + // Finally, we should have an array of JOIN clauses that we can + // implode together and return as the complete SQL for the + // join clause of the query under construction. return implode(' ', $sql); } @@ -173,11 +170,7 @@ final protected function wheres(Query $query) // Each WHERE clause array has a "type" that is assigned by the query // builder, and each type has its own compiler function. We will call - // the appropriate compiler for each where clause in the query. - // - // Keeping each particular where clause in its own "compiler" allows - // us to keep the query generation process very granular, making it - // easier to customize derived grammars for other databases. + // the appropriate compiler for each where clause. foreach ($query->wheres as $where) { $sql[] = $where['connector'].' '.$this->{$where['type']}($where); @@ -187,7 +180,7 @@ final protected function wheres(Query $query) { // We attach the boolean connector to every where segment just // for convenience. Once we have built the entire clause we'll - // remove the first instance of a connector from the clause. + // remove the first instance of a connector. return 'WHERE '.preg_replace('/AND |OR /', '', implode(' ', $sql), 1); } } @@ -296,9 +289,7 @@ protected function orderings(Query $query) { foreach ($query->orderings as $ordering) { - $direction = strtoupper($ordering['direction']); - - $sql[] = $this->wrap($ordering['column']).' '.$direction; + $sql[] = $this->wrap($ordering['column']).' '.strtoupper($ordering['direction']); } return 'ORDER BY '.implode(', ', $sql); @@ -341,12 +332,12 @@ public function insert(Query $query, $values) // Force every insert to be treated like a batch insert. This simply makes // creating the SQL syntax a little easier on us since we can always treat - // the values as if it is an array containing multiple inserts. + // the values as if it contains multiple inserts. if ( ! is_array(reset($values))) $values = array($values); // Since we only care about the column names, we can pass any of the insert // arrays into the "columnize" method. The columns should be the same for - // every insert to the table so we can just use the first record. + // every record inserted into the table. $columns = $this->columnize(array_keys(reset($values))); // Build the list of parameter place-holders of values bound to the query. @@ -370,10 +361,9 @@ public function update(Query $query, $values) { $table = $this->wrap_table($query->from); - // Each column in the UPDATE statement needs to be wrapped in keyword - // identifiers, and a place-holder needs to be created for each value - // in the array of bindings. Of course, if the value of the binding - // is an expression, the expression string will be injected. + // Each column in the UPDATE statement needs to be wrapped in the keyword + // identifiers, and a place-holder needs to be created for each value in + // the array of bindings, so we'll build the sets first. foreach ($values as $column => $value) { $columns[] = $this->wrap($column).' = '.$this->parameter($value); @@ -381,10 +371,9 @@ public function update(Query $query, $values) $columns = implode(', ', $columns); - // UPDATE statements may be constrained by a WHERE clause, so we'll - // run the entire where compilation process for those contraints. - // This is easily achieved by passing the query to the "wheres" - // method which will call all of the where compilers. + // UPDATE statements may be constrained by a WHERE clause, so we'll run + // the entire where compilation process for those contraints. This is + // easily achieved by passing it to the "wheres" method. return trim("UPDATE {$table} SET {$columns} ".$this->wheres($query)); } @@ -398,9 +387,6 @@ public function delete(Query $query) { $table = $this->wrap_table($query->from); - // Like the UPDATE statement, the DELETE statement is constrained - // by WHERE clauses, so we'll need to run the "wheres" method to - // make the WHERE clauses for the query. return trim("DELETE FROM {$table} ".$this->wheres($query)); } @@ -413,17 +399,16 @@ public function delete(Query $query) */ public function shortcut($sql, $bindings) { - // Laravel provides an easy short-cut notation for writing raw - // WHERE IN statements. If (...) is in the query, it will be - // replaced with the correct number of parameters based on - // the bindings for the query. + // Laravel provides an easy short-cut notation for writing raw WHERE IN + // statements. If (...) is in the query, it will be replaced with the + // correct number of parameters based on the bindings. if (strpos($sql, '(...)') !== false) { for ($i = 0; $i < count($bindings); $i++) { - // If the binding is an array, we can just assume it's - // used to fill a "where in" condition, so we'll just - // replace the next place-holder in the query. + // If the binding is an array, we can just assume it's used to + // fill a "where in" condition, so we will just replace the + // next place-holder in the query with the constraint. if (is_array($bindings[$i])) { $parameters = $this->parameterize($bindings[$i]); diff --git a/laravel/database/query/grammars/sqlserver.php b/laravel/database/query/grammars/sqlserver.php index 6b3c8127..8edb30c0 100644 --- a/laravel/database/query/grammars/sqlserver.php +++ b/laravel/database/query/grammars/sqlserver.php @@ -23,8 +23,7 @@ public function select(Query $query) // SQL Server does not currently implement an "OFFSET" type keyword, so we // actually have to generate the ANSI standard SQL for doing offset like - // functionality. In the next version of SQL Server, an OFFSET like - // keyword is included for convenience. + // functionality. OFFSET is in SQL Server 2012, however. if ($query->offset > 0) { return $this->ansi_offset($query, $sql); @@ -32,7 +31,7 @@ public function select(Query $query) // Once all of the clauses have been compiled, we can join them all as // one statement. Any segments that are null or an empty string will - // be removed from the array of clauses before they are imploded. + // be removed from the array before imploding. return $this->concatenate($sql); } @@ -48,13 +47,9 @@ protected function selects(Query $query) $select = ($query->distinct) ? 'SELECT DISTINCT ' : 'SELECT '; - // Instead of using a "LIMIT" keyword, SQL Server uses the "TOP" - // keyword within the SELECT statement. So, if we have a limit, - // we will add it here. - // - // We will not add the TOP clause if there is an offset however, - // since we will have to handle offsets using the ANSI syntax - // and will need to remove the TOP clause in that situation. + // Instead of using a "LIMIT" keyword, SQL Server uses the TOP keyword + // within the SELECT statement. So, if we have a limit, we will add + // it to the query here if there is not an OFFSET present. if ($query->limit > 0 and $query->offset <= 0) { $select .= 'TOP '.$query->limit.' '; @@ -72,18 +67,17 @@ protected function selects(Query $query) */ protected function ansi_offset(Query $query, $components) { - // An ORDER BY clause is required to make this offset query - // work, so if one doesn't exist, we'll just create a dummy - // clause to satisfy the database. + // An ORDER BY clause is required to make this offset query work, so if + // one doesn't exist, we'll just create a dummy clause to trick the + // database and pacify it so it doesn't complain about the query. if ( ! isset($components['orderings'])) { $components['orderings'] = 'ORDER BY (SELECT 0)'; } - // We need to add the row number to the query results so we - // can compare it against the offset and limit values given - // for the statement. To do that we'll add an expression to - // the select statement for the row number. + // We need to add the row number to the query so we can compare it to + // the offset and limit values given for the statement. So we'll add + // an expression to the select for the row number. $orderings = $components['orderings']; $components['selects'] .= ", ROW_NUMBER() OVER ({$orderings}) AS RowNum"; @@ -92,10 +86,9 @@ protected function ansi_offset(Query $query, $components) $start = $query->offset + 1; - // Next we need to calculate the constraint that should be - // placed on the row number to get the correct offset and - // limit on the query. If a limit has not been set, we'll - // only add a constraint to handle offset. + // Next we need to calculate the constraint that should be placed on + // the row number to get the correct offset and limit on the query. + // If there is not limit, we'll just handle the offset. if ($query->limit > 0) { $finish = $query->offset + $query->limit; @@ -107,10 +100,9 @@ protected function ansi_offset(Query $query, $components) $constraint = ">= {$start}"; } - // Now, we're finally ready to build the final SQL query. - // We'll create a common table expression with the query - // and then select all of the results from it where the - // row number is between oru given limit and offset. + // We're finally ready to build the final SQL query so we'll create + // a common table expression with the query and select all of the + // results with row numbers between the limit and offset. $sql = $this->concatenate($components); return "SELECT * FROM ($sql) AS TempTable WHERE RowNum {$constraint}";