Skip to content
This repository has been archived by the owner on Dec 4, 2023. It is now read-only.

Commit

Permalink
feat: prep work for fuzzy matching
Browse files Browse the repository at this point in the history
  • Loading branch information
mkenigs committed Aug 21, 2023
1 parent 48a21c1 commit c577716
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 0 deletions.
9 changes: 9 additions & 0 deletions include/flox/pkgdb/read.hh
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "flox/core/exceptions.hh"
#include "flox/core/types.hh"
#include "flox/core/command.hh"
#include "flox/package.hh"


/* -------------------------------------------------------------------------- */
Expand Down Expand Up @@ -251,6 +252,14 @@ class PkgDbReadOnly {

}; /* End class `PkgDbReadOnly' */

/**
* Calculate a distance that can be used to order packages by how close they
* are to a match string.
* @param Package The Package to
* @param match String to look for in Package's fields.
* @return Distance between pkg and match.
*/
std::optional<size_t> distanceFromMatch( Package & pkg, std::string match );

/* -------------------------------------------------------------------------- */

Expand Down
5 changes: 5 additions & 0 deletions src/pkgdb/query-builder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ buildPkgQuery( PkgQueryArgs && params )
{
q.where( column( "pname" ) == ":pname" );
}

if ( params.match.has_value() && !params.match->empty() )
{
q.where( "( name LIKE '%:match%' ) OR ( description LIKE '%:match%' )" );
}

if ( params.version.has_value() )
{
Expand Down
43 changes: 43 additions & 0 deletions src/pkgdb/read.cc
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,49 @@ PkgDbReadOnly::getDescendantAttrSets( row_id root )
}


/* -------------------------------------------------------------------------- */

std::optional<size_t>
distanceFromMatch( Package & pkg, std::string match )
{
if ( match.empty() ) { return std::nullopt; }

std::string pname = pkg.getPname();
// TODO match on attrName. That's not currently possible because attrName is
// meaningful for flakes, but for catalogs, only the attrName of parent is
// meaningful (attrName is a version string).

// Don't give description any weight if pname matches exactly. It's not
// especially meaningful if a description mentions its own name.
if ( pname == match )
{
// pname matches exactly
return 0;
}

bool pnameMatches = (pname.find(match) != std::string::npos);
auto description = pkg.getDescription();
bool descriptionMatches = (description.has_value() && description->find(match) != std::string::npos);

if ( pnameMatches ) {
if ( descriptionMatches )
{
// pname and description match
return 1;
}
// only pname matches
return 2;
}

if ( descriptionMatches )
{
// only description matches
return 3;
}
// nothing matches
return 4;
}

/* -------------------------------------------------------------------------- */

} /* End Namespace `flox::pkgdb' */
Expand Down
67 changes: 67 additions & 0 deletions tests/read.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/* ========================================================================== *
*
* @file read.cc
*
* @brief Tests for `read.cc`.
*
*
* -------------------------------------------------------------------------- */

#include <assert.h>

#include "flox/pkgdb/read.hh"
#include "test.hh"
#include "flox/flake-package.hh"

/* -------------------------------------------------------------------------- */

/**
* Test ability to add `AttrSet` rows.
* This test should run before all others since it essentially expects
* `AttrSets` to be empty.
*/
bool
test_distanceFromMatch()
{
// auto pkg = flox::FlakePackage();
// flox::pkgdb::distanceFromMatch(pkg, "match");
return true;
}

/* ========================================================================== */

int
main( int argc, char * argv[] )
{
int ec = EXIT_SUCCESS;
# define RUN_TEST( ... ) _RUN_TEST( ec, __VA_ARGS__ )

/* -------------------------------------------------------------------------- */

nix::Verbosity verbosity;
if ( ( 1 < argc ) && ( std::string_view( argv[1] ) == "-v" ) )
{
verbosity = nix::lvlDebug;
}
else
{
verbosity = nix::lvlWarn;
}

/* -------------------------------------------------------------------------- */

{
RUN_TEST( distanceFromMatch );
}

/* -------------------------------------------------------------------------- */

return ec;
}


/* -------------------------------------------------------------------------- *
*
*
*
* ========================================================================== */

0 comments on commit c577716

Please sign in to comment.