Get example running again with default index locations
This commit is contained in:
parent
78693a7b1e
commit
3055cb96ec
8 changed files with 107 additions and 76 deletions
|
@ -22,13 +22,13 @@ ghee set -s name=Wulfrum -s id=0 -s state=CA ./people/Wulfrum
|
|||
ghee idx -v -k id ./people ./people:id
|
||||
|
||||
# Index the dataset by state and ID
|
||||
ghee idx -v -k state -k id ./people ./people:state:id
|
||||
ghee idx -v -k state -k id ./people
|
||||
|
||||
# Get the name of everybody from California
|
||||
ghee get -w state=CA -f name ./people
|
||||
|
||||
# Get the name of everybody from California, taking advantage of the state index
|
||||
# This will avoid traversing irrelevant portions of the index
|
||||
ghee get -w state=CA -f name ./people:state:id
|
||||
ghee get -w state=CA -f name ./people/:state:id
|
||||
|
||||
cd ..
|
|
@ -137,7 +137,7 @@ enum Commands {
|
|||
#[arg(help = "Path to recursively index")]
|
||||
src: PathBuf,
|
||||
#[arg(help = "Path to output the new index to")]
|
||||
dest: PathBuf,
|
||||
dest: Option<PathBuf>,
|
||||
#[arg(name = "key", short, long, help = "xattrs to index by")]
|
||||
keys: Vec<Xattr>,
|
||||
#[arg(short, long)]
|
||||
|
|
|
@ -8,16 +8,21 @@ use walkdir::WalkDir;
|
|||
|
||||
use crate::parser::assignment::Assignment;
|
||||
use crate::parser::value::Value;
|
||||
use crate::paths::sub_idx_path;
|
||||
use crate::XATTR_KEY;
|
||||
use crate::{cmd::set, parser::key::Key};
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub fn idx(src: &PathBuf, dest: &PathBuf, keys: &Key, verbose: &bool) {
|
||||
pub fn idx(src: &PathBuf, dest: &Option<PathBuf>, keys: &Key, verbose: &bool) {
|
||||
if keys.is_empty() {
|
||||
panic!("No keys were provided to index by");
|
||||
}
|
||||
|
||||
let dest = dest.clone().unwrap_or_else(|| {
|
||||
sub_idx_path(src, keys).unwrap_or_else(|e| panic!("Could not get sub-index path: {}", e))
|
||||
});
|
||||
|
||||
for entry in WalkDir::new(src) {
|
||||
let entry = entry.unwrap_or_else(|e| panic!("Could not read directory: {}", e));
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ extern crate lazy_static;
|
|||
pub mod cli;
|
||||
pub mod cmd;
|
||||
pub mod parser;
|
||||
pub mod paths;
|
||||
|
||||
use parser::xattr::{parse_xattr, Xattr};
|
||||
use xdg::BaseDirectories;
|
||||
|
|
|
@ -17,6 +17,35 @@ pub fn array(i: &[u8]) -> IResult<&[u8], Vec<Value>> {
|
|||
)(i)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_array() {
|
||||
assert_eq!(
|
||||
array(b"[1,2,3,4]".as_slice()),
|
||||
Ok((
|
||||
b"".as_slice(),
|
||||
vec![1f64, 2f64, 3f64, 4f64]
|
||||
.into_iter()
|
||||
.map(Value::from)
|
||||
.collect()
|
||||
))
|
||||
);
|
||||
assert_eq!(
|
||||
array(b"[ 1 ,2 , 3, A, \"B\" ,\"C\",Defg]"),
|
||||
Ok((
|
||||
b"".as_slice(),
|
||||
vec![
|
||||
Value::from(1f64),
|
||||
Value::from(2f64),
|
||||
Value::from(3f64),
|
||||
Value::from("A"),
|
||||
Value::from("B"),
|
||||
Value::from("C"),
|
||||
Value::from("Defg")
|
||||
]
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
pub mod assignment;
|
||||
pub mod index;
|
||||
pub mod key;
|
||||
|
|
|
@ -2,61 +2,17 @@ use std::{collections::HashMap, ffi::OsStr};
|
|||
|
||||
use clap::{builder::TypedValueParser, Arg, Command};
|
||||
use nom::{
|
||||
bytes::complete::take_while,
|
||||
character::complete::char,
|
||||
character::is_space,
|
||||
multi::separated_list0,
|
||||
sequence::{delimited, pair, terminated},
|
||||
sequence::{pair, terminated},
|
||||
IResult,
|
||||
};
|
||||
|
||||
use super::{
|
||||
relation::{parse_relation, Relation},
|
||||
value::{parse_value, Value},
|
||||
space,
|
||||
value::Value,
|
||||
xattr::{parse_xattr, Xattr},
|
||||
};
|
||||
|
||||
fn space(i: &[u8]) -> IResult<&[u8], &[u8]> {
|
||||
take_while(move |x| is_space(x))(i)
|
||||
}
|
||||
|
||||
fn array(i: &[u8]) -> IResult<&[u8], Vec<Value>> {
|
||||
delimited(
|
||||
char('['),
|
||||
separated_list0(char(','), delimited(space, parse_value, space)),
|
||||
char(']'),
|
||||
)(i)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_array() {
|
||||
assert_eq!(
|
||||
array(b"[1,2,3,4]".as_slice()),
|
||||
Ok((
|
||||
b"".as_slice(),
|
||||
vec![1f64, 2f64, 3f64, 4f64]
|
||||
.into_iter()
|
||||
.map(Value::from)
|
||||
.collect()
|
||||
))
|
||||
);
|
||||
assert_eq!(
|
||||
array(b"[ 1 ,2 , 3, A, \"B\" ,\"C\",Defg]"),
|
||||
Ok((
|
||||
b"".as_slice(),
|
||||
vec![
|
||||
Value::from(1f64),
|
||||
Value::from(2f64),
|
||||
Value::from(3f64),
|
||||
Value::from("A"),
|
||||
Value::from("B"),
|
||||
Value::from("C"),
|
||||
Value::from("Defg")
|
||||
]
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Predicate {
|
||||
xattr: Xattr,
|
||||
|
@ -81,6 +37,28 @@ fn parse_predicate(i: &[u8]) -> IResult<&[u8], Predicate> {
|
|||
.map(|(i, (xattr, relation))| (i, Predicate { xattr, relation }))
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct PredicateParser;
|
||||
impl TypedValueParser for PredicateParser {
|
||||
type Value = Predicate;
|
||||
|
||||
fn parse_ref(
|
||||
&self,
|
||||
_cmd: &Command,
|
||||
_arg: Option<&Arg>,
|
||||
value: &OsStr,
|
||||
) -> Result<Self::Value, clap::error::Error<clap::error::RichFormatter>> {
|
||||
parse_predicate(value.to_string_lossy().as_bytes())
|
||||
.map(|(_remainder, predicate)| predicate)
|
||||
.map_err(|e| {
|
||||
clap::error::Error::raw(
|
||||
clap::error::ErrorKind::InvalidValue,
|
||||
format!("Malformed WHERE clause: {}\n", e),
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_predicate() {
|
||||
assert!(parse_predicate(b"").is_err());
|
||||
|
@ -131,25 +109,3 @@ fn test_parse_predicate() {
|
|||
))
|
||||
);
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct PredicateParser;
|
||||
impl TypedValueParser for PredicateParser {
|
||||
type Value = Predicate;
|
||||
|
||||
fn parse_ref(
|
||||
&self,
|
||||
_cmd: &Command,
|
||||
_arg: Option<&Arg>,
|
||||
value: &OsStr,
|
||||
) -> Result<Self::Value, clap::error::Error<clap::error::RichFormatter>> {
|
||||
parse_predicate(value.to_string_lossy().as_bytes())
|
||||
.map(|(_remainder, predicate)| predicate)
|
||||
.map_err(|e| {
|
||||
clap::error::Error::raw(
|
||||
clap::error::ErrorKind::InvalidValue,
|
||||
format!("Malformed WHERE clause: {}\n", e),
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use nom::bytes::complete::is_not;
|
||||
use nom::combinator::map;
|
||||
use nom::number::complete::double;
|
||||
|
||||
|
@ -29,7 +30,12 @@ impl Value {
|
|||
pub fn as_bytes(&self) -> Vec<u8> {
|
||||
match self {
|
||||
Self::Number(x) => format!("{}", x).into_bytes(),
|
||||
Self::String(s) => s.clone().into_bytes(),
|
||||
Self::String(s) => {
|
||||
let mut bytes = s.clone().into_bytes();
|
||||
bytes.insert(0, b'"');
|
||||
bytes.push(b'"');
|
||||
bytes
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -95,8 +101,8 @@ impl Into<serde_json::Value> for Value {
|
|||
|
||||
pub fn string(i: &[u8]) -> IResult<&[u8], String> {
|
||||
alt((
|
||||
delimited(tag("'"), take_while(is_alphanumeric), tag("'")),
|
||||
delimited(tag("\""), take_while(is_alphanumeric), tag("\"")),
|
||||
delimited(tag("'"), is_not("'"), tag("'")),
|
||||
delimited(tag("\""), is_not("\""), tag("\"")),
|
||||
take_while1(is_alphanumeric),
|
||||
))(i)
|
||||
.map(|(i, b)| (i, String::from_utf8_lossy(b).to_string()))
|
||||
|
|
34
src/paths.rs
Normal file
34
src/paths.rs
Normal file
|
@ -0,0 +1,34 @@
|
|||
use std::{ffi::OsString, os::unix::prelude::OsStringExt, path::PathBuf};
|
||||
|
||||
use thiserror::Error;
|
||||
|
||||
use crate::parser::key::Key;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum SubIdxPathErr {
|
||||
#[error("The provided key was empty")]
|
||||
EmptyKey,
|
||||
}
|
||||
|
||||
/// The path of a sub-index: an index nested inside another (primary) index
|
||||
pub fn sub_idx_path(view_of: &PathBuf, key: &Key) -> Result<PathBuf, SubIdxPathErr> {
|
||||
if key.is_empty() {
|
||||
return Err(SubIdxPathErr::EmptyKey);
|
||||
}
|
||||
|
||||
let mut sub_idx_dirname = OsString::new();
|
||||
|
||||
for k in key {
|
||||
sub_idx_dirname.push(":");
|
||||
if k.namespace == b"user" {
|
||||
sub_idx_dirname.push(OsString::from_vec(k.attr.clone()));
|
||||
} else {
|
||||
sub_idx_dirname.push(k.to_osstring());
|
||||
}
|
||||
}
|
||||
|
||||
let mut sub_idx_path = view_of.clone();
|
||||
sub_idx_path.push(sub_idx_dirname);
|
||||
|
||||
Ok(sub_idx_path)
|
||||
}
|
Loading…
Reference in a new issue