Racket: How do I get information from a structure that is inside a structure? - structure

straight to my question :). Lets say we have:
(define-struct person (age sex code))
(define-struct subject (person times))
(define P1 (make-subject (make-person 19 'f 'OM29Q) (list 299 194 242 303 243)))
Is it possible to get the information from the structure person for example the age? If so how do I implement something like that?
I need that bit of Information to work with that.
I am already familiar with the selector function like (subject-person P1) but that does not help me with my problem.
Thanks in advance!

If a-subject is a subject structure, then (subject-person a-subject) will return a person. To get the age of that person, use the selector person-age, that is write: (person-age (subject-person a-subject)).

Related

How to clean the commets table SQL?

I have a table with IDS and COMMENTS, in which people chose on a website the reason why they ended their subscription, and that data is sent to a table.
The persons can choose more reasons, but all the reasons are sent into a single row like:
id = 111 comments = I don't like the productI hate youNever expected this
Can I rearange this table to receive the following?
id= 111 / comments= I don't like the product
id= 111 / comments= I hate you
id= 11 / comments= Never expected this
Thanks for the help!
Then this may get you to where you want
$in= "I don't like the productI hate youNever expected this";
$str = preg_replace("([A-Z])", "££$0", $in);
$arr = explode("££",trim($str, '££'));
print_r($arr);
RESULT
Array
(
[0] => I don't like the product
[1] => I hate you
[2] => Never expected this
)

Get all records with child records OR field length > 250

I have a Comment model which has-many attachments. What I want to return, is all of the comments which either have one or more attachment records, OR whose comment is longer than 250 characters.
Is there any way I can do this without writing it entirely in pure SQL? I'm struggling to build up a WHERE clause in just the rails method. It's not quite as simple as I'd hoped :(
Ideally I want this to be a scope but whatever will work is fine
You could try:
Comment.includes(:attachments).where('attachments.comment_id IS NOT NULL OR LEN(comments.content) > 250')
The WHERE clause should follow the pattern o the following pseudo-code
WHERE Length(Comment_field) > 250
OR EXISTS (Select COMMENT_ID from attachments)
Jump into the irb or rails c (console) do this from command-line to get it then plug it in.
c = YourCommentModel.where('attachments > ?', 1)
len250 = c = YourCommentModel.where('attachments.length> ?', 250)
first one gives comments of greater than 1, second gives comments > 250

ActiveRecord: How do I find records by all of their associated records?

With ActiveRecord you can pass a field and an array into WHERE like so:
Product.joins(:category).where('category.id' => [x,y,z])
(in this case Product has a many to many relationship with Category)
This uses the IN operator to find all products in categories with an ID of x, y, or z
What I would like to do is find all products in categories with an ID of x, y, AND z. I know you can produce this sort of result like so:
Product.joins(:category).where('category.id' => x).where('category.id' => y).where('category.id' => z)
In other words, I want to find products that have all of the categories supplied.
I feel like I could do be doing something much simpler here. Any ideas?
Update: I believe this question is relevant, still having trouble getting it to work. Still think there might be another way to do this.
Havent tried... but something like below should give you hint to get started -
Product.joins(:categories).select("products.*, GROUP_CONCAT('categories.id') as category_ids").group('products.id').having('category_ids = ?', [1,2,3])
How about this:
Product.joins(:category)
.where('category.id = ? AND category.id = ? AND category.id = ?',x,y,z)

Speed Performance In Recursive SQL Requests

I have so category and this categories have unlimited sub category.
In Database Table, Fields are ID, UpperID and Title.
If I call a category and its subcategory in DataTable with recursive method in program(ASP.NET project)
performance is very bad.
And many user will use this application so everything goes bad.
Maybe All categories Fill to A Cache object and then we musnt go to Database.
But category count is 15000 or 20000.
So I think isn't a good method.
What can I do for fast performance?
Are you give me any suggestion?
caching or other in-memory-persistance is by far better than doing this on a relational system :) ... hey... it's oop!
just my 2 cents!
eg.
var categories = /* method for domain-objects*/.ToDictionary(category => category.ID);
foreach (var category in categories.Values)
{
if (!category.ParentCategoryID.HasValue)
{
continue;
}
Category parentCategory;
if (categories.TryGetValue(category.ParentCategoryID.Value, out parentCategory))
{
parentCategory.AddSubCategory(category);
}
}
et voila ... your tree is ready to go!
edit:
do you exactly know where your performance bottle-neck is?...
to give you some ideas, eg:
loading from database
building up the structure
querying the structure
loading from database:
then you should load it once and be sure to have some changetracking/notifying to get changes (if made) or optimize your query!
building up the structure:
the way i create the tree (traversal part) is the wastest you can do with a Dictionary<TKey, TValue>
querying the structure:
the structure i've used in my example is faster than List<T>. Dictionary<TKey, TValue> uses an index over the keys - so you may use int for the keys (IDs)
edit:
So you use DataTable to fix the
problem. Now you've got 2 problems: me
and DataTable
what do you have right now? where are you starting from? can you determine where your mudhole is? give us code!
Thanks All,
I find my solution with Common Table Expressions(CTE) fifty- fifty.
Its allow fast recursive queries.
WITH CatCTE(OID, Name, ParentID)
AS
(
SELECT OID, Name, ParentID FROM Work.dbo.eaCategory
WHERE OID = 0
UNION ALL
SELECT C.OID, C.Name, C.ParentID FROM Work.dbo.eaCategory C JOIN CatCTE as CTE ON C.ParentID= CTE.OID
)
SELECT * FROM CatCTE

nHibernate collections and alias criteria

I have a simple test object model in which there are schools, and a school has a collection of students.
I would like to retrieve a school and all its students who are above a certain age.
I carry out the following query, which obtains a given school and the children which are above a certain age:
public School GetSchoolAndStudentsWithDOBAbove(int schoolid, DateTime dob)
{
var school = this.Session.CreateCriteria(typeof(School))
.CreateAlias("Students", "students")
.Add(Expression.And(Expression.Eq("SchoolId", schoolid), Expression.Gt("students.DOB", dob)))
.UniqueResult<School>();
return school;
}
This all works fine and I can see the query going to the database and returning the expected number of rows.
However, when I carry out either of the following, it gives me the total number of students in the given school (regardless of the preceding request) by running another query:
foreach (Student st in s.Students)
{
Console.WriteLine(st.FirstName);
}
Assert.AreEqual(s.Students.Count, 3);
Can anyone explain why?
You made your query on the School class and you restricted your results on it, not on the mapped related objects.
Now there are many ways to do this.
You can make a static filter as IanL said, however its not really flexible.
You can just iterate the collection like mxmissile but that is ugly and slow (especially considering lazy loading considerations)
I would provide 2 different solutions:
In the first you maintain the query you have and you fire a dynamic filter on the collection (maintaining a lazy-loaded collection) and doing a round-trip to the database:
var school = GetSchoolAndStudentsWithDOBAbove(5, dob);
IQuery qDob = nhSession.CreateFilter(school.Students, "where DOB > :dob").SetDateTime("dob", dob);
IList<Student> dobedSchoolStudents = qDob.List<Student>();
In the second solution just fetch both the school and the students in one shot:
object result = nhSession.CreateQuery(
"select ss, st from School ss, Student st
where ss.Id = st.School.Id and ss.Id = :schId and st.DOB > :dob")
.SetInt32("schId", 5).SetDateTime("dob", dob).List();
ss is a School object and st is a Student collection.
And this can definitely be done using the criteria query you use now (using Projections)
Unfortunately s.Students will not contain your "queried" results. You will have to create a separate query for Students to reach your goal.
foreach(var st in s.Students.Where(x => x.DOB > dob))
Console.WriteLine(st.FirstName);
Warning: That will still make second trip to the db depending on your mapping, and it will still retrieve all students.
I'm not sure but you could possibly use Projections to do all this in one query, but I am by no means an expert on that.
You do have the option of filtering data. If it there is a single instance of the query mxmissle option would be the better choice.
Nhibernate Filter Documentation
Filters do have there uses, but depending on the version you are using there can be issues where filtered collections are not cached correctly.