Complete example on findByAttributes in Yii - yii

I am appreciated if someone shows a complete example on how to use findByAttributes in Yii framework.
Official doc # http://www.yiiframework.com/doc/api/1.1/CActiveRecord#findByAttributes-detail
public CActiveRecord findByAttributes(array $attributes, mixed $condition='', array $params=array ( ))
I know how to use $attributes. I do not see a good reason to use $condition and $params in findByAttributes.
Please tell me under what scenario, you use them in findByAttributes.
Thank you

It seems like it was included to match similar function in other frameworks and best used when your query is mostly an array of column names like array('dept_id'=>2,'active'=>'y') -- there might be times in your program where it's easier to pass an array in this format rather than having to re-write them into conditions. You might want to add additional conditions in the $condition paramater or ones that $attributes may not support like project_name LIKE "foo%".
$params are used here like other query types, to bind condition values to column types for filtering.
see: http://www.yiiframework.com/doc/guide/1.1/en/database.ar#reading-record
Info: When a query condition is about
matching some columns with the
specified values, we can use
findByAttributes(). We let the
$attributes parameters be an array of
the values indexed by the column
names. In some frameworks, this task
can be achieved by calling methods
like findByNameAndTitle. Although this
approach looks attractive, it often
causes confusion, conflict and issues
like case-sensitivity of column names.

example of findByAttributes() :
$modelname->findByAttributes(array('fieldName1'=>$value1,'fieldName2'=>$value2));

Related

Include Sub-Entities from relations when loading an Entity in Groovy Service

What I'm trying to achieve here is to load some fields from sub-entities.
For instance, let's suppose i want to load some features for the product list. In xml it's pretty clear:
<row-actions>
<entity-find-one entity-name="mantle.product.feature.ProductFeature" value-field="brandList">
<field-map field-name="productFeatureId" from="featureList.productFeatureId"/>
<field-map field-name="productFeatureTypeEnumId" from="featureList.productFeatureId" value="PftBrand"/>
</entity-find-one>
</row-actions>
Is there a way to do something similar in groovy, without iterating through the whole product list and add the desired fields manually?
Also, can somebody give me a short example with the concrete use of sqlFind(http://www.moqui.org/javadoc/org/moqui/entity/EntityFacade.html) ?
I tried to solve the issue i'm asking about using a join query but I couldn't figure out how the SQL query is supposed to look like.
a. The element 'entity-find-one' queries on primary key and returns a single map. You need to use the 'entity-find' element .
b. Yes, you can always drop down to groovy using the script tag. e.g. Just use ec.entity.find("mantle.product.feature.ProductFeature") or whatever you need in your groovy script.
c. In moqui, joined tables are handled by the 'view-entity' element and you can predefine your own (place in your 'entities' folder) or use the many existing ones that are provided in the framework. You don't need SQL.
EDIT - Sorry, you can also do it on the fly by using the EntityFind.makeEntityDynamicView() method.
Hope that helps.

How to make criteria with array field in Hibernate

I'm using Hibernate and Postgres and defined a character(1)[] column type.
So I donĀ“t know how to make this criteria to find a value in the array.
Like this query
SELECT * FROM cpfbloqueado WHERE bloqueados #> ARRAY['V']::character[]
I am not familiar with Postgres and its types but you can define your own type using custom basic type mapping. That could simplify the query.
There are many threads here on SO regarding Postres array types and Hibernate, for instance, this one. Another array mapping example that could be useful is here. At last, here is an example of using Criteria with user type.
Code example could be
List result = session.createCriteria(Cpfbloqueado.class)
.setProjection(Projections.projectionList()
.add(Projections.property("characterColumn.attribute"), PostgresCharArrayType.class)
)
.setResultTransformer(Transformer.aliasToBean(Cpfbloqueado.class))
.add(...) // add where restrictions here
.list()
Also, if it is not important for the implementation, you can define max length in the entity model, annotating your field with #Column(length = 1).
Or if you need to store an array of characters with length of 1 it is possible to use a collection type.
I hope I got the point right, however, it would be nice if the problem domain was better described.
So you have array of single characters... Problem is that in PG that is not fixed length. I had this problem, but around 10 years ago. At that time I had that column mapped as string, and that way I was able to process internal data - simply slice by comma, and do what is needed.
If you hate that way, as I did... Look for columns with text[] type - that is more common, so it is quite easy to find out something. Please look at this sample project:
https://github.com/phstudy/jpa-array-converter-sample

RESTful API Design OR Predicates

I'm designing a RESTful API and I'm trying to work out how I could represent a predicate with OR an operator when querying for a resource.
For example if I had a resource Foo with a property Name, how would you search for all Foo resources with a name matching "Name1" OR "Name2"?
This is straight forward when it's an AND operator as I could do the following:
http://www.website.com/Foo?Name=Name1&Age=19
The other approach I've seen is to post the search in the body.
You will need to pick your own approach, but I can name few that seem to be pretty logical (although not without disadvantages):
Option 1.: Using | operator:
http://www.website.com/Foo?Name=Name1|Name2
Option 2.: Using modified query param to allow selection by one of the values from the set (list of possible comma-separated values):
http://www.website.com/Foo?Name_in=Name1,Name2
Option 3.: Using PHP-like notation to provide list instead of single string:
http://www.website.com/Foo?Name[]=Name1&Name[]=Name2
All of the above mentioned options have one huge advantage: they do not interfere with other query params.
But as I mentioned, pick your own approach and be consistent about it across your API.
Well one quick way to fixing that is to add an additional parameter that is identifying the relationship between your parameters wether they're an and or an or for example:
http://www.website.com/Foo?Name=Name1&Age=19&or=true
Or for much more complex queries just keep a single parameter and in it include your whole query by making up your own little query language and on the server side you would parse the whole string and extract the information and the statement.

Android Notepad Uri Explanation

In the android Notes demo, it accepts the URI:
sUriMatcher.addURI(NotePad.AUTHORITY, "notes", NOTES);
sUriMatcher.addURI(NotePad.AUTHORITY, "notes/#", NOTE_ID);
Where the difference between notes and notes/# is that notes/# returns the note who's ID matches #.
However, the managedQuery() method that is used to get data from the content provider has the following parameters:
Parameters
uri The URI of the content provider to query.
projection List of columns to return.
selection SQL WHERE clause.
selectionArgs The arguments to selection, if any ?s are pesent
sortOrder SQL ORDER BY clause.
So, is there any particular cause for the design decision of providing a URI for that, rather than just using the selection parameter? Or is it just a matter of taste?
Thank you.
I thinks its so you can do more complex lookups without having to complicate your selections and arguments. For example in my project I have multiple tables but use the same selection and arguments. To filter content. By using the URI I don't have interpret the query, I can just switch on the URI. It.might be personal taste to begin with. But in more complex scenarios you appreciate the URI. You can also use * to match strings in the same.way you can with#.
I think it's mostly a matter of taste. IMHO, putting the id in the Uri is a little cleaner since you can make the id opaque rather than require the client to know that it actually represents a specific row id. For instance, you can pass a lookup key (like in the the Contacts API) rather than a specific row id.

Filter inputs in custom ContentProvider functions

In a custom ContentProvider I need to filter out some columns specified in the inputs. Given the text-oriented Android interfaces this is giving me a hard time.
For example the input on MyContentProvider.query() would effectively ask something like:
SELECT column_a, column_b FROM my_table WHERE column_a=1 AND column_b=red;
The problem is that at this particular MyContentProvider _column_b_ might not make any sense and would not be present in the table. Filtering the projection so that only relevant columns remain can be easily done since it's a String[]. However, filtering the String "where" (selection) and "selectionArgs" inputs for these columns is not trivial. If done properly it would become:
SELECT column_a FROM my_table WHERE column_a=1;
Otherwise one would get a SQLiteException "no such column".
So, is there any easy way to ignore or filter columns from such an sql statement or do I need to go and write some smart albeit very limited regexp parsing code for the selection part?
The reason I'm not getting the right inputs is because I maintain a custom ContentProvider as an interface to address, but I talk to multiple custom ContentProviders herein (in the background). One way or another, I would need to filter the selection somewhere.
Please note that I am not asking simply how to do a query or use the SELECT ... WHERE statement. However it concerns my implementation of the query() function.
Since you are extending your MyContentProvider with ContentProvider why don't you just overload the query() method?
Look at ContentProvider - Sharing Content using the ContentProvider for someone elses example on how to create a custom ContentProvider. You should have full control over what data you fetch from your SQLiteDatabase.
More importantly, look at the arguments provided to query(), as they contain the information you need to you in a way where you can dynamically build the query from what is passed into the method call.
Depending on if you can find a good query builder, you have an opportunity to build a small but powerful abstraction layer to build your queries, so that you minimize the amount of actual SQL that you write yourself.
Also, always remember to sanitize your inputs!