Contao CMS Query a 'checkboxWizard' BLOB field - mysql

I have a question about how to query a 'checkboxWizard' BLOB field. In have added a such field to tl_member. This is working very fine. I can add “0 to N” selection to each members. Let’s call this field “myBlob”.
Now the questions is how to query “myBlob” with the Contao way? Let’s say I want all member that are in the postal code “12120” and that have the id “2” of “myBlob” selected. Not only “2” but at least this one.
$arrColumn[] = "tl_member.postal=?";
$arrValues[] = 12120;
$arrColumn[] = "tl_member.myBlob=?"; <- how to say “contains in the blob” here?
$arrValues[] = 2;
self::findBy($arrColumn, $arrValues)

The only way to do this (when using the default Contao method for such relationships) is to create a query like:
… WHERE myBlob LIKE '%"2"%'
So in your case it might be:
$arrColumn[] = "tl_member.myBlob LIKE ?";
$arrValues[] = '%"2"%';
However, this is of course cumbersome and might not work in all cases.
May be a better way would be to use codefog/contao-haste with its 'many to many' helper: https://github.com/codefog/contao-haste/blob/master/docs/Model/index.md
This way you will have a separate table containing the references.

Related

Rails, MySql, JSON column which stores array of UUIDs - Need to do exact match

I have a model called lists, which has a column called item_ids. item_ids is a JSON column (MySQL) and the column contains array of UUIDs, each referring to one item.
Now when someone creates a new list, I need to search whether there is an existing list with same set of UUIDs, and I want to do this search using query itself for faster response. Also use ActiveRecord querying as much as possible.
How do i achieve this?
item_ids = ["11E85378-CFE8-39F8-89DC-7086913CFD4B", "11E85354-304C-0664-9E81-0A281BE2CA42"]
v = List.new(item_ids: item_ids)
v.save!
Now, how do I check whether a list exists which has item ids exactly matches with that mentioned in query ? Following wont work.
list_count = List.where(item_ids: item_ids).count
Edit 1
List.where("JSON_CONTAINS(item_ids, ?) ", item_ids.to_json).count
This statement works, but it counts even if only one of the item matches. Looking for exact number of items.
Edit 2
List.where("JSON_CONTAINS( item_ids, ?) and JSON_LENGTH(item_ids) = ?", item_ids.to_json, item_ids.size).count
Looks like this is working
You can implement a has many relation between lists and items and then access like this.
List.includes(:item).where('items.id in (?)',item_ids)
To implement has_many relation:
http://guides.rubyonrails.org/association_basics.html#the-has-many-through-association

correctly fetch nested list in SQL

I have a design problem with SQL request:
I need to return data looking like:
listChannels:
-idChannel
name
listItems:
-data
-data
-idChannel
name
listItems:
-data
-data
The solution I have now is to send a first request:
*"SELECT * FROM Channel WHERE idUser = ..."*
and then in the loop fetching the result, I send for each raw another request to feel the nested list:
"SELECT data FROM Item WHERE idChannel = ..."
It's going to kill the app and obviously not the way to go.
I know how to use the join keyword, but it's not exactly what I want as it would return a row for each data of each listChannels with all the information of the channels.
How to solve this common problem in a clean and efficient way ?
The "SQL" way of doing this produces of table with columns idchannel, channelname, and the columns for item.
select c.idchannel, c.channelname, i.data
from channel c join
item i
on c.idchannel = i.idchannel
order by c.idchannel, i.item;
Remember that a SQL query returns a result set in the form of a table. That means that all the rows have the same columns. If you want a list of columns, then you can do an aggregation and put the items in a list:
select c.idchannel, c.channelname, group_concat(i.data) as items
from channel c join
item i
on c.idchannel = i.idchannel
group by c.idchannel, c.channelname;
The above uses MySQL syntax, but most databases support similar functionality.
SQL is made for accessing two-dimensional data tables. (There are more possibilities, but they are very complex and maybe not standardized)
So the best way to solve your problem is to use multiple requests. Please also consider using transactions, if possible.

cakephp retrive data from one table excluding the associated tables

I am struggling with a basic problem. i am using cake php 2.5. i try to apply the find query in the company model and receiving all the data from companies and with its associations, but i only want to receive the data from company table and want to exclude the data from rest of relationships, can anyone help me with this. below are my queries.
$this->loadModel('Company');
$fields=array('id','name','logo','status');
$conditions=array('status'=>1);
$search_companies = $this->Company->find('first',
compact(array('conditions'=>$conditions,'fields'=>$fields)));
print_r($search_companies);die();
echo json_encode($search_companies);die();
With out seeing your data output, I am just going to take a stab at the problem.
Inside your $search_companies variable you are getting a multidimensional array probably with the other values of the other tables.
Why not just select the one array:
$wantedData = $search_companies['Company'];
// The key Company (which is the model) should be the data you are wanting.
Try setting model's recursive value to -1
$this->Company->recursive = -1;
$search_companies = $this->Company->find('first',
compact(array('conditions'=>$conditions,'fields'=>$fields)));
With this you will not fire the joins queries and therefore you only retrieve model's information.
Cakephp provide this functionality that we can unblind few/all associations on a any model. the keyword unbindModel is used for this purpose. inside the unblindModel you can define the association type and model(s) name that you want to unblind for that specific association.
$this->CurrentModelName->unbindModel(array('AssociationName' => array('ModelName_Youwwant_unblind')));

magento table "sales_flat_order" field "protect_code" explanation

We are working on magento database and tables. Magento seems to write a code in table sales_flat_order field protect_code to define if there is a invoice or a shipment done already. It would look something like
01b335 or
a0a243
But there is no key to understand what this protection code means. Is there an explanation of the meaning of these codes and how they are generated?
Where is it generated?
If you look in app/code/core/Mage/Sales/Model/Order.php on around line 2052, you will find the following:
$this->setData('protect_code', substr(md5(uniqid(mt_rand(), true) . ':' . microtime(true)), 5, 6));
This is where protect_code is generated for the order (using a combination of md5, uniqid, and random integer.
What is it used for?
If you look in app/code/core/Mage/Sales/Helper/Guest.php and find the loadValidOrder function. You will see protect_code used in some areas to ensure the order being loaded is the correct one for the guest's cookie value.
It's also used in other areas, such as tracking information comparisons. You can see several instances of the getProtectCode() method being called in the Shipment models to compare the order to the tracking information. An example of a function that uses it is:
public function getTrackingInfoByTrackId()
{
$track = Mage::getModel('sales/order_shipment_track')->load($this->getTrackId());
if ($track->getId() && $this->getProtectCode() == $track->getProtectCode()) {
$this->_trackingInfo = array(array($track->getNumberDetail()));
}
return $this->_trackingInfo;
}
As you can see with $this->getProtectCode() == $track->getProtectCode(), the tracking protect_code must match the Shipment protect_code.

Can I create sperate queries for different views?

I'm learning sqlalchemy and not sure if I grasp it fully yet(I'm more used to writing queries by hand but I like the idea of abstracting the queries and getting objects). I'm going through the tutorial and trying to apply it to my code and ran into this part when defining a model:
def __repr__(self):
return "<User('%s','%s', '%s')>" % (self.name, self.fullname, self.password)
Its useful because I can just search for a username and get only the info about the user that I want but is there a way to either have multiple of these type of views that I can call? or am I using it wrong and should be writing a specific query for getting different data for different views?
Some context to why I'm asking my site has different templates, and most pages will just need the usersname, first/last name but some pages will require things like twitter or Facebook urls(also fields in the model).
First of all, __repr__ is not a view, so if you have a simple model User with defined columns, and you query for a User, all the columns will get loaded from the database, and not only those used in __repr__.
Lets take model Book (from the example refered to later) as a basis:
class Book(Base):
book_id = Column(Integer, primary_key=True)
title = Column(String(200), nullable=False)
summary = Column(String(2000))
excerpt = Column(Text)
photo = Column(Binary)
The first option to skip loading some columns is to use Deferred Column Loading:
class Book(Base):
# ...
excerpt = deferred(Column(Text))
photo = deferred(Column(Binary))
In this case when you execute query session.query(Book).get(1), the photo and excerpt columns will not be loaded until accessed from the code, at which point another query against the database will be executed to load the missing data.
But if you know before you query for the Book that you need the column photo immediately, you can still override the deferred behavior with undefer option: query = session.query(Book).options(undefer('photo')).get(1).
Basically, the suggestion here is to defer all the columns (in your case: except username, password etc) and in each use case (view) override with undefer those you know you need for that particular view. Please also see the group parameter of deferred, so that you can group the attributes by use case (view).
Another way would be to query only some columns, but in this case you are getting the tuple instance instead of the model instance (in your case User), so it is potentially OK for form filling, but not so good for model validation: session.query(Book.id, Book.title).all()