Skip to content

Commit 732d519

Browse files
Merge pull request apache#154 from rafael-telles/flight-sql-cpp-server-update
[C++] Implement CommandStatementUpdate on server example
2 parents 4e66c39 + fef63b7 commit 732d519

8 files changed

Lines changed: 102 additions & 1 deletion

File tree

cpp/src/arrow/flight/flight-sql/client_impl.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,10 @@ Status FlightSqlClientT<T>::ExecuteUpdate(const FlightCallOptions& options,
9191

9292
const FlightDescriptor& descriptor = GetFlightDescriptorForCommand(command);
9393

94+
std::unique_ptr<FlightStreamWriter> writer;
9495
std::unique_ptr<FlightMetadataReader> reader;
9596

96-
ARROW_RETURN_NOT_OK(client->DoPut(options, descriptor, NULLPTR, NULL, &reader));
97+
ARROW_RETURN_NOT_OK(client->DoPut(options, descriptor, NULLPTR, &writer, &reader));
9798

9899
std::shared_ptr<Buffer> metadata;
99100

cpp/src/arrow/flight/flight-sql/example/sqlite_server.cc

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,28 @@ Status SQLiteFlightSqlServer::DoGetTables(const pb::sql::CommandGetTables& comma
265265
return Status::OK();
266266
}
267267

268+
Status SQLiteFlightSqlServer::DoPutCommandStatementUpdate(
269+
const pb::sql::CommandStatementUpdate& command, const ServerCallContext& context,
270+
std::unique_ptr<FlightMessageReader>& reader,
271+
std::unique_ptr<FlightMetadataWriter>& writer) {
272+
const std::string& sql = command.query();
273+
274+
std::shared_ptr<SqliteStatement> statement;
275+
ARROW_RETURN_NOT_OK(SqliteStatement::Create(db_, sql, &statement));
276+
277+
pb::sql::DoPutUpdateResult result;
278+
279+
int64_t record_count;
280+
ARROW_RETURN_NOT_OK(statement->ExecuteUpdate(&record_count));
281+
282+
result.set_record_count(record_count);
283+
284+
const std::shared_ptr<Buffer>& buffer = Buffer::FromString(result.SerializeAsString());
285+
ARROW_RETURN_NOT_OK(writer->WriteMetadata(*buffer));
286+
287+
return Status::OK();
288+
}
289+
268290
} // namespace example
269291
} // namespace sql
270292
} // namespace flight

cpp/src/arrow/flight/flight-sql/example/sqlite_server.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ class SQLiteFlightSqlServer : public FlightSqlServerBase {
6161
Status DoGetSchemas(const pb::sql::CommandGetSchemas& command,
6262
const ServerCallContext& context,
6363
std::unique_ptr<FlightDataStream>* result) override;
64+
Status DoPutCommandStatementUpdate(
65+
const pb::sql::CommandStatementUpdate& update, const ServerCallContext& context,
66+
std::unique_ptr<FlightMessageReader>& reader,
67+
std::unique_ptr<FlightMetadataWriter>& writer) override;
6468

6569
Status GetFlightInfoTables(const pb::sql::CommandGetTables& command,
6670
const ServerCallContext& context,

cpp/src/arrow/flight/flight-sql/example/sqlite_statement.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,15 @@ Status SqliteStatement::Reset(int* rc) {
9494

9595
sqlite3_stmt* SqliteStatement::GetSqlite3Stmt() { return stmt_; }
9696

97+
Status SqliteStatement::ExecuteUpdate(int64_t* result) {
98+
int rc;
99+
ARROW_RETURN_NOT_OK(Step(&rc));
100+
101+
*result = sqlite3_changes(db_);
102+
103+
return Status::OK();
104+
}
105+
97106
} // namespace example
98107
} // namespace sql
99108
} // namespace flight

cpp/src/arrow/flight/flight-sql/example/sqlite_statement.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ class SqliteStatement {
5656
/// \brief Returns the underlying sqlite3_stmt.
5757
sqlite3_stmt* GetSqlite3Stmt();
5858

59+
/// \brief Executes an UPDATE, INSERT or DELETE statement.
60+
/// \param[out] result The number of rows changed by execution.
61+
/// \return Status.
62+
Status ExecuteUpdate(int64_t* result);
63+
5964
private:
6065
sqlite3* db_;
6166
sqlite3_stmt* stmt_;

cpp/src/arrow/flight/flight-sql/sql_server.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,23 @@ Status FlightSqlServerBase::DoGet(const ServerCallContext& context, const Ticket
126126
return Status::Invalid("The defined request is invalid.");
127127
}
128128

129+
Status FlightSqlServerBase::DoPut(const ServerCallContext& context,
130+
std::unique_ptr<FlightMessageReader> reader,
131+
std::unique_ptr<FlightMetadataWriter> writer) {
132+
const FlightDescriptor& request = reader->descriptor();
133+
134+
google::protobuf::Any any;
135+
any.ParseFromArray(request.cmd.data(), static_cast<int>(request.cmd.size()));
136+
137+
if (any.Is<pb::sql::CommandStatementUpdate>()) {
138+
pb::sql::CommandStatementUpdate command;
139+
any.UnpackTo(&command);
140+
return DoPutCommandStatementUpdate(command, context, reader, writer);
141+
}
142+
143+
return Status::Invalid("The defined request is invalid.");
144+
}
145+
129146
Status FlightSqlServerBase::GetFlightInfoCatalogs(const ServerCallContext& context,
130147
const FlightDescriptor& descriptor,
131148
std::unique_ptr<FlightInfo>* info) {
@@ -246,6 +263,13 @@ Status FlightSqlServerBase::GetFlightInfoImportedKeys(
246263
return Status::NotImplemented("DoGetExportedKeys not implemented");
247264
}
248265

266+
Status FlightSqlServerBase::DoPutCommandStatementUpdate(
267+
const pb::sql::CommandStatementUpdate& command, const ServerCallContext& context,
268+
std::unique_ptr<FlightMessageReader>& reader,
269+
std::unique_ptr<FlightMetadataWriter>& writer) {
270+
return Status::NotImplemented("DoPutCommandStatementUpdate not implemented");
271+
}
272+
249273
std::shared_ptr<Schema> SqlSchema::GetCatalogsSchema() {
250274
return arrow::schema({field("catalog_name", utf8())});
251275
}

cpp/src/arrow/flight/flight-sql/sql_server.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ class FlightSqlServerBase : public FlightServerBase {
3939
Status DoGet(const ServerCallContext& context, const Ticket& request,
4040
std::unique_ptr<FlightDataStream>* stream) override;
4141

42+
Status DoPut(const ServerCallContext& context,
43+
std::unique_ptr<FlightMessageReader> reader,
44+
std::unique_ptr<FlightMetadataWriter> writer) override;
45+
4246
/// \brief Gets a FlightInfo for executing a SQL query.
4347
/// \param[in] command The CommandStatementQuery object containing the SQL
4448
/// statement.
@@ -257,6 +261,17 @@ class FlightSqlServerBase : public FlightServerBase {
257261
virtual Status DoGetImportedKeys(const pb::sql::CommandGetImportedKeys& command,
258262
const ServerCallContext& context,
259263
std::unique_ptr<FlightDataStream>* result);
264+
265+
/// \brief Executes an update SQL statement.
266+
/// \param[in] command The CommandStatementUpdate object containing the SQL statement.
267+
/// \param[in] context The call context.
268+
/// \param[in] reader a sequence of uploaded record batches.
269+
/// \param[in] writer send metadata back to the client.
270+
/// \return Status.
271+
virtual Status DoPutCommandStatementUpdate(
272+
const pb::sql::CommandStatementUpdate& command, const ServerCallContext& context,
273+
std::unique_ptr<FlightMessageReader>& reader,
274+
std::unique_ptr<FlightMetadataWriter>& writer);
260275
};
261276

262277
/// \brief Auxiliary class containing all Schemas used on Flight SQL.

cpp/src/arrow/flight/flight-sql/sql_server_test.cc

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,27 @@ TEST(TestFlightSqlServer, TestCommandGetSchemas) {
285285
ASSERT_EQ(0, table->num_rows());
286286
}
287287

288+
TEST(TestFlightSqlServer, TestCommandStatementUpdate) {
289+
int64_t result;
290+
ASSERT_OK(sql_client->ExecuteUpdate(
291+
{},
292+
"INSERT INTO intTable (keyName, value) VALUES "
293+
"('KEYNAME1', 1001), ('KEYNAME2', 1002), ('KEYNAME3', 1003)",
294+
&result));
295+
ASSERT_EQ(3, result);
296+
297+
ASSERT_OK(
298+
sql_client->ExecuteUpdate({},
299+
"UPDATE intTable SET keyName = 'KEYNAME1' "
300+
"WHERE keyName = 'KEYNAME2' OR keyName = 'KEYNAME3'",
301+
&result));
302+
ASSERT_EQ(2, result);
303+
304+
ASSERT_OK(sql_client->ExecuteUpdate(
305+
{}, "DELETE FROM intTable WHERE keyName = 'KEYNAME1'", &result));
306+
ASSERT_EQ(3, result);
307+
}
308+
288309
auto env =
289310
::testing::AddGlobalTestEnvironment(new TestFlightSqlServer);
290311

0 commit comments

Comments
 (0)