Find all rows which match substring, with moor / moor_flutter - flutter

I want to select all rows which match a substring with moor / moor_flutter.
In SQL, you'd do something like this:
'SELECT * FROM [table] WHERE [field] LIKE '%[substring]%'
Is there a 'moor-like' way of doing this?
The closest I've come, is this:
Stream<List<Task>> watchTable() {
return (select(tableItem)..where((tbl) => CustomExpression<bool>("field LIKE '%substring%'"))).watch();
}
But unfortunately that's not a nice typesafe / moor-like way.

Here is the example what I have done for like query:
// Get all the doctors [by optional params city and area]
Future<List<DoctorMaster>> getAllDoctors({String city = "", String area = ""}) {
return (select(doctorMasters)..where((tbl) => tbl.city.like(city) & tbl.area.like(area))).get();
}
You can do something like that for your purpose.
Stream<List<Task>> watchTable() {
return (select(tableItem)..where((tbl) => tbl.yourField.like('%substring%'))).watch();
}
Hope it will work. Thanks

Related

Is it possible to compare with a number in "Where"?

I am new in Entity Framework and I have a little question.
Is it possible to compare in "Where" with a number.
I will add code example.
var source = db.Book.Where(book => book.Count > 0);
So, I need to get all book items where count more than zero.
Thanks in advance for your help!
Here is the structure of database
I'm not sure why you are trying to query the entire table to check if there is any record, yet you can do something like:
var query = context.Books.Any() ? context.Books.ToList() : null;
if (query is not null)
{
query.ForEach(b =>
{
Console.WriteLine($"ID:{b.Id}, Title:{b.Title}");
});
}
However, if you are trying to find out if there is duplication available, you can use the following query:
var query = context.Books.FirstOrDefault(b => b.Title == "some title")
is not null ? context.Books.ToList() : null;
if (query is not null)
{
query.ForEach(b =>
{
Console.WriteLine($"ID:{b.Id}, Title:{b.Title}");
});
}
By the way, I don't think it is a good idea to have such a scenario.

Conditions in prepared statements in postgres

I need to add a condition inside prepared statement in postgres.
Pseudocode (doesn't works, fires an error "argument of WHERE must be type boolean, not type text"):
if (nameFilter) {
whereParam = `name LIKE %${nameFilter}%`
} else {
whereParam = "true"
}
let query = prepare("SELECT * FROM users WHERE $1", whereParam);
Pseudocode (works but looks ugly):
if (nameFilter) {
likeParam = `%${nameFilter}%`
} else {
likeParam = "%"
}
let query = prepare("SELECT * FROM users WHERE name LIKE $1", likeParam);
For some reasons(query is really complex with a bunch of AND) manipulations with a string is not an option, so this will not help
if (nameFilter) {
q = `SELECT * FROM users WHERE name LIKE $1`
} else {
q = "SELECT * FROM users"
}
let query = prepare(q, nameFilter);
Desirable to have statement similar to SELECT * FROM users WHERE $1 AND $2 AND $3 ...
Any suggestions?
This query will work for you.
select * from users where
case
when coalesce($1, '') = '' then true
else (name ~ $1)
end;
The only thing you can pass as a parameter is a constant; you cannot pass part of an SQL query like name LIKE '%pattern%'.
So if your query is really different every time, you have to construct the SQL string in your code, just like you say you cannot do "for some reasons".
It may be annoying, but there is no other way.
When you construct an SQL statement, make sure you never concatenate strings like this:
sql = "SELECT * FROM users WHERE username ='" + username + "'"
because that would be vulnerable to SQL injection.

TypeORM / Postgres - Include all in relation where at least one meets requirement

I am very new to SQL/TypeORM in general and I'm currently facing a problem where I want to load match participants related to a match where at least one participant has a passed userId. The query could be thought of as "Load all my matches with my opponents". I have three tables:
public.match << OneToMany >> public.match_participant << ManyToOne >> public.user
So far I have gone about doing:
select * from public.match m
left join public.match_participant mp on mp."matchId" = m.id
left join public.user u on u.id = mp."userId"
where u.id = 3
and in typeORM
repository
.createQueryBuilder('match')
.leftJoinAndSelect('match.participants', 'participants')
.leftJoinAndSelect('participants.user', 'user')
.where('user.id=:id')
.setParameter('id', 1)
.getMany();
Which of course loads all matches, participants and users for that particular userId but other participants are not included. I believe something like a "subquery" could be of use but I can't seem to figure it out.
Any help is greatly appreciated!
Thanks in advance.
After a bunch of trial and error I learned how to convert a pure query to the builder. The solution was the following:
matchRepository
.createQueryBuilder('match')
.innerJoin(
query => {
return query
.from(MatchParticipant, 'p')
.select('p."matchId"')
.where('p."userId" = :id');
},
'selfMatch',
'"selfMatch"."matchId" = match.id',
)
.leftJoinAndSelect('match.participants', 'participants')
.leftJoinAndSelect('participants.user', 'user')
.setParameter('id', id)
.getMany();
I don't think you even need the query builder for this.
#Entity()
class Match {
#OneToMany(...)
participants: MatchParticipant[];
}
#Entity()
class MatchParticipant {
#ManyToOne(...)
match: Match;
#ManyToOne(...)
participant: Participant;
}
#Entity()
class User {
#OneToMany(...)
matches: MatchParticipant[];
}
// ...
repository.manager.find(MatchParticipant, { where: { match: { participants: { participant: { id } } } } });

How to Data Fetch using Entity Framework in dotnet core

I have a table called "UserAnswers".below screenshot contains table data
I want to get data by surveyId and group by CreatedBy column.
for an example
There is a user called "amara#gmail.com".this user contains 4 records for a SurveyId.
I want to get this like below
Answers : [
{"2"},
{"1","0","1","1"},
{"1","2","4","3"},
{"Blue"}]
But my code returns this array for every rows.I meant duplicate records returning.
Here is my code
var qstns = await (from uans in _context.UserAnswers
where uans.SurveyId == id
select new UserAnswersReturnDto
{
UserEmail = uans.CreatedBy,
Qustns = (from ans in _context.UserAnswers
where ans.CreatedBy == uans.CreatedBy
select new UserAnswersSet
{
QNo = ans.QNo,
Ansrs = JsonConvert.DeserializeObject<JArray>(string.IsNullOrEmpty(ans.Answers) ? "[]" : ans.Answers)
}).ToArray()
}).ToListAsync();
So how to solve this issue.I opened many questions for this problem,but no one answered.Please help me.Thanks in advanced
You need to actually group your data before returning:
I used LINQ Lambda notation, but it should be quite easy to translate back to query if you're so inclined:
var qstns = _context.UserAnswers.Where(uans => uans.SurveyId == id)
.GroupBy(uans => uans.CreatedBy)
.Select(grans => new UserAnswersReturnDto {
UserEmail = grans.Key,
Qustions = grans.Select(ans => new UserAnswersSet() {
QNo = ans.QNo,
Ansrs = ans.Answers
}).ToList()
} ).ToList();
I didn't have time to double-check this, but I hope it serves as a guide to help you solve your issue!
There is no group by statement in your linq query.

How to use multiple placeholder values with LIKE sql in mysqljs/mysql?

It's easy to get this to work if there's only one placeholder value. For example:
con.query('select * from user where firstname like ?', "%" + firstname + "%", (err, result) => {
// do something
});
If you have two placeholders, you need to put them in an array, like so:
con.query('select * from user where firstname = ? and lastname = ?', ['Joe', 'Bloggs'], (err, result) => {
// do something
});
How can I convert this query so it will work with like? In other words, how can I get this to work:
con.query('select * from user where firstname like ? and lastname like ?', myArray, (err, result) => {
// do something
});
I need to somehow make myArray act like ['%Joe%', '%Bloggs%'].
Thank you.
I know it's late, but it maybe useful with someone with same question.
You can use something like this
"SELECT * FROM user WHERE firstname LIKE concat('%' , ?, '%') and lastname LIKE concat('%' , ?, '%')"