1 module cassandra.table;
2 
3 import cassandra.cql.result;
4 import cassandra.cql.utils;
5 import cassandra.keyspace;
6 import cassandra.internal.utils;
7 
8 import std.algorithm : map;
9 import std.array : array, join;
10 import std..string : format;
11 
12 
13 struct CassandraTable {
14 	private {
15 		CassandraKeyspace m_keyspace;
16 		string m_name;
17 	}
18 
19 	this(CassandraKeyspace keyspace, string name)
20 	{
21 		enforceValidIdentifier(name);
22 		m_keyspace = keyspace;
23 		m_name = name;
24 	}
25 
26 	bool exists()
27 	{
28 		auto sysks = m_keyspace.client.getKeyspace("system");
29 		auto res = sysks.query(format(`SELECT columnfamily_name FROM schema_columnfamilies WHERE keyspace_name='%s' AND columnfamily_name='%s'`, m_keyspace.name, m_name));
30 		return !res.empty;
31 	}
32 
33 	ColumnDescription[] describe()
34 	{
35 		auto res = m_keyspace.query(format("SELECT * FROM %s", m_name));
36 		return res.metadata.column_specs.map!(cs => ColumnDescription(cs.name, cs.type)).array;
37 	}
38 
39 	void insert(T)(T fields)
40 		if (is(T == struct) || is(T == class))
41 	{
42 		auto column_names = fieldNames!T[].join(", ");
43 		auto column_values = valueStrings(fields)[].join(", ");
44 		auto str = format("INSERT INTO %s (%s) VALUES (%s)", m_name, column_names, column_values);
45 		m_keyspace.query(str, Consistency.any);
46 	}
47 
48 	void truncate()
49 	{
50 		m_keyspace.query("TRUNCATE "~m_name);
51 	}
52 
53 	CassandraResult select(string expr = null/*, order, limit*/)
54 	{
55 		string query = "SELECT * FROM "~m_name;
56 		if (expr) query ~= "WHERE "~expr;
57 		return m_keyspace.query(query);
58 	}
59 
60 	void createIndex(string column, string custom_class = null)
61 	{
62 		m_keyspace.query(format("CREATE %sINDEX ON %s.%s (%s) %s",
63 			custom_class.length ? "CUSTOM " : "", m_keyspace.name, m_name, column,
64 			custom_class.length ? " USING " ~ custom_class : ""));
65 	}
66 }
67 
68 struct ColumnDescription {
69 	string name;
70 	Option type;
71 }
72 
73 private string[T.tupleof.length] fieldNames(T)()
74 {
75 	string[T.tupleof.length] ret;
76 	foreach (i, FT; typeof(T.tupleof))
77 		ret[i] = __traits(identifier, T.tupleof[i]);
78 	return ret;
79 }
80 private string[T.tupleof.length] valueStrings(T)(T fields)
81 {
82 	string[T.tupleof.length] ret;
83 	foreach (i, F; fields.tupleof)
84 		ret[i] = toCQLString(F);
85 	return ret;
86 }