Doctrine 2 Uppercase First Letter - mysql

I need to uppercase the first letter of word while fetching data using Select query in Doctrine2.
I tried UCASE , but it is not supported in Doctrine 2.
Is there any other way to Uppercase the first letter in Doctrine2 ?

You can achieve same effect by utilizing Lifecycle Callbacks if doing this on database level is not really required.
For example, in your entity, write a post-load method like this:
<?php
namespace MyApp\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\HasLifecycleCallbacks <-- NOTICE THIS ANNOTATION
*/
class MyEntity
{
/**
* #ORM\PostLoad <-- AND THIS
*/
public function capitalizeField()
{
$this->field = mb_ucfirst($this->field);
}
}
Update after two years:
This approach solves the problem. Anyway, in a similar situation I would prefer to change the case before writing the data into the database, if possible. I mean that lifecycle callbacks are not free. Another option is changing the case in presentation/view layer. Today, utilizing the whole event mechanism to change the case of a single value sounds overkill to me.

Do it in MySQL, e.g.
SELECT CONCAT(UPPER(LEFT(the_field, 1)),LOWER(SUBSTRING(the_field, 2))) FROM the_table
or if you don't want to alter the field excpet the first letter:
SELECT CONCAT(UPPER(LEFT(the_field, 1)),SUBSTRING(the_field, 2)) FROM the_table

Related

Laravel eloquent query table names case insensitive

Is it possible to make eloquent queries case insensitive? An issue came when I decided to move my website to production (move from my local machine to the host server). MariaDB on my host server is case sensitive and I don't have an access to its config file. The problem is that I have a Users table which is used in laravel auth. The queries of laravel in lower case like:
select * from `users` where `id` = 1 limit 1
I really need to know how to make queries case insensitive, because I have hundreds queries with Users table.
As we've been discussing in the comments, adding the protected $table = 'StRaNgE-tAbLe-NaMe'; to a MyModel.php will work on a case-by-case basis.
If you have a more structured naming convention, but it does not follow laravel's default, then you could create a trait or model base class to override Model getTable().
$model->getTable() looks like this...
/**
* Get the table associated with the model.
*
* #return string
*/
public function getTable()
{
if (! isset($this->table)) {
return str_replace(
'\\', '', Str::snake(Str::plural(class_basename($this)))
);
}
return $this->table;
}

Why does MySQL permit non-exact matches in SELECT queries?

Here's the story. I'm testing doing some security testing (using zaproxy) of a Laravel (PHP framework) application running with a MySQL database as the primary store for data.
Zaproxy is reporting a possible SQL injection for a POST request URL with the following payload:
id[]=3-2&enabled[]=on
Basically, it's an AJAX request to turn on/turn off a particular feature in a list. Zaproxy is fuzzing the request: where the id value is 3-2, there should be an integer - the id of the item to update.
The problem is that this request is working. It should fail, but the code is actually updating the item where id = 3.
I'm doing things the way I'm supposed to: the model is retrieved using Eloquent's Model::find($id) method, passing in the id value from the request (which, after a bit of investigation, was determined to be the string "3-2"). AFAIK, the Eloquent library should be executing the query by binding the ID value to a parameter.
I tried executing the query using Laravel's DB class with the following code:
$result = DB::select("SELECT * FROM table WHERE id=?;", array("3-2"));
and got the row for id = 3.
Then I tried executing the following query against my MySQL database:
SELECT * FROM table WHERE id='3-2';
and it did retrieve the row where id = 3. I also tried it with another value: "3abc". It looks like any value prefixed with a number will retrieve a row.
So ultimately, this appears to be a problem with MySQL. As far as I'm concerned, if I ask for a row where id = '3-2' and there is no row with that exact ID value, then I want it to return an empty set of results.
I have two questions:
Is there a way to change this behaviour? It appears to be at the level of the database server, so is there anything in the database server configuration to prevent this kind of thing?
This looks like a serious security issue to me. Zaproxy is able to inject some arbitrary value and make changes to my database. Admittedly, this is a fairly minor issue for my application, and the (probably) only values that would work will be values prefixed with a number, but still...
SELECT * FROM table WHERE id= ? AND ? REGEXP "^[0-9]$";
This will be faster than what I suggested in the comments above.
Edit: Ah, I see you can't change the query. Then it is confirmed, you must sanitize the inputs in code. Another very poor and dirty option, if you are in an odd situation where you can't change query but can change database, is to change the id field to [VAR]CHAR.
I believe this is due to MySQL automatically converting your strings into numbers when comparing against a numeric data type.
https://dev.mysql.com/doc/refman/5.1/en/type-conversion.html
mysql> SELECT 1 > '6x';
-> 0
mysql> SELECT 7 > '6x';
-> 1
mysql> SELECT 0 > 'x6';
-> 0
mysql> SELECT 0 = 'x6';
-> 1
You want to really just put armor around MySQL to prevent such a string from being compared. Maybe switch to a different SQL server.
Without re-writing a bunch of code then in all honesty the correct answer is
This is a non-issue
Zaproxy even states that it's possibly a SQL injection attack, meaning that it does not know! It never said "umm yeah we deleted tables by passing x-y-and-z to your query"
// if this is legal and returns results
$result = DB::select("SELECT * FROM table WHERE id=?;", array("3"));
// then why is it an issue for this
$result = DB::select("SELECT * FROM table WHERE id=?;", array("3-2"));
// to be interpreted as
$result = DB::select("SELECT * FROM table WHERE id=?;", array("3"));
You are parameterizing your queries so Zaproxy is off it's rocker.
Here's what I wound up doing:
First, I suspect that my expectations were a little unreasonable. I was expecting that if I used parameterized queries, I wouldn't need to sanitize my inputs. This is clearly not the case. While parameterized queries eliminate some of the most pernicious SQL injection attacks, this example shows that there is still a need to examine your inputs and make sure you're getting the right stuff from the user.
So, with that said... I decided to write some code to make checking ID values easier. I added the following trait to my application:
trait IDValidationTrait
{
/**
* Check the ID value to see if it's valid
*
* This is an abstract function because it will be defined differently
* for different models. Some models have IDs which are strings,
* others have integer IDs
*/
abstract public static function isValidID($id);
/**
* Check the ID value & fail (throw an exception) if it is not valid
*/
public static function validIDOrFail($id)
{
...
}
/**
* Find a model only if the ID matches EXACTLY
*/
public static function findExactID($id)
{
...
}
/**
* Find a model only if the ID matches EXACTLY or throw an exception
*/
public static function findExactIDOrFail($id)
{
...
}
}
Thus, whenever I would normally use the find() method on my model class to retrieve a model, instead I use either findExactID() or findExactIDOrFail(), depending on how I want to handle the error.
Thank you to everyone who commented - you helped me to focus my thinking and to understand better what was going on.

MySQL proxy better way to detect select query

I am using lua script
https://github.com/clofresh/mysql-proxy-cache to cache the select query.
But there is a problem with the way it is detecting select statement.
It is using following code
return query:sub(1,6):lower() == 'select'
This will not work if select query is nested in (). Example:
(SELECT * from tbl_name);
Is there a way to remove extra () in mysql proxy ?
or Is there a better way to detect select query?
I would try to write a normalizing script using the String Library that detect common patterns and replaces them with equivalent normalized sql.
One example is your parenteses but also queries where the where parts have been moved around could benefit from this.
The queries are actually inside of the the parentheses, not inside of a string? That shouldn't parse correctly, even with a plug in. If it is in a string then simply use :sub(2, 7), however, if it is not, then put it inside of a string. Create a function that basically reproduces the function, except puts it in a string, e.g.:
function mysqlQuery(mysqlString)
loadstring(mysqlString)();
return mysqlString;
end
mysqlQuery("SELECT * from tbl");

macro-like function as filter in postgresql

I have a table with some RDF statements inside, like Quads(graph, subject, verb, object) and I find myself doing queries like:
select * from quads where verb = 'rdf:type' and object = 'smtg:Type'
select * from quads where verb = 'rdf:label' and object = 'bla bla'
I would like to express this in a form like
select * from quads where type('smtg:Type')
select * from quads where label('bla bla')
While this seems a "trivial" text substitution, I have no idea of how and if this would be implementable in postgresql, though I sort of expect this to be impossible.
To the best of my knowledge I can use a function to hardcode the constants, and do
select * from quads where rdftype() = verb and object = 'smtg:Type'
or I can use a function as the from argument like
select * from typed('smtg:Type')
sadly, the former is quite verbose, and the latter does not seem to be amendable to combination e.g. I can't do an hypothetical
select * from quads where type('smtg:Type') and inGraph('mygraph')
Is there a way to do what I want? It seems impossible, but I wonder if there is a way.
EDIT: a sqlfiddle instance: http://sqlfiddle.com/#!1/40b2c/3 .
To be more clear, the reason why this seems unfeasible is that the macro-ish function would be returning a boolean (it is used in the where clause, as if it where a select $1=somevalue) but using an "implicit" row argument in which it would access multiple fields at once, and I have not seen such an example in the pg docs.
and the latter [function] does not seem to be amendable to combination e.g. I
can't do an hypothetical
As long as the return type is stable, you can do pretty much anything in a plpgsql function.
You did not disclose how to resolve type('smtg:Type') or inGraph('mygraph') - are these supposed to be functions? Returning .. what?
But for a simple case like this even a plain SQL function should do the job:
CREATE OR REPLACE FUNCTION f_foo (_type text, _graph text DEFAULT NULL)
RETURNS SETOF quads AS
$func$
SELECT *
FROM quads
WHERE CASE WHEN $1 IS NOT NULL THEN ... ELSE ... END
AND CASE WHEN $2 IS NOT NULL THEN ... ELSE ... END
ORDER BY ...;
$func$ LANGUAGE sql;
In PostgreSQL 9.2 or later you can also use parameter names instead of positional parameters ($1, $2, ..) in SQL functions.
Call:
Since I defined a DEFAULT for the second parameter, you can call this function with one or two parameters:
SELECT * FROM f_foo('smtg:Type');
Or:
SELECT * FROM f_foo('smtg:Type', 'mygraph');

SQL select everything with arbitrary IN clause

This will sound silly, but trust me it is for a good (i.e. over-engineered) cause.
Is it possible to write a SQL query using an IN clause which selects everything in that table without knowing anything about the table? Keep in mind this would mean you can't use a subquery that references the table.
In other words I would like to find a statement to replace "SOMETHING" in the following query:
SELECT * FROM table_a WHERE table_a.id IN (SOMETHING)
so that the results are identical to:
SELECT * FROM table_a
by doing nothing beyond changing the value of "SOMETHING"
To satisfy the curious I'll share the reason for the question.
1) I have a FactoryObject abstract class which grants all models that extend it some glorious factory method magic using two template methods: getData() and load()
2) Models must implement the template methods. getData is a static method that accepts ID constraints, pulls rows from the database, and returns a set of associative arrays. load is not static, accepts an associative array, and populates the object based on that array.
3) The non-abstract part of FactoryObject implements a getObject() and a getObjects() method. These call getData, create objects, and loads() the array responses from getData to create and return populated objects.
getObjects() requires ID constraints as an input, either in the form of a list or in the form of a subquery, which are then passed to getData(). I wanted to make it possible to pass in no ID constraints to get all objects.
The problem is that only the models know about their tables. getObjects() is implemented at a higher level and so it doesn't know what to pass getData(), unless there was a universal "return everything" clause for IN.
There are other solutions. I can modify the API to require getData to accept a special parameter and return everything, or I can implement a static getAll[ModelName]s() method at the model level which calls:
static function getAllModelObjects() {
return getObjects("select [model].id from [model]");
}
This is reasonable and may fit the architecture anyway, but I was curious so I thought I would ask!
Works on SQL Server:
SELECT * FROM table_a WHERE table_a.id IN (table_a.id)
Okay, I hate saying no so I had to come up with another solution for you.
Since mysql is opensource you can get the source and incorporate a new feature that understands the infinity symbol. Then you just need to get the mysql community to buy into the usefulness of this feature (steer the conversation away from security as much as possible in your attempts to do so), and then get your company to upgrade their dbms to the new version once this feature has been implemented.
Problem solved.
The answer is simple. The workaround is to add some criteria like these:
# to query on a number column
AND (-1 in (-1) OR sample_table.sample_column in (-1))
# or to query on a string column
AND ('%' in ('%') OR sample_table.sample_column in ('%'))
Therefore, in your example, two following queries should return the same result as soon as you pass -1 as the parameter value.
SELECT * FROM table_a;
SELECT * FROM table_a WHERE (-1 in (-1) OR table_a.id in (-1));
And whenever you want to filter something out, you can pass it as a parameter. For example, in the following query, the records with id of 1, 2 and 6 are filtered.
SELECT * FROM table_a WHERE (-1 in (1, 2, 6) OR table_a.id in (1, 2, 6));
In this case, we have a default value like -1 or % and we have a parameter that can be anything. If the parameter is the default value, nothing is filtered.
I suggest % character as the default value if you are querying over a text column or -1 if you are querying over the PK of the table. But it totally depends to you to substitute % or -1 with any reserved character or number that you decide on.
similiar to #brandonmoore:
select * from table_a where table_a.id not in ('0')
How about:
select * from table_a where table_a.id not ine ('somevaluethatwouldneverpossiblyexistintable_a.id')
EDIT:
As much as I would like to continue thinking of a way to solve your problem, I know there isn't a way to so I figure I'll go ahead and be the first person to tell you so I can at least get credit for the answer. It's truly a bittersweet victory though :/
If you provide more info though maybe I or someone else can help you think of another workaround.