@@ -443,6 +443,13 @@ lazy_static! {
443443 LIMIT :limit" ,
444444 common_select_sql = COMMON_METADATA_SELECT
445445 ) ;
446+ static ref SEARCH_QUERY_SQL : String = format!(
447+ "{common_select_sql}
448+ WHERE search_term NOT NULL
449+ ORDER BY updated_at DESC
450+ LIMIT :limit" ,
451+ common_select_sql = COMMON_METADATA_SELECT
452+ ) ;
446453 static ref QUERY_SQL : String = format!(
447454 "{common_select_sql}
448455 WHERE
@@ -507,6 +514,20 @@ pub fn get_most_recent(db: &PlacesDb, limit: i32) -> Result<Vec<HistoryMetadata>
507514 )
508515}
509516
517+ // Returns the most recent history metadata entries where search term is not null (newest first),
518+ // limited by `limit`.
519+ //
520+ // Internally this uses [`SEARCH_QUERY_SQL`], ordered by descending `updated_at`.
521+ pub fn get_most_recent_search_entries ( db : & PlacesDb , limit : i32 ) -> Result < Vec < HistoryMetadata > > {
522+ db. query_rows_and_then_cached (
523+ SEARCH_QUERY_SQL . as_str ( ) ,
524+ rusqlite:: named_params! {
525+ ":limit" : limit,
526+ } ,
527+ HistoryMetadata :: from_row,
528+ )
529+ }
530+
510531pub fn get_highlights (
511532 db : & PlacesDb ,
512533 weights : HistoryHighlightWeights ,
@@ -1486,6 +1507,213 @@ mod tests {
14861507 assert_eq ! ( most_recents[ 2 ] . url, "https://example.com/1" ) ;
14871508 }
14881509
1510+ #[ test]
1511+ fn test_get_most_recent_search_entries_empty ( ) {
1512+ let conn = PlacesDb :: open_in_memory ( ConnectionType :: ReadWrite ) . expect ( "memory db" ) ;
1513+ let rows = get_most_recent_search_entries ( & conn, 5 ) . expect ( "query ok" ) ;
1514+ assert ! ( rows. is_empty( ) ) ;
1515+ }
1516+
1517+ #[ test]
1518+ fn test_get_most_recent_search_entries_with_limits_and_same_observation ( ) {
1519+ let conn = PlacesDb :: open_in_memory ( ConnectionType :: ReadWrite ) . expect ( "memory db" ) ;
1520+
1521+ note_observation ! ( & conn,
1522+ url "http://mozilla.org/1/" ,
1523+ view_time None ,
1524+ search_term Some ( "search_term_1" ) ,
1525+ document_type None ,
1526+ referrer_url None ,
1527+ title None
1528+ ) ;
1529+
1530+ bump_clock ( ) ;
1531+
1532+ note_observation ! ( & conn,
1533+ url "http://mozilla.org/1/" ,
1534+ view_time None ,
1535+ search_term Some ( "search_term_1" ) ,
1536+ document_type None ,
1537+ referrer_url None ,
1538+ title None
1539+ ) ;
1540+
1541+ bump_clock ( ) ;
1542+
1543+ note_observation ! ( & conn,
1544+ url "http://mozilla.org/1/" ,
1545+ view_time None ,
1546+ search_term Some ( "search_term_1" ) ,
1547+ document_type None ,
1548+ referrer_url None ,
1549+ title None
1550+ ) ;
1551+
1552+ // Limiting to 1 should return the most recent entry where search is not null.
1553+ let most_recents1 = get_most_recent_search_entries ( & conn, 1 ) . expect ( "query ok" ) ;
1554+ assert_eq ! ( most_recents1. len( ) , 1 ) ;
1555+ assert_eq ! ( most_recents1[ 0 ] . url, "http://mozilla.org/1/" ) ;
1556+
1557+ // Limiting to 3 should also return one entry, since we only have one unique URL.
1558+ let most_recents2 = get_most_recent_search_entries ( & conn, 3 ) . expect ( "query ok" ) ;
1559+ assert_eq ! ( most_recents2. len( ) , 1 ) ;
1560+ assert_eq ! ( most_recents2[ 0 ] . url, "http://mozilla.org/1/" ) ;
1561+
1562+ // Limiting to 10 should also return one entry, since we only have one unique URL.
1563+ let most_recents3 = get_most_recent_search_entries ( & conn, 10 ) . expect ( "query ok" ) ;
1564+ assert_eq ! ( most_recents3. len( ) , 1 ) ;
1565+ assert_eq ! ( most_recents3[ 0 ] . url, "http://mozilla.org/1/" ) ;
1566+ }
1567+
1568+ #[ test]
1569+ fn test_get_most_recent_search_entries_with_limits_and_different_observations ( ) {
1570+ let conn = PlacesDb :: open_in_memory ( ConnectionType :: ReadWrite ) . expect ( "memory db" ) ;
1571+
1572+ note_observation ! ( & conn,
1573+ url "http://mozilla.org/1/" ,
1574+ view_time None ,
1575+ search_term Some ( "search_term_1" ) ,
1576+ document_type None ,
1577+ referrer_url None ,
1578+ title None
1579+ ) ;
1580+
1581+ bump_clock ( ) ;
1582+
1583+ note_observation ! ( & conn,
1584+ url "http://mozilla.org/2/" ,
1585+ view_time Some ( 20 ) ,
1586+ search_term None ,
1587+ document_type Some ( DocumentType :: Regular ) ,
1588+ referrer_url None ,
1589+ title None
1590+ ) ;
1591+
1592+ bump_clock ( ) ;
1593+
1594+ note_observation ! ( & conn,
1595+ url "http://mozilla.org/3/" ,
1596+ view_time None ,
1597+ search_term Some ( "search_term_2" ) ,
1598+ document_type None ,
1599+ referrer_url None ,
1600+ title None
1601+ ) ;
1602+
1603+ bump_clock ( ) ;
1604+
1605+ note_observation ! ( & conn,
1606+ url "http://mozilla.org/4/" ,
1607+ view_time None ,
1608+ search_term Some ( "search_term_3" ) ,
1609+ document_type None ,
1610+ referrer_url None ,
1611+ title None
1612+ ) ;
1613+
1614+ // Limiting to 1 should return the most recent entry where search is not null.
1615+ let most_recents1 = get_most_recent_search_entries ( & conn, 1 ) . expect ( "query ok" ) ;
1616+ assert_eq ! ( most_recents1. len( ) , 1 ) ;
1617+ assert_eq ! ( most_recents1[ 0 ] . url, "http://mozilla.org/4/" ) ;
1618+
1619+ // Limiting to 2 should return the two most recent entries.
1620+ let most_recents2 = get_most_recent_search_entries ( & conn, 2 ) . expect ( "query ok" ) ;
1621+ assert_eq ! ( most_recents2. len( ) , 2 ) ;
1622+ assert_eq ! ( most_recents2[ 0 ] . url, "http://mozilla.org/4/" ) ;
1623+ assert_eq ! ( most_recents2[ 1 ] . url, "http://mozilla.org/3/" ) ;
1624+
1625+ // Limiting to 10 should return all three entries, in the correct order.
1626+ let most_recents3 = get_most_recent_search_entries ( & conn, 10 ) . expect ( "query ok" ) ;
1627+ assert_eq ! ( most_recents3. len( ) , 3 ) ;
1628+ assert_eq ! ( most_recents3[ 0 ] . url, "http://mozilla.org/4/" ) ;
1629+ assert_eq ! ( most_recents3[ 1 ] . url, "http://mozilla.org/3/" ) ;
1630+ assert_eq ! ( most_recents3[ 2 ] . url, "http://mozilla.org/1/" ) ;
1631+ }
1632+
1633+ #[ test]
1634+ fn test_get_most_recent_search_entries_with_negative_limit_with_same_observation ( ) {
1635+ let conn = PlacesDb :: open_in_memory ( ConnectionType :: ReadWrite ) . expect ( "memory db" ) ;
1636+
1637+ note_observation ! ( & conn,
1638+ url "http://mozilla.org/1/" ,
1639+ view_time None ,
1640+ search_term Some ( "search_term_1" ) ,
1641+ document_type None ,
1642+ referrer_url None ,
1643+ title None
1644+ ) ;
1645+
1646+ bump_clock ( ) ;
1647+
1648+ note_observation ! ( & conn,
1649+ url "http://mozilla.org/1/" ,
1650+ view_time None ,
1651+ search_term Some ( "search_term_1" ) ,
1652+ document_type None ,
1653+ referrer_url None ,
1654+ title None
1655+ ) ;
1656+
1657+ bump_clock ( ) ;
1658+
1659+ note_observation ! ( & conn,
1660+ url "http://mozilla.org/1/" ,
1661+ view_time None ,
1662+ search_term Some ( "search_term_1" ) ,
1663+ document_type None ,
1664+ referrer_url None ,
1665+ title None
1666+ ) ;
1667+
1668+ // Limiting to -1 should return all entries properly ordered.
1669+ let most_recents = get_most_recent_search_entries ( & conn, -1 ) . expect ( "query ok" ) ;
1670+ assert_eq ! ( most_recents. len( ) , 1 ) ;
1671+ assert_eq ! ( most_recents[ 0 ] . url, "http://mozilla.org/1/" ) ;
1672+ }
1673+
1674+ #[ test]
1675+ fn test_get_most_recent_search_entries_with_negative_limit_with_different_observations ( ) {
1676+ let conn = PlacesDb :: open_in_memory ( ConnectionType :: ReadWrite ) . expect ( "memory db" ) ;
1677+
1678+ note_observation ! ( & conn,
1679+ url "http://mozilla.org/1/" ,
1680+ view_time None ,
1681+ search_term Some ( "search_term_1" ) ,
1682+ document_type None ,
1683+ referrer_url None ,
1684+ title None
1685+ ) ;
1686+
1687+ bump_clock ( ) ;
1688+
1689+ note_observation ! ( & conn,
1690+ url "http://mozilla.org/2/" ,
1691+ view_time None ,
1692+ search_term Some ( "search_term_2" ) ,
1693+ document_type None ,
1694+ referrer_url None ,
1695+ title None
1696+ ) ;
1697+
1698+ bump_clock ( ) ;
1699+
1700+ note_observation ! ( & conn,
1701+ url "http://mozilla.org/3/" ,
1702+ view_time None ,
1703+ search_term Some ( "search_term_3" ) ,
1704+ document_type None ,
1705+ referrer_url None ,
1706+ title None
1707+ ) ;
1708+
1709+ // Limiting to -1 should return all entries properly ordered.
1710+ let most_recents = get_most_recent_search_entries ( & conn, -1 ) . expect ( "query ok" ) ;
1711+ assert_eq ! ( most_recents. len( ) , 3 ) ;
1712+ assert_eq ! ( most_recents[ 0 ] . url, "http://mozilla.org/3/" ) ;
1713+ assert_eq ! ( most_recents[ 1 ] . url, "http://mozilla.org/2/" ) ;
1714+ assert_eq ! ( most_recents[ 2 ] . url, "http://mozilla.org/1/" ) ;
1715+ }
1716+
14891717 #[ test]
14901718 fn test_get_highlights ( ) {
14911719 let conn = PlacesDb :: open_in_memory ( ConnectionType :: ReadWrite ) . expect ( "memory db" ) ;
0 commit comments