Codeigniter order_by with CONVERT - mysql

I have to order a selection by CONVERT(`codExtern`, SIGNED) with codeIgniter.
If I use it like this:
$this->db->order_by(" CONVERT(`codExtern`, SIGNED) ");
the codeigniter puts the SIGNED word between `-s, like:
CONVERT(codExtern, `INTEGER` )
How can I make it work?

Unfortunately you can't disable identifier protection with parameters like in the select() method. CI will call CI_DB_driver::_protect_identifiers on the input if it has a , in it.
Currently you can workaround this if you set the supposedly "private" property $_protect_identifiers to false on your $this->db before calling the order_by method so when it runs it will skip this, and then flip it back (it helps with problematic column/table names for example). This is probably not a really good idea, in future CI versions this property might became really private and your code will break.
Unfortunately the database library cannot be extended, but if you are not afraid of modifying the files under system you can create an exception in the order_by() method just like the "order by random()" got one.

Related

(Spring JPA) Method name query

First of all, sorry for my poor english.
I want to change the following query to 'findBy~' method, but i don't know how to.
#Query(value = "SELECT t FROM Table t WHERE (b.num1 <= :variable or b.num1 IS NULL) AND (b.num2 >= :variable or b.num2 IS NULL)")
Or, is it impossible to get the result by using 'findby~' method name?
I would appreciate if anyone could reply.
Spring Data JPA does have support for all the conditions in your query and nesting of conditions. I'd argue that your query name will become unnecesarelly verbose. It would end up as
Table findByNum1LessThanEqualOrNum1IsNullAndNum2GreaterThanEqualOrNum2IsNull(Integer var0, Integer var1);
This should return the appropiate query, but you'd need to send the variable twice, once for each equals.
With #Query you have the freedom to call your query as you'd like and reuse the same variable.
Now, you CAN fix the downsides of using named methods by using a default method like
default Table myQuery (Integer var) {
return findByNum1LessThanEqualOrNum1IsNullAndNum2GreaterThanEqualOrNum2IsNull(var, var);
}
So you call this instead of the actual query, but then again, it would be much cleaner to use #Query with a proper, descriptive or even self-documenting name if you don't comment your code (you should comment your code). In any case, I suggest you use method names for simple queries and use #Query for anything more complex.
Please, refer to the following links for further reading:
Spring JPA Query Creation
Spring JPA Query Keyword Repository
LeafyJava article on Query Precedence Tricks, which also provides and example of how to change your query logic in case the conditions aren't arranged as you want.
This SO question also provides a bit of insight.

Same ID which occurs multiple times with SQL-IN Operator at rails

I use the following sql statement:
Keyword.where("id IN (#{params[:keyword_ids]})").order("find_in_set(id, '#{params[:keyword_ids]}')")
The Problem at this statement is that if "keyword id" hold the same id more than ones, the call returns it only ones.
But I need the same number(not fulfilled) as well as the same order(which is fulfilled with this statement) which occurs in the array, independent if the same id occurs more than ones.
How should I change that statement to fix.
Thanks, dot
Well, that's not a bug, it's a feature ;)
My first recommendation would be to sanitize your input. Passing params[:keyword_ids] directly to the database, despite the help that the Rails framework does, is prone to lead to some kind of vulnerability sooner or later.
Secondly, the easiest solution is probably to keep the query as is, convert the results to a map and map the input params to the result.
Sth like
keywords = Keyword.where('id IN (?)', checked_keyword_ids)
keyword_map = Hash[keywords.map { |kw| [kw.id, kw] }]
checked_keyword_ids.map { |id| keyword_map[id] }

Overriding ilike method by like in grails createCriteria

In my application we have collation set for MYSQL in such a way that "like" condition is always case in-sensitive. So, we need conditionally ilike to replaced with like at run time based on config. (Because, in future database might be Oracle or some other DB.Want to handle this at application level.)
Tried one solution which does not works. I want this at application level:
grails.orm.HibernateCriteriaBuilder.metaClass.ilike={String propertyName, Object propertyValue->
println "-------------------${propertyName}, ${propertyValue}"
delegate.like(propertyName, propertyValue)
}
def criteria= MyDomain.createCriteria()
criteria.list(){
ilike('name','%dasda%')
}
So, Any other way would also be appreciated.
Thanks in Advance,
Anuj Aneja

Creating an OR statement using existing conditions hash

I am working on a problem where I need to add an OR clause to a set of existing conditions. The current conditions are built in a hash in a method and at the end, they are used in the where clause. Here is a simplified example:
...
conds.merge!({:users => {:archived => false}})
Model.where(conds)
I am trying to add an OR clause to the current set of conditions so it would be something like '(conditions) OR new_condition'. I'd like to add the OR statement without converting each addition to the conds hash into a string. That would be my last option. I was hoping someone has done something like this before (without using Arel). I seem to recall in Rails 2 there was a way to parse a conditions hash using a method from the model (something like Model.some_method(conds) would produce the where clause string. Maybe that would be a good option to just add the OR clause on to that string. Any ideas are appreciated. Thank you for your help!
I found a way to do what I needed. Instead of changing all of the conditions that I am building, I am parsing the conditions to SQL using sanitize_sql_for_conditions. This is a private method in ActiveRecord, so I had to put a method on the model to allow me to access it. Here is my model method:
def self.convert_conditions_hash_to_sql(conditions)
self.sanitize_sql_for_conditions(conditions)
end
So, once I convert my conditions to text, I can add my OR clause (along with the appropriate parentheses) to the end of the original conditions. So, it would go something like this:
Model.where('(?) OR (model.type = ? AND model.id IN(?))', Model.convert_conditions_hash_to_sql(conds), model_type, model_id_array)

RegEx to insert a string before each table in a MySQL query

I need to take a MySQL query and insert a string before each table name. The solution doesn't need to be one line but obviously it's a regex problem. It will be implemented in PHP so having programming logic is also fine.
Rationale and Background:
I'm revamping my code base to allow for table prefixes (eg: 'nx_users' instead of 'users') and I'd like to have a function that will automate that for me so I don't need to find every query and modify it manually.
Example:
SELECT * FROM users, teams WHERE users.team_id = teams.team_id ORDER BY users.last_name
Using the prefix 'nx_', it should change to
SELECT * FROM nx_users, nx_ teams WHERE nx_ users.team_id = nx_ teams.team_id ORDER BY nx_ users.last_name
Obviously it should handle other cases such as table aliases, joins, and other common MySQL commands.
Has anybody done this?
How big of a code base are we talking about here? A regular expression for something like this is seriously flirting with disaster and I think you're probably better off looking for every mysql_query or whatever in your code and making the changes yourself. It shouldn't take more than the hour you'd spend implementing your regex and fixing all the edge cases that it will undoubtedly miss.
Using a regex to rewrite code is going to be problematic.
If you need to dynamically change this string, then you need to separate out your sql logic into one place, and have a $table_prefix variable that is appropriately placed in every sql query. The variable can then be set by the calling code.
$query = "SELECT foo from " . $table_prefix . "bar WHERE 1";
If you are encapsulating this in a class, all the better.
This example does not take into consideration any escaping or security concerns.
First off, regular expressions alone are not up to the task. Consider things like:
select sender from email where subject like "from users group by email"
To really do this you need something that will parse the SQL, produce a parse tree which you can modify, and then emit the modified SQL from the modified parse tree. With that, it's doable, but not advisable (for the reasons Paolo gave).
A better approach would be to grep through your source looking for either the table names, the function you use to sent SQL, the word from, or something like it at script something to throw you into an editor at those points.