PageRenderTime 53ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/src/java/org/apache/cassandra/cql3/UntypedResultSet.java

https://github.com/beobal/cassandra
Java | 459 lines | 360 code | 71 blank | 28 comment | 31 complexity | afdd27138374886f463a46ae8551e7f4 MD5 | raw file
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing,
  13. * software distributed under the License is distributed on an
  14. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  15. * KIND, either express or implied. See the License for the
  16. * specific language governing permissions and limitations
  17. * under the License.
  18. */
  19. package org.apache.cassandra.cql3;
  20. import java.net.InetAddress;
  21. import java.nio.ByteBuffer;
  22. import java.util.*;
  23. import com.google.common.annotations.VisibleForTesting;
  24. import org.apache.cassandra.schema.ColumnMetadata;
  25. import org.apache.cassandra.cql3.statements.SelectStatement;
  26. import org.apache.cassandra.db.*;
  27. import org.apache.cassandra.db.marshal.*;
  28. import org.apache.cassandra.db.partitions.PartitionIterator;
  29. import org.apache.cassandra.db.rows.*;
  30. import org.apache.cassandra.schema.TableMetadata;
  31. import org.apache.cassandra.service.ClientState;
  32. import org.apache.cassandra.service.pager.QueryPager;
  33. import org.apache.cassandra.transport.ProtocolVersion;
  34. import org.apache.cassandra.utils.AbstractIterator;
  35. import org.apache.cassandra.utils.FBUtilities;
  36. /** a utility for doing internal cql-based queries */
  37. public abstract class UntypedResultSet implements Iterable<UntypedResultSet.Row>
  38. {
  39. public static UntypedResultSet create(ResultSet rs)
  40. {
  41. return new FromResultSet(rs);
  42. }
  43. public static UntypedResultSet create(List<Map<String, ByteBuffer>> results)
  44. {
  45. return new FromResultList(results);
  46. }
  47. public static UntypedResultSet create(SelectStatement select, QueryPager pager, int pageSize)
  48. {
  49. return new FromPager(select, pager, pageSize);
  50. }
  51. /**
  52. * This method is intended for testing purposes, since it executes query on cluster
  53. * and not on the local node only.
  54. */
  55. @VisibleForTesting
  56. public static UntypedResultSet create(SelectStatement select,
  57. ConsistencyLevel cl,
  58. ClientState clientState,
  59. QueryPager pager,
  60. int pageSize)
  61. {
  62. return new FromDistributedPager(select, cl, clientState, pager, pageSize);
  63. }
  64. public boolean isEmpty()
  65. {
  66. return size() == 0;
  67. }
  68. public abstract int size();
  69. public abstract Row one();
  70. // No implemented by all subclasses, but we use it when we know it's there (for tests)
  71. public abstract List<ColumnSpecification> metadata();
  72. private static class FromResultSet extends UntypedResultSet
  73. {
  74. private final ResultSet cqlRows;
  75. private FromResultSet(ResultSet cqlRows)
  76. {
  77. this.cqlRows = cqlRows;
  78. }
  79. public int size()
  80. {
  81. return cqlRows.size();
  82. }
  83. public Row one()
  84. {
  85. if (cqlRows.size() != 1)
  86. throw new IllegalStateException("One row required, " + cqlRows.size() + " found");
  87. return new Row(cqlRows.metadata.requestNames(), cqlRows.rows.get(0));
  88. }
  89. public Iterator<Row> iterator()
  90. {
  91. return new AbstractIterator<Row>()
  92. {
  93. Iterator<List<ByteBuffer>> iter = cqlRows.rows.iterator();
  94. protected Row computeNext()
  95. {
  96. if (!iter.hasNext())
  97. return endOfData();
  98. return new Row(cqlRows.metadata.requestNames(), iter.next());
  99. }
  100. };
  101. }
  102. public List<ColumnSpecification> metadata()
  103. {
  104. return cqlRows.metadata.requestNames();
  105. }
  106. }
  107. private static class FromResultList extends UntypedResultSet
  108. {
  109. private final List<Map<String, ByteBuffer>> cqlRows;
  110. private FromResultList(List<Map<String, ByteBuffer>> cqlRows)
  111. {
  112. this.cqlRows = cqlRows;
  113. }
  114. public int size()
  115. {
  116. return cqlRows.size();
  117. }
  118. public Row one()
  119. {
  120. if (cqlRows.size() != 1)
  121. throw new IllegalStateException("One row required, " + cqlRows.size() + " found");
  122. return new Row(cqlRows.get(0));
  123. }
  124. public Iterator<Row> iterator()
  125. {
  126. return new AbstractIterator<Row>()
  127. {
  128. Iterator<Map<String, ByteBuffer>> iter = cqlRows.iterator();
  129. protected Row computeNext()
  130. {
  131. if (!iter.hasNext())
  132. return endOfData();
  133. return new Row(iter.next());
  134. }
  135. };
  136. }
  137. public List<ColumnSpecification> metadata()
  138. {
  139. throw new UnsupportedOperationException();
  140. }
  141. }
  142. private static class FromPager extends UntypedResultSet
  143. {
  144. private final SelectStatement select;
  145. private final QueryPager pager;
  146. private final int pageSize;
  147. private final List<ColumnSpecification> metadata;
  148. private FromPager(SelectStatement select, QueryPager pager, int pageSize)
  149. {
  150. this.select = select;
  151. this.pager = pager;
  152. this.pageSize = pageSize;
  153. this.metadata = select.getResultMetadata().requestNames();
  154. }
  155. public int size()
  156. {
  157. throw new UnsupportedOperationException();
  158. }
  159. public Row one()
  160. {
  161. throw new UnsupportedOperationException();
  162. }
  163. public Iterator<Row> iterator()
  164. {
  165. return new AbstractIterator<Row>()
  166. {
  167. private Iterator<List<ByteBuffer>> currentPage;
  168. protected Row computeNext()
  169. {
  170. int nowInSec = FBUtilities.nowInSeconds();
  171. while (currentPage == null || !currentPage.hasNext())
  172. {
  173. if (pager.isExhausted())
  174. return endOfData();
  175. try (ReadExecutionController executionController = pager.executionController();
  176. PartitionIterator iter = pager.fetchPageInternal(pageSize, executionController))
  177. {
  178. currentPage = select.process(iter, nowInSec).rows.iterator();
  179. }
  180. }
  181. return new Row(metadata, currentPage.next());
  182. }
  183. };
  184. }
  185. public List<ColumnSpecification> metadata()
  186. {
  187. return metadata;
  188. }
  189. }
  190. /**
  191. * Pager that calls `execute` rather than `executeInternal`
  192. */
  193. private static class FromDistributedPager extends UntypedResultSet
  194. {
  195. private final SelectStatement select;
  196. private final ConsistencyLevel cl;
  197. private final ClientState clientState;
  198. private final QueryPager pager;
  199. private final int pageSize;
  200. private final List<ColumnSpecification> metadata;
  201. private FromDistributedPager(SelectStatement select,
  202. ConsistencyLevel cl,
  203. ClientState clientState,
  204. QueryPager pager, int pageSize)
  205. {
  206. this.select = select;
  207. this.cl = cl;
  208. this.clientState = clientState;
  209. this.pager = pager;
  210. this.pageSize = pageSize;
  211. this.metadata = select.getResultMetadata().requestNames();
  212. }
  213. public int size()
  214. {
  215. throw new UnsupportedOperationException();
  216. }
  217. public Row one()
  218. {
  219. throw new UnsupportedOperationException();
  220. }
  221. public Iterator<Row> iterator()
  222. {
  223. return new AbstractIterator<Row>()
  224. {
  225. private Iterator<List<ByteBuffer>> currentPage;
  226. protected Row computeNext()
  227. {
  228. int nowInSec = FBUtilities.nowInSeconds();
  229. while (currentPage == null || !currentPage.hasNext())
  230. {
  231. if (pager.isExhausted())
  232. return endOfData();
  233. try (PartitionIterator iter = pager.fetchPage(pageSize, cl, clientState, System.nanoTime()))
  234. {
  235. currentPage = select.process(iter, nowInSec).rows.iterator();
  236. }
  237. }
  238. return new Row(metadata, currentPage.next());
  239. }
  240. };
  241. }
  242. public List<ColumnSpecification> metadata()
  243. {
  244. return metadata;
  245. }
  246. }
  247. public static class Row
  248. {
  249. private final Map<String, ByteBuffer> data = new HashMap<>();
  250. private final List<ColumnSpecification> columns = new ArrayList<>();
  251. public Row(Map<String, ByteBuffer> data)
  252. {
  253. this.data.putAll(data);
  254. }
  255. public Row(List<ColumnSpecification> names, List<ByteBuffer> columns)
  256. {
  257. this.columns.addAll(names);
  258. for (int i = 0; i < names.size(); i++)
  259. data.put(names.get(i).name.toString(), columns.get(i));
  260. }
  261. public static Row fromInternalRow(TableMetadata metadata, DecoratedKey key, org.apache.cassandra.db.rows.Row row)
  262. {
  263. Map<String, ByteBuffer> data = new HashMap<>();
  264. ByteBuffer[] keyComponents = SelectStatement.getComponents(metadata, key);
  265. for (ColumnMetadata def : metadata.partitionKeyColumns())
  266. data.put(def.name.toString(), keyComponents[def.position()]);
  267. Clustering<?> clustering = row.clustering();
  268. for (ColumnMetadata def : metadata.clusteringColumns())
  269. data.put(def.name.toString(), clustering.bufferAt(def.position()));
  270. for (ColumnMetadata def : metadata.regularAndStaticColumns())
  271. {
  272. if (def.isSimple())
  273. {
  274. Cell<?> cell = row.getCell(def);
  275. if (cell != null)
  276. data.put(def.name.toString(), cell.buffer());
  277. }
  278. else
  279. {
  280. ComplexColumnData complexData = row.getComplexColumnData(def);
  281. if (complexData != null)
  282. data.put(def.name.toString(), ((CollectionType)def.type).serializeForNativeProtocol(complexData.iterator(), ProtocolVersion.V3));
  283. }
  284. }
  285. return new Row(data);
  286. }
  287. public boolean has(String column)
  288. {
  289. // Note that containsKey won't work because we may have null values
  290. return data.get(column) != null;
  291. }
  292. public ByteBuffer getBlob(String column)
  293. {
  294. return data.get(column);
  295. }
  296. public String getString(String column)
  297. {
  298. return UTF8Type.instance.compose(data.get(column));
  299. }
  300. public boolean getBoolean(String column)
  301. {
  302. return BooleanType.instance.compose(data.get(column));
  303. }
  304. public byte getByte(String column)
  305. {
  306. return ByteType.instance.compose(data.get(column));
  307. }
  308. public short getShort(String column)
  309. {
  310. return ShortType.instance.compose(data.get(column));
  311. }
  312. public int getInt(String column)
  313. {
  314. return Int32Type.instance.compose(data.get(column));
  315. }
  316. public double getDouble(String column)
  317. {
  318. return DoubleType.instance.compose(data.get(column));
  319. }
  320. public ByteBuffer getBytes(String column)
  321. {
  322. return data.get(column);
  323. }
  324. public InetAddress getInetAddress(String column)
  325. {
  326. return InetAddressType.instance.compose(data.get(column));
  327. }
  328. public UUID getUUID(String column)
  329. {
  330. return UUIDType.instance.compose(data.get(column));
  331. }
  332. public Date getTimestamp(String column)
  333. {
  334. return TimestampType.instance.compose(data.get(column));
  335. }
  336. public long getLong(String column)
  337. {
  338. return LongType.instance.compose(data.get(column));
  339. }
  340. public <T> Set<T> getSet(String column, AbstractType<T> type)
  341. {
  342. ByteBuffer raw = data.get(column);
  343. return raw == null ? null : SetType.getInstance(type, true).compose(raw);
  344. }
  345. public <T> List<T> getList(String column, AbstractType<T> type)
  346. {
  347. ByteBuffer raw = data.get(column);
  348. return raw == null ? null : ListType.getInstance(type, true).compose(raw);
  349. }
  350. public <K, V> Map<K, V> getMap(String column, AbstractType<K> keyType, AbstractType<V> valueType)
  351. {
  352. ByteBuffer raw = data.get(column);
  353. return raw == null ? null : MapType.getInstance(keyType, valueType, true).compose(raw);
  354. }
  355. public Map<String, String> getTextMap(String column)
  356. {
  357. return getMap(column, UTF8Type.instance, UTF8Type.instance);
  358. }
  359. public <T> Set<T> getFrozenSet(String column, AbstractType<T> type)
  360. {
  361. ByteBuffer raw = data.get(column);
  362. return raw == null ? null : SetType.getInstance(type, false).compose(raw);
  363. }
  364. public <T> List<T> getFrozenList(String column, AbstractType<T> type)
  365. {
  366. ByteBuffer raw = data.get(column);
  367. return raw == null ? null : ListType.getInstance(type, false).compose(raw);
  368. }
  369. public <K, V> Map<K, V> getFrozenMap(String column, AbstractType<K> keyType, AbstractType<V> valueType)
  370. {
  371. ByteBuffer raw = data.get(column);
  372. return raw == null ? null : MapType.getInstance(keyType, valueType, false).compose(raw);
  373. }
  374. public Map<String, String> getFrozenTextMap(String column)
  375. {
  376. return getFrozenMap(column, UTF8Type.instance, UTF8Type.instance);
  377. }
  378. public List<ColumnSpecification> getColumns()
  379. {
  380. return columns;
  381. }
  382. @Override
  383. public String toString()
  384. {
  385. return data.toString();
  386. }
  387. }
  388. }