Skip to content

Commit 86ed68b

Browse files
author
Bogdan Degtyariov
committed
Merge branch 'wl12496' Counting methods
2 parents d1181a4 + 5f2dc34 commit 86ed68b

File tree

7 files changed

+221
-10
lines changed

7 files changed

+221
-10
lines changed

include/mysqlx/xapi.h

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ typedef object_id* MYSQLX_GUID;
170170
#define MYSQLX_ERROR_VIEW_TYPE_MSG "Statement must be of VIEW type"
171171
#define MYSQLX_ERROR_OUTPUT_BUFFER_NULL "The output buffer cannot be NULL"
172172
#define MYSQLX_ERROR_OUTPUT_BUFFER_ZERO "The output buffer cannot have zero length"
173+
#define MYSQLX_ERROR_OUTPUT_VARIABLE_NULL "The output variable cannot be NULL"
173174
#define MYSQLX_ERROR_OP_NOT_SUPPORTED "The operation is not supported by the function"
174175
#define MYSQLX_ERROR_WRONG_SSL_MODE "Wrong value for SSL Mode"
175176
#define MYSQLX_ERROR_NO_TLS_SUPPORT "Can not create TLS session - this connector is built without TLS support"
@@ -1201,6 +1202,22 @@ mysqlx_sql_new(mysqlx_session_t *sess, const char *query,
12011202
====================================================================
12021203
*/
12031204

1205+
/**
1206+
Return a number of documents in a collection.
1207+
1208+
@param collection collection handle
1209+
@param[out] count the number of documents in a given collection
1210+
is returned through the parameter
1211+
1212+
@return `RESULT_OK` - on success; `RESULT_ERR` - on error
1213+
1214+
@ingroup xapi_coll
1215+
*/
1216+
1217+
PUBLIC_API int
1218+
mysqlx_collection_count(mysqlx_collection_t *collection, uint64_t *count);
1219+
1220+
12041221
/**
12051222
Execute a collection FIND statement with a specific find
12061223
criteria.
@@ -1724,6 +1741,22 @@ PUBLIC_API int mysqlx_set_modify_array_delete(mysqlx_stmt_t *stmt, ...);
17241741
*/
17251742

17261743

1744+
/**
1745+
Return a number of rows in a table
1746+
1747+
@param table table handle
1748+
@param[out] the number of rows in a given table is returned
1749+
through the parameter
1750+
1751+
@return `RESULT_OK` - on success; `RESULT_ERR` - on error
1752+
1753+
@ingroup xapi_coll
1754+
*/
1755+
1756+
PUBLIC_API int
1757+
mysqlx_table_count(mysqlx_table_t *table, uint64_t *count);
1758+
1759+
17271760
/**
17281761
Execute a table SELECT statement with a WHERE clause.
17291762
@@ -2568,13 +2601,19 @@ mysqlx_get_affected_count(mysqlx_result_t *res);
25682601
handle is valid.
25692602
25702603
@param result result handle
2571-
@param[out] num number of records buffered
2604+
@param[out] num number of records buffered. Zero is never returned. If the
2605+
number of records to buffer is zero the function returns
2606+
`RESULT_ERR`
25722607
25732608
@return `RESULT_OK` - on success; `RESULT_ERR` - on error. If the error
25742609
occurred it can be retrieved by `mysqlx_error()` function.
25752610
25762611
@note Even in case of an error some rows/documents might be buffered if they
25772612
were retrieved before the error occurred.
2613+
@note When called for second time on the same result the function
2614+
does not store anything because the data is already buffered.
2615+
Instead it returns the number of items that have not been
2616+
fetched yet.
25782617
25792618
@ingroup xapi_res
25802619
*/
@@ -2583,6 +2622,27 @@ PUBLIC_API int
25832622
mysqlx_store_result(mysqlx_result_t *result, size_t *num);
25842623

25852624

2625+
/**
2626+
Function for getting the number of remaining cached items in a result.
2627+
If nothing is cached if will attempt to store result in the internal
2628+
cache like `mysqlx_store_result()`.
2629+
2630+
@param result result handle
2631+
@param[out] num number of records buffered.
2632+
2633+
@return `RESULT_OK` - on success; `RESULT_ERR` - on error. If the error
2634+
occurred it can be retrieved by `mysqlx_error()` function.
2635+
2636+
@note Even in case of an error some rows/documents might be buffered if they
2637+
were retrieved before the error occurred.
2638+
2639+
@ingroup xapi_res
2640+
*/
2641+
2642+
PUBLIC_API int
2643+
mysqlx_get_count(mysqlx_result_t *result, size_t *num);
2644+
2645+
25862646
/**
25872647
Get identifiers of the documents added to the collection.
25882648

xapi/crud.cc

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,3 +636,28 @@ int mysqlx_stmt_struct::add_multiple_documents(va_list &args)
636636
set_diagnostic("No documents specified for ADD operation.", 0);
637637
return rc;
638638
}
639+
640+
template <class T>
641+
uint64_t get_count(T &obj)
642+
{
643+
mysqlx_session_struct &sess = obj.get_session();
644+
mysqlx_stmt_struct *stmt =
645+
sess.new_stmt<OP_SELECT>(obj);
646+
if (!stmt)
647+
throw_error("Failed to create statement");
648+
649+
if (RESULT_OK != mysqlx_set_items(stmt, "COUNT(*)", PARAM_END))
650+
throw_error("Failed to bind parameter");
651+
652+
return stmt->exec()->read_row()->get(0).get_uint();
653+
}
654+
655+
uint64_t mysqlx_collection_struct::count()
656+
{
657+
return get_count(*this);
658+
}
659+
660+
uint64_t mysqlx_table_struct::count()
661+
{
662+
return get_count(*this);
663+
}

xapi/crud_internal.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@ struct mysqlx_result_struct
8080
set_diagnostic(mysqlx_error_struct(m_reply->get_error()));
8181
}
8282

83-
8483
mysqlx_error_struct *get_next_warning();
8584

8685
/*

xapi/mysqlx.cc

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -811,20 +811,35 @@ const char * STDCALL mysqlx_json_fetch_one(mysqlx_result_struct *res, size_t *le
811811
}
812812

813813

814-
int STDCALL
815-
mysqlx_store_result(mysqlx_result_struct *result, size_t *num)
814+
int STDCALL _store_result(mysqlx_result_struct *result, size_t *num,
815+
bool no_data_error)
816816
{
817817
SAFE_EXCEPTION_BEGIN(result, RESULT_ERROR)
818-
if (!result->has_data())
818+
if (no_data_error && !result->has_data())
819819
throw Mysqlx_exception("Attempt to store data for result without a data set");
820-
cdk::row_count_t row_num = result->count();
821-
if (num)
822-
*num = row_num;
823-
return RESULT_OK;
820+
821+
cdk::row_count_t row_num = result->count();
822+
if (num)
823+
*num = row_num;
824+
return RESULT_OK;
824825
SAFE_EXCEPTION_END(result, RESULT_ERROR)
825826
}
826827

827828

829+
int STDCALL
830+
mysqlx_store_result(mysqlx_result_struct *result, size_t *num)
831+
{
832+
return _store_result(result, num, true);
833+
}
834+
835+
836+
int STDCALL
837+
mysqlx_get_count(mysqlx_result_struct *result, size_t *num)
838+
{
839+
return _store_result(result, num, false);
840+
}
841+
842+
828843
/*
829844
Accessing row fields
830845
-------------------------------------------------------------------------
@@ -1482,6 +1497,27 @@ mysqlx_table_delete(mysqlx_table_struct *table, const char *criteria)
14821497
}
14831498

14841499

1500+
int STDCALL
1501+
mysqlx_table_count(mysqlx_table_t *table, uint64_t *count)
1502+
{
1503+
SAFE_EXCEPTION_BEGIN(table, RESULT_ERROR)
1504+
PARAM_NULL_CHECK(count, table, MYSQLX_ERROR_OUTPUT_VARIABLE_NULL, RESULT_ERROR);
1505+
*count = table->count();
1506+
return RESULT_OK;
1507+
SAFE_EXCEPTION_END(table, RESULT_ERROR)
1508+
}
1509+
1510+
1511+
int STDCALL
1512+
mysqlx_collection_count(mysqlx_collection_t *collection, uint64_t *count)
1513+
{
1514+
SAFE_EXCEPTION_BEGIN(collection, RESULT_ERROR)
1515+
PARAM_NULL_CHECK(count, collection, MYSQLX_ERROR_OUTPUT_VARIABLE_NULL, RESULT_ERROR);
1516+
*count = collection->count();
1517+
return RESULT_OK;
1518+
SAFE_EXCEPTION_END(collection, RESULT_ERROR)
1519+
}
1520+
14851521
mysqlx_result_struct * STDCALL
14861522
mysqlx_collection_find(mysqlx_collection_struct *collection, const char *criteria)
14871523
{

xapi/mysqlx_cc_internal.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,8 @@ struct mysqlx_collection_struct
395395
, m_sess(schema.get_session())
396396
{}
397397

398+
uint64_t count();
399+
398400
bool exists()
399401
{
400402
return
@@ -453,6 +455,8 @@ struct mysqlx_table_struct
453455
, m_sess(schema.get_session())
454456
{}
455457

458+
uint64_t count();
459+
456460
bool exists()
457461
{
458462
return

xapi/tests/test.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ using namespace ::std;
5656
}
5757

5858
#define ERR_CHECK(A, C) if((A) == RESULT_ERROR) { \
59-
cout << endl << "Error!" << mysqlx_stmt_error_message(C) << endl; \
59+
cout << endl << "Error!" << mysqlx_error_message(C) << endl; \
6060
FAIL(); \
6161
}
6262

xapi/tests/xapi_crud-t.cc

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,93 @@
5050
"{\"_id\": \"C8B27676E8A1D1E12C250850273BD114\", \"a_key\": 5, \"b_key\": \"so long world\", \"c_key\": 88.888}"
5151
};
5252

53+
TEST_F(xapi, test_count)
54+
{
55+
mysqlx_result_t *res;
56+
mysqlx_schema_t *schema;
57+
mysqlx_collection_t *collection;
58+
mysqlx_table_t *table;
59+
mysqlx_stmt_t *stmt;
60+
mysqlx_row_t *row;
61+
const char *schema_name = "cc_crud_test";
62+
const char *coll_name = "coll_test";
63+
const char *tab_name = "tab_test";
64+
char buf[512];
65+
int i, j;
66+
size_t count = 0;
67+
uint64_t rec_count = 0;
68+
69+
AUTHENTICATE();
70+
71+
mysqlx_schema_drop(get_session(), schema_name);
72+
ERR_CHECK(mysqlx_schema_create(get_session(), schema_name),
73+
get_session());
74+
schema = mysqlx_get_schema(get_session(), schema_name, 0);
75+
ERR_CHECK(mysqlx_collection_create(schema, coll_name), schema);
76+
collection = mysqlx_get_collection(schema, coll_name, 0);
77+
78+
ERR_CHECK(mysqlx_collection_count(collection, &rec_count), collection);
79+
EXPECT_EQ(0, rec_count);
80+
81+
stmt = mysqlx_collection_add_new(collection);
82+
for (i = 0; i < 100; ++i)
83+
{
84+
sprintf(buf, "{\"name\" : \"name %02d\"}", i);
85+
ERR_CHECK(mysqlx_set_add_document(stmt, buf), stmt);
86+
}
87+
CRUD_CHECK(res = mysqlx_execute(stmt), stmt);
88+
rec_count = 0;
89+
ERR_CHECK(mysqlx_collection_count(collection, &rec_count), collection);
90+
EXPECT_EQ(100, rec_count);
91+
92+
sprintf(buf, "CREATE TABLE %s.%s (id int)",
93+
schema_name, tab_name);
94+
CRUD_CHECK(res = mysqlx_sql(get_session(), buf, MYSQLX_NULL_TERMINATED),
95+
get_session());
96+
table = mysqlx_get_table(schema, tab_name, 0);
97+
ERR_CHECK(mysqlx_table_count(table, &rec_count), table);
98+
EXPECT_EQ(0, rec_count);
99+
100+
stmt = mysqlx_table_insert_new(table);
101+
for (i = 0; i < 100; ++i)
102+
{
103+
ERR_CHECK(mysqlx_set_insert_row(stmt, PARAM_UINT(i), PARAM_END), stmt);
104+
}
105+
CRUD_CHECK(res = mysqlx_execute(stmt), stmt);
106+
ERR_CHECK(mysqlx_table_count(table, &rec_count), table);
107+
EXPECT_EQ(100, rec_count);
108+
109+
stmt = mysqlx_table_select_new(table);
110+
ERR_CHECK(mysqlx_set_select_where(stmt, "id < 10"), stmt);
111+
ERR_CHECK(mysqlx_set_select_order_by(stmt, "id", SORT_ORDER_ASC, PARAM_END), stmt);
112+
CRUD_CHECK(res = mysqlx_execute(stmt), stmt);
113+
114+
ERR_CHECK(mysqlx_get_count(res, &count), res);
115+
EXPECT_EQ(10, count);
116+
117+
ERR_CHECK(mysqlx_get_count(res, &count), res);
118+
EXPECT_EQ(10, count);
119+
120+
j = 0;
121+
while ((row = mysqlx_row_fetch_one(res)) != NULL)
122+
{
123+
// Call again to make sure rows are inact
124+
int64_t id = 0;
125+
126+
ERR_CHECK(mysqlx_get_count(res, &count), res);
127+
EXPECT_EQ((9 - j), count);
128+
ERR_CHECK(mysqlx_get_sint(row, 0, &id), row);
129+
EXPECT_EQ(j, id);
130+
++j;
131+
}
132+
EXPECT_EQ(10, j);
133+
134+
// Check how mysqlx_get_count() handles next result
135+
EXPECT_EQ(RESULT_NULL, mysqlx_next_result(res));
136+
ERR_CHECK(mysqlx_get_count(res, &count), res);
137+
EXPECT_EQ(0, count);
138+
}
139+
53140
TEST_F(xapi, test_merge_patch)
54141
{
55142
SKIP_IF_NO_XPLUGIN

0 commit comments

Comments
 (0)