SubSonic InlineQuery returning wrong results with ExecuteAsCollection - subsonic

Using SubSonic 2.2, I have this query:
string q = #"SELECT Media.Id, Media.Title FROM Media WHERE Media.UserId = 7"
DAL.MediumCollection matches = new InlineQuery().ExecuteAsCollection<DAL.MediumCollection>(q).Load();
Looping through "matches" results in every single entry in the "Media" table.
However, when I do this:
IDataReader reader = new InlineQuery().ExecuteReader(q);
It returns the correct rows. Why is ExecuteAsCollection returning something completely different from ExecuteReader? Has anyone else experience this strange behavior?

I think it's because you're calling .Load(). That's overwriting your original query.

ExecuteAsCollection() should do it.
When you call the Load() method it's just like doing new DAL.MediumCollection().Load() that returns all the data in the table.

Related

getDocumentByKey with a number vector doesn't find the document

I have a 2 column sorted view and try to get a document the following code:
var searchArr = new java.util.Vector();
searchArr.addElement(10000310);
searchArr.addElement(45);
var customerdoc:NotesDocument = viw.getDocumentByKey(searchArr,true);
but the result is null.
If I use only the first element for the key (10000310), then I get (the first) doc with that key. But with the 2-element-vector the lookup returns null.
the same in LotusScript works fine:
Dim searchkey(1) As Double
searchkey(0) = 10000307
searchkey(1) = 45
Set doc = luview.Getdocumentbykey(searchkey, true)
gives me the document I need.
Confusing, for me ....
Uwe
This is a known bug, hopefully to be fixed in 9.0.2. See this question getDocumentByKey with view category separated by "\\" in XPages
Your LS example uses an array, not a Vector. I am not even sure if it is intended to work with a Vector - never did that. So just use an array here, too, as the key.

Astyanax parepared statement withvalues() not working properly

today I migrated to Astyanax 1.56.42 and discovered, that withValues() on prepared statements doesn't seem to work properly with SQL SELECT...WHERE...IN ().
ArrayList<ByteBuffer> uids = new ArrayList<ByteBuffer>(fileUids.size());
for (int i = 0; i < fileUids.size(); i++) {
uids.add(ByteBuffer.wrap(UUIDtoByteArray(fileUids.get(i)), 0, 16));
}
result = KEYSPACE.prepareQuery(CF_FILESYSTEM)
.withCql("SELECT * from files where file_uid in (?);")
.asPreparedStatement()
.withValues(uids)
.execute();
If my ArrayList contains more than one entry, this results in error
SEVERE: com.netflix.astyanax.connectionpool.exceptions.BadRequestException: BadRequestException: [host=hostname(hostname):9160, latency=5(5), attempts=1]InvalidRequestException(why:there were 1 markers(?) in CQL but 2 bound variables)
What am I doing wrong? Is there any other way to handle a SQL SELECT...WHERE...IN () - statement or did I find a bug?
Best regards
Chris
As you mentioned because you are supplying a collection (ArrayList) to a single ? Astyanax throws an exception. I think you need to add a ? for each element you want to have inside the IN clause.
Say you want to have 2 ints stored in an ArrayList called arrayListObj the where clause, your statement looks like this:
SELECT & FROM users WHERE somevalue IN (arrayListObj);
Because you are suppling a collection, this cant work, so you will need multiple ?'s. I.e. you want :
SELECT name, occupation FROM users WHERE userid IN (arrayListObj.get(0), arrayListObj.get(1));
I couldn't find anything on the Astyanax wiki about using the IN clause with prepared statements.

How to deserialize DynamicComposite column value?

I am trying to implement a data model where row keys are Strings, column names are Longs and column values are DynamicComposites. Using Hector, an example of the stored procedure looks like this:
// create the value
DynamicComposite colVal = new DynamicComposite();
colVal.add(0, "someString");
colVal.setComparatorByPosition(0, "org.apache.cassandra.db.marshal.UTF8Type");
colVal.setSerializerByPosition(0, StringSerializer.get());
// create the column
HColumnImpl<Long, DynamicComposite> newCol = new
HColumnImpl<Long, DynamicComposite>(longSerializer,
dynamicCompositeSerializer);
newCol.setName(longValue);
newCol.setValue(colVal);
newCol.setClock(keySpace.createClock());
// insert the new column
Mutator<String> mutator = HFactory.createMutator(keySpace,stringSerializer);
mutator.addInsertion("rowKey","columnFamilyName",newCol);
mutator.execute();
Now, when I try to retrieve the data:
// create the query
SliceQuery<String,Long,DynamicComposite> sq =
HFactory.createSliceQuery(keySpace, stringSerializer, longSerializer,
dynamicCompositeSerializer);
// set the query
sq.setColumnFamily("columnFamilyName");
sq.setKey("rowKey");
sq.setColumnNames(longValue);
// execute the query
QueryResult<ColumnSlice<Long, DynamicComposite>> qr = sq.execute();
// get the data
qr.get().getColumnByName(longValue).getValue();
or when I just try to get plain byes:
// get the data
dynamicSerializer.fromByteBuffer(qr.get().
getColumnByName(longValue).getValueBytes());
I run into an exception:
Exception in thread "main" java.lang.NullPointerException
at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:191)
at com.google.common.collect.ImmutableClassToInstanceMap.getInstance(ImmutableClassToInstanceMap.java:147)
at me.prettyprint.hector.api.beans.AbstractComposite.serializerForComparator(AbstractComposite.java:321)
at me.prettyprint.hector.api.beans.AbstractComposite.getSerializer(AbstractComposite.java:344)
at me.prettyprint.hector.api.beans.AbstractComposite.deserialize(AbstractComposite.java:713)
at me.prettyprint.hector.api.beans.DynamicComposite.fromByteBuffer(DynamicComposite.java:25)
at me.prettyprint.cassandra.serializers.DynamicCompositeSerializer.fromByteBuffer(DynamicCompositeSerializer.java:35)
As far as I have understood from all the tutorials I read, it should be possible to use DynamicComposite as column value. Therefore I want to ask: what am I doing wrong? From the exception it seems I am just forgetting to set something somewhere.
Radovan,
Its probably due to compatibility issues of the Guava library used in conjuction with the Hector version.
See also : https://github.com/hector-client/hector/pull/591
I am on Hector-core-1.1-1.jar, in combination with the Guava-14.0.jar I get the same error as you. When I use it with the Guava-12.0.1.jar however it works fine for me.

Kohana 3.2 ORM Does not contain model info

I'm working with Kohana 3.2 and have the following code in my controller.
$Blog_Post = new Model_Blogpost();
$Blog_Post->where('id', '=', 1);
$Blog_Post->find();
$content = $Blog_Post->content;
I Currently have 3 records in my db with id's 1, 2, and 3.
$Blog_Post->content, or any other field return null. and I'm not sure why.
Use ORM::factory('blogpost', $id) or new Model_Blogpost($id) if you need an object with PK == $id.
Check your model after loading.
if $Blog_Post->loaded()
{
// it works!
}
else
{
// record not found
}
If record not found, you can see last DB query with $Blog_Post->last_query()
UPD. From comments. Your model will not work with this modifications. Note that ORM data stored in $_object property, and $Blog_Post->content is just a shortcut for $Blog_Post->_object['content'] via __get() method. Of course, if you define public $content property, $Blog_Post->content will return NULL value instead of using DB data.
There is no reason for defining model fields as properties. If you need IDE hints, just use PHPDOC.
At the firm I work for we were looking into upgrading to 3.2 very recently. However, in our evaluation I don't recall seeing a difference in ORM handling methods.
Yours above looks like it should be something like this:
$Blog_Post = ORM::factory('blogpost')->where('id', '=', 1)->find();
$content = $Blog_Post->content;
Assuming your table is called blogposts, of course. I may be wrong about that and if I am, can you link to the documentation that shows this kind of model interaction?

Search query with Subsonic

Ok,
Today I am trying to learn Subsonic. Pretty cool stuff.
I am trying to build some search functionality into my website but am struggling about how I might achieve this in Subsonic.
I have one search field that could contain multiple keywords. I want to return results that match all of the keywords. The target on the search is a single text column.
So far I have this (it runs but never returns results):
return new SubSonic.Select().From(Visit.Schema)
.InnerJoin(InfopathArchive.VisitIdColumn, Visit.VisitIdColumn)
.Where(InfopathArchive.XmlDocColumn).Like(keywords)
.ExecuteTypedList<Visit>();
There is a one to one mapping between the Visit table and the InfoPathArchive table. I just want to return the collection of Visits that have the keywords in the related XMLDocColumn.
If I could get that working it would be great. Now the second problem is that if someone searches for 'australia processmodel' then obviously the above code should only return that exact phrase. How can I create a query that splits up my search term so that it must return documents that contain ALL of the individual search terms?
Any help appreciated.
Edit: Ok, so the basic search works, but the multiple keyword search doesnt. I did what Adam suggested but it seems Subsonic only uses one parameter for the query.
Here is the code:
List<string> wordsInQueryList = keywords.Split(' ').ToList();
SqlQuery q = Select.AllColumnsFrom<Visit>()
.InnerJoin(InfopathArchive.VisitIdColumn, Visit.VisitIdColumn)
.Where(Visit.IsDeletedColumn).IsEqualTo(false);
foreach(string wordInQuery in wordsInQueryList)
{
q = q.And(InfopathArchive.XmlDocColumn).Like("%" + wordInQuery + "%");
}
return q.ExecuteTypedList();
Then if I look at the query that Subsonic generates:
SELECT (bunch of columns)
FROM [dbo].[Visit]
INNER JOIN [dbo].[InfopathArchive] ON [dbo].[Visit].[VisitId] = [dbo].[InfopathArchive].[VisitId]
WHERE [dbo].[Visit].[IsDeleted] = #IsDeleted
AND [dbo].[InfopathArchive].[XmlDoc] LIKE #XmlDoc
AND [dbo].[InfopathArchive].[XmlDoc] LIKE #XmlDoc
So it ends up that only the last keyword is being searched for.
Any ideas?
First question:
return new SubSonic.Select().From(Visit.Schema)
.InnerJoin(InfopathArchive.VisitIdColumn, Visit.VisitIdColumn)
.Where(InfopathArchive.XmlDocColumn).Like("%" + keywords + "%")
.ExecuteTypedList<Visit>();
Second question:
Pass a List of words in your query to a function that builds a SubSonic query as follows
SqlQuery query = DB.Select().From(Visit.Schema)
.InnerJoin(InfopathArchive.VisitIdColumn, Visit.VisitIdColumn)
.Where("1=1");
foreach(string wordInQuery in wordsInQueryList)
{
query = query.And(InfopathArchive.XmlDocColumn).Like("%" + wordInQuery + "%")
}
return query.ExecuteTypedList<Visit>();
Obviously this is untested but it should point you in the right direction.
You can do what Adam is suggesting or with 2.2 you can simply use "Contains()" instead of Like("%...%"). We also support StartsWith and EndsWith() :)

Resources