Skip to content

Commit

Permalink
[MOD] Databases: refactorings
Browse files Browse the repository at this point in the history
  • Loading branch information
ChristianGruen committed Mar 3, 2025
1 parent f931bd2 commit 40f663a
Show file tree
Hide file tree
Showing 15 changed files with 84 additions and 89 deletions.
22 changes: 0 additions & 22 deletions basex-core/src/main/java/org/basex/core/Context.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import org.basex.query.util.pkg.*;
import org.basex.query.value.seq.*;
import org.basex.server.*;
import org.basex.util.list.*;
import org.basex.util.log.*;
import org.basex.util.options.*;

Expand Down Expand Up @@ -270,27 +269,6 @@ public String clientName() {
return client != null ? client.clientName() : user != null ? user.name() : null;
}

/**
* Returns all databases for which the current user has read access.
* @return resulting list
*/
public StringList listDBs() {
return listDBs(null);
}

/**
* Returns all databases for which the current user has read access.
* @param pattern database pattern (can be {@code null})
* @return resulting list
*/
public StringList listDBs(final String pattern) {
final StringList dbs = databases.listDBs(pattern), sl = new StringList(dbs.size());
for(final String db : dbs) {
if(user.has(Perm.READ, db)) sl.add(db);
}
return sl;
}

/**
* Assigns an external object.
* @param object external object
Expand Down
100 changes: 55 additions & 45 deletions basex-core/src/main/java/org/basex/core/Databases.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.util.*;
import java.util.regex.*;

import org.basex.core.users.*;
import org.basex.io.*;
import org.basex.util.*;
import org.basex.util.list.*;
Expand Down Expand Up @@ -45,73 +46,60 @@ public final class Databases {
}

/**
* Lists all available databases and backups.
* @return database and backup list
* Returns the sorted names of all databases and backups.
* @return databases and backups
*/
public StringList all() {
return list(null, null, true);
}

/**
* Returns the sorted names of all databases.
* @return databases and backups
*/
public StringList list() {
return list(true, null);
return list(null, null, false);
}

/**
* Lists all available databases matching the given name. Supports glob patterns.
* Returns the sorted names of all databases.
* @param user accessing user
* @param pattern database pattern (can be {@code null})
* @return database list
* @return databases
*/
StringList listDBs(final String pattern) {
return list(false, pattern);
public StringList list(final User user, final String pattern) {
return list(user, pattern, false);
}

/**
* Returns the sorted names of all available databases and, optionally, backups.
* Filters for {@code name} if not {@code null} with glob support.
* @param backup return backups?
* Returns the sorted names of all databases and, optionally, backups.
* @param user accessing user (can be {@code null})
* @param pattern database pattern (can be {@code null})
* @return database and backups list
* @param all include names of backed up databases
* @return databases and, optionally, backups
*/
private StringList list(final boolean backup, final String pattern) {
private StringList list(final User user, final String pattern, final boolean all) {
final Pattern pt = pattern == null ? null : regex(pattern);
final IOFile[] files = soptions.dbPath().children();
final StringList list = new StringList(files.length);
final HashSet<String> map = new HashSet<>(files.length);
for(final IOFile file : files) {
final StringList list = new StringList();
final HashSet<String> map = new HashSet<>();
for(final IOFile file : soptions.dbPath().children()) {
final String name = file.name();
String add = null;
if(backup && name.endsWith(IO.ZIPSUFFIX)) {
String entry = null;
if(all && name.endsWith(IO.ZIPSUFFIX)) {
final String[] split = ZIPPATTERN.split(name);
if(split.length > 0 && !split[0].equals(name)) add = split[0];
if(split.length > 0 && !split[0].equals(name)) entry = split[0];
} else if(file.isDir() && !Strings.startsWith(name, '.')) {
add = name;
entry = name;
}
// add entry if it matches the pattern, and has not already been added
if(add != null && (pt == null || pt.matcher(add).matches()) && map.add(add)) {
list.add(add);
// add entry if it has not already been added, matches the pattern, and is accessible
if(entry != null && map.add(entry) && (pt == null || pt.matcher(entry).matches()) &&
(user == null || user.has(Perm.READ, entry))) {
list.add(entry);
}
}
return list.sort(false);
}

/**
* Returns a regular expression for the specified name pattern.
* @param pattern pattern
* @return regular expression
*/
public static Pattern regex(final String pattern) {
return regex(pattern, "");
}

/**
* Returns a regular expression for the specified name pattern.
* @param pattern pattern (can be {@code null})
* @param suffix regular expression suffix
* @return regular expression or {@code null}
*/
private static Pattern regex(final String pattern, final String suffix) {
if(pattern == null) return null;
final String nm = REGEX.matcher(pattern).matches() ? IOFile.regex(pattern) :
pattern.replaceAll("([" + REGEXCHARS + "])", "\\\\$1") + suffix;
return Pattern.compile(nm, Prop.CASE ? 0 : Pattern.CASE_INSENSITIVE);
}

/**
* Returns the names of all backups.
* @return backups
Expand Down Expand Up @@ -146,6 +134,15 @@ public StringList backups(final String name) {
return backups.sort(Prop.CASE, false);
}

/**
* Returns a regular expression for the specified name pattern.
* @param pattern pattern
* @return regular expression
*/
public static Pattern regex(final String pattern) {
return regex(pattern, "");
}

/**
* Extracts the name of a database from the name of a backup.
* @param backup name of the backup (empty string for general data), optionally followed by date
Expand Down Expand Up @@ -193,6 +190,19 @@ public static boolean validPattern(final String pattern) {
return valid(pattern, true);
}

/**
* Returns a regular expression for the specified name pattern.
* @param pattern pattern (can be {@code null})
* @param suffix regular expression suffix
* @return regular expression or {@code null}
*/
private static Pattern regex(final String pattern, final String suffix) {
if(pattern == null) return null;
final String nm = REGEX.matcher(pattern).matches() ? IOFile.regex(pattern) :
pattern.replaceAll("([" + REGEXCHARS + "])", "\\\\$1") + suffix;
return Pattern.compile(nm, Prop.CASE ? 0 : Pattern.CASE_INSENSITIVE);
}

/**
* Checks if the specified string is a valid database name.
* @param name name to be checked (can be {@code null})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ protected boolean run() {
return error(NAME_INVALID_X, pattern);

// retrieve all databases
final StringList names = pattern.isEmpty() ? new StringList("") : context.listDBs(pattern);
final StringList names = pattern.isEmpty() ? new StringList("") :
context.databases.list(context.user(), pattern);
if(names.isEmpty()) return error(DB_NOT_FOUND_X, pattern);

// loop through all databases
Expand Down
8 changes: 5 additions & 3 deletions basex-core/src/main/java/org/basex/core/cmd/DropBackup.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,15 @@ protected boolean run() {
if(!(general || Databases.validPattern(pattern))) return error(NAME_INVALID_X, pattern);

// loop through all databases and collect databases to be dropped
final StringList names = general ? new StringList("") : context.listDBs(pattern);
final Databases db = context.databases;
final User user = context.user();
final StringList names = general ? new StringList("") : db.list(user, pattern);
// if the given argument is not a database name, it could be the name of a backup file
if(names.isEmpty() && context.user().has(Perm.READ, pattern)) names.add(pattern);
if(names.isEmpty() && user.has(Perm.READ, pattern)) names.add(pattern);

// drop all backups
for(final String name : names) {
for(final String backup : context.databases.backups(name)) {
for(final String backup : db.backups(name)) {
drop(backup, soptions);
}
}
Expand Down
2 changes: 1 addition & 1 deletion basex-core/src/main/java/org/basex/core/cmd/DropDB.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ protected boolean run() {
if(!Databases.validPattern(pattern)) return error(NAME_INVALID_X, pattern);

// retrieve all databases; return true if no database is found (no error)
final StringList dbs = context.listDBs(pattern);
final StringList dbs = context.databases.list(context.user(), pattern);
if(dbs.isEmpty()) return info(NO_DB_DROPPED);

// loop through all databases
Expand Down
5 changes: 3 additions & 2 deletions basex-core/src/main/java/org/basex/core/cmd/List.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,12 @@ private boolean list() throws IOException {
final Table table = new Table();
table.description = DATABASES_X;

final boolean create = context.user().has(Perm.CREATE);
final User user = context.user();
final boolean create = user.has(Perm.CREATE);
table.header.add(NAME).add(RESOURCES).add(SIZE);
if(create) table.header.add(INPUT_PATH);

for(final String name : context.listDBs()) {
for(final String name : context.databases.list(user, null)) {
String file;
long dbsize = 0;
int count = 0;
Expand Down
4 changes: 2 additions & 2 deletions basex-core/src/main/java/org/basex/core/users/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ public synchronized String code(final Algorithm algorithm, final Code code) {
* @param db database pattern (can be {@code null})
* @return permission
*/
public synchronized Perm perm(final String db) {
public synchronized Perm permission(final String db) {
if(db != null) {
final Entry<String, Perm> entry = find(db);
if(entry != null) return entry.getValue();
Expand Down Expand Up @@ -265,7 +265,7 @@ public synchronized boolean has(final Perm perm) {
* @return result of check
*/
public synchronized boolean has(final Perm perm, final String db) {
return perm(db).ordinal() >= perm.ordinal();
return permission(db).ordinal() >= perm.ordinal();
}

/**
Expand Down
2 changes: 1 addition & 1 deletion basex-core/src/main/java/org/basex/core/users/Users.java
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ public synchronized Table info(final String db, final Context ctx) {

for(final String user : S_USERINFO) table.header.add(user);
for(final User user : users(db, ctx)) {
table.contents.add(new TokenList().add(user.name()).add(user.perm(db).toString()));
table.contents.add(new TokenList().add(user.name()).add(user.permission(db).toString()));
}
return table.sort().toTop(token(ADMIN));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ enum Action {
DialogInput(final String old, final BaseXDialog dialog, final Action action) {
super(dialog, action.title);
this.action = action;
databases = dialog.gui().context.listDBs();
final Context ctx = dialog.gui().context;
databases = ctx.databases.list();

set(new BaseXLabel(action.label + COL, false, true).border(0, 0, 6, 0), BorderLayout.NORTH);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public DialogManage(final GUI gui) {
panel.setLayout(new BorderLayout(4, 0));

// create database chooser
final String[] dbs = gui.context.databases.list().finish();
final String[] dbs = gui.context.databases.all().finish();
choice = new BaseXList(this, false, dbs);
choice.setSize(240, 600);
final Data data = gui.context.data();
Expand Down Expand Up @@ -139,7 +139,7 @@ public void action(final Object cmp) {
final Context ctx = gui.context;
if(refresh) {
// rebuild databases and focus list chooser
choice.setData(ctx.databases.list().finish());
choice.setData(ctx.databases.all().finish());
choice.requestFocusInWindow();
refresh = false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ public void action(final Object comp) {
// database will be empty
inf = EMPTY_DB;
icon = Msg.WARN;
} else if(gui.context.listDBs().contains(nm)) {
} else if(gui.context.databases.list().contains(nm)) {
// old database will be overwritten
inf = OVERWRITE_DB;
icon = Msg.WARN;
Expand Down
9 changes: 5 additions & 4 deletions basex-core/src/main/java/org/basex/query/func/db/DbList.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public Value value(final QueryContext qc) throws QueryException {
*/
private static Value list(final QueryContext qc) {
final Context ctx = qc.context;
final StringList dbs = ctx.listDBs();
final StringList dbs = ctx.databases.list(ctx.user(), null);
final TokenList list = new TokenList(dbs.size());
for(final String name : dbs) list.add(name);
return StrSeq.get(list);
Expand All @@ -59,9 +59,10 @@ private Iter resources(final QueryContext qc) throws QueryException {
final Data data = toData(qc);
final String path = defined(1) ? toString(arg(1), qc) : "";

final IntList docs = data.resources.docs(path);
final StringList binaries = data.resources.paths(path, ResourceType.BINARY);
final StringList values = data.resources.paths(path, ResourceType.VALUE);
final Resources resources = data.resources;
final IntList docs = resources.docs(path);
final StringList binaries = resources.paths(path, ResourceType.BINARY);
final StringList values = resources.paths(path, ResourceType.VALUE);
final int ds = docs.size(), bs = ds + binaries.size(), size = bs + values.size();

return new BasicIter<Str>(size) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public Value value(final QueryContext qc) throws QueryException {
*/
private static Iter list(final QueryContext qc) {
final Context ctx = qc.context;
final StringList dbs = ctx.listDBs();
final StringList dbs = ctx.databases.list(ctx.user(), null);
return new BasicIter<FNode>(dbs.size()) {
@Override
public FNode get(final long i) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ final Value eval(final IOContent query, final boolean updating, final QueryConte
final HashMap<String, Value> bindings = toBindings(arg(1), qc);
final XQueryOptions options = new XQueryOptions();
final User user = qc.context.user();
options.put(XQueryOptions.PERMISSION, user.perm(""));
options.put(XQueryOptions.PERMISSION, user.permission(""));
toOptions(arg(2), options, qc);

final Perm perm = Perm.get(options.get(XQueryOptions.PERMISSION).toString());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,12 @@ public void addData(final Data data) {
@Override
synchronized void add(final Update update, final QueryContext qc) throws QueryException {
// check permissions
final User user = qc.context.user();
if(update instanceof NameUpdate) {
if(!qc.context.user().has(Perm.CREATE, ((NameUpdate) update).name()))
if(!user.has(Perm.CREATE, ((NameUpdate) update).name()))
throw BASEX_PERMISSION_X.get(update.info(), Perm.CREATE);
} else if(update instanceof DataUpdate) {
if(!qc.context.user().has(Perm.WRITE, ((DataUpdate) update).data().meta.name))
if(!user.has(Perm.WRITE, ((DataUpdate) update).data().meta.name))
throw BASEX_PERMISSION_X.get(update.info(), Perm.WRITE);
}
super.add(update, qc);
Expand Down

0 comments on commit 40f663a

Please sign in to comment.