Using SQL functions with doctrine and TYPO3 - doctrine

I am migrating an old TYPO3-extension to the current build and am trying to change my database access to using doctrine. For the most part that worked great, but now I came upon a few select queries, that make use of SQL-functions e.g. "Year(FROM_UNIXTIME())".
I tried using the sql function as is in the following form:
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('mytable');
$queryBuilder
->select('i.*','c.title AS cat_title','c.uid AS cat_uid')
->from('mytable','i')
->join('c'
...
)
->join('d'
...
)
->where(
$queryBuilder->expr()->eq('Year(FROM_UNIXTIME(i.datetime))', $queryBuilder->createNamedParameter($year, \PDO::PARAM_STR))
)
The problem is only with the where part, if i get a read-out on the SQL statement the where clause is simply omitted, as if the line of code never happened.
I then proceeded to make debug statements around the where statement and encapsulate it in a try catch block with a log attached to it:
It executes fine, without error, but does nothing.
After google, I now believe, that i would need to implement that function again using the DQL user functions, but the documentation on the typo3 site offers no mention of this and so i am a little unsure as to how to proceed.
Can someone point me in the right direction?
Any help would be much appreciated
Regards
Theo

I defaulted to using php to parse the years to full dates and convert them to unix timestamps. The option of using the ORM was there, but simply too much to handle.
I implemented it as follows:
// to convert towards db:
$queryBuilder->createNamedParameter(mktime(0,0,0,1,1, (int)$year), \PDO::PARAM_INT)
// and back:
$queryBuilder->select('i.datetime AS yearb')
// ... the rest of the query seems of litle interest
;
$current = date("Y",$queryBuilder->execute()->fetch()['yearb']);

You can use plain SQL:
$queryBuilder
->select('i.*','c.title AS cat_title','c.uid AS cat_uid')
->from('mytable','i')
->join('c'
...
)
->join('d'
...
)
->where(
'Year(FROM_UNIXTIME(i.datetime)) = '.$queryBuilder->createNamedParameter($year, \PDO::PARAM_STR)
)

Related

How to do string functions on a db table column?

I am trying to do string replace on entries of a column inside a db table. So far, I have reached till here:
$misa = DB::table('mis')->pluck('name');
for($i=0;;$i++)
{
$misa[$i] = substr_replace("$misa[$i]","",-3);
}
The error I am getting is "Undefined offset:443".
P.S. I am not a full-fledged programmer. Only trying to develop a few simple programs for my business. Thank You.
Since it's a collection, use the transform() collection method transform it and avoid this kind of errors. Also, you can just use str_before() method to transform each string:
$misa = DB::table('mis')->pluck('name');
$misa->transform(function($i) {
return str_before($i, ':ut');
});
There are a few ways to make this query prettier and FASTER! The beauty of Laravel is that we have the use of both Eloquent for pretty queries and then Collections to manage the data in a user friendly way. So, first lets clean up the query. You can instead use a DB::Raw select and do all of the string replacing in the query itself like so:
$misa = DB::table('mis')->select(DB::raw("REPLACE(name, ':ut' , '') as name"));
Now, we have a collection containing only the name column, and you've removed ':ut' in your specific case and simply replaced it with an empty string all within the MySQL query itself.
Surprise! That's it. No further php manipulation is required making this process much faster (will be noticeable in large data sets - trust me).
Cheers!

Paginate causes crashing in Laravel 4

I am learning about Laravel 4 and I'm trying its pagination. I created a simple query to test the pagination, yet it always end up hanging. If I use get(), it works fine, but when I replace get() with paginate(), it hangs. Here is my code:
DB::table("samp_tbl")
->select("id","activity")
->whereNull("deleted_at")
->orderBy("id","desc")
->paginate(5);
Could someone tell me what's wrong with my code?
In case anyone else comes across this issue it's because you are using orderBy. In the Note: area on this page http://laravel.com/docs/4.2/pagination#usage it explains that laravel has issues with groupBy. However I also would assume this would go for orderBy as well. Writing a custom query would be recommended in your case.
create a model for your database and it will work fine

CSV insert to database

This is not working as we discussed previously, for some reason and I have done is create some $vars for the uploaded file.
Code available here (Pastebin).
But never actually inserts anything
When doing a var_dump($csv_row) i get: bool(false)
var_dump($fh) shows: resource(89) of type (stream)
var_dump($insert_str) shows all 1700 records from the csv file (obviously too big to post on here)
So I’m guessing the while statement or the whole from if statement is wrong somewhere. Really really would appreciate some help on this, I need to get it working by tomorrow (monday)
You seem to be using the codeigniter database library wrong. I can see a
$this->db->set($insert_str);
but no $this->db->insert() to be found. The set() method only useful with an update() or insert() following it, See the docs, search for $this->db->set().
You either want to use the $this->db->insert_batch() (on the same doc page, unfortunately no direct links for sections) form and build up an array of arrays with your records (so you won't have to create a long sql string either).
Or you can use the $this->db->query() and just feed the $insert_str to it where you now call $this->db->set().
According to your question:
var_dump($insert_str) shows all 1700 records from the csv file
So i would rule out the possibility of the while loop or the if not working.
Put this code at the top of the controller or before reading csv file
ini_set('auto_detect_line_endings', true);
Check if this will work for you

Getting a count of results with join, in active record

Conider this simple query:
$this->db->join('bids','bids.bid_for = request_quote.quoteid','left');
Is there any way possible to alter it, so instead of joining the result, it would instead join the COUNT of all bids it find?
I could rewrite this in plain SQL, but it is a part of bigger query, which I dont want to rewrite in SQL
Tough one. I've looked at the CI's source code, and I don't see a "hack" for that.
Perhaps you could use this CI's method:
$this->db->count_all_results();
Ok after messing around for couple hours I got it to work, so ill share it just in case anyone need it again:
public function getAllJobsByUserId($userid){
$this->db->select('quoteid')->select('quoteby')->select('country_from')
->select('country_to')->select('city_from')->select('city_to')
->select('countries.country_name, countries_to.country_name AS country_name_to')
->select('COUNT(\'bids.bid_id\') as bid_count');
$this->db->from('request_quote');
$this->db->where('quoteby',$userid);
$this->db->join('countries','countries.country_id = request_quote.country_from');
$this->db->join('countries as countries_to','countries_to.country_id = request_quote.country_to');
$this->db->join('bids as bid_count','bid_count.bid_for = request_quote.quoteid','outter');
$query=$this->db->get();
return $query->result();
}
This seem to work. But still in future ill probably write more complex queries in straight up SQL :)

OrderBy("it." + sort) -- Hard coding in LINQ to Entity framework?

I have been trying to use dynamic LINQ to Entity in my application for specifying the OrderBy attribute at runtime. However when using the code as described in the majority of documentation:
var query = context.Customer.OrderBy("Name");
I received the following exception:
System.Data.EntitySqlException: 'Name' could not be resolved in the current scope or context. Make sure that all referenced variables are in scope, that required schemas are loaded, and that namespaces are referenced correctly.
After much searching I found this MSDN page:
http://msdn.microsoft.com/en-us/library/bb358828.aspx
Which included the following code example:
ObjectQuery<Product> productQuery2 = productQuery1.OrderBy("it.ProductID");
This prompted me to change my code to the following:
var query = context.Customer.OrderBy("it.Name");
After this the code works perfectly. Would anyone be able to confirm that this is indeed the correct way to get OrderBy working with LINQ to Entity? I can’t believe that the framework would have been implemented in this way, perhaps I have overlooked something?
Thanks, Matt
The it.Name syntax is ESQL and is indeed specific to the EF. There are good reasons to use this sometimes (e.g., collation specifiers), but it's not what I normally do.
Usually I use standard LINQ expressions:
var query = context.Customer.OrderBy(p => p.Name);
You can also use System.Linq.Dynamic, if you download it from Code Gallery, and then your original query:
var query = context.Customer.OrderBy("Name");
...will work.
No nice way, so far
My answer to this question was to create a stored procedure which has parameter to control sorting.

Resources