sort and research with graph coredata - cosmicmind

My code is:
let risultato = DataManager.sharedInstance.graph.searchForEntity(
properties: [(key: "tempo", value: "00:00:40.00",
("valore","decimi")])
But I want my result to satisfy both conditions is a so or no and.
How should I do this?
Also how can I do the sort the entity according to a key?

In order to filter, Graph takes a programmatic approach, rather than writing complex queries. So the first thing would be to get the collection of data that you are looking for, which is done through OR. The AND is handled in the filter
let result = graph.searchForEntity(properties: [("valore", "decimi")]).filter { (entity: Entity) in
return entity["tempo"] as? String == "00:00:40.00"
}
For sorting, you can do this, since the result data structure is an Array
let sorted: [Entity] = result.sort ({ $0["key"] as? String > $1["key"] as? String })
let sorted: [Entity] = result.sort { (a: Entity, b: Entity) -> Bool in
return a["key"] as? String > b["key"] as? String
}
FYI
Also, you don't need a shared instance of Graph through DataManager.sharedInstance. Any instance of Graph will reference the same data. That is one of the benefits that Graph offers.

Related

get title from Zotero item

Still very new to Rust, trying to understand how to extract the title of a JournalArticle using the Zotero crate.
I've got this, and can confirm the item is retrieved successfully:
let zc = ZoteroCredentials::new();
let z = ZoteroInit::set_user(&zc.api_id, &zc.api_key);
let item = z.get_item(item_id, None).unwrap();
From here, I see that an item.data is an ItemType, specifically a JournalArticleData. But I'm fundamentally not quite understanding how to either a) serialize this to JSON, or b) access .title as a property.
For context, this would be the result of a Rocket GET route.
Any help would much appreciated!
It sounds like the part you're missing is how to use pattern matching on an enum. I'm not familiar with zotero so this is all based on the docs, with verbose type annotations to be explicit about what I think I'm doing:
use zotero::data_structure::item::{Item, ItemType, JournalArticleData};
let item: Item = z.get_item(item_id, None).unwrap();
// Now we must extract the JournalArticle from the ItemType, which is an enum
// and therefore requires pattern matching.
let article: JournalArticleData = match item.data {
ItemType::JournalArticle(a) => a,
something_else => todo!("handle wrong type of item"),
}
let title: String = article.title;
(The match could also be written as an if let just as well.)
You could also use pattern matching to go through the entire structure, rather than only the enum which requires it:
match z.get_item(item_id, None).unwrap() {
Item {
data: ItemType::JournalArticle(JournalArticleData {
title,
..
}),
..
} => {
// Use the `title` variable here
},
something_else => todo!("handle wrong type of item"),
}

coreData returning only one result

Having this weird issue, No matter what predicate I apply its only returning one result, and if I don't add any predicate its returns all the rows of the table, what I want is only return the rows with matching progIds
I have the list of programIds and based on that I want to search in TvInfo table.
.......
......
progId = [Int64(3211),Int64(16844)] // hardcored ids from tvInfo table
let tvInfoRequest: NSFetchRequest<TvInfo> = TvInfo.fetchRequest()
tvInfoRequest.predicate = NSPredicate(format: "progId == %i", argumentArray: progId)
tvInfoRequest.returnsDistinctResults = true
tvInfoRequest.resultType = .managedObjectResultType
var tvShows = [TvInfo]()
coreDataStack.managedObjectContext.performAndWait({
do{
let tvInfoResult = try self.coreDataStack.managedObjectContext.fetch(tvInfoRequest)
tvShows = tvInfoResult
} catch {
fatalError("Error fetching channels displayShow")
}
})
I thought maybe some issue with progId (type mismatch Int64), so I tried fetching using the tvShow name (with exact showNames from tvInfo table still getting only one result, (first name passed in the array)
tvInfoRequest.predicate = NSPredicate(format: "progName MATCHES %#", argumentArray: ["Supercar Superbuild","Kanahiya Bhaiya Live"])
weird thing is I used the same logic to fetch progIds from channels Table and its working fine(getting progId with exact matches) and its working for other tables also like channel Id fetching from channel tables
// fetching progIds from channel table
let tvScheduleRequest: NSFetchRequest<TvSchedule> = TvSchedule.fetchRequest()
tvScheduleRequest.predicate = NSPredicate(format: "chId == %i", argumentArray: channelIds)
tvScheduleRequest.returnsDistinctResults = true
var progId = [Int64]()
coreDataStack.managedObjectContext.performAndWait({
do{
let tvScheduleResult = try self.coreDataStack.managedObjectContext.fetch(tvScheduleRequest)
if tvScheduleResult.count > 0 {
for array in tvScheduleResult {
progId.append(array.progId)
}
}
} catch {
fatalError("Error fetching channels to display show")
}
})
PS:
Its returning 1 row so it's not an issue of context, wrong key,
thread
there are data in table as if I don't apply any predicate its
returning 100+ rows
I am using argumentArray for predicate, not single args CVarArg.
Thanks for help
In predicate try using %# instead of %i.
tvInfoRequest.predicate = NSPredicate(format: "progId == %i", argumentArray: progId).
One more thing check the variable that you are passing to predicate progId.

NHibernate queryover how to apply date isbetween without including the from and todate

I am trying to write NHibernate queryover to select all records which has been deleted between two dates. I am using IsBetween().And(). But how do i write if i dont want to include both the fromdate and todate?
Here is my query:
public IEnumerable<DeletedRecord> Search(
DateTime deletedFrom,
DateTime deletedTo
)
{
DeletedRecord delAlias = null;
var query = Session.QueryOver(() => delAlias);
query.Where(() => delAlias.DeletedDate.IsBetween(deletedFrom).And(deletedTo));
return query.Future<DeletedRecord>();
}
Can anyone help me how to achieve so that i can bring all records after the deletedFrom date and before the deletedTo date?
Thanks
Just construct your date in 2 steps:
var query = Session.QueryOver(() => delAlias);
if(youNeedFromDate) //first step
query = query.Where(() => delAlias.DeletedDate >= deletedFrom);
if(youNeedToDate) //second step
query = query.Where(() => delAlias.DeletedDate <= deletedTo);
youNeedFromDate and youNeedToDate are bool variables that you can pass to your function or it could be different condition upon your logic.
Such cases happen quite often . defining extension method helps a lot. see below
public static IQueryOver<T, T> WhereIf<T>(this IQueryOver<T, T> query,bool condition, Expression<Func<T, bool>> expression) where T : class
{
if (condition)
{
query = query.And(expression);
}
return query;
}
Using the above you can chain you conditions and only it will only include the where condition if the first arg evaluates to true.
var query= Session.QueryOver<DeletedRecord>()
.WhereIf(filterByFrom,d=>d.DeletedDate>=fromDate)
.WhereIf(filterByTo,d=>d.DeletedDate<=toDate);

Thread-Safe Query Expressions F#

I have a set of functions which using FSharp.Data.TypeProviders makes several calls to the database via sql to retrieve data.
The code looks like the following:
let query_one (firstName:string) (lastName:string) =
query { for a in db.Names do
where (a.firstname = FirstName && a.secondname = LastName)
select a } |> Seq.last
let query_two (jobTitle:string) =
query { for a in db.Jobs do
where (a.jobId = jobTitle)
select a } |> Seq.last
let detailsList = new List<('a*'b)>()
let queries =
workerDetails
|> Array.Parallel.map (fun (firstn, lastn, jobt) ->
let j1 = query_one firstn lastn
let j2 = query_two jobt
detailsList.add (j1,j2) )
When I run this I get the following:
A first chance exception of type 'System.ArgumentException' occurred
in FSharp.Core.dll
Additional information: An item with the same key has already been
added.
To be more exact:
System.ArgumentException: An item with the same key has already been
added. at
Microsoft.FSharp.Linq.RuntimeHelpers.LeafExpressionConverter.EvaluateQuotation(FSharpExpr
e) at
Microsoft.FSharp.Linq.QueryModule.EvalNonNestedInner(CanEliminate
canElim, FSharpExpr queryProducingSequence) at
Microsoft.FSharp.Linq.QueryModule.EvalNonNestedOuter(CanEliminate
canElim, FSharpExpr tm) at
Microsoft.FSharp.Linq.QueryModule.clo#1737-1.Microsoft-FSharp-Linq-ForwardDeclarations-IQueryMethods-Execute[a,b](FSharpExpr`1
) ... ... at
Microsoft.FSharp.Collections.ArrayModule.Parallel.Map#714-3.Invoke(Int32
obj) at
System.Threading.Tasks.Parallel.<>c__DisplayClassf`1.b__c()
at System.Threading.Tasks.Task.InnerInvoke() at
System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask) at
System.Threading.Tasks.Task.<>c__DisplayClass11.b__10(Object
param0)<---
I also tried running it from C# using Parallel.For().. I am probably missing something basic. Is there an easy way to make a function thread-safe? or a query expression?
Thanks for the help!
Possible option to resolve:
When I included the call for the database context in the function in resolved the parralel exception. Such as:
let query_one (firstName:string) (lastName:string) =
let db = temp_schema.GetDataContext()
query { for a in db.Names do
where (a.firstname = FirstName && a.secondname = LastName)
select a } |> Seq.last

Linq Invalid Cast Exception Same Object Type

I wrote this query and as my understanding of the business rules has improved I have modified it.
In this most recent iteration I was testing to see if indeed I had some redundancy that could be removed. Let me first give you the query then the error.
public List<ExternalForums> GetAllExternalForums(int extforumBoardId)
{
List<ExternalForums> xtrnlfrm = new List<ExternalForums>();
var query = _forumExternalBoardsRepository.Table
.Where(id => id.Id == extforumBoardId)
.Select(ExtForum => ExtForum.ExternalForums);
foreach (ExternalForums item in query)
{
xtrnlfrm.Add(new ExternalForums { Id = item.Id , ForumName = item.ForumName, ForumUrl = item.ForumUrl });
}
return xtrnlfrm;
}
Now in case it isn't obvious the query select is returning List of ExternalForums. I then loop through said list and add the items to another List of ExternalForums object. This is the redundancy I was expecting to remove.
Precompiler was gtg so I ran through it one time to very everything was kosher before refactoring and ran into a strange error as I began the loop.
Unable to cast object of System.Collections.Generic.HashSet
NamSpcA.NamSpcB.ExternalForums to type NamSpcA.NamSpcB.ExternalForums.
Huh? They are the same object types.
So am I doing something wrong in the way I am projecting my select?
TIA
var query = _forumExternalBoardsRepository.Table
.Where(id => id.Id == extforumBoardId)
.Select(ExtForum => ExtForum.ExternalForums);
This query returns IEnumerable<T> where T is type of ExtForum.ExternalForums property, which I would expect to be another collection, this time of ExternalForum. And the error message matches that, saying you have IEnumerable<HashSet<ExternalForums>>.
If you need that collection of collections to be flattened into one big collection of ExternalForums use SelectMany instead:
var query = _forumExternalBoardsRepository.Table
.Where(id => id.Id == extforumBoardId)
.SelectMany(ExtForum => ExtForum.ExternalForums);

Resources