Fetch query from Magento database -- mysql_num_rows - database

What function is equal to mysql_num_rows in Magento?

For Magento, the proper equivalent is PHP's count() function.
Why?
Magento usually uses Varien_Data_Collection instances to fetch result sets containing multiple records. Varien implements the Lazy Load Pattern for these collections, that is, no result set will be fetched before you really need it.
If you take a look at the Varien_Data_Collection class, you'll see, that this class does implement PHP's Countable interface and the proper count() method for this interface:
class Varien_Data_Collection implements IteratorAggregate, Countable
{
:
public function count()
{
$this->load();
return count($this->_items);
}
:
}
If you're asking yourself now, what got lazy loading to do with counting records, then you need to know that querying a collection the usual Magento way, e.g. like this:
$collection = Mage::getModel('catalog/product')
->getCollection()
->addFieldToFilter(
'status',
Mage_Catalog_Model_Product_Status::STATUS_ENABLED
);
does not fetch the result set at all. But, how do you count records of a result set which hasn't been fetched yet? Right, you can't. And neither can mysql_num_rows. It fetches the result set first.
Now, when you call count() on the collection, e.g. by
$n = count($collection);
PHP's core count() function will detect that the passed argument $collection implements a Countable interface and has its own count() method defined, so it will call that one.
This leads to really fetching the result set* and storing it to $this->_items, which finally allows counting the records and return the number.
* In Magento you can also call foreach ($collection as $product) to really fetch the result set, but that's another story.

Related

Rails update remove number from an array attribute?

Is there a way to remove a number from an attibute array in an update? For example, if I want to update all of an alchy's booze stashes if he runs out of a particular type of booze:
Alchy has_many :stashes
Stash.available_booze_types = [] (filled with booze.ids)
Booze is also a class
#booze.id = 7
if #booze.is_all_gone
#alchy.stashes.update(available_booze_types: "remove #booze.id")
end
update: #booze.id may or may not be present in the available_booze_types array
... so if #booze.id was in any of the Alchy.stash instances (in the available_booze_types attribute array), it would be removed.
I think you can do what you want in the following way:
if #booze.is_all_gone
#alchy.stashes.each do |stash|
stash.available_booze_types.delete(#booze.id)
end
end
However, it looks to me like there are better ways to do what you are trying to do. Rails gives you something like that array by using relations. Also, the data in the array will be lost if you reset the app (if as I understand available_booze_types is an attribute which is not stored in a database). If your application is correctly set up (an stash has many boozes), an scope like the following in Stash class seems to me like the correct approach:
scope :available_boozes, -> { joins(:boozes).where("number > ?", 0) }
You can use it in the following way:
#alchy.stashes.available_boozes
which would only return the ones that are available.

How do I bulk/chunk paginate existing Seq[(String)] session value in Gatling?

I am executing a call that saves a lot of values into a Seq[(String)], it looks as follows:
.exec(session => {session.set("Ids", session("externalIds").as[Seq[String]])})
There is a reason why I have to create another session variable called Ids our of externalIds but I wont get into it now.
I than have to execute another call and paginate 10 values out of ${Ids} until I send them all.
(So in case of 100 values, I'll have to execute this call 10 times)
The JSON looks as follows:
..."Ids": [
"962950",
"962955",
"962959",
"962966",
"962971",
"962974",
"962978",
"962983",
"962988",
"962991"
],...
What I usually do when I have to iterate through one value each time is simply:
.foreach("${Ids}", "id") {
exec(getSomething)
}
But since I need to send a [...] Of 10 values each, I am not sure if it should even be in the scenario level. Help! :)
Use transform in your check to transform your Seq[String] into chunks, eg with Seq#grouped.
I couldn't figure out how to go about this within the session so I took it
outside to a function and here is the solution:
.exec(session => {session.set("idSeqList", convertFileIdSeqToFileIdSeqList(session("idsSeq").as[Seq[String]]))})
def convertFileIdSeqToFileIdSeqList(idSeq: Seq[String]): Seq[Seq[String]] = {
idSeq.grouped(10).toList
}
Note that when placing your list within a JSON body, you will need to use .jsonStringify() to format it correctly in the JSON context like so:
"ids": ${ids.jsonStringify()},

Django - would these query sets be cached?

class UnassignedThread(models.Manager):
def get_queryset(self):
return super(UnassignedThread,
self).get_queryset().filter(
_irc_name__isnull=True)
Would results = ThreadVault.unassigned_threads.all() be cached? I am not certain if _isnull=True counts as being a evaluated(since the evaluation causes the cache).
Also, if have a model called ThreadVault, and I want to look up if threads #777 and #888 exist in the database, which way is the best to utilize cache to do the look up?
ThreadVault.objects.get(thread_id="777")
ThreadVault.objects.get(thread_id="888")
or
results = ThreadVault.objects.all()
for ticket in results:
if ticket.thread_id == "777" or ticket.thread_id == "888":
do something
No, querysets are lazy until they are sliced or iterated. filter simply adds conditions to the query, but does not evaluate it.
For your second question, neither of these are great, although the first is vastly preferable to the second (which involves loading and iterating through every object in the table). Instead, you should use exists() in conjunction with an __in filter:
ThreadVault.objects.filter(thread_id__in=["777", "888"].exists()
Neither of these questions has anything to do with caching.
th_ids = ["777","888"]
ThreadVault.objects.filter(thread_id__in=th_ids).exists()
for caching your view
from django.views.decorators.cache import cache_page
#cache_page(60 * 15)
def my_view(request):

Using Active Record pattern in CakePHP, and avoiding passing arrays around

As my CakePHP 2.4 app gets bigger, I'm noticing I'm passing a lot of arrays around in the model layer. Cake has kinda led me down this path because it returns arrays, not objects, from it's find calls. But more and more, it feels like terrible practice.
For example, in my Job model, I've got a method like this:
public function durationInSeconds($job) {
return $job['Job']['estimated_hours'] * 3600; // convert to seconds
}
Where as I imagine that using active record patter, it should look more like this:
public function durationInSeconds() {
return $this->data['Job']['estimated_hours'] * 3600; // convert to seconds
}
(ie, take no parameter, and assume the current instance represents the Job you want to work with)
Is that second way better?
And if so, how do I use it when, for example, I'm looping through the results of a find('all') call? Cake returns an array - do I loop through that array and do a read for every single row? (seems a waste to re-fetch the info from the database)
Or should I implement a kind of setActiveRecord method that emulates read, like this:
function setActiveRecord($row){
$this->id = $row['Job']['id'];
$this->dtaa = $row;
}
Or is there a better way?
EDIT: The durationInSeconds method was just a simplest possible example. I know for that particular case, I could use virtual fields. But in other cases I've got methods that are somewhat complex, where virtual fields won't do.
The best solution depends on the issue you need to solve. But if you have to make a call to a function for each result row, perhaps it is necessary to redesign the query taking all the necessary data.
In this case that you have shown, you can use simply a virtual Field on Job model:
$this->virtualFields = array(
'duration_in_seconds' => 'Job.estimated_hours * 3600',
):
..and/or you can use a method like this:
public function durationInSeconds($id = null) {
if (!empty($id)) {
$this->id = $id;
}
return $this->field('estimated_hours') * 3600; // convert to seconds
}

GoogleAppEngine - query with some custom filter

I am quite new with appEnginy and objectify. However I need to fetch a single row from db to get some value from it. I tried to fetch element by ofy().load().type(Branch.class).filter("parent_branch_id", 0).first() but the result is FirstRef(null). However though when I run following loop:
for(Branch b : ofy().load().type(Branch.class).list()) {
System.out.println(b.id +". "+b.tree_label+" - parent is " +b.parent_branch_id);
};
What do I do wrong?
[edit]
Ofcourse Branch is a database entity, if it matters parent_branch_id is of type long.
If you want a Branch as the result of your request, I think you miss a .now():
Branch branch = ofy().load().type(Branch.class).filter("parent_branch_id", 0).first().now();
It sounds like you don't have an #Index annotation on your parent_branch_id property. When you do ofy().load().type(Branch.class).list(), Objectify is effectively doing a batch get by kind (like doing Query("Branch") with the low-level API) so it doesn't need the property indexes. As soon as you add a filter(), it uses a query.
Assuming you are using Objectify 4, properties are not indexed by default. You can index all the properties in your entity by adding an #Index annotation to the class. The annotation reference provides useful info.
Example from the Objectify API reference:
LoadResult<Thing> th = ofy.load().type(Thing.class).filter("foo", foo).first();
Thing th = ofy.load().type(Thing.class).filter("foo", foo).first().now();
So you need to make sure member "foo" has an #Index and use the now() to fetch the first element. This will return a null if no element is found.
May be "parent_branch_id"in your case is a long, in which case the value must be 0L and not 0.

Resources