diff --git a/configure.py b/configure.py index dffc9b2d70..6a4c8add6d 100755 --- a/configure.py +++ b/configure.py @@ -520,6 +520,7 @@ urchin_core = (['database.cc', 'streaming/messages/outgoing_file_message.cc', 'streaming/messages/incoming_file_message.cc', 'gc_clock.cc', + 'partition_slice_builder.cc', ] + [Antlr3Grammar('cql3/Cql.g')] + [Thrift('interface/cassandra.thrift', 'Cassandra')] diff --git a/partition_slice_builder.cc b/partition_slice_builder.cc new file mode 100644 index 0000000000..0b49be04d6 --- /dev/null +++ b/partition_slice_builder.cc @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2015 Cloudius Systems, Ltd. + */ + +#include +#include +#include + +#include "partition_slice_builder.hh" + +partition_slice_builder::partition_slice_builder(const schema& schema) + : _schema(schema) +{ + _options.set(); + _options.set(); + _options.set(); +} + +query::partition_slice +partition_slice_builder::build() { + std::vector ranges; + if (_row_ranges) { + ranges = std::move(*_row_ranges); + } else { + ranges.emplace_back(query::clustering_range::make_open_ended_both_sides()); + } + + std::vector static_columns; + if (_static_columns) { + static_columns = std::move(*_static_columns); + } else { + boost::range::push_back(static_columns, + _schema.static_columns() | boost::adaptors::transformed(std::mem_fn(&column_definition::id))); + } + + std::vector regular_columns; + if (_regular_columns) { + regular_columns = std::move(*_regular_columns); + } else { + boost::range::push_back(regular_columns, + _schema.regular_columns() | boost::adaptors::transformed(std::mem_fn(&column_definition::id))); + } + + return { + std::move(ranges), + std::move(static_columns), + std::move(regular_columns), + std::move(_options) + }; +} + +partition_slice_builder& +partition_slice_builder::with_range(query::clustering_range range) { + if (!_row_ranges) { + _row_ranges = std::vector(); + } + _row_ranges->emplace_back(std::move(range)); + return *this; +} + +partition_slice_builder& +partition_slice_builder::with_no_regular_columns() { + _regular_columns = std::vector(); + return *this; +} + +partition_slice_builder& +partition_slice_builder::with_regular_column(bytes name) { + if (!_regular_columns) { + _regular_columns = std::vector(); + } + + const column_definition* def = _schema.get_column_definition(name); + if (!def) { + throw std::runtime_error(sprint("No such column: %s", _schema.regular_column_name_type()->to_string(name))); + } + if (!def->is_regular()) { + throw std::runtime_error(sprint("Column is not regular: %s", _schema.regular_column_name_type()->to_string(name))); + } + _regular_columns->push_back(def->id); + return *this; +} + +partition_slice_builder& +partition_slice_builder::with_no_static_columns() { + _static_columns = std::vector(); + return *this; +} + +partition_slice_builder& +partition_slice_builder::with_static_column(bytes name) { + if (!_static_columns) { + _static_columns = std::vector(); + } + + const column_definition* def = _schema.get_column_definition(name); + if (!def) { + throw std::runtime_error(sprint("No such column: %s", utf8_type->to_string(name))); + } + if (!def->is_static()) { + throw std::runtime_error(sprint("Column is not static: %s", utf8_type->to_string(name))); + } + _static_columns->push_back(def->id); + return *this; +} diff --git a/partition_slice_builder.hh b/partition_slice_builder.hh new file mode 100644 index 0000000000..178d6fc9cd --- /dev/null +++ b/partition_slice_builder.hh @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2015 Cloudius Systems, Ltd. + */ + +#pragma once + +#include +#include + +#include "query-request.hh" +#include "schema.hh" + +// +// Fluent builder for query::partition_slice. +// +// Selects everything by default, unless restricted. Each property can be +// restricted separately. For example, by default all static columns are +// selected, but if with_static_column() is called then only that column will +// be included. Still, all regular columns and the whole clustering range will +// be selected (unless restricted). +// +class partition_slice_builder { + std::experimental::optional> _regular_columns; + std::experimental::optional> _static_columns; + std::experimental::optional> _row_ranges; + const schema& _schema; + query::partition_slice::option_set _options; +public: + partition_slice_builder(const schema& schema); + + partition_slice_builder& with_static_column(bytes name); + partition_slice_builder& with_no_static_columns(); + partition_slice_builder& with_regular_column(bytes name); + partition_slice_builder& with_no_regular_columns(); + partition_slice_builder& with_range(query::clustering_range range); + + query::partition_slice build(); +};