/** * Cleans up whitespace, any trailing semicolons, and prefixed comments that a string is * unregistered, in order to come up with a canonical representation of this sql string. * Note that for backwards compatibility, this method condenses contiguous whitespace * into a single space. For example, "foo\t \nbar;" becomes "foo bar". */ public static String canonicalizeString(String sql) { return canonicalizeString(sql, false); }
/** * A Factory used by the SQL class to turn a string sql query into an SQLString object. * This may just contain the sql given, or the given SQL may be overriden in the database and the object returned * will reflect that new SQL from the DB. * * @param sql The string to be used in a query * @return a SQLString object representing the given SQL */ @SuppressWarnings("GuardedByChecker") static FinalSQLString getUnregisteredQuery(String sql) { assert !isValidKey(sql) : "Unregistered Queries should not look like keys"; //$NON-NLS-1$ FinalSQLString cached = cachedUnregistered.get(canonicalizeStringAndRemoveWhitespaceEntirely(sql)); if (null != cached) { callbackOnUse.noteUse((SQLString) cached.delegate); return cached; } return new FinalSQLString(new SQLString(sql)); }
boolean insertManyUnregisteredQuery(Connection c, String sql, Iterable<Object[]> list) throws PalantirSqlException { return basicSql.insertMany( c, SQLString.getUnregisteredQuery(sql), Iterables.toArray(list, Object[].class)); }
/** * Same as the overloaded registerQuery, but overrides the query for a specific DBType. * @param key Unique identifier representing this query * @param sql The query that will be stored * @param dbType Override the query for this DBType. * If this value is null, it is the same as <code>registerQuery(key, sql)</code> */ public static RegisteredSQLString registerQuery(String key, String sql, DBType dbType) { if (dbType == null) { return registerQuery(key, sql); } SQLString sqlString = new SQLString(key, sql, dbType); ConcurrentMap<DBType, FinalSQLString> newHash = new ConcurrentHashMap<DBType, FinalSQLString>(); ConcurrentMap<DBType, FinalSQLString> dbTypeHash = registeredValuesOverride.putIfAbsent(key, newHash); if (null == dbTypeHash) { dbTypeHash = newHash; } FinalSQLString newVal = new FinalSQLString(sqlString); FinalSQLString oldVal = dbTypeHash.put(dbType, newVal); assert null == oldVal || newVal.delegate.equals(oldVal.delegate) : "newVal: " + newVal + " oldVal: " + oldVal; //$NON-NLS-1$ //$NON-NLS-2$ return new RegisteredSQLString(sqlString); }
/** * Returns the long value of the first field selected given a query. If no rows are returned, * will throw SQLException. * <p> * If the value of the first field is null then 0 will be returned in prod, but an assert will * be thrown in test. */ long selectLong(Connection c, String key, Object... vs) throws PalantirSqlException, PalantirInterruptedException { return basicSql.selectLongInternal(c, SQLString.getByKey(key, c), vs, null, true); }
@Test public void testCanonicalizeStringAndRemoveWhitespaceEntirely() { List<String> testBatch = ImmutableList.of( "/* UnregisteredSQLString */ insert foo into bar; /* UnregisteredSQLString */insert foo into bar;", "insert foo into bar; /* UnregisteredSQLString */ insert foo into bar"); String canonicalBatch = "insertfoointobar;insertfoointobar"; testBatch.forEach(sql -> assertEquals(canonicalBatch, SQLString.canonicalizeStringAndRemoveWhitespaceEntirely(sql))); }
/** * Contructor for registered SQL. * @param key The query key * @param sql The string to be used in a query * @param dbType This is only used in making the SQL comment */ protected SQLString(String key, String sql, DBType dbType) { super(key, makeCommentString(key, dbType) + sql); }
/** * Same as the overloaded registerQuery, but overrides the query for a specific DBType. * @param key Unique identifier representing this query * @param sql The query that will be stored * @param dbTypes Override the query for this list of DBTypes. These are not allowed to be null. */ public static void registerQuery(String key, String sql, DBType... dbTypes) { Validate.notEmpty(dbTypes, "DbType list may not be empty"); //$NON-NLS-1$ for (DBType type : dbTypes) { Validate.notNull(type, "dbType must not be null"); //$NON-NLS-1$ registerQuery(key, sql, type); } }
/** * Call this function to store a query to be used later with the given key. * @param key Unique identifier for this query * @param sql The query that will be stored */ public static RegisteredSQLString registerQuery(String key, String sql) { SQLString sqlString = new SQLString(key, sql, null); FinalSQLString newVal = new FinalSQLString(sqlString); FinalSQLString oldVal = registeredValues.put(key, newVal); assert null == oldVal || oldVal.delegate.equals(newVal.delegate) : "newVal: " + newVal + " oldVal: " + oldVal; //$NON-NLS-1$ //$NON-NLS-2$ return new RegisteredSQLString(sqlString); }
assert isValidKey(key) : "Keys only consist of word characters"; //$NON-NLS-1$ assert registeredValues.containsKey(key) || registeredValuesOverride.containsKey(key) : "Couldn't find SQLString key: " + key + ", dbtype " + dbType; //$NON-NLS-1$ //$NON-NLS-2$
boolean insertMany(Connection c, String key, Iterable<Object[]> list) throws PalantirSqlException { return basicSql.insertMany( c, SQLString.getByKey(key, c), Iterables.toArray(list, Object[].class)); }
/** * Same as the overloaded registerQuery, but overrides the query for a specific DBType. * @param key Unique identifier representing this query * @param sql The query that will be stored * @param dbType Override the query for this DBType. * If this value is null, it is the same as <code>registerQuery(key, sql)</code> */ public static RegisteredSQLString registerQuery(String key, String sql, DBType dbType) { if (dbType == null) { return registerQuery(key, sql); } SQLString sqlString = new SQLString(key, sql, dbType); ConcurrentMap<DBType, FinalSQLString> newHash = new ConcurrentHashMap<DBType, FinalSQLString>(); ConcurrentMap<DBType, FinalSQLString> dbTypeHash = registeredValuesOverride.putIfAbsent(key, newHash); if (null == dbTypeHash) { dbTypeHash = newHash; } FinalSQLString newVal = new FinalSQLString(sqlString); FinalSQLString oldVal = dbTypeHash.put(dbType, newVal); assert null == oldVal || newVal.delegate.equals(oldVal.delegate) : "newVal: " + newVal + " oldVal: " + oldVal; //$NON-NLS-1$ //$NON-NLS-2$ return new RegisteredSQLString(sqlString); }
/** * Contructor for unregistered (dynamic) SQL. * @param sql The string to be used in a query */ private SQLString(String sql) { super(null, makeCommentString(null, null) + sql); }
String sql = String.format(sqlFormat, whereClause); String keyString = key.toString(); registerQuery(keyString, sql, type); map.put(keySet, keyString);
/** * Call this function to store a query to be used later with the given key. * @param key Unique identifier for this query * @param sql The query that will be stored */ public static RegisteredSQLString registerQuery(String key, String sql) { SQLString sqlString = new SQLString(key, sql, null); FinalSQLString newVal = new FinalSQLString(sqlString); FinalSQLString oldVal = registeredValues.put(key, newVal); assert null == oldVal || oldVal.delegate.equals(newVal.delegate) : "newVal: " + newVal + " oldVal: " + oldVal; //$NON-NLS-1$ //$NON-NLS-2$ return new RegisteredSQLString(sqlString); }
assert isValidKey(key) : "Keys only consist of word characters"; //$NON-NLS-1$ assert registeredValues.containsKey(key) || registeredValuesOverride.containsKey(key) : "Couldn't find SQLString key: " + key + ", dbtype " + dbType; //$NON-NLS-1$ //$NON-NLS-2$
void updateManyUnregisteredQuery(Connection c, String sql, Iterable<Object[]> list) throws PalantirSqlException { basicSql.updateMany( c, SQLString.getUnregisteredQuery(sql), Iterables.toArray(list, Object[].class)); }
/** * Returns the long value of the first field selected given a query If no rows are returned, * will return defaultVal. * <p> * If the value of the first field is null, then defaultVal will be returned. This means that if * defaultVal is non-null, then this method won't return null. */ Long selectLongWithDefault(Connection c, String key, Long defaultVal, Object... vs) throws PalantirSqlException, PalantirInterruptedException { return basicSql.selectLongInternal(c, SQLString.getByKey(key, c), vs, defaultVal, false); }
/** * A Factory used by the SQL class to turn a string sql query into an SQLString object. * This may just contain the sql given, or the given SQL may be overriden in the database and the object returned * will reflect that new SQL from the DB. * * @param sql The string to be used in a query * @return a SQLString object representing the given SQL */ @SuppressWarnings("GuardedByChecker") static FinalSQLString getUnregisteredQuery(String sql) { assert !isValidKey(sql) : "Unregistered Queries should not look like keys"; //$NON-NLS-1$ FinalSQLString cached = cachedUnregistered.get(canonicalizeStringAndRemoveWhitespaceEntirely(sql)); if (null != cached) { callbackOnUse.noteUse((SQLString) cached.delegate); return cached; } return new FinalSQLString(new SQLString(sql)); }
@VisibleForTesting static String canonicalizeStringAndRemoveWhitespaceEntirely(String sql) { return canonicalizeString(sql, true); }