-
Hey, there I want to perform full text search across a column for which I need to execute query like SELECT app_name, mainfest FROM mainfests_fts WHERE mainfest MATCH ("android", "cli"); In this, fn query_fts(repos: Vec<PathBuf>, query: &str) -> Result<Vec<RawData>, ScoopieError> {
let args: Vec<&str> = query.split(" ").collect();
let fetch_row = |row: &Row| -> Result<MainfestEntry, Error> {
let app_name = row.get(0)?;
let mainfest = row.get(1)?;
Ok(MainfestEntry { app_name, mainfest })
};
let results: Result<Vec<Vec<RawData>>, ScoopieError> = repos
.par_iter()
.map(|repo| -> Result<Vec<RawData>, ScoopieError> {
let conn = Connection::open(&repo)
.map_err(|_| ScoopieError::Database(DatabaseError::UnableToOpen))?;
let mut stmt = conn
.prepare("SELECT app_name, mainfest FROM mainfests_fts WHERE mainfest MATCH (?)")
.map_err(|_| ScoopieError::Database(DatabaseError::FailedToMkStmt))?;
let rows = stmt
.query_map(params![args], fetch_row)
.map_err(|_| ScoopieError::Query(QueryError::FailedToQuery))?;
rows.into_iter()
.map(|row| -> Result<RawData, ScoopieError> {
let row =
row.map_err(|_| ScoopieError::Query(QueryError::FailedToRetrieveData))?;
let app_name = row.app_name;
let mainfest = row.mainfest;
Ok(RawData::new(&repo, app_name, mainfest))
})
.collect()
})
.collect();
let results: Vec<Vec<RawData>> = results?;
Ok(results.concat())
} But on compilation it returns: error[E0425]: cannot find value `repos` in this scope
--> src\query.rs:67:60
|
67 | let results: Result<Vec<Vec<RawData>>, ScoopieError> = repos
| ^^^^^ help: a local variable with a similar name exists: `repo`
error[E0277]: the trait bound `Vec<&str>: ToSql` is not satisfied
--> src\query.rs:78:28
|
78 | .query_map(params![args], fetch_row)
| ^^^^^^^^^^^^^ the trait `ToSql` is not implemented for `Vec<&str>`
|
= help: the trait `ToSql` is implemented for `Vec<u8>`
= note: required for the cast from `Vec<&str>` to the object type `dyn ToSql`
= note: this error originates in the macro `params` (in Nightly builds, run with -Z macro-backtrace for more info)
Some errors have detailed explanations: E0277, E0425.
For more information about an error, try `rustc --explain E0277`.
error: could not compile `scoopie` (bin "scoopie") due to 2 previous errors What could be possible solution to achieve it. |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 13 replies
-
https://github.com/rusqlite/rusqlite/issues?page=2&q=is%3Aissue+vec |
Beta Was this translation helpful? Give feedback.
-
Hey there, I have found solution for this without needing to unpack vector in parameter. Here it is: fn query_fts(query: &str) -> Result<Vec<AppInfo>, ScoopieError> {
let query = query
.split_whitespace()
.map(|term| format!("{term}*"))
.collect::<Vec<String>>()
.join(" AND ");
let results = Query::builder(
"SELECT app_name, mainfest FROM mainfests_fts WHERE mainfest MATCH ? COLLATE nocase",
)?
.run(&query)?;
results
.par_iter()
.map(|raw_result| AppInfo::from(raw_result))
.collect()
}
pub struct Query {
repos: Vec<PathBuf>,
stmt: String,
}
impl Query {
pub fn builder(stmt: &str) -> Result<Query, ScoopieError> {
let repos = Config::read()?.latest_repos()?;
Ok(Self {
repos,
stmt: stmt.into(),
})
}
pub fn run(&self, params: &str) -> Result<Vec<RawData>, ScoopieError> {
let fetch_row = |row: &Row| -> Result<(String, String), Error> {
let app_name = row.get(0)?;
let mainfest = row.get(1)?;
Ok((app_name, mainfest))
};
let results: Result<Vec<Vec<RawData>>, ScoopieError> = self
.repos
.par_iter()
.map(|repo| -> Result<Vec<RawData>, ScoopieError> {
let conn = Connection::open(&repo)
.map_err(|_| ScoopieError::Database(DatabaseError::UnableToOpen))?;
let mut stmt = conn
.prepare(&self.stmt)
.map_err(|_| ScoopieError::Database(DatabaseError::FailedToMkStmt))?;
let rows = stmt
.query_map(params![params], fetch_row)
.map_err(|_| ScoopieError::Query(QueryError::FailedToQuery))?;
rows.into_iter()
.map(|row| -> Result<RawData, ScoopieError> {
let row =
row.map_err(|_| ScoopieError::Query(QueryError::FailedToRetrieveData))?;
let app_name = row.0;
let mainfest = row.1;
Ok(RawData::new(&repo, app_name, mainfest))
})
.collect()
})
.collect();
let results = results?;
Ok(results.concat())
}
} however it doesn't gives the desired result as below query gives SELECT app_name, mainfest FROM mainfests_fts WHERE mainfest MATCH ("android", "cli"); Until I found any good solution, I'm closing this discussion till then. |
Beta Was this translation helpful? Give feedback.
Because rarray is a table-valued-function:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=d954eabbcce57ae2e36ff4445384ad7e