diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-21 11:54:28 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-21 11:54:28 +0000 |
commit | e6918187568dbd01842d8d1d2c808ce16a894239 (patch) | |
tree | 64f88b554b444a49f656b6c656111a145cbbaa28 /src/arrow/c_glib/arrow-flight-glib | |
parent | Initial commit. (diff) | |
download | ceph-e6918187568dbd01842d8d1d2c808ce16a894239.tar.xz ceph-e6918187568dbd01842d8d1d2c808ce16a894239.zip |
Adding upstream version 18.2.2.upstream/18.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/arrow/c_glib/arrow-flight-glib')
-rw-r--r-- | src/arrow/c_glib/arrow-flight-glib/arrow-flight-glib.h | 24 | ||||
-rw-r--r-- | src/arrow/c_glib/arrow-flight-glib/arrow-flight-glib.hpp | 24 | ||||
-rw-r--r-- | src/arrow/c_glib/arrow-flight-glib/client.cpp | 405 | ||||
-rw-r--r-- | src/arrow/c_glib/arrow-flight-glib/client.h | 104 | ||||
-rw-r--r-- | src/arrow/c_glib/arrow-flight-glib/client.hpp | 39 | ||||
-rw-r--r-- | src/arrow/c_glib/arrow-flight-glib/common.cpp | 1467 | ||||
-rw-r--r-- | src/arrow/c_glib/arrow-flight-glib/common.h | 268 | ||||
-rw-r--r-- | src/arrow/c_glib/arrow-flight-glib/common.hpp | 63 | ||||
-rw-r--r-- | src/arrow/c_glib/arrow-flight-glib/meson.build | 82 | ||||
-rw-r--r-- | src/arrow/c_glib/arrow-flight-glib/server.cpp | 724 | ||||
-rw-r--r-- | src/arrow/c_glib/arrow-flight-glib/server.h | 144 | ||||
-rw-r--r-- | src/arrow/c_glib/arrow-flight-glib/server.hpp | 38 |
12 files changed, 3382 insertions, 0 deletions
diff --git a/src/arrow/c_glib/arrow-flight-glib/arrow-flight-glib.h b/src/arrow/c_glib/arrow-flight-glib/arrow-flight-glib.h new file mode 100644 index 000000000..6fc8f43d8 --- /dev/null +++ b/src/arrow/c_glib/arrow-flight-glib/arrow-flight-glib.h @@ -0,0 +1,24 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#pragma once + +#include <arrow-flight-glib/client.h> +#include <arrow-flight-glib/common.h> +#include <arrow-flight-glib/server.h> diff --git a/src/arrow/c_glib/arrow-flight-glib/arrow-flight-glib.hpp b/src/arrow/c_glib/arrow-flight-glib/arrow-flight-glib.hpp new file mode 100644 index 000000000..11e1fe94d --- /dev/null +++ b/src/arrow/c_glib/arrow-flight-glib/arrow-flight-glib.hpp @@ -0,0 +1,24 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#pragma once + +#include <arrow-flight-glib/client.hpp> +#include <arrow-flight-glib/common.hpp> +#include <arrow-flight-glib/server.hpp> diff --git a/src/arrow/c_glib/arrow-flight-glib/client.cpp b/src/arrow/c_glib/arrow-flight-glib/client.cpp new file mode 100644 index 000000000..7610fc985 --- /dev/null +++ b/src/arrow/c_glib/arrow-flight-glib/client.cpp @@ -0,0 +1,405 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include <arrow-glib/arrow-glib.hpp> + +#include <arrow-flight-glib/client.hpp> +#include <arrow-flight-glib/common.hpp> + +G_BEGIN_DECLS + +/** + * SECTION: client + * @section_id: client + * @title: Client related classes + * @include: arrow-flight-glib/arrow-flight-glib.h + * + * #GAFlightStreamReader is a class for reading record batches from a + * server. + * + * #GAFlightCallOptions is a class for options of each call. + * + * #GAFlightClientOptions is a class for options of each client. + * + * #GAFlightClient is a class for Apache Arrow Flight client. + * + * Since: 5.0.0 + */ + +G_DEFINE_TYPE(GAFlightStreamReader, + gaflight_stream_reader, + GAFLIGHT_TYPE_RECORD_BATCH_READER) + +static void +gaflight_stream_reader_init(GAFlightStreamReader *object) +{ +} + +static void +gaflight_stream_reader_class_init(GAFlightStreamReaderClass *klass) +{ +} + +typedef struct GAFlightCallOptionsPrivate_ { + arrow::flight::FlightCallOptions options; +} GAFlightCallOptionsPrivate; + +G_DEFINE_TYPE_WITH_PRIVATE(GAFlightCallOptions, + gaflight_call_options, + G_TYPE_OBJECT) + +#define GAFLIGHT_CALL_OPTIONS_GET_PRIVATE(obj) \ + static_cast<GAFlightCallOptionsPrivate *>( \ + gaflight_call_options_get_instance_private( \ + GAFLIGHT_CALL_OPTIONS(obj))) + +static void +gaflight_call_options_finalize(GObject *object) +{ + auto priv = GAFLIGHT_CALL_OPTIONS_GET_PRIVATE(object); + + priv->options.~FlightCallOptions(); + + G_OBJECT_CLASS(gaflight_call_options_parent_class)->finalize(object); +} + +static void +gaflight_call_options_init(GAFlightCallOptions *object) +{ + auto priv = GAFLIGHT_CALL_OPTIONS_GET_PRIVATE(object); + new(&priv->options) arrow::flight::FlightCallOptions; +} + +static void +gaflight_call_options_class_init(GAFlightCallOptionsClass *klass) +{ + auto gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->finalize = gaflight_call_options_finalize; +} + +/** + * gaflight_call_options_new: + * + * Returns: The newly created options for a call. + * + * Since: 5.0.0 + */ +GAFlightCallOptions * +gaflight_call_options_new(void) +{ + return static_cast<GAFlightCallOptions *>( + g_object_new(GAFLIGHT_TYPE_CALL_OPTIONS, NULL)); +} + + +typedef struct GAFlightClientOptionsPrivate_ { + arrow::flight::FlightClientOptions options; +} GAFlightClientOptionsPrivate; + +G_DEFINE_TYPE_WITH_PRIVATE(GAFlightClientOptions, + gaflight_client_options, + G_TYPE_OBJECT) + +#define GAFLIGHT_CLIENT_OPTIONS_GET_PRIVATE(obj) \ + static_cast<GAFlightClientOptionsPrivate *>( \ + gaflight_client_options_get_instance_private( \ + GAFLIGHT_CLIENT_OPTIONS(obj))) + +static void +gaflight_client_options_finalize(GObject *object) +{ + auto priv = GAFLIGHT_CLIENT_OPTIONS_GET_PRIVATE(object); + + priv->options.~FlightClientOptions(); + + G_OBJECT_CLASS(gaflight_client_options_parent_class)->finalize(object); +} + +static void +gaflight_client_options_init(GAFlightClientOptions *object) +{ + auto priv = GAFLIGHT_CLIENT_OPTIONS_GET_PRIVATE(object); + new(&(priv->options)) arrow::flight::FlightClientOptions; + priv->options = arrow::flight::FlightClientOptions::Defaults(); +} + +static void +gaflight_client_options_class_init(GAFlightClientOptionsClass *klass) +{ + auto gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->finalize = gaflight_client_options_finalize; +} + +/** + * gaflight_client_options_new: + * + * Returns: The newly created options for a client. + * + * Since: 5.0.0 + */ +GAFlightClientOptions * +gaflight_client_options_new(void) +{ + return static_cast<GAFlightClientOptions *>( + g_object_new(GAFLIGHT_TYPE_CLIENT_OPTIONS, NULL)); +} + + +typedef struct GAFlightClientPrivate_ { + arrow::flight::FlightClient *client; +} GAFlightClientPrivate; + +enum { + PROP_CLIENT = 1, +}; + +G_DEFINE_TYPE_WITH_PRIVATE(GAFlightClient, + gaflight_client, + G_TYPE_OBJECT) + +#define GAFLIGHT_CLIENT_GET_PRIVATE(obj) \ + static_cast<GAFlightClientPrivate *>( \ + gaflight_client_get_instance_private( \ + GAFLIGHT_CLIENT(obj))) + +static void +gaflight_client_finalize(GObject *object) +{ + auto priv = GAFLIGHT_CLIENT_GET_PRIVATE(object); + + delete priv->client; + + G_OBJECT_CLASS(gaflight_client_parent_class)->finalize(object); +} + +static void +gaflight_client_set_property(GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + auto priv = GAFLIGHT_CLIENT_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_CLIENT: + priv->client = + static_cast<arrow::flight::FlightClient *>(g_value_get_pointer(value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gaflight_client_init(GAFlightClient *object) +{ +} + +static void +gaflight_client_class_init(GAFlightClientClass *klass) +{ + auto gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->finalize = gaflight_client_finalize; + gobject_class->set_property = gaflight_client_set_property; + + GParamSpec *spec; + spec = g_param_spec_pointer("client", + "Client", + "The raw arrow::flight::FlightClient *", + static_cast<GParamFlags>(G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property(gobject_class, PROP_CLIENT, spec); +} + +/** + * gaflight_client_new: + * @location: A #GAFlightLocation to be connected. + * @options: (nullable): A #GAFlightClientOptions. + * @error: (nullable): Return location for a #GError or %NULL. + * + * Returns: (nullable): The newly created client, %NULL on error. + * + * Since: 5.0.0 + */ +GAFlightClient * +gaflight_client_new(GAFlightLocation *location, + GAFlightClientOptions *options, + GError **error) +{ + const auto flight_location = gaflight_location_get_raw(location); + std::unique_ptr<arrow::flight::FlightClient> flight_client; + arrow::Status status; + if (options) { + const auto flight_options = gaflight_client_options_get_raw(options); + status = arrow::flight::FlightClient::Connect(*flight_location, + *flight_options, + &flight_client); + } else { + status = arrow::flight::FlightClient::Connect(*flight_location, + &flight_client); + } + if (garrow::check(error, status, "[flight-client][new]")) { + return gaflight_client_new_raw(flight_client.release()); + } else { + return NULL; + } +} + +/** + * gaflight_client_list_flights: + * @client: A #GAFlightClient. + * @criteria: (nullable): A #GAFlightCriteria. + * @options: (nullable): A #GAFlightCallOptions. + * @error: (nullable): Return location for a #GError or %NULL. + * + * Returns: (nullable) (element-type GAFlightInfo) (transfer full): + * The returned list of #GAFlightInfo on success, %NULL on error. + * + * Since: 5.0.0 + */ +GList * +gaflight_client_list_flights(GAFlightClient *client, + GAFlightCriteria *criteria, + GAFlightCallOptions *options, + GError **error) +{ + auto flight_client = gaflight_client_get_raw(client); + arrow::flight::Criteria flight_default_criteria; + auto flight_criteria = &flight_default_criteria; + if (criteria) { + flight_criteria = gaflight_criteria_get_raw(criteria); + } + arrow::flight::FlightCallOptions flight_default_options; + auto flight_options = &flight_default_options; + if (options) { + flight_options = gaflight_call_options_get_raw(options); + } + std::unique_ptr<arrow::flight::FlightListing> flight_listing; + auto status = flight_client->ListFlights(*flight_options, + *flight_criteria, + &flight_listing); + if (!garrow::check(error, + status, + "[flight-client][list-flights]")) { + return NULL; + } + GList *listing = NULL; + std::unique_ptr<arrow::flight::FlightInfo> flight_info; + while (true) { + status = flight_listing->Next(&flight_info); + if (!garrow::check(error, + status, + "[flight-client][list-flights]")) { + g_list_free_full(listing, g_object_unref); + return NULL; + } + if (!flight_info) { + break; + } + auto info = gaflight_info_new_raw(flight_info.release()); + listing = g_list_prepend(listing, info); + } + return g_list_reverse(listing); +} + +/** + * gaflight_client_do_get: + * @client: A #GAFlightClient. + * @ticket: A #GAFlightTicket. + * @options: (nullable): A #GAFlightCallOptions. + * @error: (nullable): Return location for a #GError or %NULL. + * + * Returns: (nullable) (transfer full): + * The #GAFlightStreamReader to read record batched from the server + * on success, %NULL on error. + * + * Since: 6.0.0 + */ +GAFlightStreamReader * +gaflight_client_do_get(GAFlightClient *client, + GAFlightTicket *ticket, + GAFlightCallOptions *options, + GError **error) +{ + auto flight_client = gaflight_client_get_raw(client); + const auto flight_ticket = gaflight_ticket_get_raw(ticket); + arrow::flight::FlightCallOptions flight_default_options; + auto flight_options = &flight_default_options; + if (options) { + flight_options = gaflight_call_options_get_raw(options); + } + std::unique_ptr<arrow::flight::FlightStreamReader> flight_reader; + auto status = flight_client->DoGet(*flight_options, + *flight_ticket, + &flight_reader); + if (garrow::check(error, + status, + "[flight-client][do-get]")) { + return gaflight_stream_reader_new_raw(flight_reader.release()); + } else { + return NULL; + } +} + + +G_END_DECLS + + +GAFlightStreamReader * +gaflight_stream_reader_new_raw( + arrow::flight::FlightStreamReader *flight_reader) +{ + return GAFLIGHT_STREAM_READER( + g_object_new(GAFLIGHT_TYPE_STREAM_READER, + "reader", flight_reader, + NULL)); +} + +arrow::flight::FlightCallOptions * +gaflight_call_options_get_raw(GAFlightCallOptions *options) +{ + auto priv = GAFLIGHT_CALL_OPTIONS_GET_PRIVATE(options); + return &(priv->options); +} + +arrow::flight::FlightClientOptions * +gaflight_client_options_get_raw(GAFlightClientOptions *options) +{ + auto priv = GAFLIGHT_CLIENT_OPTIONS_GET_PRIVATE(options); + return &(priv->options); +} + +arrow::flight::FlightClient * +gaflight_client_get_raw(GAFlightClient *client) +{ + auto priv = GAFLIGHT_CLIENT_GET_PRIVATE(client); + return priv->client; +} + +GAFlightClient * +gaflight_client_new_raw(arrow::flight::FlightClient *flight_client) +{ + return GAFLIGHT_CLIENT(g_object_new(GAFLIGHT_TYPE_CLIENT, + "client", flight_client, + NULL)); +} diff --git a/src/arrow/c_glib/arrow-flight-glib/client.h b/src/arrow/c_glib/arrow-flight-glib/client.h new file mode 100644 index 000000000..bc2971161 --- /dev/null +++ b/src/arrow/c_glib/arrow-flight-glib/client.h @@ -0,0 +1,104 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#pragma once + +#include <arrow-flight-glib/common.h> + +G_BEGIN_DECLS + + +#define GAFLIGHT_TYPE_STREAM_READER \ + (gaflight_stream_reader_get_type()) +G_DECLARE_DERIVABLE_TYPE(GAFlightStreamReader, + gaflight_stream_reader, + GAFLIGHT, + STREAM_READER, + GAFlightRecordBatchReader) +struct _GAFlightStreamReaderClass +{ + GAFlightRecordBatchReaderClass parent_class; +}; + + +#define GAFLIGHT_TYPE_CALL_OPTIONS (gaflight_call_options_get_type()) +G_DECLARE_DERIVABLE_TYPE(GAFlightCallOptions, + gaflight_call_options, + GAFLIGHT, + CALL_OPTIONS, + GObject) +struct _GAFlightCallOptionsClass +{ + GObjectClass parent_class; +}; + +GARROW_AVAILABLE_IN_5_0 +GAFlightCallOptions * +gaflight_call_options_new(void); + + +#define GAFLIGHT_TYPE_CLIENT_OPTIONS (gaflight_client_options_get_type()) +G_DECLARE_DERIVABLE_TYPE(GAFlightClientOptions, + gaflight_client_options, + GAFLIGHT, + CLIENT_OPTIONS, + GObject) +struct _GAFlightClientOptionsClass +{ + GObjectClass parent_class; +}; + +GARROW_AVAILABLE_IN_5_0 +GAFlightClientOptions * +gaflight_client_options_new(void); + + +#define GAFLIGHT_TYPE_CLIENT (gaflight_client_get_type()) +G_DECLARE_DERIVABLE_TYPE(GAFlightClient, + gaflight_client, + GAFLIGHT, + CLIENT, + GObject) +struct _GAFlightClientClass +{ + GObjectClass parent_class; +}; + +GARROW_AVAILABLE_IN_5_0 +GAFlightClient * +gaflight_client_new(GAFlightLocation *location, + GAFlightClientOptions *options, + GError **error); + +GARROW_AVAILABLE_IN_5_0 +GList * +gaflight_client_list_flights(GAFlightClient *client, + GAFlightCriteria *criteria, + GAFlightCallOptions *options, + GError **error); + +GARROW_AVAILABLE_IN_6_0 +GAFlightStreamReader * +gaflight_client_do_get(GAFlightClient *client, + GAFlightTicket *ticket, + GAFlightCallOptions *options, + GError **error); + + +G_END_DECLS diff --git a/src/arrow/c_glib/arrow-flight-glib/client.hpp b/src/arrow/c_glib/arrow-flight-glib/client.hpp new file mode 100644 index 000000000..1e68761b7 --- /dev/null +++ b/src/arrow/c_glib/arrow-flight-glib/client.hpp @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#pragma once + +#include <arrow/flight/api.h> + +#include <arrow-flight-glib/client.h> + + +GAFlightStreamReader * +gaflight_stream_reader_new_raw(arrow::flight::FlightStreamReader *flight_reader); + +arrow::flight::FlightCallOptions * +gaflight_call_options_get_raw(GAFlightCallOptions *options); + +arrow::flight::FlightClientOptions * +gaflight_client_options_get_raw(GAFlightClientOptions *options); + +arrow::flight::FlightClient * +gaflight_client_get_raw(GAFlightClient *client); +GAFlightClient * +gaflight_client_new_raw(arrow::flight::FlightClient *flight_client); diff --git a/src/arrow/c_glib/arrow-flight-glib/common.cpp b/src/arrow/c_glib/arrow-flight-glib/common.cpp new file mode 100644 index 000000000..81b00f7a3 --- /dev/null +++ b/src/arrow/c_glib/arrow-flight-glib/common.cpp @@ -0,0 +1,1467 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include <arrow-glib/arrow-glib.hpp> + +#include <arrow-flight-glib/common.hpp> + +G_BEGIN_DECLS + +/** + * SECTION: common + * @section_id: common + * @title: Classes both for client and server + * @include: arrow-flight-glib/arrow-flight-glib.h + * + * #GAFlightCriteria is a class for criteria. + * + * #GAFlightLocation is a class for location. + * + * #GAFlightDescriptor is a base class for all descriptor classes such + * as #GAFlightPathDescriptor. + * + * #GAFlightPathDescriptor is a class for path descriptor. + * + * #GAFlightCommandDescriptor is a class for command descriptor. + * + * #GAFlightTicket is a class for ticket. + * + * #GAFlightEndpoint is a class for endpoint. + * + * #GAFlightInfo is a class for flight information. + * + * #GAFlightStreamChunk is a class for a chunk in stream. + * + * #GAFlightRecordBatchReader is a class for reading record batches. + * + * Since: 5.0.0 + */ + +typedef struct GAFlightCriteriaPrivate_ { + arrow::flight::Criteria criteria; + GBytes *expression; +} GAFlightCriteriaPrivate; + +enum { + PROP_EXPRESSION = 1, +}; + +G_DEFINE_TYPE_WITH_PRIVATE(GAFlightCriteria, + gaflight_criteria, + G_TYPE_OBJECT) + +#define GAFLIGHT_CRITERIA_GET_PRIVATE(obj) \ + static_cast<GAFlightCriteriaPrivate *>( \ + gaflight_criteria_get_instance_private( \ + GAFLIGHT_CRITERIA(obj))) + +static void +gaflight_criteria_dispose(GObject *object) +{ + auto priv = GAFLIGHT_CRITERIA_GET_PRIVATE(object); + + if (priv->expression) { + g_bytes_unref(priv->expression); + priv->expression = NULL; + } + + G_OBJECT_CLASS(gaflight_criteria_parent_class)->dispose(object); +} + +static void +gaflight_criteria_finalize(GObject *object) +{ + auto priv = GAFLIGHT_CRITERIA_GET_PRIVATE(object); + + priv->criteria.~Criteria(); + + G_OBJECT_CLASS(gaflight_criteria_parent_class)->finalize(object); +} + +static void +gaflight_criteria_set_property(GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + auto priv = GAFLIGHT_CRITERIA_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_EXPRESSION: + if (priv->expression) { + g_bytes_unref(priv->expression); + } + priv->expression = static_cast<GBytes *>(g_value_dup_boxed(value)); + { + gsize size; + auto data = g_bytes_get_data(priv->expression, &size); + priv->criteria.expression.assign(static_cast<const char *>(data), + size); + } + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gaflight_criteria_get_property(GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + auto priv = GAFLIGHT_CRITERIA_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_EXPRESSION: + g_value_set_boxed(value, priv->expression); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gaflight_criteria_init(GAFlightCriteria *object) +{ + auto priv = GAFLIGHT_CRITERIA_GET_PRIVATE(object); + new(&priv->criteria) arrow::flight::Criteria; +} + +static void +gaflight_criteria_class_init(GAFlightCriteriaClass *klass) +{ + auto gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->dispose = gaflight_criteria_dispose; + gobject_class->finalize = gaflight_criteria_finalize; + gobject_class->set_property = gaflight_criteria_set_property; + gobject_class->get_property = gaflight_criteria_get_property; + + GParamSpec *spec; + /** + * GAFlightCriteria:expression: + * + * Opaque criteria expression, dependent on server implementation. + * + * Since: 5.0.0 + */ + spec = g_param_spec_boxed("expression", + "Expression", + "Opaque criteria expression, " + "dependent on server implementation", + G_TYPE_BYTES, + static_cast<GParamFlags>(G_PARAM_READWRITE)); + g_object_class_install_property(gobject_class, PROP_EXPRESSION, spec); +} + +/** + * gaflight_criteria_new: + * @expression: A #GBytes. + * + * Returns: The newly created #GAFlightCriteria, %NULL on error. + * + * Since: 5.0.0 + */ +GAFlightCriteria * +gaflight_criteria_new(GBytes *expression) +{ + return GAFLIGHT_CRITERIA( + g_object_new(GAFLIGHT_TYPE_CRITERIA, + "expression", expression, + NULL)); +} + + +typedef struct GAFlightLocationPrivate_ { + arrow::flight::Location location; +} GAFlightLocationPrivate; + +G_DEFINE_TYPE_WITH_PRIVATE(GAFlightLocation, + gaflight_location, + G_TYPE_OBJECT) + +#define GAFLIGHT_LOCATION_GET_PRIVATE(obj) \ + static_cast<GAFlightLocationPrivate *>( \ + gaflight_location_get_instance_private( \ + GAFLIGHT_LOCATION(obj))) + +static void +gaflight_location_finalize(GObject *object) +{ + auto priv = GAFLIGHT_LOCATION_GET_PRIVATE(object); + + priv->location.~Location(); + + G_OBJECT_CLASS(gaflight_location_parent_class)->finalize(object); +} + +static void +gaflight_location_init(GAFlightLocation *object) +{ + auto priv = GAFLIGHT_LOCATION_GET_PRIVATE(object); + new(&priv->location) arrow::flight::Location; +} + +static void +gaflight_location_class_init(GAFlightLocationClass *klass) +{ + auto gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->finalize = gaflight_location_finalize; +} + +/** + * gaflight_location_new: + * @uri: An URI to specify location. + * @error: (nullable): Return location for a #GError or %NULL. + * + * Returns: (nullable): The newly created location, %NULL on error. + * + * Since: 5.0.0 + */ +GAFlightLocation * +gaflight_location_new(const gchar *uri, + GError **error) +{ + auto location = GAFLIGHT_LOCATION(g_object_new(GAFLIGHT_TYPE_LOCATION, NULL)); + auto flight_location = gaflight_location_get_raw(location); + if (garrow::check(error, + arrow::flight::Location::Parse(uri, flight_location), + "[flight-location][new]")) { + return location; + } else { + g_object_unref(location); + return NULL; + } +} + +/** + * gaflight_location_to_string: + * @location: A #GAFlightLocation. + * + * Returns: A representation of this URI as a string. + * + * It should be freed with g_free() when no longer needed. + * + * Since: 5.0.0 + */ +gchar * +gaflight_location_to_string(GAFlightLocation *location) +{ + const auto flight_location = gaflight_location_get_raw(location); + return g_strdup(flight_location->ToString().c_str()); +} + +/** + * gaflight_location_get_scheme: + * @location: A #GAFlightLocation. + * + * Returns: The scheme of this URI. + * + * It should be freed with g_free() when no longer needed. + * + * Since: 5.0.0 + */ +gchar * +gaflight_location_get_scheme(GAFlightLocation *location) +{ + const auto flight_location = gaflight_location_get_raw(location); + return g_strdup(flight_location->scheme().c_str()); +} + +/** + * gaflight_location_equal: + * @location: A #GAFlightLocation. + * @other_location: A #GAFlightLocation to be compared. + * + * Returns: %TRUE if both of them represents the same URI, %FALSE otherwise. + * + * Since: 5.0.0 + */ +gboolean +gaflight_location_equal(GAFlightLocation *location, + GAFlightLocation *other_location) +{ + const auto flight_location = gaflight_location_get_raw(location); + const auto flight_other_location = gaflight_location_get_raw(other_location); + return flight_location->Equals(*flight_other_location); +} + + +typedef struct GAFlightDescriptorPrivate_ { + arrow::flight::FlightDescriptor descriptor; +} GAFlightDescriptorPrivate; + +enum { + PROP_DESCRIPTOR = 1, +}; + +G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE(GAFlightDescriptor, + gaflight_descriptor, + G_TYPE_OBJECT) + +#define GAFLIGHT_DESCRIPTOR_GET_PRIVATE(obj) \ + static_cast<GAFlightDescriptorPrivate *>( \ + gaflight_descriptor_get_instance_private( \ + GAFLIGHT_DESCRIPTOR(obj))) + +static void +gaflight_descriptor_finalize(GObject *object) +{ + auto priv = GAFLIGHT_DESCRIPTOR_GET_PRIVATE(object); + + priv->descriptor.~FlightDescriptor(); + + G_OBJECT_CLASS(gaflight_descriptor_parent_class)->finalize(object); +} + +static void +gaflight_descriptor_set_property(GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + auto priv = GAFLIGHT_DESCRIPTOR_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_DESCRIPTOR: + priv->descriptor = *static_cast<arrow::flight::FlightDescriptor *>( + g_value_get_pointer(value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gaflight_descriptor_init(GAFlightDescriptor *object) +{ + auto priv = GAFLIGHT_DESCRIPTOR_GET_PRIVATE(object); + new(&priv->descriptor) arrow::flight::FlightDescriptor; +} + +static void +gaflight_descriptor_class_init(GAFlightDescriptorClass *klass) +{ + auto gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->finalize = gaflight_descriptor_finalize; + gobject_class->set_property = gaflight_descriptor_set_property; + + GParamSpec *spec; + spec = g_param_spec_pointer("descriptor", + "Descriptor", + "The raw arrow::flight::FlightDescriptor", + static_cast<GParamFlags>(G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property(gobject_class, PROP_EXPRESSION, spec); +} + +/** + * gaflight_descriptor_to_string: + * @descriptor: A #GAFlightDescriptor. + * + * Returns: A descriptor as a string. + * + * It should be freed with g_free() when no longer needed. + * + * Since: 5.0.0 + */ +gchar * +gaflight_descriptor_to_string(GAFlightDescriptor *descriptor) +{ + auto flight_descriptor = gaflight_descriptor_get_raw(descriptor); + return g_strdup(flight_descriptor->ToString().c_str()); +} + +/** + * gaflight_descriptor_equal: + * @descriptor: A #GAFlightDescriptor. + * @other_descriptor: A #GAFlightDescriptor to be compared. + * + * Returns: %TRUE if both of them represents the same descriptor, + * %FALSE otherwise. + * + * Since: 5.0.0 + */ +gboolean +gaflight_descriptor_equal(GAFlightDescriptor *descriptor, + GAFlightDescriptor *other_descriptor) +{ + const auto flight_descriptor = + gaflight_descriptor_get_raw(descriptor); + const auto flight_other_descriptor = + gaflight_descriptor_get_raw(other_descriptor); + return flight_descriptor->Equals(*flight_other_descriptor); +} + + +G_DEFINE_TYPE(GAFlightPathDescriptor, + gaflight_path_descriptor, + GAFLIGHT_TYPE_DESCRIPTOR) + +static void +gaflight_path_descriptor_init(GAFlightPathDescriptor *object) +{ +} + +static void +gaflight_path_descriptor_class_init(GAFlightPathDescriptorClass *klass) +{ +} + +/** + * gaflight_path_descriptor_new: + * @paths: (array length=n_paths): List of paths identifying a + * particular dataset. + * @n_paths: The number of @paths. + * + * Returns: The newly created #GAFlightPathDescriptor. + * + * Since: 5.0.0 + */ +GAFlightPathDescriptor * +gaflight_path_descriptor_new(const gchar **paths, + gsize n_paths) +{ + std::vector<std::string> flight_paths; + for (gsize i = 0; i < n_paths; i++) { + flight_paths.push_back(paths[i]); + } + auto flight_descriptor = arrow::flight::FlightDescriptor::Path(flight_paths); + return GAFLIGHT_PATH_DESCRIPTOR( + gaflight_descriptor_new_raw(&flight_descriptor)); +} + +/** + * gaflight_path_descriptor_get_paths: + * @descriptor: A #GAFlightPathDescriptor. + * + * Returns: (nullable) (array zero-terminated=1) (transfer full): + * The paths in this descriptor. + * + * It must be freed with g_strfreev() when no longer needed. + * + * Since: 5.0.0 + */ +gchar ** +gaflight_path_descriptor_get_paths(GAFlightPathDescriptor *descriptor) +{ + const auto flight_descriptor = + gaflight_descriptor_get_raw(GAFLIGHT_DESCRIPTOR(descriptor)); + const auto &flight_paths = flight_descriptor->path; + if (flight_paths.empty()) { + return NULL; + } else { + auto paths = g_new(gchar *, flight_paths.size() + 1); + gsize i = 0; + for (const auto &flight_path : flight_paths) { + paths[i++] = g_strdup(flight_path.c_str()); + } + paths[i] = NULL; + return paths; + } +} + + +G_DEFINE_TYPE(GAFlightCommandDescriptor, + gaflight_command_descriptor, + GAFLIGHT_TYPE_DESCRIPTOR) + +static void +gaflight_command_descriptor_init(GAFlightCommandDescriptor *object) +{ +} + +static void +gaflight_command_descriptor_class_init(GAFlightCommandDescriptorClass *klass) +{ +} + +/** + * gaflight_command_descriptor_new: + * @command: Opaque value used to express a command. + * + * Returns: The newly created #GAFlightCommandDescriptor. + * + * Since: 5.0.0 + */ +GAFlightCommandDescriptor * +gaflight_command_descriptor_new(const gchar *command) +{ + auto flight_descriptor = arrow::flight::FlightDescriptor::Command(command); + return GAFLIGHT_COMMAND_DESCRIPTOR( + gaflight_descriptor_new_raw(&flight_descriptor)); +} + +/** + * gaflight_command_descriptor_get_command: + * @descriptor: A #GAFlightCommandDescriptor. + * + * Returns: The opaque value used to express a command. + * + * It should be freed with g_free() when no longer needed. + * + * Since: 5.0.0 + */ +gchar * +gaflight_command_descriptor_get_command(GAFlightCommandDescriptor *descriptor) +{ + const auto flight_descriptor = + gaflight_descriptor_get_raw(GAFLIGHT_DESCRIPTOR(descriptor)); + const auto &flight_command = flight_descriptor->cmd; + return g_strdup(flight_command.c_str()); +} + + +typedef struct GAFlightTicketPrivate_ { + arrow::flight::Ticket ticket; + GBytes *data; +} GAFlightTicketPrivate; + +enum { + PROP_DATA = 1, +}; + +G_DEFINE_TYPE_WITH_PRIVATE(GAFlightTicket, + gaflight_ticket, + G_TYPE_OBJECT) + +#define GAFLIGHT_TICKET_GET_PRIVATE(obj) \ + static_cast<GAFlightTicketPrivate *>( \ + gaflight_ticket_get_instance_private( \ + GAFLIGHT_TICKET(obj))) + +static void +gaflight_ticket_dispose(GObject *object) +{ + auto priv = GAFLIGHT_TICKET_GET_PRIVATE(object); + + if (priv->data) { + g_bytes_unref(priv->data); + priv->data = NULL; + } + + G_OBJECT_CLASS(gaflight_ticket_parent_class)->dispose(object); +} + +static void +gaflight_ticket_finalize(GObject *object) +{ + auto priv = GAFLIGHT_TICKET_GET_PRIVATE(object); + + priv->ticket.~Ticket(); + + G_OBJECT_CLASS(gaflight_ticket_parent_class)->finalize(object); +} + +static void +gaflight_ticket_set_property(GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + auto priv = GAFLIGHT_TICKET_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_DATA: + if (priv->data) { + g_bytes_unref(priv->data); + } + priv->data = static_cast<GBytes *>(g_value_dup_boxed(value)); + { + gsize size; + auto data = g_bytes_get_data(priv->data, &size); + priv->ticket.ticket.assign(static_cast<const char *>(data), + size); + } + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gaflight_ticket_get_property(GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + auto priv = GAFLIGHT_TICKET_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_DATA: + g_value_set_boxed(value, priv->data); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gaflight_ticket_init(GAFlightTicket *object) +{ + auto priv = GAFLIGHT_TICKET_GET_PRIVATE(object); + new(&priv->ticket) arrow::flight::Ticket; +} + +static void +gaflight_ticket_class_init(GAFlightTicketClass *klass) +{ + auto gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->dispose = gaflight_ticket_dispose; + gobject_class->finalize = gaflight_ticket_finalize; + gobject_class->set_property = gaflight_ticket_set_property; + gobject_class->get_property = gaflight_ticket_get_property; + + GParamSpec *spec; + /** + * GAFlightTicket:data: + * + * Opaque identifier or credential to use when requesting a data + * stream with the DoGet RPC. + * + * Since: 5.0.0 + */ + spec = g_param_spec_boxed("data", + "Data", + "Opaque identifier or credential to use " + "when requesting a data stream with the DoGet RPC", + G_TYPE_BYTES, + static_cast<GParamFlags>(G_PARAM_READWRITE)); + g_object_class_install_property(gobject_class, PROP_DATA, spec); +} + +/** + * gaflight_ticket_new: + * @data: A #GBytes. + * + * Returns: The newly created #GAFlightTicket, %NULL on error. + * + * Since: 5.0.0 + */ +GAFlightTicket * +gaflight_ticket_new(GBytes *data) +{ + return GAFLIGHT_TICKET( + g_object_new(GAFLIGHT_TYPE_TICKET, + "data", data, + NULL)); +} + +/** + * gaflight_ticket_equal: + * @ticket: A #GAFlightTicket. + * @other_ticket: A #GAFlightTicket to be compared. + * + * Returns: %TRUE if both of them represents the same ticket, %FALSE otherwise. + * + * Since: 5.0.0 + */ +gboolean +gaflight_ticket_equal(GAFlightTicket *ticket, + GAFlightTicket *other_ticket) +{ + const auto flight_ticket = gaflight_ticket_get_raw(ticket); + const auto flight_other_ticket = gaflight_ticket_get_raw(other_ticket); + return flight_ticket->Equals(*flight_other_ticket); +} + + +typedef struct GAFlightEndpointPrivate_ { + arrow::flight::FlightEndpoint endpoint; + GAFlightTicket *ticket; + GList *locations; +} GAFlightEndpointPrivate; + +enum { + PROP_TICKET = 1, +}; + +G_DEFINE_TYPE_WITH_PRIVATE(GAFlightEndpoint, + gaflight_endpoint, + G_TYPE_OBJECT) + +#define GAFLIGHT_ENDPOINT_GET_PRIVATE(obj) \ + static_cast<GAFlightEndpointPrivate *>( \ + gaflight_endpoint_get_instance_private( \ + GAFLIGHT_ENDPOINT(obj))) + +static void +gaflight_endpoint_dispose(GObject *object) +{ + auto priv = GAFLIGHT_ENDPOINT_GET_PRIVATE(object); + + if (priv->ticket) { + g_object_unref(priv->ticket); + priv->ticket = NULL; + } + + if (priv->locations) { + g_list_free_full(priv->locations, g_object_unref); + priv->locations = NULL; + } + + G_OBJECT_CLASS(gaflight_endpoint_parent_class)->dispose(object); +} + +static void +gaflight_endpoint_finalize(GObject *object) +{ + auto priv = GAFLIGHT_ENDPOINT_GET_PRIVATE(object); + + priv->endpoint.~FlightEndpoint(); + + G_OBJECT_CLASS(gaflight_endpoint_parent_class)->finalize(object); +} + +static void +gaflight_endpoint_get_property(GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + auto priv = GAFLIGHT_ENDPOINT_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_TICKET: + g_value_set_object(value, priv->ticket); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gaflight_endpoint_init(GAFlightEndpoint *object) +{ + auto priv = GAFLIGHT_ENDPOINT_GET_PRIVATE(object); + new(&priv->endpoint) arrow::flight::FlightEndpoint; +} + +static void +gaflight_endpoint_class_init(GAFlightEndpointClass *klass) +{ + auto gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->dispose = gaflight_endpoint_dispose; + gobject_class->finalize = gaflight_endpoint_finalize; + gobject_class->get_property = gaflight_endpoint_get_property; + + GParamSpec *spec; + /** + * GAFlightEndpoint:ticket: + * + * Opaque ticket identify; use with DoGet RPC. + * + * Since: 5.0.0 + */ + spec = g_param_spec_object("ticket", + "Ticket", + "Opaque ticket identify; use with DoGet RPC", + GAFLIGHT_TYPE_TICKET, + static_cast<GParamFlags>(G_PARAM_READABLE)); + g_object_class_install_property(gobject_class, PROP_TICKET, spec); +} + +/** + * gaflight_endpoint_new: + * @ticket: A #GAFlightTicket. + * @locations: (element-type GAFlightLocation): A list of #GAFlightLocation. + * + * Returns: The newly created #GAFlightEndpoint, %NULL on error. + * + * Since: 5.0.0 + */ +GAFlightEndpoint * +gaflight_endpoint_new(GAFlightTicket *ticket, + GList *locations) +{ + auto endpoint = gaflight_endpoint_new_raw(nullptr, ticket); + auto priv = GAFLIGHT_ENDPOINT_GET_PRIVATE(endpoint); + for (auto node = locations; node; node = node->next) { + auto location = GAFLIGHT_LOCATION(node->data); + priv->endpoint.locations.push_back(*gaflight_location_get_raw(location)); + } + return endpoint; +} + +/** + * gaflight_endpoint_equal: + * @endpoint: A #GAFlightEndpoint. + * @other_endpoint: A #GAFlightEndpoint to be compared. + * + * Returns: %TRUE if both of them represents the same endpoint, + * %FALSE otherwise. + * + * Since: 5.0.0 + */ +gboolean +gaflight_endpoint_equal(GAFlightEndpoint *endpoint, + GAFlightEndpoint *other_endpoint) +{ + const auto flight_endpoint = gaflight_endpoint_get_raw(endpoint); + const auto flight_other_endpoint = gaflight_endpoint_get_raw(other_endpoint); + return flight_endpoint->Equals(*flight_other_endpoint); +} + +/** + * gaflight_endpoint_get_locations: + * @endpoint: A #GAFlightEndpoint. + * + * Returns: (nullable) (element-type GAFlightLocation) (transfer full): + * The locations in this endpoint. + * + * It must be freed with g_list_free() and g_object_unref() when no + * longer needed. You can use `g_list_free_full(locations, + * g_object_unref)`. + * + * Since: 5.0.0 + */ +GList * +gaflight_endpoint_get_locations(GAFlightEndpoint *endpoint) +{ + const auto flight_endpoint = gaflight_endpoint_get_raw(endpoint); + GList *locations = NULL; + for (const auto &flight_location : flight_endpoint->locations) { + auto location = gaflight_location_new(flight_location.ToString().c_str(), + nullptr); + locations = g_list_prepend(locations, location); + } + return g_list_reverse(locations); +} + + +typedef struct GAFlightInfoPrivate_ { + arrow::flight::FlightInfo info; +} GAFlightInfoPrivate; + +enum { + PROP_INFO = 1, +}; + +G_DEFINE_TYPE_WITH_PRIVATE(GAFlightInfo, + gaflight_info, + G_TYPE_OBJECT) + +#define GAFLIGHT_INFO_GET_PRIVATE(obj) \ + static_cast<GAFlightInfoPrivate *>( \ + gaflight_info_get_instance_private( \ + GAFLIGHT_INFO(obj))) + +static void +gaflight_info_finalize(GObject *object) +{ + auto priv = GAFLIGHT_INFO_GET_PRIVATE(object); + + priv->info.~FlightInfo(); + + G_OBJECT_CLASS(gaflight_info_parent_class)->finalize(object); +} + +static void +gaflight_info_set_property(GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + auto priv = GAFLIGHT_INFO_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_INFO: + { + auto info = + static_cast<arrow::flight::FlightInfo *>(g_value_get_pointer(value)); + new(&(priv->info)) arrow::flight::FlightInfo(*info); + } + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gaflight_info_init(GAFlightInfo *object) +{ +} + +static void +gaflight_info_class_init(GAFlightInfoClass *klass) +{ + auto gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->finalize = gaflight_info_finalize; + gobject_class->set_property = gaflight_info_set_property; + + GParamSpec *spec; + spec = g_param_spec_pointer("info", + "Info", + "The raw arrow::flight::FlightInfo *", + static_cast<GParamFlags>(G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property(gobject_class, PROP_INFO, spec); +} + +/** + * gaflight_info_new: + * @schema: A #GArrowSchema. + * @descriptor: A #GAFlightDescriptor. + * @endpoints: (element-type GAFlightEndpoint): A list of #GAFlightEndpoint. + * @total_records: The number of total records. + * @total_bytes: The number of total bytes. + * @error: (nullable): Return location for a #GError or %NULL. + * + * Returns: (nullable): The newly created #GAFlightInfo, %NULL on error. + * + * Since: 5.0.0 + */ +GAFlightInfo * +gaflight_info_new(GArrowSchema *schema, + GAFlightDescriptor *descriptor, + GList *endpoints, + gint64 total_records, + gint64 total_bytes, + GError **error) +{ + auto arrow_schema = garrow_schema_get_raw(schema); + auto flight_descriptor = gaflight_descriptor_get_raw(descriptor); + std::vector<arrow::flight::FlightEndpoint> flight_endpoints; + for (auto node = endpoints; node; node = node->next) { + auto endpoint = GAFLIGHT_ENDPOINT(node->data); + flight_endpoints.push_back(*gaflight_endpoint_get_raw(endpoint)); + } + auto flight_info_result = + arrow::flight::FlightInfo::Make(*arrow_schema, + *flight_descriptor, + flight_endpoints, + total_records, + total_bytes); + if (!garrow::check(error, + flight_info_result, + "[flight-info][new]")) { + return NULL; + } + return gaflight_info_new_raw(&(*flight_info_result)); +} + +/** + * gaflight_info_equal: + * @info: A #GAFlightInfo. + * @other_info: A #GAFlightInfo to be compared. + * + * Returns: %TRUE if both of them represents the same information, + * %FALSE otherwise. + * + * Since: 5.0.0 + */ +gboolean +gaflight_info_equal(GAFlightInfo *info, + GAFlightInfo *other_info) +{ + const auto flight_info = gaflight_info_get_raw(info); + const auto flight_other_info = gaflight_info_get_raw(other_info); + return + (flight_info->serialized_schema() == + flight_other_info->serialized_schema()) && + (flight_info->descriptor() == + flight_other_info->descriptor()) && + (flight_info->endpoints() == + flight_other_info->endpoints()) && + (flight_info->total_records() == + flight_other_info->total_records()) && + (flight_info->total_bytes() == + flight_other_info->total_bytes()); +} + +/** + * gaflight_info_get_schema: + * @info: A #GAFlightInfo. + * @options: (nullable): A #GArrowReadOptions. + * @error: (nullable): Return location for a #GError or %NULL. + * + * Returns: (transfer full): Deserialized #GArrowSchema, %NULL on error. + * + * Since: 5.0.0 + */ +GArrowSchema * +gaflight_info_get_schema(GAFlightInfo *info, + GArrowReadOptions *options, + GError **error) +{ + const auto flight_info = gaflight_info_get_raw(info); + arrow::Status status; + std::shared_ptr<arrow::Schema> arrow_schema; + if (options) { + auto arrow_memo = garrow_read_options_get_dictionary_memo_raw(options); + status = flight_info->GetSchema(arrow_memo, &arrow_schema); + } else { + arrow::ipc::DictionaryMemo arrow_memo; + status = flight_info->GetSchema(&arrow_memo, &arrow_schema); + } + if (garrow::check(error, status, "[flight-info][get-schema]")) { + return garrow_schema_new_raw(&arrow_schema); + } else { + return NULL; + } +} + +/** + * gaflight_info_get_descriptor: + * @info: A #GAFlightInfo. + * + * Returns: (transfer full): The #GAFlightDescriptor of the information. + * + * Since: 5.0.0 + */ +GAFlightDescriptor * +gaflight_info_get_descriptor(GAFlightInfo *info) +{ + const auto flight_info = gaflight_info_get_raw(info); + return gaflight_descriptor_new_raw(&(flight_info->descriptor())); +} + +/** + * gaflight_info_get_endpoints: + * @info: A #GAFlightInfo. + * + * Returns: (element-type GAFlightEndpoint) (transfer full): + * The list of #GAFlightEndpoint of the information. + * + * Since: 5.0.0 + */ +GList * +gaflight_info_get_endpoints(GAFlightInfo *info) +{ + const auto flight_info = gaflight_info_get_raw(info); + GList *endpoints = NULL; + for (const auto &flight_endpoint : flight_info->endpoints()) { + auto endpoint = gaflight_endpoint_new_raw(&flight_endpoint, nullptr); + endpoints = g_list_prepend(endpoints, endpoint); + } + return g_list_reverse(endpoints); +} + +/** + * gaflight_info_get_total_records: + * @info: A #GAFlightInfo. + * + * Returns: The number of total records of the information. + * + * Since: 5.0.0 + */ +gint64 +gaflight_info_get_total_records(GAFlightInfo *info) +{ + const auto flight_info = gaflight_info_get_raw(info); + return flight_info->total_records(); +} + +/** + * gaflight_info_get_total_bytes: + * @info: A #GAFlightInfo. + * + * Returns: The number of total bytes of the information. + * + * Since: 5.0.0 + */ +gint64 +gaflight_info_get_total_bytes(GAFlightInfo *info) +{ + const auto flight_info = gaflight_info_get_raw(info); + return flight_info->total_bytes(); +} + +typedef struct GAFlightStreamChunkPrivate_ { + arrow::flight::FlightStreamChunk chunk; +} GAFlightStreamChunkPrivate; + +enum { + PROP_CHUNK = 1, +}; + +G_DEFINE_TYPE_WITH_PRIVATE(GAFlightStreamChunk, + gaflight_stream_chunk, + G_TYPE_OBJECT) + +#define GAFLIGHT_STREAM_CHUNK_GET_PRIVATE(obj) \ + static_cast<GAFlightStreamChunkPrivate *>( \ + gaflight_stream_chunk_get_instance_private( \ + GAFLIGHT_STREAM_CHUNK(obj))) + +static void +gaflight_stream_chunk_finalize(GObject *object) +{ + auto priv = GAFLIGHT_STREAM_CHUNK_GET_PRIVATE(object); + + priv->chunk.~FlightStreamChunk(); + + G_OBJECT_CLASS(gaflight_info_parent_class)->finalize(object); +} + +static void +gaflight_stream_chunk_set_property(GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + auto priv = GAFLIGHT_STREAM_CHUNK_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_CHUNK: + priv->chunk = + *static_cast<arrow::flight::FlightStreamChunk *>( + g_value_get_pointer(value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gaflight_stream_chunk_init(GAFlightStreamChunk *object) +{ +} + +static void +gaflight_stream_chunk_class_init(GAFlightStreamChunkClass *klass) +{ + auto gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->finalize = gaflight_stream_chunk_finalize; + gobject_class->set_property = gaflight_stream_chunk_set_property; + + GParamSpec *spec; + spec = g_param_spec_pointer("chunk", + "Stream chunk", + "The raw arrow::flight::FlightStreamChunk *", + static_cast<GParamFlags>(G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property(gobject_class, PROP_CHUNK, spec); +} + +/** + * gaflight_stream_chunk_get_data: + * @chunk: A #GAFlightStreamChunk. + * + * Returns: (transfer full): The data of the chunk. + * + * Since: 6.0.0 + */ +GArrowRecordBatch * +gaflight_stream_chunk_get_data(GAFlightStreamChunk *chunk) +{ + auto flight_chunk = gaflight_stream_chunk_get_raw(chunk); + return garrow_record_batch_new_raw(&(flight_chunk->data)); +} + +/** + * gaflight_stream_chunk_get_metadata: + * @chunk: A #GAFlightStreamChunk. + * + * Returns: (nullable) (transfer full): The metadata of the chunk. + * + * The metadata may be NULL. + * + * Since: 6.0.0 + */ +GArrowBuffer * +gaflight_stream_chunk_get_metadata(GAFlightStreamChunk *chunk) +{ + auto flight_chunk = gaflight_stream_chunk_get_raw(chunk); + if (flight_chunk->app_metadata) { + return garrow_buffer_new_raw(&(flight_chunk->app_metadata)); + } else { + return NULL; + } +} + + +typedef struct GAFlightRecordBatchReaderPrivate_ { + arrow::flight::MetadataRecordBatchReader *reader; +} GAFlightRecordBatchReaderPrivate; + +enum { + PROP_READER = 1, +}; + +G_DEFINE_TYPE_WITH_PRIVATE(GAFlightRecordBatchReader, + gaflight_record_batch_reader, + G_TYPE_OBJECT) + +#define GAFLIGHT_RECORD_BATCH_READER_GET_PRIVATE(obj) \ + static_cast<GAFlightRecordBatchReaderPrivate *>( \ + gaflight_record_batch_reader_get_instance_private( \ + GAFLIGHT_RECORD_BATCH_READER(obj))) + +static void +gaflight_record_batch_reader_finalize(GObject *object) +{ + auto priv = GAFLIGHT_RECORD_BATCH_READER_GET_PRIVATE(object); + + delete priv->reader; + + G_OBJECT_CLASS(gaflight_info_parent_class)->finalize(object); +} + +static void +gaflight_record_batch_reader_set_property(GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + auto priv = GAFLIGHT_RECORD_BATCH_READER_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_READER: + priv->reader = + static_cast<arrow::flight::MetadataRecordBatchReader *>( + g_value_get_pointer(value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gaflight_record_batch_reader_init(GAFlightRecordBatchReader *object) +{ +} + +static void +gaflight_record_batch_reader_class_init(GAFlightRecordBatchReaderClass *klass) +{ + auto gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->finalize = gaflight_record_batch_reader_finalize; + gobject_class->set_property = gaflight_record_batch_reader_set_property; + + GParamSpec *spec; + spec = g_param_spec_pointer("reader", + "Reader", + "The raw arrow::flight::MetadataRecordBatchReader *", + static_cast<GParamFlags>(G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property(gobject_class, PROP_READER, spec); +} + +/** + * gaflight_record_batch_reader_read_next: + * @reader: A #GAFlightRecordBatchReader. + * @error: (nullable): Return location for a #GError or %NULL. + * + * Returns: (transfer full): The next chunk on success, %NULL on end + * of stream, %NULL on error. + * + * Since: 6.0.0 + */ +GAFlightStreamChunk * +gaflight_record_batch_reader_read_next(GAFlightRecordBatchReader *reader, + GError **error) +{ + auto flight_reader = gaflight_record_batch_reader_get_raw(reader); + arrow::flight::FlightStreamChunk flight_chunk; + auto status = flight_reader->Next(&flight_chunk); + if (garrow::check(error, status, "[flight-record-batch-reader][read-next]")) { + if (flight_chunk.data) { + return gaflight_stream_chunk_new_raw(&flight_chunk); + } else { + return NULL; + } + } else { + return NULL; + } +} + +/** + * gaflight_record_batch_reader_read_all: + * @reader: A #GAFlightRecordBatchReader. + * @error: (nullable): Return location for a #GError or %NULL. + * + * Returns: (transfer full): The all data on success, %NULL on error. + * + * Since: 6.0.0 + */ +GArrowTable * +gaflight_record_batch_reader_read_all(GAFlightRecordBatchReader *reader, + GError **error) +{ + auto flight_reader = gaflight_record_batch_reader_get_raw(reader); + std::shared_ptr<arrow::Table> arrow_table; + auto status = flight_reader->ReadAll(&arrow_table); + if (garrow::check(error, status, "[flight-record-batch-reader][read-all]")) { + return garrow_table_new_raw(&arrow_table); + } else { + return NULL; + } +} + + +G_END_DECLS + + +GAFlightCriteria * +gaflight_criteria_new_raw(const arrow::flight::Criteria *flight_criteria) +{ + auto criteria = g_object_new(GAFLIGHT_TYPE_CRITERIA, NULL); + auto priv = GAFLIGHT_CRITERIA_GET_PRIVATE(criteria); + priv->criteria = *flight_criteria; + priv->expression = g_bytes_new(priv->criteria.expression.data(), + priv->criteria.expression.size()); + return GAFLIGHT_CRITERIA(criteria); +} + +arrow::flight::Criteria * +gaflight_criteria_get_raw(GAFlightCriteria *criteria) +{ + auto priv = GAFLIGHT_CRITERIA_GET_PRIVATE(criteria); + return &(priv->criteria); +} + +arrow::flight::Location * +gaflight_location_get_raw(GAFlightLocation *location) +{ + auto priv = GAFLIGHT_LOCATION_GET_PRIVATE(location); + return &(priv->location); +} + +GAFlightDescriptor * +gaflight_descriptor_new_raw( + const arrow::flight::FlightDescriptor *flight_descriptor) +{ + GType gtype = GAFLIGHT_TYPE_DESCRIPTOR; + switch (flight_descriptor->type) { + case arrow::flight::FlightDescriptor::DescriptorType::PATH: + gtype = GAFLIGHT_TYPE_PATH_DESCRIPTOR; + break; + case arrow::flight::FlightDescriptor::DescriptorType::CMD: + gtype = GAFLIGHT_TYPE_COMMAND_DESCRIPTOR; + break; + default: + break; + } + return GAFLIGHT_DESCRIPTOR(g_object_new(gtype, + "descriptor", flight_descriptor, + NULL)); +} + +arrow::flight::FlightDescriptor * +gaflight_descriptor_get_raw(GAFlightDescriptor *descriptor) +{ + auto priv = GAFLIGHT_DESCRIPTOR_GET_PRIVATE(descriptor); + return &(priv->descriptor); +} + +GAFlightTicket * +gaflight_ticket_new_raw(const arrow::flight::Ticket *flight_ticket) +{ + auto ticket = g_object_new(GAFLIGHT_TYPE_TICKET, NULL); + auto priv = GAFLIGHT_TICKET_GET_PRIVATE(ticket); + priv->ticket = *flight_ticket; + priv->data = g_bytes_new(priv->ticket.ticket.data(), + priv->ticket.ticket.size()); + return GAFLIGHT_TICKET(ticket); +} + +arrow::flight::Ticket * +gaflight_ticket_get_raw(GAFlightTicket *ticket) +{ + auto priv = GAFLIGHT_TICKET_GET_PRIVATE(ticket); + return &(priv->ticket); +} + +GAFlightEndpoint * +gaflight_endpoint_new_raw(const arrow::flight::FlightEndpoint *flight_endpoint, + GAFlightTicket *ticket) +{ + auto endpoint = GAFLIGHT_ENDPOINT(g_object_new(GAFLIGHT_TYPE_ENDPOINT, + NULL)); + auto priv = GAFLIGHT_ENDPOINT_GET_PRIVATE(endpoint); + if (ticket) { + priv->ticket = ticket; + g_object_ref(priv->ticket); + priv->endpoint.ticket = *gaflight_ticket_get_raw(priv->ticket); + } else { + auto data = g_bytes_new(flight_endpoint->ticket.ticket.data(), + flight_endpoint->ticket.ticket.length()); + auto ticket = gaflight_ticket_new(data); + g_bytes_unref(data); + priv->ticket = ticket; + priv->endpoint.ticket.ticket = flight_endpoint->ticket.ticket; + } + if (flight_endpoint) { + priv->endpoint.locations = flight_endpoint->locations; + } + return endpoint; +} + +arrow::flight::FlightEndpoint * +gaflight_endpoint_get_raw(GAFlightEndpoint *endpoint) +{ + auto priv = GAFLIGHT_ENDPOINT_GET_PRIVATE(endpoint); + return &(priv->endpoint); +} + +GAFlightInfo * +gaflight_info_new_raw(arrow::flight::FlightInfo *flight_info) +{ + return GAFLIGHT_INFO(g_object_new(GAFLIGHT_TYPE_INFO, + "info", flight_info, + NULL)); +} + +arrow::flight::FlightInfo * +gaflight_info_get_raw(GAFlightInfo *info) +{ + auto priv = GAFLIGHT_INFO_GET_PRIVATE(info); + return &(priv->info); +} + +GAFlightStreamChunk * +gaflight_stream_chunk_new_raw(arrow::flight::FlightStreamChunk *flight_chunk) +{ + return GAFLIGHT_STREAM_CHUNK( + g_object_new(GAFLIGHT_TYPE_STREAM_CHUNK, + "chunk", flight_chunk, + NULL)); +} + +arrow::flight::FlightStreamChunk * +gaflight_stream_chunk_get_raw(GAFlightStreamChunk *chunk) +{ + auto priv = GAFLIGHT_STREAM_CHUNK_GET_PRIVATE(chunk); + return &(priv->chunk); +} + +arrow::flight::MetadataRecordBatchReader * +gaflight_record_batch_reader_get_raw(GAFlightRecordBatchReader *reader) +{ + auto priv = GAFLIGHT_RECORD_BATCH_READER_GET_PRIVATE(reader); + return priv->reader; +} diff --git a/src/arrow/c_glib/arrow-flight-glib/common.h b/src/arrow/c_glib/arrow-flight-glib/common.h new file mode 100644 index 000000000..368fb665b --- /dev/null +++ b/src/arrow/c_glib/arrow-flight-glib/common.h @@ -0,0 +1,268 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#pragma once + +#include <arrow-glib/arrow-glib.h> + +G_BEGIN_DECLS + + +#define GAFLIGHT_TYPE_CRITERIA (gaflight_criteria_get_type()) +G_DECLARE_DERIVABLE_TYPE(GAFlightCriteria, + gaflight_criteria, + GAFLIGHT, + CRITERIA, + GObject) +struct _GAFlightCriteriaClass +{ + GObjectClass parent_class; +}; + +GARROW_AVAILABLE_IN_5_0 +GAFlightCriteria * +gaflight_criteria_new(GBytes *expression); + + +#define GAFLIGHT_TYPE_LOCATION (gaflight_location_get_type()) +G_DECLARE_DERIVABLE_TYPE(GAFlightLocation, + gaflight_location, + GAFLIGHT, + LOCATION, + GObject) +struct _GAFlightLocationClass +{ + GObjectClass parent_class; +}; + +GARROW_AVAILABLE_IN_5_0 +GAFlightLocation * +gaflight_location_new(const gchar *uri, + GError **error); + +GARROW_AVAILABLE_IN_5_0 +gchar * +gaflight_location_to_string(GAFlightLocation *location); + +GARROW_AVAILABLE_IN_5_0 +gchar * +gaflight_location_get_scheme(GAFlightLocation *location); + +GARROW_AVAILABLE_IN_5_0 +gboolean +gaflight_location_equal(GAFlightLocation *location, + GAFlightLocation *other_location); + + +#define GAFLIGHT_TYPE_DESCRIPTOR (gaflight_descriptor_get_type()) +G_DECLARE_DERIVABLE_TYPE(GAFlightDescriptor, + gaflight_descriptor, + GAFLIGHT, + DESCRIPTOR, + GObject) +struct _GAFlightDescriptorClass +{ + GObjectClass parent_class; +}; + +GARROW_AVAILABLE_IN_5_0 +gchar * +gaflight_descriptor_to_string(GAFlightDescriptor *descriptor); + +GARROW_AVAILABLE_IN_5_0 +gboolean +gaflight_descriptor_equal(GAFlightDescriptor *descriptor, + GAFlightDescriptor *other_descriptor); + + +#define GAFLIGHT_TYPE_PATH_DESCRIPTOR (gaflight_path_descriptor_get_type()) +G_DECLARE_DERIVABLE_TYPE(GAFlightPathDescriptor, + gaflight_path_descriptor, + GAFLIGHT, + PATH_DESCRIPTOR, + GAFlightDescriptor) +struct _GAFlightPathDescriptorClass +{ + GAFlightDescriptorClass parent_class; +}; + +GARROW_AVAILABLE_IN_5_0 +GAFlightPathDescriptor * +gaflight_path_descriptor_new(const gchar **paths, + gsize n_paths); + +GARROW_AVAILABLE_IN_5_0 +gchar ** +gaflight_path_descriptor_get_paths(GAFlightPathDescriptor *descriptor); + + +#define GAFLIGHT_TYPE_COMMAND_DESCRIPTOR (gaflight_command_descriptor_get_type()) +G_DECLARE_DERIVABLE_TYPE(GAFlightCommandDescriptor, + gaflight_command_descriptor, + GAFLIGHT, + COMMAND_DESCRIPTOR, + GAFlightDescriptor) +struct _GAFlightCommandDescriptorClass +{ + GAFlightDescriptorClass parent_class; +}; + +GARROW_AVAILABLE_IN_5_0 +GAFlightCommandDescriptor * +gaflight_command_descriptor_new(const gchar *command); + +GARROW_AVAILABLE_IN_5_0 +gchar * +gaflight_command_descriptor_get_command(GAFlightCommandDescriptor *descriptor); + + +#define GAFLIGHT_TYPE_TICKET (gaflight_ticket_get_type()) +G_DECLARE_DERIVABLE_TYPE(GAFlightTicket, + gaflight_ticket, + GAFLIGHT, + TICKET, + GObject) +struct _GAFlightTicketClass +{ + GObjectClass parent_class; +}; + +GARROW_AVAILABLE_IN_5_0 +GAFlightTicket * +gaflight_ticket_new(GBytes *data); + +GARROW_AVAILABLE_IN_5_0 +gboolean +gaflight_ticket_equal(GAFlightTicket *ticket, + GAFlightTicket *other_ticket); + + +#define GAFLIGHT_TYPE_ENDPOINT (gaflight_endpoint_get_type()) +G_DECLARE_DERIVABLE_TYPE(GAFlightEndpoint, + gaflight_endpoint, + GAFLIGHT, + ENDPOINT, + GObject) +struct _GAFlightEndpointClass +{ + GObjectClass parent_class; +}; + +GARROW_AVAILABLE_IN_5_0 +GAFlightEndpoint * +gaflight_endpoint_new(GAFlightTicket *ticket, + GList *locations); + +GARROW_AVAILABLE_IN_5_0 +gboolean +gaflight_endpoint_equal(GAFlightEndpoint *endpoint, + GAFlightEndpoint *other_endpoint); + +GARROW_AVAILABLE_IN_5_0 +GList * +gaflight_endpoint_get_locations(GAFlightEndpoint *endpoint); + + +#define GAFLIGHT_TYPE_INFO (gaflight_info_get_type()) +G_DECLARE_DERIVABLE_TYPE(GAFlightInfo, + gaflight_info, + GAFLIGHT, + INFO, + GObject) +struct _GAFlightInfoClass +{ + GObjectClass parent_class; +}; + +GARROW_AVAILABLE_IN_5_0 +GAFlightInfo * +gaflight_info_new(GArrowSchema *schema, + GAFlightDescriptor *descriptor, + GList *endpoints, + gint64 total_records, + gint64 total_bytes, + GError **error); + +GARROW_AVAILABLE_IN_5_0 +gboolean +gaflight_info_equal(GAFlightInfo *info, + GAFlightInfo *other_info); + +GARROW_AVAILABLE_IN_5_0 +GArrowSchema * +gaflight_info_get_schema(GAFlightInfo *info, + GArrowReadOptions *options, + GError **error); +GARROW_AVAILABLE_IN_5_0 +GAFlightDescriptor * +gaflight_info_get_descriptor(GAFlightInfo *info); +GARROW_AVAILABLE_IN_5_0 +GList * +gaflight_info_get_endpoints(GAFlightInfo *info); +GARROW_AVAILABLE_IN_5_0 +gint64 +gaflight_info_get_total_records(GAFlightInfo *info); +GARROW_AVAILABLE_IN_5_0 +gint64 +gaflight_info_get_total_bytes(GAFlightInfo *info); + + +#define GAFLIGHT_TYPE_STREAM_CHUNK (gaflight_stream_chunk_get_type()) +G_DECLARE_DERIVABLE_TYPE(GAFlightStreamChunk, + gaflight_stream_chunk, + GAFLIGHT, + STREAM_CHUNK, + GObject) +struct _GAFlightStreamChunkClass +{ + GObjectClass parent_class; +}; + +GARROW_AVAILABLE_IN_6_0 +GArrowRecordBatch * +gaflight_stream_chunk_get_data(GAFlightStreamChunk *chunk); +GARROW_AVAILABLE_IN_6_0 +GArrowBuffer * +gaflight_stream_chunk_get_metadata(GAFlightStreamChunk *chunk); + + +#define GAFLIGHT_TYPE_RECORD_BATCH_READER \ + (gaflight_record_batch_reader_get_type()) +G_DECLARE_DERIVABLE_TYPE(GAFlightRecordBatchReader, + gaflight_record_batch_reader, + GAFLIGHT, + RECORD_BATCH_READER, + GObject) +struct _GAFlightRecordBatchReaderClass +{ + GObjectClass parent_class; +}; + +GARROW_AVAILABLE_IN_6_0 +GAFlightStreamChunk * +gaflight_record_batch_reader_read_next(GAFlightRecordBatchReader *reader, + GError **error); + +GARROW_AVAILABLE_IN_6_0 +GArrowTable * +gaflight_record_batch_reader_read_all(GAFlightRecordBatchReader *reader, + GError **error); + + +G_END_DECLS diff --git a/src/arrow/c_glib/arrow-flight-glib/common.hpp b/src/arrow/c_glib/arrow-flight-glib/common.hpp new file mode 100644 index 000000000..d23f7c886 --- /dev/null +++ b/src/arrow/c_glib/arrow-flight-glib/common.hpp @@ -0,0 +1,63 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#pragma once + +#include <arrow/flight/api.h> + +#include <arrow-flight-glib/common.h> + + +GAFlightCriteria * +gaflight_criteria_new_raw(const arrow::flight::Criteria *flight_criteria); +arrow::flight::Criteria * +gaflight_criteria_get_raw(GAFlightCriteria *criteria); + +arrow::flight::Location * +gaflight_location_get_raw(GAFlightLocation *location); + +GAFlightDescriptor * +gaflight_descriptor_new_raw( + const arrow::flight::FlightDescriptor *flight_descriptor); +arrow::flight::FlightDescriptor * +gaflight_descriptor_get_raw(GAFlightDescriptor *descriptor); + +GAFlightTicket * +gaflight_ticket_new_raw(const arrow::flight::Ticket *flight_ticket); +arrow::flight::Ticket * +gaflight_ticket_get_raw(GAFlightTicket *ticket); + +GAFlightEndpoint * +gaflight_endpoint_new_raw(const arrow::flight::FlightEndpoint *flight_endpoint, + GAFlightTicket *ticket); +arrow::flight::FlightEndpoint * +gaflight_endpoint_get_raw(GAFlightEndpoint *endpoint); + +GAFlightInfo * +gaflight_info_new_raw(arrow::flight::FlightInfo *flight_info); +arrow::flight::FlightInfo * +gaflight_info_get_raw(GAFlightInfo *info); + +GAFlightStreamChunk * +gaflight_stream_chunk_new_raw(arrow::flight::FlightStreamChunk *flight_chunk); +arrow::flight::FlightStreamChunk * +gaflight_stream_chunk_get_raw(GAFlightStreamChunk *chunk); + +arrow::flight::MetadataRecordBatchReader * +gaflight_record_batch_reader_get_raw(GAFlightRecordBatchReader *reader); diff --git a/src/arrow/c_glib/arrow-flight-glib/meson.build b/src/arrow/c_glib/arrow-flight-glib/meson.build new file mode 100644 index 000000000..c17415fee --- /dev/null +++ b/src/arrow/c_glib/arrow-flight-glib/meson.build @@ -0,0 +1,82 @@ +# -*- indent-tabs-mode: nil -*- +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +sources = files( + 'client.cpp', + 'common.cpp', + 'server.cpp', +) + +c_headers = files( + 'arrow-flight-glib.h', + 'client.h', + 'common.h', + 'server.h', +) + +cpp_headers = files( + 'arrow-flight-glib.hpp', + 'client.hpp', + 'common.hpp', + 'server.hpp', +) + +headers = c_headers + cpp_headers +install_headers(headers, subdir: 'arrow-flight-glib') + +dependencies = [ + arrow_flight, + arrow_glib, +] +libarrow_flight_glib = library('arrow-flight-glib', + sources: sources, + install: true, + dependencies: dependencies, + include_directories: base_include_directories, + soversion: so_version, + version: library_version) +arrow_flight_glib = declare_dependency(link_with: libarrow_flight_glib, + include_directories: base_include_directories, + dependencies: dependencies) + +pkgconfig.generate(libarrow_flight_glib, + filebase: 'arrow-flight-glib', + name: 'Apache Arrow Flight GLib', + description: 'C API for Apache Arrow Flight based on GLib', + version: version, + requires: ['arrow-glib', 'arrow-flight']) + +if have_gi + gnome.generate_gir(libarrow_flight_glib, + dependencies: declare_dependency(sources: arrow_glib_gir), + sources: sources + c_headers, + namespace: 'ArrowFlight', + nsversion: api_version, + identifier_prefix: 'GAFlight', + symbol_prefix: 'gaflight', + export_packages: 'arrow-flight-glib', + includes: [ + 'Arrow-1.0', + ], + install: true, + extra_args: [ + '--warn-all', + '--include-uninstalled=./arrow-glib/Arrow-1.0.gir', + ]) +endif diff --git a/src/arrow/c_glib/arrow-flight-glib/server.cpp b/src/arrow/c_glib/arrow-flight-glib/server.cpp new file mode 100644 index 000000000..eb05284c1 --- /dev/null +++ b/src/arrow/c_glib/arrow-flight-glib/server.cpp @@ -0,0 +1,724 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include <arrow/util/make_unique.h> + +#include <arrow-glib/arrow-glib.hpp> + +#include <arrow-flight-glib/common.hpp> +#include <arrow-flight-glib/server.hpp> + +G_BEGIN_DECLS + +/** + * SECTION: server + * @section_id: server + * @title: Server related classes + * @include: arrow-flight-glib/arrow-flight-glib.h + * + * #GAFlightDataStream is a class for producing a sequence of IPC + * payloads to be sent in `FlightData` protobuf messages. Generally, + * this is not used directly. Generally, #GAFlightRecordBatchStream is + * used instead. + * + * #GAFlightRecordBatchStream is a class for producing a sequence of + * IPC payloads to be sent in `FlightData` protobuf messages by + * #GArrowRecordBatchReader`. + * + * #GAFlightServerOptions is a class for options of each server. + * + * #GAFlightServerCallContext is a class for context of each server call. + * + * #GAFlightServer is a class to develop an Apache Arrow Flight server. + * + * Since: 5.0.0 + */ + + +typedef struct GAFlightDataStreamPrivate_ { + arrow::flight::FlightDataStream *stream; +} GAFlightDataStreamPrivate; + +enum { + PROP_STREAM = 1, +}; + +G_DEFINE_TYPE_WITH_PRIVATE(GAFlightDataStream, + gaflight_data_stream, + G_TYPE_OBJECT) + +#define GAFLIGHT_DATA_STREAM_GET_PRIVATE(obj) \ + static_cast<GAFlightDataStreamPrivate *>( \ + gaflight_data_stream_get_instance_private( \ + GAFLIGHT_DATA_STREAM(obj))) + +static void +gaflight_data_stream_finalize(GObject *object) +{ + auto priv = GAFLIGHT_DATA_STREAM_GET_PRIVATE(object); + + delete priv->stream; + + G_OBJECT_CLASS(gaflight_data_stream_parent_class)->finalize(object); +} + +static void +gaflight_data_stream_set_property(GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + auto priv = GAFLIGHT_DATA_STREAM_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_STREAM: + priv->stream = static_cast<arrow::flight::FlightDataStream *>( + g_value_get_pointer(value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gaflight_data_stream_init(GAFlightDataStream *object) +{ +} + +static void +gaflight_data_stream_class_init(GAFlightDataStreamClass *klass) +{ + auto gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->finalize = gaflight_data_stream_finalize; + gobject_class->set_property = gaflight_data_stream_set_property; + + GParamSpec *spec; + spec = g_param_spec_pointer("stream", + "Stream", + "The raw arrow::flight::FlightDataStream *", + static_cast<GParamFlags>(G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property(gobject_class, PROP_STREAM, spec); +} + + +typedef struct GAFlightRecordBatchStreamPrivate_ { + GArrowRecordBatchReader *reader; +} GAFlightRecordBatchStreamPrivate; + +enum { + PROP_READER = 1, +}; + +G_DEFINE_TYPE_WITH_PRIVATE(GAFlightRecordBatchStream, + gaflight_record_batch_stream, + GAFLIGHT_TYPE_DATA_STREAM) + +#define GAFLIGHT_RECORD_BATCH_STREAM_GET_PRIVATE(obj) \ + static_cast<GAFlightRecordBatchStreamPrivate *>( \ + gaflight_record_batch_stream_get_instance_private( \ + GAFLIGHT_RECORD_BATCH_STREAM(obj))) + +static void +gaflight_record_batch_stream_dispose(GObject *object) +{ + auto priv = GAFLIGHT_RECORD_BATCH_STREAM_GET_PRIVATE(object); + + if (priv->reader) { + g_object_unref(priv->reader); + priv->reader = NULL; + } + + G_OBJECT_CLASS(gaflight_record_batch_stream_parent_class)->dispose(object); +} + +static void +gaflight_record_batch_stream_set_property(GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + auto priv = GAFLIGHT_RECORD_BATCH_STREAM_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_READER: + priv->reader = GARROW_RECORD_BATCH_READER(g_value_dup_object(value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gaflight_record_batch_stream_get_property(GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + auto priv = GAFLIGHT_RECORD_BATCH_STREAM_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_READER: + g_value_set_object(value, priv->reader); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gaflight_record_batch_stream_init(GAFlightRecordBatchStream *object) +{ +} + +static void +gaflight_record_batch_stream_class_init(GAFlightRecordBatchStreamClass *klass) +{ + auto gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->dispose = gaflight_record_batch_stream_dispose; + gobject_class->set_property = gaflight_record_batch_stream_set_property; + gobject_class->get_property = gaflight_record_batch_stream_get_property; + + GParamSpec *spec; + /** + * GAFlightRecordBatchStream:reader: + * + * The reader that produces record batches. + * + * Since: 6.0.0 + */ + spec = g_param_spec_object("reader", + "Reader", + "The reader that produces record batches", + GARROW_TYPE_RECORD_BATCH_READER, + static_cast<GParamFlags>(G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property(gobject_class, PROP_READER, spec); +} + +/** + * gaflight_record_batch_stream_new: + * @reader: A #GArrowRecordBatchReader to be read. + * @options: (nullable): A #GArrowWriteOptions for writing record batches to + * a client. + * + * Returns: The newly created #GAFlightRecordBatchStream. + * + * Since: 6.0.0 + */ +GAFlightRecordBatchStream * +gaflight_record_batch_stream_new(GArrowRecordBatchReader *reader, + GArrowWriteOptions *options) +{ + auto arrow_reader = garrow_record_batch_reader_get_raw(reader); + auto arrow_options_default = arrow::ipc::IpcWriteOptions::Defaults(); + arrow::ipc::IpcWriteOptions *arrow_options = NULL; + if (options) { + arrow_options = garrow_write_options_get_raw(options); + } else { + arrow_options = &arrow_options_default; + } + auto stream = arrow::internal::make_unique< + arrow::flight::RecordBatchStream>(arrow_reader, *arrow_options); + return static_cast<GAFlightRecordBatchStream *>( + g_object_new(GAFLIGHT_TYPE_RECORD_BATCH_STREAM, + "stream", stream.release(), + "reader", reader, + NULL)); +} + + +typedef struct GAFlightServerOptionsPrivate_ { + arrow::flight::FlightServerOptions options; + GAFlightLocation *location; +} GAFlightServerOptionsPrivate; + +enum { + PROP_LOCATION = 1, +}; + +G_DEFINE_TYPE_WITH_PRIVATE(GAFlightServerOptions, + gaflight_server_options, + G_TYPE_OBJECT) + +#define GAFLIGHT_SERVER_OPTIONS_GET_PRIVATE(obj) \ + static_cast<GAFlightServerOptionsPrivate *>( \ + gaflight_server_options_get_instance_private( \ + GAFLIGHT_SERVER_OPTIONS(obj))) + +static void +gaflight_server_options_dispose(GObject *object) +{ + auto priv = GAFLIGHT_SERVER_OPTIONS_GET_PRIVATE(object); + + if (priv->location) { + g_object_unref(priv->location); + priv->location = NULL; + } + + G_OBJECT_CLASS(gaflight_server_options_parent_class)->dispose(object); +} + +static void +gaflight_server_options_finalize(GObject *object) +{ + auto priv = GAFLIGHT_SERVER_OPTIONS_GET_PRIVATE(object); + + priv->options.~FlightServerOptions(); + + G_OBJECT_CLASS(gaflight_server_options_parent_class)->finalize(object); +} + +static void +gaflight_server_options_set_property(GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + auto priv = GAFLIGHT_SERVER_OPTIONS_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_LOCATION: + { + priv->location = GAFLIGHT_LOCATION(g_value_dup_object(value)); + auto flight_location = gaflight_location_get_raw(priv->location); + new(&(priv->options)) arrow::flight::FlightServerOptions(*flight_location); + } + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gaflight_server_options_get_property(GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + auto priv = GAFLIGHT_SERVER_OPTIONS_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_LOCATION: + g_value_set_object(value, priv->location); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gaflight_server_options_init(GAFlightServerOptions *object) +{ +} + +static void +gaflight_server_options_class_init(GAFlightServerOptionsClass *klass) +{ + auto gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->dispose = gaflight_server_options_dispose; + gobject_class->finalize = gaflight_server_options_finalize; + gobject_class->set_property = gaflight_server_options_set_property; + gobject_class->get_property = gaflight_server_options_get_property; + + GParamSpec *spec; + spec = g_param_spec_object("location", + "Location", + "The location to be listened", + GAFLIGHT_TYPE_LOCATION, + static_cast<GParamFlags>(G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property(gobject_class, PROP_LOCATION, spec); +} + +/** + * gaflight_server_options_new: + * @location: A #GAFlightLocation to be listened. + * + * Returns: The newly created options for a server. + * + * Since: 5.0.0 + */ +GAFlightServerOptions * +gaflight_server_options_new(GAFlightLocation *location) +{ + return static_cast<GAFlightServerOptions *>( + g_object_new(GAFLIGHT_TYPE_SERVER_OPTIONS, + "location", location, + NULL)); +} + + +typedef struct GAFlightServerCallContextPrivate_ { + arrow::flight::ServerCallContext *call_context; +} GAFlightServerCallContextPrivate; + +enum { + PROP_CALL_CONTEXT = 1, +}; + +G_DEFINE_TYPE_WITH_PRIVATE(GAFlightServerCallContext, + gaflight_server_call_context, + G_TYPE_OBJECT) + +#define GAFLIGHT_SERVER_CALL_CONTEXT_GET_PRIVATE(obj) \ + static_cast<GAFlightServerCallContextPrivate *>( \ + gaflight_server_call_context_get_instance_private( \ + GAFLIGHT_SERVER_CALL_CONTEXT(obj))) + +static void +gaflight_server_call_context_set_property(GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + auto priv = GAFLIGHT_SERVER_CALL_CONTEXT_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_CALL_CONTEXT: + priv->call_context = + static_cast<arrow::flight::ServerCallContext *>( + g_value_get_pointer(value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gaflight_server_call_context_init(GAFlightServerCallContext *object) +{ +} + +static void +gaflight_server_call_context_class_init(GAFlightServerCallContextClass *klass) +{ + auto gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->set_property = gaflight_server_call_context_set_property; + + GParamSpec *spec; + spec = g_param_spec_pointer("call-context", + "Call context", + "The raw arrow::flight::ServerCallContext", + static_cast<GParamFlags>(G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property(gobject_class, PROP_CALL_CONTEXT, spec); +} + + +G_END_DECLS +namespace gaflight { + class DataStream : public arrow::flight::FlightDataStream { + public: + DataStream(GAFlightDataStream *gastream) : + arrow::flight::FlightDataStream(), + gastream_(gastream) { + } + + ~DataStream() override { + g_object_unref(gastream_); + } + + std::shared_ptr<arrow::Schema> schema() override { + auto stream = gaflight_data_stream_get_raw(gastream_); + return stream->schema(); + } + + arrow::Status GetSchemaPayload( + arrow::flight::FlightPayload *payload) override { + auto stream = gaflight_data_stream_get_raw(gastream_); + return stream->GetSchemaPayload(payload); + } + + arrow::Status Next(arrow::flight::FlightPayload *payload) override { + auto stream = gaflight_data_stream_get_raw(gastream_); + return stream->Next(payload); + } + + private: + GAFlightDataStream *gastream_; + }; + + class Server : public arrow::flight::FlightServerBase { + public: + Server(GAFlightServer *gaserver) : gaserver_(gaserver) { + } + + arrow::Status + ListFlights( + const arrow::flight::ServerCallContext &context, + const arrow::flight::Criteria *criteria, + std::unique_ptr<arrow::flight::FlightListing> *listing) override { + auto gacontext = gaflight_server_call_context_new_raw(&context); + GAFlightCriteria *gacriteria = NULL; + if (criteria) { + gacriteria = gaflight_criteria_new_raw(criteria); + } + GError *gerror = NULL; + auto gaflights = gaflight_server_list_flights(gaserver_, + gacontext, + gacriteria, + &gerror); + if (gacriteria) { + g_object_unref(gacriteria); + } + g_object_unref(gacontext); + if (gerror) { + return garrow_error_to_status(gerror, + arrow::StatusCode::UnknownError, + "[flight-server][list-flights]"); + } + std::vector<arrow::flight::FlightInfo> flights; + for (auto node = gaflights; node; node = node->next) { + auto gaflight = GAFLIGHT_INFO(node->data); + flights.push_back(*gaflight_info_get_raw(gaflight)); + g_object_unref(gaflight); + } + g_list_free(gaflights); + *listing = arrow::internal::make_unique< + arrow::flight::SimpleFlightListing>(flights); + return arrow::Status::OK(); + } + + arrow::Status DoGet( + const arrow::flight::ServerCallContext &context, + const arrow::flight::Ticket &ticket, + std::unique_ptr<arrow::flight::FlightDataStream> *stream) override { + auto gacontext = gaflight_server_call_context_new_raw(&context); + auto gaticket = gaflight_ticket_new_raw(&ticket); + GError *gerror = NULL; + auto gastream = gaflight_server_do_get(gaserver_, + gacontext, + gaticket, + &gerror); + g_object_unref(gaticket); + g_object_unref(gacontext); + if (gerror) { + return garrow_error_to_status(gerror, + arrow::StatusCode::UnknownError, + "[flight-server][do-get]"); + } + *stream = arrow::internal::make_unique<DataStream>(gastream); + return arrow::Status::OK(); + } + + private: + GAFlightServer *gaserver_; + }; +}; +G_BEGIN_DECLS + +typedef struct GAFlightServerPrivate_ { + gaflight::Server server; +} GAFlightServerPrivate; + +G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE(GAFlightServer, + gaflight_server, + G_TYPE_OBJECT) + +#define GAFLIGHT_SERVER_GET_PRIVATE(obj) \ + static_cast<GAFlightServerPrivate *>( \ + gaflight_server_get_instance_private( \ + GAFLIGHT_SERVER(obj))) + +static void +gaflight_server_finalize(GObject *object) +{ + auto priv = GAFLIGHT_SERVER_GET_PRIVATE(object); + + priv->server.~Server(); + + G_OBJECT_CLASS(gaflight_server_parent_class)->finalize(object); +} + +static void +gaflight_server_init(GAFlightServer *object) +{ + auto priv = GAFLIGHT_SERVER_GET_PRIVATE(object); + new(&(priv->server)) gaflight::Server(object); +} + +static void +gaflight_server_class_init(GAFlightServerClass *klass) +{ + auto gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->finalize = gaflight_server_finalize; +} + +/** + * gaflight_server_listen: + * @server: A #GAFlightServer. + * @options: A #GAFlightServerOptions. + * @error: (nullable): Return location for a #GError or %NULL. + * + * Returns: %TRUE on success, %FALSE on error. + * + * Since: 5.0.0 + */ +gboolean +gaflight_server_listen(GAFlightServer *server, + GAFlightServerOptions *options, + GError **error) +{ + auto flight_server = gaflight_server_get_raw(server); + const auto flight_options = gaflight_server_options_get_raw(options); + return garrow::check(error, + flight_server->Init(*flight_options), + "[flight-server][listen]"); +} + +/** + * gaflight_server_new: + * @server: A #GAFlightServer. + * + * Returns: The port number listening. + * + * Since: 5.0.0 + */ +gint +gaflight_server_get_port(GAFlightServer *server) +{ + const auto flight_server = gaflight_server_get_raw(server); + return flight_server->port(); +} + +/** + * gaflight_server_shutdown: + * @server: A #GAFlightServer. + * @error: (nullable): Return location for a #GError or %NULL. + * + * Shuts down the serve. This function can be called from signal + * handler or another thread. + * + * Returns: %TRUE on success, %FALSE on error. + * + * Since: 5.0.0 + */ +gboolean +gaflight_server_shutdown(GAFlightServer *server, + GError **error) +{ + auto flight_server = gaflight_server_get_raw(server); + return garrow::check(error, + flight_server->Shutdown(), + "[flight-server][shutdown]"); +} + +/** + * gaflight_server_list_flights: + * @server: A #GAFlightServer. + * @context: A #GAFlightServerCallContext. + * @criteria: (nullable): A #GAFlightCriteria. + * @error: (nullable): Return location for a #GError or %NULL. + * + * Returns: (element-type GAFlightInfo) (transfer full): + * #GList of #GAFlightInfo on success, %NULL on error. + * + * Since: 5.0.0 + */ +GList * +gaflight_server_list_flights(GAFlightServer *server, + GAFlightServerCallContext *context, + GAFlightCriteria *criteria, + GError **error) +{ + auto klass = GAFLIGHT_SERVER_GET_CLASS(server); + if (!(klass && klass->list_flights)) { + g_set_error(error, + GARROW_ERROR, + GARROW_ERROR_NOT_IMPLEMENTED, + "not implemented"); + return NULL; + } + return (*(klass->list_flights))(server, context, criteria, error); +} + +/** + * gaflight_server_do_get: + * @server: A #GAFlightServer. + * @context: A #GAFlightServerCallContext. + * @ticket: A #GAFlightTicket. + * @error: (nullable): Return location for a #GError or %NULL. + * + * Returns: (transfer full): #GAFlightDataStream on success, %NULL on error. + * + * Since: 6.0.0 + */ +GAFlightDataStream * +gaflight_server_do_get(GAFlightServer *server, + GAFlightServerCallContext *context, + GAFlightTicket *ticket, + GError **error) +{ + auto klass = GAFLIGHT_SERVER_GET_CLASS(server); + if (!(klass && klass->do_get)) { + g_set_error(error, + GARROW_ERROR, + GARROW_ERROR_NOT_IMPLEMENTED, + "not implemented"); + return NULL; + } + return (*(klass->do_get))(server, context, ticket, error); +} + + +G_END_DECLS + + +arrow::flight::FlightDataStream * +gaflight_data_stream_get_raw(GAFlightDataStream *stream) +{ + auto priv = GAFLIGHT_DATA_STREAM_GET_PRIVATE(stream); + return priv->stream; +} + +arrow::flight::FlightServerOptions * +gaflight_server_options_get_raw(GAFlightServerOptions *options) +{ + auto priv = GAFLIGHT_SERVER_OPTIONS_GET_PRIVATE(options); + return &(priv->options); +} + +GAFlightServerCallContext * +gaflight_server_call_context_new_raw( + const arrow::flight::ServerCallContext *call_context) +{ + return GAFLIGHT_SERVER_CALL_CONTEXT( + g_object_new(GAFLIGHT_TYPE_SERVER_CALL_CONTEXT, + "call-context", call_context, + NULL)); +} + +arrow::flight::FlightServerBase * +gaflight_server_get_raw(GAFlightServer *server) +{ + auto priv = GAFLIGHT_SERVER_GET_PRIVATE(server); + return &(priv->server); +} diff --git a/src/arrow/c_glib/arrow-flight-glib/server.h b/src/arrow/c_glib/arrow-flight-glib/server.h new file mode 100644 index 000000000..107fe44bf --- /dev/null +++ b/src/arrow/c_glib/arrow-flight-glib/server.h @@ -0,0 +1,144 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#pragma once + +#include <arrow-flight-glib/common.h> + +G_BEGIN_DECLS + + +#define GAFLIGHT_TYPE_DATA_STREAM \ + (gaflight_data_stream_get_type()) +G_DECLARE_DERIVABLE_TYPE(GAFlightDataStream, + gaflight_data_stream, + GAFLIGHT, + DATA_STREAM, + GObject) +struct _GAFlightDataStreamClass +{ + GObjectClass parent_class; +}; + + +#define GAFLIGHT_TYPE_RECORD_BATCH_STREAM \ + (gaflight_record_batch_stream_get_type()) +G_DECLARE_DERIVABLE_TYPE(GAFlightRecordBatchStream, + gaflight_record_batch_stream, + GAFLIGHT, + RECORD_BATCH_STREAM, + GAFlightDataStream) +struct _GAFlightRecordBatchStreamClass +{ + GAFlightDataStreamClass parent_class; +}; + +GARROW_AVAILABLE_IN_6_0 +GAFlightRecordBatchStream * +gaflight_record_batch_stream_new(GArrowRecordBatchReader *reader, + GArrowWriteOptions *options); + + +#define GAFLIGHT_TYPE_SERVER_OPTIONS (gaflight_server_options_get_type()) +G_DECLARE_DERIVABLE_TYPE(GAFlightServerOptions, + gaflight_server_options, + GAFLIGHT, + SERVER_OPTIONS, + GObject) +struct _GAFlightServerOptionsClass +{ + GObjectClass parent_class; +}; + +GARROW_AVAILABLE_IN_5_0 +GAFlightServerOptions * +gaflight_server_options_new(GAFlightLocation *location); + + +#define GAFLIGHT_TYPE_SERVER_CALL_CONTEXT \ + (gaflight_server_call_context_get_type()) +G_DECLARE_DERIVABLE_TYPE(GAFlightServerCallContext, + gaflight_server_call_context, + GAFLIGHT, + SERVER_CALL_CONTEXT, + GObject) +struct _GAFlightServerCallContextClass +{ + GObjectClass parent_class; +}; + + +#define GAFLIGHT_TYPE_SERVER (gaflight_server_get_type()) +G_DECLARE_DERIVABLE_TYPE(GAFlightServer, + gaflight_server, + GAFLIGHT, + SERVER, + GObject) +/** + * GAFlightServerClass: + * @list_flights: A virtual function to implement `ListFlights` API. + * @do_get: A virtual function to implement `DoGet` API. + * + * Since: 5.0.0 + */ +struct _GAFlightServerClass +{ + GObjectClass parent_class; + + GList *(*list_flights)(GAFlightServer *server, + GAFlightServerCallContext *context, + GAFlightCriteria *criteria, + GError **error); + GAFlightDataStream *(*do_get)(GAFlightServer *server, + GAFlightServerCallContext *context, + GAFlightTicket *ticket, + GError **error); +}; + +GARROW_AVAILABLE_IN_5_0 +gboolean +gaflight_server_listen(GAFlightServer *server, + GAFlightServerOptions *options, + GError **error); +GARROW_AVAILABLE_IN_5_0 +gint +gaflight_server_get_port(GAFlightServer *server); +GARROW_AVAILABLE_IN_5_0 +gboolean +gaflight_server_shutdown(GAFlightServer *server, + GError **error); +GARROW_AVAILABLE_IN_5_0 +gboolean +gaflight_server_wait(GAFlightServer *server, + GError **error); + +GARROW_AVAILABLE_IN_5_0 +GList * +gaflight_server_list_flights(GAFlightServer *server, + GAFlightServerCallContext *context, + GAFlightCriteria *criteria, + GError **error); +GARROW_AVAILABLE_IN_6_0 +GAFlightDataStream * +gaflight_server_do_get(GAFlightServer *server, + GAFlightServerCallContext *context, + GAFlightTicket *ticket, + GError **error); + +G_END_DECLS diff --git a/src/arrow/c_glib/arrow-flight-glib/server.hpp b/src/arrow/c_glib/arrow-flight-glib/server.hpp new file mode 100644 index 000000000..f7f2a7aba --- /dev/null +++ b/src/arrow/c_glib/arrow-flight-glib/server.hpp @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#pragma once + +#include <arrow/flight/api.h> + +#include <arrow-flight-glib/server.h> + + +arrow::flight::FlightDataStream * +gaflight_data_stream_get_raw(GAFlightDataStream *stream); + +arrow::flight::FlightServerOptions * +gaflight_server_options_get_raw(GAFlightServerOptions *options); + +GAFlightServerCallContext * +gaflight_server_call_context_new_raw( + const arrow::flight::ServerCallContext *flight_context); + +arrow::flight::FlightServerBase * +gaflight_server_get_raw(GAFlightServer *server); |