@SuppressWarnings("unchecked") public <K, V> Map<K, V> getMap(int i, Class<K> keysClass, Class<V> valuesClass) { DataType type = metadata.getType(i); if (type.getName() != DataType.Name.MAP) throw new InvalidTypeException( String.format("Column %s is not of map type", metadata.getName(i))); Class<?> expectedKeysClass = type.getTypeArguments().get(0).getName().javaType; Class<?> expectedValuesClass = type.getTypeArguments().get(1).getName().javaType; if (!keysClass.isAssignableFrom(expectedKeysClass) || !valuesClass.isAssignableFrom(expectedValuesClass)) throw new InvalidTypeException( String.format( "Column %s is a map of %s->%s (CQL type %s), cannot be retrieve as a map of %s->%s", metadata.getName(i), expectedKeysClass, expectedValuesClass, type, keysClass, valuesClass)); ByteBuffer value = data.get(i); if (value == null) return Collections.<K, V>emptyMap(); return Collections.unmodifiableMap(Codec.<Map<K, V>>getCodec(type).compose(value)); }
public void udtSerDeserTest(int version) throws Exception { ListType<?> lt = ListType.getInstance(Int32Type.instance, true); SetType<?> st = SetType.getInstance(UTF8Type.instance, true); MapType<?, ?> mt = MapType.getInstance(UTF8Type.instance, LongType.instance, true); UserType udt = new UserType( "ks", bb("myType"), Arrays.asList(bb("f1"), bb("f2"), bb("f3"), bb("f4")), Arrays.asList(LongType.instance, lt, st, mt)); Map<ColumnIdentifier, Term.Raw> value = new HashMap<>(); value.put(ci("f1"), lit(42)); value.put(ci("f2"), new Lists.Literal(Arrays.<Term.Raw>asList(lit(3), lit(1)))); value.put(ci("f3"), new Sets.Literal(Arrays.<Term.Raw>asList(lit("foo"), lit("bar")))); value.put( ci("f4"), new Maps.Literal( Arrays.<Pair<Term.Raw, Term.Raw>>asList( Pair.<Term.Raw, Term.Raw>create(lit("foo"), lit(24)), Pair.<Term.Raw, Term.Raw>create(lit("bar"), lit(12))))); UserTypes.Literal u = new UserTypes.Literal(value); Term t = u.prepare("ks", columnSpec("myValue", udt)); QueryOptions options = QueryOptions.DEFAULT; if (version == 2) options = QueryOptions.fromProtocolV2(ConsistencyLevel.ONE, Collections.<ByteBuffer>emptyList()); else if (version != 3) throw new AssertionError("Invalid protocol version for test"); ByteBuffer serialized = t.bindAndGet(options); ByteBuffer[] fields = udt.split(serialized); assertEquals(4, fields.length); assertEquals(bytes(42L), fields[0]); // Note that no matter what the protocol version has been used in bindAndGet above, the // collections inside // a UDT should alway be serialized with version 3 of the protocol. Which is why we don't use // 'version' // on purpose below. assertEquals( Arrays.asList(3, 1), lt.getSerializer().deserializeForNativeProtocol(fields[1], 3)); LinkedHashSet<String> s = new LinkedHashSet<>(); s.addAll(Arrays.asList("bar", "foo")); assertEquals(s, st.getSerializer().deserializeForNativeProtocol(fields[2], 3)); LinkedHashMap<String, Long> m = new LinkedHashMap<>(); m.put("bar", 12L); m.put("foo", 24L); assertEquals(m, mt.getSerializer().deserializeForNativeProtocol(fields[3], 3)); }
@SuppressWarnings("unchecked") public <T> Set<T> getSet(int i, Class<T> elementsClass) { DataType type = metadata.getType(i); if (type.getName() != DataType.Name.SET) throw new InvalidTypeException( String.format("Column %s is not of set type", metadata.getName(i))); Class<?> expectedClass = type.getTypeArguments().get(0).getName().javaType; if (!elementsClass.isAssignableFrom(expectedClass)) throw new InvalidTypeException( String.format( "Column %s is a set of %s (CQL type %s), cannot be retrieve as a set of %s", metadata.getName(i), expectedClass, type, elementsClass)); ByteBuffer value = data.get(i); if (value == null) return Collections.<T>emptySet(); return Collections.unmodifiableSet(Codec.<Set<T>>getCodec(type).compose(value)); }
@SuppressWarnings("unchecked") public <T> List<T> getList(int i, Class<T> elementsClass) { DataType type = metadata.getType(i); if (type.getName() != DataType.Name.LIST) throw new InvalidTypeException( String.format("Column %s is not of list type", metadata.getName(i))); Class<?> expectedClass = type.getTypeArguments().get(0).getName().javaType; if (!elementsClass.isAssignableFrom(expectedClass)) throw new InvalidTypeException( String.format( "Column %s is a list of %s (CQL type %s), cannot be retrieve as a list of %s", metadata.getName(i), expectedClass, type, elementsClass)); ByteBuffer value = data.get(i); if (value == null) return Collections.<T>emptyList(); // TODO: we could avoid the getCodec call if we kept a reference to the original message. return Collections.unmodifiableList(Codec.<List<T>>getCodec(type).compose(value)); }
public void applyPropertiesTo(CFMetaData cfmd) throws RequestValidationException { cfmd.defaultValidator(defaultValidator) .keyValidator(keyValidator) .columnMetadata(getColumns()) .setDense(isDense); cfmd.addColumnMetadataFromAliases( keyAliases, keyValidator, ColumnDefinition.Type.PARTITION_KEY); cfmd.addColumnMetadataFromAliases( columnAliases, comparator, ColumnDefinition.Type.CLUSTERING_KEY); if (valueAlias != null) cfmd.addColumnMetadataFromAliases( Collections.<ByteBuffer>singletonList(valueAlias), defaultValidator, ColumnDefinition.Type.COMPACT_VALUE); properties.applyToCFMetadata(cfmd); }
public RowMutation mutationForKey( CFDefinition cfDef, ByteBuffer key, ColumnNameBuilder builder, boolean isRange, UpdateParameters params, ColumnGroupMap group) throws InvalidRequestException { QueryProcessor.validateKey(key); RowMutation rm = new RowMutation(cfDef.cfm.ksName, key); ColumnFamily cf = rm.addOrGet(columnFamily()); if (columns.isEmpty() && builder.componentCount() == 0) { // No columns, delete the row cf.delete(new DeletionInfo(params.timestamp, params.localDeletionTime)); } else { if (isRange) { ByteBuffer start = builder.copy().build(); ByteBuffer end = builder.buildAsEndOfRange(); QueryProcessor.validateColumnName(start); // If start is good, end is too cf.addAtom(params.makeRangeTombstone(start, end)); } else { // Delete specific columns if (cfDef.isCompact) { ByteBuffer columnName = builder.build(); QueryProcessor.validateColumnName(columnName); cf.addColumn(params.makeTombstone(columnName)); } else { Iterator<Pair<CFDefinition.Name, Term>> iter = toRemove.iterator(); while (iter.hasNext()) { Pair<CFDefinition.Name, Term> p = iter.next(); CFDefinition.Name column = p.left; if (column.type.isCollection()) { CollectionType validator = (CollectionType) column.type; Term keySelected = p.right; if (keySelected == null) { // Delete the whole collection ByteBuffer start = builder.copy().add(column.name.key).build(); QueryProcessor.validateColumnName(start); ColumnNameBuilder b = iter.hasNext() ? builder.copy() : builder; ByteBuffer end = b.add(column.name.key).buildAsEndOfRange(); cf.addAtom(params.makeRangeTombstone(start, end)); } else { builder.add(column.name.key); List<Term> args = Collections.singletonList(keySelected); Operation op; switch (validator.kind) { case LIST: op = ListOperation.DiscardKey(args); break; case SET: op = SetOperation.Discard(args); break; case MAP: op = MapOperation.DiscardKey(keySelected); break; default: throw new InvalidRequestException("Unknown collection type: " + validator.kind); } op.execute( cf, builder, validator, params, group == null ? null : group.getCollection(column.name.key)); } } else { ColumnNameBuilder b = iter.hasNext() ? builder.copy() : builder; ByteBuffer columnName = b.add(column.name.key).build(); QueryProcessor.validateColumnName(columnName); cf.addColumn(params.makeTombstone(columnName)); } } } } } return rm; }