Skip to content

Commit 8645499

Browse files
authored
JAVA-1310/JAVA-1316: Allow more customization of mapper behavior (apache#814)
JAVA-1310: Make mapper's ignored properties configurable. JAVA-1316: Add strategy for resolving properties into CQL names. This is a squashed commit, including significant contributions from @adutra and @tolbertam.
1 parent f5db4e0 commit 8645499

55 files changed

Lines changed: 3679 additions & 588 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

changelog/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
- [bug] JAVA-1418: Make Guava version detection more reliable.
2020
- [new feature] JAVA-1174: Add ifNotExists option to mapper.
2121
- [improvement] JAVA-1414: Optimize Metadata.escapeId and Metadata.handleId.
22+
- [improvement] JAVA-1310: Make mapper's ignored properties configurable.
23+
- [improvement] JAVA-1316: Add strategy for resolving properties into CQL names.
2224

2325
Merged from 3.1.x branch:
2426

driver-core/src/main/java/com/datastax/driver/core/AggregateMetadata.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -195,21 +195,21 @@ public String toString() {
195195
private String asCQLQuery(boolean formatted) {
196196

197197
StringBuilder sb = new StringBuilder("CREATE AGGREGATE ")
198-
.append(Metadata.escapeId(keyspace.getName()))
198+
.append(Metadata.quoteIfNecessary(keyspace.getName()))
199199
.append('.');
200200

201201
appendSignature(sb);
202202

203203
TableMetadata.spaceOrNewLine(sb, formatted)
204204
.append("SFUNC ")
205-
.append(Metadata.escapeId(stateFuncSimpleName))
205+
.append(Metadata.quoteIfNecessary(stateFuncSimpleName))
206206
.append(" STYPE ")
207207
.append(stateType.asFunctionParameterString());
208208

209209
if (finalFuncSimpleName != null)
210210
TableMetadata.spaceOrNewLine(sb, formatted)
211211
.append("FINALFUNC ")
212-
.append(Metadata.escapeId(finalFuncSimpleName));
212+
.append(Metadata.quoteIfNecessary(finalFuncSimpleName));
213213

214214
if (initCond != null)
215215
TableMetadata.spaceOrNewLine(sb, formatted)
@@ -234,7 +234,7 @@ private String formatInitCond() {
234234

235235
private void appendSignature(StringBuilder sb) {
236236
sb
237-
.append(Metadata.escapeId(simpleName))
237+
.append(Metadata.quoteIfNecessary(simpleName))
238238
.append('(');
239239
boolean first = true;
240240
for (DataType type : argumentTypes) {

driver-core/src/main/java/com/datastax/driver/core/ColumnMetadata.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ public int hashCode() {
121121

122122
@Override
123123
public String toString() {
124-
String str = Metadata.escapeId(name) + ' ' + type;
124+
String str = Metadata.quoteIfNecessary(name) + ' ' + type;
125125
return isStatic ? str + " static" : str;
126126
}
127127

driver-core/src/main/java/com/datastax/driver/core/FunctionMetadata.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -163,9 +163,9 @@ private String asCQLQuery(boolean formatted) {
163163
StringBuilder sb = new StringBuilder("CREATE FUNCTION ");
164164

165165
sb
166-
.append(Metadata.escapeId(keyspace.getName()))
166+
.append(Metadata.quoteIfNecessary(keyspace.getName()))
167167
.append('.')
168-
.append(Metadata.escapeId(simpleName))
168+
.append(Metadata.quoteIfNecessary(simpleName))
169169
.append('(');
170170

171171
boolean first = true;
@@ -179,7 +179,7 @@ private String asCQLQuery(boolean formatted) {
179179
DataType type = entry.getValue();
180180
sb
181181
.append(TableMetadata.spaces(4, formatted))
182-
.append(Metadata.escapeId(name))
182+
.append(Metadata.quoteIfNecessary(name))
183183
.append(' ')
184184
.append(type.asFunctionParameterString());
185185
}
@@ -226,7 +226,7 @@ public KeyspaceMetadata getKeyspace() {
226226
public String getSignature() {
227227
StringBuilder sb = new StringBuilder();
228228
sb
229-
.append(Metadata.escapeId(simpleName))
229+
.append(Metadata.quoteIfNecessary(simpleName))
230230
.append('(');
231231
boolean first = true;
232232
for (DataType type : arguments.values()) {

driver-core/src/main/java/com/datastax/driver/core/IndexMetadata.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ static IndexMetadata fromLegacy(ColumnMetadata column, ColumnMetadata.Raw raw) {
113113
}
114114

115115
private static String targetFromLegacyOptions(ColumnMetadata column, Map<String, String> options) {
116-
String columnName = Metadata.escapeId(column.getName());
116+
String columnName = Metadata.quoteIfNecessary(column.getName());
117117
if (options.containsKey(INDEX_KEYS_OPTION_NAME))
118118
return String.format("keys(%s)", columnName);
119119
if (options.containsKey(INDEX_ENTRIES_OPTION_NAME))
@@ -202,9 +202,9 @@ public String getOption(String name) {
202202
* @return the 'CREATE INDEX' query corresponding to this index.
203203
*/
204204
public String asCQLQuery() {
205-
String keyspaceName = Metadata.escapeId(table.getKeyspace().getName());
206-
String tableName = Metadata.escapeId(table.getName());
207-
String indexName = Metadata.escapeId(this.name);
205+
String keyspaceName = Metadata.quoteIfNecessary(table.getKeyspace().getName());
206+
String tableName = Metadata.quoteIfNecessary(table.getName());
207+
String indexName = Metadata.quoteIfNecessary(this.name);
208208
return isCustomIndex()
209209
? String.format("CREATE CUSTOM INDEX %s ON %s.%s (%s) USING '%s' %s;", indexName, keyspaceName, tableName, getTarget(), getIndexClassName(), getOptionsAsCql())
210210
: String.format("CREATE INDEX %s ON %s.%s (%s);", indexName, keyspaceName, tableName, getTarget());

driver-core/src/main/java/com/datastax/driver/core/KeyspaceMetadata.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ public String exportAsString() {
292292
public String asCQLQuery() {
293293
StringBuilder sb = new StringBuilder();
294294

295-
sb.append("CREATE KEYSPACE ").append(Metadata.escapeId(name)).append(" WITH ");
295+
sb.append("CREATE KEYSPACE ").append(Metadata.quoteIfNecessary(name)).append(" WITH ");
296296
sb.append("REPLICATION = { 'class' : '").append(replication.get("class")).append('\'');
297297
for (Map.Entry<String, String> entry : replication.entrySet()) {
298298
if (entry.getKey().equals("class"))

driver-core/src/main/java/com/datastax/driver/core/MaterializedViewMetadata.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -155,9 +155,9 @@ public TableMetadata getBaseTable() {
155155
@Override
156156
protected String asCQLQuery(boolean formatted) {
157157

158-
String keyspaceName = Metadata.escapeId(keyspace.getName());
159-
String baseTableName = Metadata.escapeId(baseTable.getName());
160-
String viewName = Metadata.escapeId(name);
158+
String keyspaceName = Metadata.quoteIfNecessary(keyspace.getName());
159+
String baseTableName = Metadata.quoteIfNecessary(baseTable.getName());
160+
String viewName = Metadata.quoteIfNecessary(name);
161161

162162
StringBuilder sb = new StringBuilder();
163163
sb.append("CREATE MATERIALIZED VIEW ")
@@ -173,7 +173,7 @@ protected String asCQLQuery(boolean formatted) {
173173
Iterator<ColumnMetadata> it = columns.values().iterator();
174174
while (it.hasNext()) {
175175
ColumnMetadata column = it.next();
176-
sb.append(spaces(4, formatted)).append(Metadata.escapeId(column.getName()));
176+
sb.append(spaces(4, formatted)).append(Metadata.quoteIfNecessary(column.getName()));
177177
if (it.hasNext()) sb.append(",");
178178
sb.append(" ");
179179
newLine(sb, formatted);
@@ -191,7 +191,7 @@ protected String asCQLQuery(boolean formatted) {
191191
// PK
192192
sb.append("PRIMARY KEY (");
193193
if (partitionKey.size() == 1) {
194-
sb.append(Metadata.escapeId(partitionKey.get(0).getName()));
194+
sb.append(Metadata.quoteIfNecessary(partitionKey.get(0).getName()));
195195
} else {
196196
sb.append('(');
197197
boolean first = true;
@@ -200,12 +200,12 @@ protected String asCQLQuery(boolean formatted) {
200200
first = false;
201201
else
202202
sb.append(", ");
203-
sb.append(Metadata.escapeId(cm.getName()));
203+
sb.append(Metadata.quoteIfNecessary(cm.getName()));
204204
}
205205
sb.append(')');
206206
}
207207
for (ColumnMetadata cm : clusteringColumns)
208-
sb.append(", ").append(Metadata.escapeId(cm.getName()));
208+
sb.append(", ").append(Metadata.quoteIfNecessary(cm.getName()));
209209
sb.append(')');
210210

211211
appendOptions(sb, formatted);

driver-core/src/main/java/com/datastax/driver/core/Metadata.java

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -148,13 +148,31 @@ private static boolean isAlphanumeric(String s) {
148148
return true;
149149
}
150150

151-
// Escape a CQL3 identifier based on its value as read from the schema
152-
// tables. Because it comes from Cassandra, we could just always quote it,
153-
// but to get a nicer output we don't do it if it's not necessary.
154-
static String escapeId(String ident) {
155-
return needsQuote(ident)
156-
? quote(ident)
157-
: ident;
151+
/**
152+
* Quotes a CQL identifier if necessary.
153+
* <p/>
154+
* This is similar to {@link #quote(String)}, except that it won't quote the input string
155+
* if it can safely be used as-is. For example:
156+
* <ul>
157+
* <li>{@code quoteIfNecessary("foo").equals("foo")} (no need to quote).</li>
158+
* <li>{@code quoteIfNecessary("Foo").equals("\"Foo\"")} (identifier is mixed case so case
159+
* sensitivity is required)</li>
160+
* <li>{@code quoteIfNecessary("foo bar").equals("\"foo bar\"")} (identifier contains
161+
* special characters)</li>
162+
* <li>{@code quoteIfNecessary("table").equals("\"table\"")} (identifier is a reserved CQL
163+
* keyword)</li>
164+
* </ul>
165+
*
166+
* @param id the "internal" form of the identifier. That is, the identifier as it would
167+
* appear in Cassandra system tables (such as {@code system_schema.tables},
168+
* {@code system_schema.columns}, etc.)
169+
* @return the identifier as it would appear in a CQL query string. This is also how you need
170+
* to pass it to public driver methods, such as {@link #getKeyspace(String)}.
171+
*/
172+
public static String quoteIfNecessary(String id) {
173+
return needsQuote(id)
174+
? quote(id)
175+
: id;
158176
}
159177

160178
/**
@@ -207,7 +225,7 @@ static String fullFunctionName(String simpleName, Collection<?> argumentTypes) {
207225
// they appear in a schema change event (in targetSignature)
208226
if (argumentType instanceof UserType) {
209227
UserType userType = (UserType) argumentType;
210-
String typeName = Metadata.escapeId(userType.getTypeName());
228+
String typeName = Metadata.quoteIfNecessary(userType.getTypeName());
211229
sb.append(typeName);
212230
} else {
213231
sb.append(argumentType);

driver-core/src/main/java/com/datastax/driver/core/TableMetadata.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -398,15 +398,15 @@ public String exportAsString() {
398398
@Override
399399
protected String asCQLQuery(boolean formatted) {
400400
StringBuilder sb = new StringBuilder();
401-
sb.append("CREATE TABLE ").append(Metadata.escapeId(keyspace.getName())).append('.').append(Metadata.escapeId(name)).append(" (");
401+
sb.append("CREATE TABLE ").append(Metadata.quoteIfNecessary(keyspace.getName())).append('.').append(Metadata.quoteIfNecessary(name)).append(" (");
402402
newLine(sb, formatted);
403403
for (ColumnMetadata cm : columns.values())
404404
newLine(sb.append(spaces(4, formatted)).append(cm).append(',').append(spaces(1, !formatted)), formatted);
405405

406406
// PK
407407
sb.append(spaces(4, formatted)).append("PRIMARY KEY (");
408408
if (partitionKey.size() == 1) {
409-
sb.append(Metadata.escapeId(partitionKey.get(0).getName()));
409+
sb.append(Metadata.quoteIfNecessary(partitionKey.get(0).getName()));
410410
} else {
411411
sb.append('(');
412412
boolean first = true;
@@ -415,12 +415,12 @@ protected String asCQLQuery(boolean formatted) {
415415
first = false;
416416
else
417417
sb.append(", ");
418-
sb.append(Metadata.escapeId(cm.getName()));
418+
sb.append(Metadata.quoteIfNecessary(cm.getName()));
419419
}
420420
sb.append(')');
421421
}
422422
for (ColumnMetadata cm : clusteringColumns)
423-
sb.append(", ").append(Metadata.escapeId(cm.getName()));
423+
sb.append(", ").append(Metadata.quoteIfNecessary(cm.getName()));
424424
sb.append(')');
425425
newLine(sb, formatted);
426426
// end PK

driver-core/src/main/java/com/datastax/driver/core/TypeCodec.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2132,7 +2132,7 @@ public ByteBuffer serialize(T value, ProtocolVersion protocolVersion) {
21322132
ByteBuffer[] elements = new ByteBuffer[length];
21332133
int i = 0;
21342134
for (UserType.Field field : definition) {
2135-
elements[i] = serializeField(value, Metadata.escapeId(field.getName()), protocolVersion);
2135+
elements[i] = serializeField(value, Metadata.quoteIfNecessary(field.getName()), protocolVersion);
21362136
size += 4 + (elements[i] == null ? 0 : elements[i].remaining());
21372137
i++;
21382138
}
@@ -2161,7 +2161,7 @@ public T deserialize(ByteBuffer bytes, ProtocolVersion protocolVersion) {
21612161
break;
21622162
int n = input.getInt();
21632163
ByteBuffer element = n < 0 ? null : CodecUtils.readBytes(input, n);
2164-
value = deserializeAndSetField(element, value, Metadata.escapeId(field.getName()), protocolVersion);
2164+
value = deserializeAndSetField(element, value, Metadata.quoteIfNecessary(field.getName()), protocolVersion);
21652165
}
21662166
return value;
21672167
} catch (BufferUnderflowException e) {
@@ -2178,9 +2178,9 @@ public String format(T value) {
21782178
for (UserType.Field field : definition) {
21792179
if (i > 0)
21802180
sb.append(",");
2181-
sb.append(Metadata.escapeId(field.getName()));
2181+
sb.append(Metadata.quoteIfNecessary(field.getName()));
21822182
sb.append(":");
2183-
sb.append(formatField(value, Metadata.escapeId(field.getName())));
2183+
sb.append(formatField(value, Metadata.quoteIfNecessary(field.getName())));
21842184
i += 1;
21852185
}
21862186
sb.append("}");

0 commit comments

Comments
 (0)