# # patch "ChangeLog" # from [097d8f47e66d6e5bb6a37dd162dcb10f785b8f40] # to [888cab399a68084c7dee66ed01fd629b98f7b727] # # patch "database.cc" # from [1ce26993177acbeb3e3d18aba17f43700372fa3c] # to [054d9765b4084da31a9e5c0e986e0ce1136255f6] # # patch "selectors.cc" # from [af2e5813aba3cdf936fbcbb31dbb05ddf3690ccc] # to [5c73d531eae8b524e9ef29211fb230f93a6ccee7] # # patch "selectors.hh" # from [54ed172da5c3a3c4721152012d831f51e693cab9] # to [495c9e9014fa7c7e33229630743f74e28751b6ad] # --- ChangeLog +++ ChangeLog @@ -1,3 +1,9 @@ +2005-06-26 Brian Downing + + * selectors.cc, database.cc: Implemented an 'h:' head selector. + 'h:net.venge.monotone' expands to all the heads on that branch, + 'h:' expands to all the heads on the current branch. + 2005-06-24 Nathaniel Smith * unix/process.cc (process_spawn): Format log output correctly. --- database.cc +++ database.cc @@ -2188,6 +2188,8 @@ break; case selectors::sel_ident: case selectors::sel_cert: + case selectors::sel_head: + case selectors::sel_raw: case selectors::sel_unknown: I(false); // don't do this. break; @@ -2221,9 +2223,13 @@ first_limit = false; else lim += " INTERSECT "; - - if (i->first == selectors::sel_ident) + + if (i->first == selectors::sel_raw) { + lim += i->second; + } + else if (i->first == selectors::sel_ident) + { lim += "SELECT id FROM revision_certs "; lim += (F("WHERE id GLOB '%s*'") % i->second).str(); --- selectors.cc +++ selectors.cc @@ -64,6 +64,9 @@ case 'e': type = sel_earlier; break; + case 'h': + type = sel_head; + break; default: W(F("unknown selector type: %c\n") % sel[0]); break; @@ -99,7 +102,42 @@ { std::string sel; decode_selector(orig_sel, type, sel, app); - app.db.complete(type, sel, limit, completions); + // Replace any head selectors in the limit with raw SQL with the + // heads hardcoded in, as the head-discovery code is way too + // complex to express in SQL. + std::vector > new_limit; + for (std::vector >::const_iterator i + = limit.begin(); + i != limit.end(); ++i) + { + if (i->first == sel_head) + { + std::set heads; + if (i->second.length() > 0) + get_branch_heads(i->second, app, heads); + else + get_branch_heads(app.branch_name(), app, heads); + bool first = true; + std::string request = "SELECT id FROM revision_certs WHERE "; + for (std::set::const_iterator i = heads.begin(); + i != heads.end(); ++i) + { + if (first) + first = false; + else + request += " OR "; + request += (F("id='%s'") % i->inner()()).str(); + } + if (first) + request += "id='none'"; // find nothing + new_limit.push_back(std::make_pair(sel_raw, request)); + } + else + { + new_limit.push_back(std::make_pair(i->first, i->second)); + } + } + app.db.complete(type, sel, new_limit, completions); } std::vector > --- selectors.hh +++ selectors.hh @@ -27,6 +27,8 @@ sel_cert, sel_earlier, sel_later, + sel_head, + sel_raw, sel_unknown } selector_type;