public void dropTables() { withTransaction(dbi -> { dbi.update("DROP TABLE jsondb"); }); }
public void dropTables() { withTransaction(dbi -> { dbi.update("DROP TABLE jsondb"); }); }
@Override public boolean exists(String path) { String baseDBPath = JsonRecordSupport.convertToDBPath(path); String like = baseDBPath+"%"; boolean rc[] = new boolean[]{false}; withTransaction(dbi -> { rc[0] = countJsonRecords(dbi, like) > 0; }); return rc[0]; }
@Override public boolean exists(String path) { String baseDBPath = JsonRecordSupport.convertToDBPath(path); String like = baseDBPath+"%"; boolean rc[] = new boolean[]{false}; withTransaction(dbi -> { rc[0] = countJsonRecords(dbi, like) > 0; }); return rc[0]; }
protected Set<String> fetchIdsByPropertyValueFullTableScan(final String collectionPath, final String property, final String value) { final String pathRegex = collectionPath + "/:[^/]+/" + property; final AtomicReference<Set<String>> ret = new AtomicReference<>(); withTransaction(dbi -> { final String query; if (databaseKind == DatabaseKind.PostgreSQL) { query = "SELECT regexp_replace(path, '(/.+/:[^/]+).*', '\\1') from jsondb where path ~ ? and value = ?"; } else if (databaseKind == DatabaseKind.H2) { query = "SELECT regexp_replace(path, '(/.+/:[^/]+).*', '$1') from jsondb where path regexp ? and value = ?"; } else { throw new UnsupportedOperationException( "Don't know how to use regex in a query with database: " + databaseKind); } final List<String> paths = dbi.createQuery(query) .bind(0, pathRegex) .bind(1, STRING_VALUE_PREFIX+value) .map(StringColumnMapper.INSTANCE).list(); ret.set(new HashSet<>(paths)); }); return ret.get(); }
public void createTables() { withTransaction(dbi -> { if(databaseKind == DatabaseKind.PostgreSQL) { dbi.update("CREATE TABLE jsondb (path VARCHAR COLLATE \"C\" PRIMARY KEY, value VARCHAR, kind INT, idx VARCHAR COLLATE \"C\")"); dbi.update("CREATE INDEX jsondb_idx ON jsondb (idx, value) WHERE idx IS NOT NULL"); } else { dbi.update("CREATE TABLE jsondb (path VARCHAR PRIMARY KEY, value VARCHAR, kind INT, idx VARCHAR)"); } }); }
protected Set<String> fetchIdsByPropertyValueFullTableScan(final String collectionPath, final String property, final String value) { final String pathRegex = collectionPath + "/:[^/]+/" + property; final AtomicReference<Set<String>> ret = new AtomicReference<>(); withTransaction(dbi -> { final String query; if (databaseKind == DatabaseKind.PostgreSQL) { query = "SELECT regexp_replace(path, '(/.+/:[^/]+).*', '\\1') from jsondb where path ~ ? and value = ?"; } else if (databaseKind == DatabaseKind.H2) { query = "SELECT regexp_replace(path, '(/.+/:[^/]+).*', '$1') from jsondb where path regexp ? and value = ?"; } else { throw new UnsupportedOperationException( "Don't know how to use regex in a query with database: " + databaseKind); } final List<String> paths = dbi.createQuery(query).bind(0, pathRegex).bind(1, value) .map(StringColumnMapper.INSTANCE).list(); ret.set(new HashSet<>(paths)); }); return ret.get(); }
public void createTables() { withTransaction(dbi -> { if(databaseKind == DatabaseKind.PostgreSQL) { dbi.update("CREATE TABLE jsondb (path VARCHAR COLLATE \"C\" PRIMARY KEY, value VARCHAR, ovalue VARCHAR, idx VARCHAR COLLATE \"C\")"); dbi.update("CREATE INDEX jsondb_idx ON jsondb (idx, value) WHERE idx IS NOT NULL"); } else { dbi.update("CREATE TABLE jsondb (path VARCHAR PRIMARY KEY, value VARCHAR, ovalue VARCHAR, idx VARCHAR)"); } if( databaseKind == DatabaseKind.H2 ) { dbi.update("CREATE ALIAS IF NOT EXISTS split_part FOR \""+Strings.class.getName()+".splitPart\""); dbi.update("CREATE ALIAS IF NOT EXISTS trim_suffix FOR \""+Strings.class.getName()+".trimSuffix\""); } }); }
@Override public Set<String> fetchIdsByPropertyValue(final String collectionPath, final String property, final String value) { String path = prefix(trimSuffix(collectionPath, "/"), "/"); String idx = path+"/#"+property; if( !indexPaths.contains(idx) ) { String message = "Index not defined for: collectionPath: " + path + ", property: " + property; LOG.warn("fetchIdsByPropertyValue not optimzed !!!: {}", message); return fetchIdsByPropertyValueFullTableScan(collectionPath, property, value); } else { final AtomicReference<Set<String>> ret = new AtomicReference<>(); withTransaction(dbi -> { final String query = "SELECT path FROM jsondb WHERE idx = ? AND value = ?"; final List<String> paths = dbi.createQuery(query) .bind(0, idx) .bind(1, STRING_VALUE_PREFIX+value) .map(StringColumnMapper.INSTANCE).list(); String suffix = "/" + property + "/"; ret.set(paths.stream() .map(x -> trimSuffix(x, suffix)) .collect(Collectors.toCollection(HashSet::new))); }); return ret.get(); } }
public SqlJsonDB(DBI dbi, EventBus bus, Collection<Index> indexes) { this.dbi = dbi; this.bus = bus; for (Index index : indexes) { this.indexes.add(index.getPath()+"/"+index.getField()); } // Lets find out the type of DB we are working with. withTransaction(x -> { try { String dbName = x.getConnection().getMetaData().getDatabaseProductName(); databaseKind = DatabaseKind.valueOf(dbName); // CockroachDB uses the PostgreSQL driver.. so need to look a little closer. if( databaseKind == DatabaseKind.PostgreSQL ) { String version = x.createQuery("SELECT VERSION()").mapTo(String.class).first(); if( version.startsWith("CockroachDB") ) { databaseKind = DatabaseKind.CockroachDB; } } } catch (@SuppressWarnings("PMD.AvoidCatchingGenericException") Exception e) { throw new IllegalStateException("Could not determine the database type", e); } }); }
@Override public Set<String> fetchIdsByPropertyValue(final String collectionPath, final String property, final String value) { String path = prefix(trimSuffix(collectionPath, "/"), "/"); String idx = path+"/"+property; if( !indexes.contains(idx) ) { String message = "Index not defined for: collectionPath: " + path + ", property: " + property; LOG.warn("fetchIdsByPropertyValue not optimzed !!!: {}", message); return fetchIdsByPropertyValueFullTableScan(collectionPath, property, value); } else { final AtomicReference<Set<String>> ret = new AtomicReference<>(); withTransaction(dbi -> { final String query = "SELECT path FROM jsondb WHERE idx = ? AND value = ?"; final List<String> paths = dbi.createQuery(query) .bind(0, idx) .bind(1, value) .map(StringColumnMapper.INSTANCE).list(); String suffix = "/" + property + "/"; ret.set(paths.stream() .map(x -> trimSuffix(x, suffix)) .collect(Collectors.toCollection(HashSet::new))); }); return ret.get(); } }
public SqlJsonDB(DBI dbi, EventBus bus, Collection<Index> indexes) { this.dbi = dbi; this.bus = bus; this.indexes = indexes; for (Index index : indexes) { this.indexPaths.add(index.getPath()+"/#"+index.getField()); } // Lets find out the type of DB we are working with. withTransaction(x -> { try { String dbName = x.getConnection().getMetaData().getDatabaseProductName(); databaseKind = DatabaseKind.valueOf(dbName); // CockroachDB uses the PostgreSQL driver.. so need to look a little closer. if( databaseKind == DatabaseKind.PostgreSQL ) { String version = x.createQuery("SELECT VERSION()").mapTo(String.class).first(); if( version.startsWith("CockroachDB") ) { databaseKind = DatabaseKind.CockroachDB; } } } catch (@SuppressWarnings("PMD.AvoidCatchingGenericException") Exception e) { throw new IllegalStateException("Could not determine the database type", e); } }); }
@Override public boolean delete(String path) { String baseDBPath = JsonRecordSupport.convertToDBPath(path); String like = baseDBPath+"%"; boolean rc[] = new boolean[]{false}; withTransaction(dbi -> { rc[0] = deleteJsonRecords(dbi, baseDBPath, like) > 0; }); if( bus!=null && rc[0] ) { bus.broadcast("jsondb-deleted", prefix(trimSuffix(path, "/"), "/")); } return rc[0]; }
@Override public boolean delete(String path) { String baseDBPath = JsonRecordSupport.convertToDBPath(path); String like = baseDBPath+"%"; boolean rc[] = new boolean[]{false}; withTransaction(dbi -> { rc[0] = deleteJsonRecords(dbi, baseDBPath, like) > 0; }); if( bus!=null && rc[0] ) { bus.broadcast("jsondb-deleted", prefix(trimSuffix(path, "/"), "/")); } return rc[0]; }
@Override public void update(String path, InputStream is) { ArrayList<String> updatePaths = new ArrayList<>(); withTransaction(dbi -> { try { BatchManager mb = new BatchManager(dbi);
@Override public void update(String path, InputStream is) { ArrayList<String> updatePaths = new ArrayList<>(); withTransaction(dbi -> { try { BatchManager mb = new BatchManager(dbi);
@Override public void set(String path, InputStream body) { withTransaction(dbi -> { BatchManager mb = new BatchManager(dbi); String baseDBPath = JsonRecordSupport.convertToDBPath(path); mb.deleteRecordsForSet(baseDBPath); try { JsonRecordSupport.jsonStreamToRecords(indexPaths, baseDBPath, body, mb.createSetConsumer()); } catch (IOException e) { throw new JsonDBException(e); } mb.flush(); }); if( bus!=null ) { bus.broadcast("jsondb-updated", prefix(trimSuffix(path, "/"), "/")); } }
@Override public void set(String path, InputStream body) { withTransaction(dbi -> { BatchManager mb = new BatchManager(dbi); String baseDBPath = JsonRecordSupport.convertToDBPath(path); mb.deleteRecordsForSet(baseDBPath); try { JsonRecordSupport.jsonStreamToRecords(indexes, baseDBPath, body, mb.createSetConsumer()); } catch (IOException e) { throw new JsonDBException(e); } mb.flush(); }); if( bus!=null ) { bus.broadcast("jsondb-updated", prefix(trimSuffix(path, "/"), "/")); } }