static DataType::ConstPtr map(DataType::ConstPtr key_type, DataType::ConstPtr value_type) { DataType::Vec types; types.push_back(key_type); types.push_back(value_type); return DataType::ConstPtr(new CollectionType(CASS_VALUE_TYPE_MAP, types)); }
DataType::Ptr decode_collection(CassValueType collection_type) { DataType::Vec types; types.push_back(decode()); if (collection_type == CASS_VALUE_TYPE_MAP) { types.push_back(decode()); } return DataType::Ptr(new CollectionType(collection_type, types, false)); }
DataType::Ptr decode_tuple() { uint16_t n; buffer_ = decode_uint16(buffer_, n); DataType::Vec types; for (uint16_t i = 0; i < n; ++i) { types.push_back(decode()); } return DataType::Ptr(new TupleType(types, false)); }
DataType::ConstPtr DataTypeCqlNameParser::parse(const std::string& type, const NativeDataTypes& native_types, KeyspaceMetadata* keyspace, bool is_frozen) { Parser parser(type, 0); std::string type_name; Parser::TypeParamsVec params; parser.parse_type_name(&type_name); std::transform(type_name.begin(), type_name.end(), type_name.begin(), tolower); DataType::ConstPtr native_type(native_types.by_cql_name(type_name)); if (native_type) { return native_type; } if (type_name == "list") { parser.parse_type_parameters(¶ms); if (params.size() != 1) { LOG_ERROR("Expecting single parameter for list %s", type.c_str()); return DataType::NIL; } DataType::ConstPtr element_type = parse(params[0], native_types, keyspace); return CollectionType::list(element_type, is_frozen); } if (type_name == "set") { parser.parse_type_parameters(¶ms); if (params.size() != 1) { LOG_ERROR("Expecting single parameter for set %s", type.c_str()); return DataType::NIL; } DataType::ConstPtr element_type = parse(params[0], native_types, keyspace); return CollectionType::set(element_type, is_frozen); } if (type_name == "map") { parser.parse_type_parameters(¶ms); if (params.size() != 2) { LOG_ERROR("Expecting two parameters for set %s", type.c_str()); return DataType::NIL; } DataType::ConstPtr key_type = parse(params[0], native_types, keyspace); DataType::ConstPtr value_type = parse(params[1], native_types, keyspace); return CollectionType::map(key_type, value_type, is_frozen); } if (type_name == "tuple") { parser.parse_type_parameters(¶ms); if (params.empty()) { LOG_ERROR("Expecting at least a one parameter for tuple %s", type.c_str()); return DataType::NIL; } DataType::Vec types; for (Parser::TypeParamsVec::iterator i = params.begin(), end = params.end(); i != end; ++i) { types.push_back(parse(*i, native_types, keyspace)); } return DataType::ConstPtr(new TupleType(types, is_frozen)); } if (type_name == "frozen") { parser.parse_type_parameters(¶ms); if (params.size() != 1) { LOG_ERROR("Expecting single parameter for frozen keyword %s", type.c_str()); return DataType::NIL; } return parse(params[0], native_types, keyspace, true); } if (type_name == "empty") { return DataType::ConstPtr(new CustomType(type_name)); } if (type_name.empty()) { return DataType::NIL; } UserType::ConstPtr user_type(keyspace->get_or_create_user_type(type_name, is_frozen)); if (user_type->is_frozen() != is_frozen) { return UserType::Ptr(new UserType(user_type->keyspace(), user_type->type_name(), user_type->fields(), is_frozen)); } return user_type; }
SharedRefPtr<ParseResult> DataTypeClassNameParser::parse_with_composite(const std::string& type, const NativeDataTypes& native_types) { Parser parser(type, 0); std::string next; parser.get_next_name(&next); if (!is_composite(next)) { DataType::ConstPtr data_type = parse_one(type, native_types); if (!data_type) { return SharedRefPtr<ParseResult>(); } return SharedRefPtr<ParseResult>(new ParseResult(data_type, is_reversed(next))); } TypeParamsVec sub_class_names; if (!parser.get_type_params(&sub_class_names)) { return SharedRefPtr<ParseResult>(); } if (sub_class_names.empty()) { LOG_ERROR("Expected at least one subclass type for a composite type"); return SharedRefPtr<ParseResult>(); } ParseResult::CollectionMap collections; const std::string& last = sub_class_names.back(); size_t count = sub_class_names.size(); if (is_collection(last)) { count--; Parser collection_parser(last, 0); collection_parser.get_next_name(); NameAndTypeParamsVec params; if (!collection_parser.get_collection_params(¶ms)) { return SharedRefPtr<ParseResult>(); } for (NameAndTypeParamsVec::const_iterator i = params.begin(), end = params.end(); i != end; ++i) { DataType::ConstPtr data_type = parse_one(i->second, native_types); if (!data_type) { return SharedRefPtr<ParseResult>(); } collections[i->first] = data_type; } } DataType::Vec types; ParseResult::ReversedVec reversed; for (size_t i = 0; i < count; ++i) { DataType::ConstPtr data_type = parse_one(sub_class_names[i], native_types); if (!data_type) { return SharedRefPtr<ParseResult>(); } types.push_back(data_type); reversed.push_back(is_reversed(sub_class_names[i])); } return SharedRefPtr<ParseResult>(new ParseResult(true, types, reversed, collections)); }
DataType::ConstPtr DataTypeClassNameParser::parse_one(const std::string& type, const NativeDataTypes& native_types) { bool is_frozen = DataTypeClassNameParser::is_frozen(type); std::string class_name; if (is_reversed(type) || is_frozen) { if (!get_nested_class_name(type, &class_name)) { return DataType::ConstPtr(); } } else { class_name = type; } Parser parser(class_name, 0); std::string next; parser.get_next_name(&next); if (starts_with(next, LIST_TYPE)) { TypeParamsVec params; if (!parser.get_type_params(¶ms) || params.empty()) { return DataType::ConstPtr(); } DataType::ConstPtr element_type(parse_one(params[0], native_types)); if (!element_type) { return DataType::ConstPtr(); } return CollectionType::list(element_type, is_frozen); } else if(starts_with(next, SET_TYPE)) { TypeParamsVec params; if (!parser.get_type_params(¶ms) || params.empty()) { return DataType::ConstPtr(); } DataType::ConstPtr element_type(parse_one(params[0], native_types)); if (!element_type) { return DataType::ConstPtr(); } return CollectionType::set(element_type, is_frozen); } else if(starts_with(next, MAP_TYPE)) { TypeParamsVec params; if (!parser.get_type_params(¶ms) || params.size() < 2) { return DataType::ConstPtr(); } DataType::ConstPtr key_type(parse_one(params[0], native_types)); DataType::ConstPtr value_type(parse_one(params[1], native_types)); if (!key_type || !value_type) { return DataType::ConstPtr(); } return CollectionType::map(key_type, value_type, is_frozen); } if (is_frozen) { LOG_WARN("Got a frozen type for something other than a collection, " "this driver might be too old for your version of Cassandra"); } if (is_user_type(next)) { parser.skip(); // Skip '(' std::string keyspace; if (!parser.read_one(&keyspace)) { return DataType::ConstPtr(); } parser.skip_blank_and_comma(); std::string hex; if (!parser.read_one(&hex)) { return DataType::ConstPtr(); } std::string type_name; if (!from_hex(hex, &type_name)) { LOG_ERROR("Invalid hex string \"%s\" for parameter", hex.c_str()); return DataType::ConstPtr(); } if (keyspace.empty() || type_name.empty()) { LOG_ERROR("UDT has no keyspace or type name"); return DataType::ConstPtr(); } parser.skip_blank_and_comma(); NameAndTypeParamsVec raw_fields; if (!parser.get_name_and_type_params(&raw_fields)) { return DataType::ConstPtr(); } UserType::FieldVec fields; for (NameAndTypeParamsVec::const_iterator i = raw_fields.begin(), end = raw_fields.end(); i != end; ++i) { DataType::ConstPtr data_type = parse_one(i->second, native_types); if (!data_type) { return DataType::ConstPtr(); } fields.push_back(UserType::Field(i->first, data_type)); } return DataType::ConstPtr(new UserType(keyspace, type_name, fields, true)); } if (is_tuple_type(type)) { TypeParamsVec raw_types; if (!parser.get_type_params(&raw_types)) { return DataType::ConstPtr(); } DataType::Vec types; for (TypeParamsVec::const_iterator i = raw_types.begin(), end = raw_types.end(); i != end; ++i) { DataType::ConstPtr data_type = parse_one(*i, native_types); if (!data_type) { return DataType::ConstPtr(); } types.push_back(data_type); } return DataType::ConstPtr(new TupleType(types, true)); } DataType::ConstPtr native_type(native_types.by_class_name(next)); if (native_type) { return native_type; } return DataType::ConstPtr(new CustomType(next)); }
static DataType::ConstPtr set(DataType::ConstPtr element_type, bool is_frozen) { DataType::Vec types; types.push_back(element_type); return DataType::ConstPtr(new CollectionType(CASS_VALUE_TYPE_SET, types, is_frozen)); }
static DataType::ConstPtr list(DataType::ConstPtr element_type) { DataType::Vec types; types.push_back(element_type); return DataType::ConstPtr(new CollectionType(CASS_VALUE_TYPE_LIST, types)); }