public static Query createQuery( final PersistenceManager persistenceManager, final String alias, final String select, final ObjectSpecification specification, final String whereClause) { final StringBuilder buf = new StringBuilder(128); appendSelect(buf, select, alias); appendFrom(buf, specification, alias); appendWhere(buf, whereClause); final String queryString = buf.toString(); LOG.debug("creating query: {}", queryString); final Query jdoQuery = persistenceManager.newQuery(queryString); // http://www.datanucleus.org/servlet/jira/browse/NUCCORE-1103 jdoQuery.addExtension("datanucleus.multivaluedFetch", "none"); return jdoQuery; }
/** * Generic method used to query the maximum number (or ID) of a column from a specified class. * * @param pm The PersistenceManager object. * @param clazz The class name to query. * @param columnName The column name to query. * @return the maximum number persisted on the class. It returns NULL if the class has no rows. */ private static long getMaxPersistedIDCore(PersistenceManager pm, Class clazz, String columnName, long defaultValue) { Query query = pm.newQuery(clazz); query.addExtension(LOAD_RESULTS_AT_COMMIT, "false"); query.setResult(String.format("max(%s)", columnName)); Long maxValue = (Long) query.execute(); return (maxValue != null) ? maxValue : defaultValue; }
/** * Checks if the table associated with class provided is empty * * @param pm PersistenceManager * @param clazz class * @return True is the table is empty * False if it not. */ private boolean isTableEmptyCore(PersistenceManager pm, Class clazz) { Query query = pm.newQuery(clazz); query.addExtension(LOAD_RESULTS_AT_COMMIT, "false"); // setRange is implemented efficiently for MySQL, Postgresql (using the LIMIT SQL keyword) // and Oracle (using the ROWNUM keyword), with the query only finding the objects required // by the user directly in the datastore. For other RDBMS the query will retrieve all // objects up to the "to" record, and will not pass any unnecessary objects that are before // the "from" record. query.setRange(0, 1); return ((List<?>) query.execute()).isEmpty(); }
/** * Purge notification id table, keeping a specified number of entries. * @param pm a {@link PersistenceManager} instance. * @param changesToKeep the number of changes the caller want to keep. */ @VisibleForTesting protected void purgeNotificationIdTableCore(PersistenceManager pm, long changesToKeep) { Preconditions.checkArgument(changesToKeep > 0, "You need to keep at least one entry in SENTRY_HMS_NOTIFICATION_ID table"); long lastNotificationID = getLastProcessedNotificationIDCore(pm); Query query = pm.newQuery(MSentryHmsNotification.class); query.addExtension(LOAD_RESULTS_AT_COMMIT, "false"); // It is an approximation of "SELECT ... LIMIT CHANGE_TO_KEEP" in SQL, because JDO w/ derby // does not support "LIMIT". // See: http://www.datanucleus.org/products/datanucleus/jdo/jdoql_declarative.html query.setFilter("notificationId <= maxNotificationIdDeleted"); query.declareParameters("long maxNotificationIdDeleted"); long numDeleted = query.deletePersistentAll(lastNotificationID - changesToKeep); if (numDeleted > 0) { LOGGER.info("Purged {} of {}", numDeleted, MSentryHmsNotification.class.getSimpleName()); } }
/** * Purge a given delta change table, with a specified number of changes to be kept. * * @param cls the class of a perm/path delta change {@link MSentryPermChange} or * {@link MSentryPathChange}. * @param pm a {@link PersistenceManager} instance. * @param changesToKeep the number of changes the caller want to keep. * @param <T> the type of delta change class. */ @VisibleForTesting <T extends MSentryChange> void purgeDeltaChangeTableCore( Class<T> cls, PersistenceManager pm, long changesToKeep) { Preconditions.checkArgument(changesToKeep >= 0, "changes to keep must be a non-negative number"); long lastChangedID = getLastProcessedChangeIDCore(pm, cls); long maxIDDeleted = lastChangedID - changesToKeep; Query query = pm.newQuery(cls); query.addExtension(LOAD_RESULTS_AT_COMMIT, "false"); // It is an approximation of "SELECT ... LIMIT CHANGE_TO_KEEP" in SQL, because JDO w/ derby // does not support "LIMIT". // See: http://www.datanucleus.org/products/datanucleus/jdo/jdoql_declarative.html query.setFilter("changeID <= maxChangedIdDeleted"); query.declareParameters("long maxChangedIdDeleted"); long numDeleted = query.deletePersistentAll(maxIDDeleted); if (numDeleted > 0) { LOGGER.info(String.format("Purged %d of %s to changeID=%d", numDeleted, cls.getSimpleName(), maxIDDeleted)); } }
/** * Checks if any MSentryChange object exists with the given changeID. * * @param pm PersistenceManager * @param changeCls class instance of type {@link MSentryChange} * @param changeID changeID * @return true if found the MSentryChange object, otherwise false. * @throws Exception */ @SuppressWarnings("unchecked") private <T extends MSentryChange> Boolean changeExistsCore( PersistenceManager pm, Class<T> changeCls, final long changeID) throws Exception { Query query = pm.newQuery(changeCls); query.addExtension(LOAD_RESULTS_AT_COMMIT, "false"); query.setFilter("this.changeID == id"); query.declareParameters("long id"); List<T> changes = (List<T>)query.execute(changeID); return !changes.isEmpty(); }
/** * Delete all stored HMS notifications starting from given ID.<p> * * The purpose of the function is to clean up notifications in cases * were we recover from HMS notifications resets. * * @param pm Persistent manager instance * @param id initial ID. All notifications starting from this ID and above are * removed. */ private void deleteNotificationsSince(PersistenceManager pm, long id) { Query query = pm.newQuery(MSentryHmsNotification.class); query.addExtension(LOAD_RESULTS_AT_COMMIT, "false"); query.setFilter("notificationId >= currentNotificationId"); query.declareParameters("long currentNotificationId"); long numDeleted = query.deletePersistentAll(id); if (numDeleted > 0) { LOGGER.info("Purged {} notification entries starting from {}", numDeleted, id); } }
private Set<MSentryRole> getRolesForUsers(PersistenceManager pm, Set<String> users) { Set<MSentryRole> result = Sets.newHashSet(); if (users != null) { Query query = pm.newQuery(MSentryUser.class); query.addExtension(LOAD_RESULTS_AT_COMMIT, "false"); query.setFilter(":p1.contains(this.userName)"); FetchGroup grp = pm.getFetchGroup(MSentryUser.class, "fetchRoles"); grp.addMember("roles"); pm.getFetchPlan().addGroup("fetchRoles"); List<MSentryUser> sentryUsers = (List) query.execute(users.toArray()); if (sentryUsers != null) { for (MSentryUser sentryUser : sentryUsers) { result.addAll(sentryUser.getRoles()); } } } return result; }
public Set<MSentryRole> getRolesForGroups(PersistenceManager pm, Set<String> groups) { Set<MSentryRole> result = Sets.newHashSet(); if (groups != null) { Query query = pm.newQuery(MSentryGroup.class); query.addExtension(LOAD_RESULTS_AT_COMMIT, "false"); query.setFilter(":p1.contains(this.groupName)"); FetchGroup grp = pm.getFetchGroup(MSentryGroup.class, "fetchRoles"); grp.addMember("roles"); pm.getFetchPlan().addGroup("fetchRoles"); List<MSentryGroup> sentryGroups = (List) query.execute(groups.toArray()); if (sentryGroups != null) { for (MSentryGroup sentryGroup : sentryGroups) { result.addAll(sentryGroup.getRoles()); } } } return result; }
public List<ObjectAdapter> process(final PersistenceQueryFindAllInstances persistenceQuery) { final ObjectSpecification specification = persistenceQuery.getSpecification(); Class<?> cls = specification.getCorrespondingClass(); final Query jdoQuery = persistenceSession.newJdoQuery(cls); // http://www.datanucleus.org/servlet/jira/browse/NUCCORE-1103 jdoQuery.addExtension("datanucleus.multivaluedFetch", "none"); if (LOG.isDebugEnabled()) { LOG.debug("allInstances(): class={}", specification.getFullIdentifier()); } try { final List<?> pojos = (List<?>) jdoQuery.execute(); return loadAdapters(pojos); } finally { jdoQuery.closeAll(); } } }
private List<?> getResultsPk(final PersistenceQueryFindUsingApplibQueryDefault persistenceQuery) { final String queryName = persistenceQuery.getQueryName(); final Map<String, Object> map = unwrap(persistenceQuery.getArgumentsAdaptersByParameterName()); final ObjectSpecification objectSpec = persistenceQuery.getSpecification(); final Class<?> cls = objectSpec.getCorrespondingClass(); if(!JdoPropertyUtils.hasPrimaryKeyProperty(objectSpec)) { throw new UnsupportedOperationException("cannot search by primary key for DataStore-assigned entities"); } final OneToOneAssociation pkOtoa = JdoPropertyUtils.getPrimaryKeyPropertyFor(objectSpec); final String pkOtoaId = pkOtoa.getId(); final String filter = pkOtoaId + "==" + map.get(pkOtoaId); final Query jdoQuery = persistenceSession.newJdoQuery(cls, filter); // http://www.datanucleus.org/servlet/jira/browse/NUCCORE-1103 jdoQuery.addExtension("datanucleus.multivaluedFetch", "none"); if (LOG.isDebugEnabled()) { LOG.debug("{} # {} ( {} )", cls.getName(), queryName, filter); } try { final List<?> results = (List<?>) jdoQuery.execute(); return Lists.newArrayList(results); } finally { jdoQuery.closeAll(); } }
/** * Get count of object of the given class * @param tClass Class to count * @param <T> Class type * @return count of objects or -1 in case of error */ @VisibleForTesting <T> Long getCount(final Class<T> tClass) { try { return tm.executeTransaction( pm -> { pm.setDetachAllOnCommit(false); // No need to detach objects Query query = pm.newQuery(); query.addExtension(LOAD_RESULTS_AT_COMMIT, "false"); query.setClass(tClass); query.setResult("count(this)"); Long result = (Long)query.execute(); return result; }); } catch (Exception e) { return COUNT_VALUE_UNKNOWN; } }
/** * Get list of all roles. Should be called inside transaction. * @param pm Persistence manager instance * @return List of all roles */ @SuppressWarnings("unchecked") public List<MSentryRole> getAllRoles(PersistenceManager pm) { Query query = pm.newQuery(MSentryRole.class); query.addExtension(LOAD_RESULTS_AT_COMMIT, "false"); FetchGroup grp = pm.getFetchGroup(MSentryRole.class, "fetchGroups"); grp.addMember("groups"); pm.getFetchPlan().addGroup("fetchGroups"); return (List<MSentryRole>) query.execute(); }
jdoQuery.addExtension("datanucleus.multivaluedFetch", "none");
private boolean hasAnyServerPrivileges(final Set<String> roleNames, final String serverName) throws Exception { if (roleNames == null || roleNames.isEmpty()) { return false; } return tm.executeTransaction( pm -> { pm.setDetachAllOnCommit(false); // No need to detach objects Query query = pm.newQuery(MSentryPrivilege.class); query.addExtension(LOAD_RESULTS_AT_COMMIT, "false"); QueryParamBuilder paramBuilder = QueryParamBuilder.addRolesFilter(query,null, roleNames); paramBuilder.add(SERVER_NAME, serverName); query.setFilter(paramBuilder.toString()); query.setResult("count(this)"); Long numPrivs = (Long) query.executeWithMap(paramBuilder.getArguments()); return numPrivs > 0; }); }
public Boolean execute(PersistenceManager pm) throws Exception { pm.setDetachAllOnCommit(false); // No need to detach objects Query query = pm.newQuery(MSentryPrivilege.class); query.addExtension(LOAD_RESULTS_AT_COMMIT, "false"); QueryParamBuilder paramBuilder = QueryParamBuilder.addUsersFilter(query,null, userNames); paramBuilder.add(SERVER_NAME, serverName); query.setFilter(paramBuilder.toString()); query.setResult("count(this)"); Long numPrivs = (Long) query.executeWithMap(paramBuilder.getArguments()); return numPrivs > 0; } });
/** * Get a single user with the given name inside a transaction * @param pm Persistence Manager instance * @param userName User name (should not be null) * @return single user with the given name */ public MSentryUser getUser(PersistenceManager pm, String userName) { Query query = pm.newQuery(MSentryUser.class); query.addExtension(LOAD_RESULTS_AT_COMMIT, "false"); query.setFilter("this.userName == :userName"); query.setUnique(true); FetchGroup grp = pm.getFetchGroup(MSentryUser.class, "fetchPrivileges"); grp.addMember("privileges"); pm.getFetchPlan().addGroup("fetchPrivileges"); return (MSentryUser) query.execute(userName); }
/** * Get a single role with the given name inside a transaction * @param pm Persistence Manager instance * @param roleName Role name (should not be null) * @return single role with the given name */ public MSentryRole getRole(PersistenceManager pm, String roleName) { Query query = pm.newQuery(MSentryRole.class); query.addExtension(LOAD_RESULTS_AT_COMMIT, "false"); query.setFilter("this.roleName == :roleName"); query.setUnique(true); FetchGroup grp = pm.getFetchGroup(MSentryRole.class, "fetchPrivileges"); grp.addMember("privileges"); pm.getFetchPlan().addGroup("fetchPrivileges"); return (MSentryRole) query.execute(roleName); }
/** * Get a single principal with the given name and type inside a transaction * @param pm Persistence Manager instance * @param name Role/user name (should not be null) * @param type Type of principal * @return single PrivilegePrincipal with the given name and type */ public PrivilegePrincipal getEntity(PersistenceManager pm, String name, SentryPrincipalType type) { Query query; if(type == SentryPrincipalType.ROLE) { query = pm.newQuery(MSentryRole.class); query.addExtension(LOAD_RESULTS_AT_COMMIT, "false"); query.setFilter("this.roleName == :roleName"); query.setUnique(true); FetchGroup grp = pm.getFetchGroup(MSentryRole.class, "fetchPrivileges"); grp.addMember("privileges"); pm.getFetchPlan().addGroup("fetchPrivileges"); } else { query = pm.newQuery(MSentryUser.class); query.addExtension(LOAD_RESULTS_AT_COMMIT, "false"); query.setFilter("this.userName == :userName"); query.setUnique(true); FetchGroup grp = pm.getFetchGroup(MSentryUser.class, "fetchPrivileges"); grp.addMember("privileges"); pm.getFetchPlan().addGroup("fetchPrivileges"); } return (PrivilegePrincipal) query.execute(name); }
/** * @return mapping data for [role,privilege] with the specific auth object */ public Map<String, Set<TSentryPrivilege>> getRoleNameTPrivilegesMap(final String dbName, final String tableName) throws Exception { return tm.executeTransaction( pm -> { pm.setDetachAllOnCommit(false); // No need to detach objects Query query = pm.newQuery(MSentryPrivilege.class); query.addExtension(LOAD_RESULTS_AT_COMMIT, "false"); QueryParamBuilder paramBuilder = QueryParamBuilder.newQueryParamBuilder(); if (!StringUtils.isEmpty(dbName)) { paramBuilder.add(DB_NAME, dbName); } if (!StringUtils.isEmpty(tableName)) { paramBuilder.add(TABLE_NAME, tableName); } query.setFilter(paramBuilder.toString()); FetchGroup grp = pm.getFetchGroup(MSentryPrivilege.class, "fetchRoles"); grp.addMember("roles"); pm.getFetchPlan().addGroup("fetchRoles"); @SuppressWarnings("unchecked") List<MSentryPrivilege> mSentryPrivileges = (List<MSentryPrivilege>) query. executeWithMap(paramBuilder.getArguments()); return getRolePrivilegesMap(mSentryPrivileges); }); }