summaryrefslogtreecommitdiffstats
path: root/src/arrow/c_glib/arrow-flight-glib
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-21 11:54:28 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-21 11:54:28 +0000
commite6918187568dbd01842d8d1d2c808ce16a894239 (patch)
tree64f88b554b444a49f656b6c656111a145cbbaa28 /src/arrow/c_glib/arrow-flight-glib
parentInitial commit. (diff)
downloadceph-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.h24
-rw-r--r--src/arrow/c_glib/arrow-flight-glib/arrow-flight-glib.hpp24
-rw-r--r--src/arrow/c_glib/arrow-flight-glib/client.cpp405
-rw-r--r--src/arrow/c_glib/arrow-flight-glib/client.h104
-rw-r--r--src/arrow/c_glib/arrow-flight-glib/client.hpp39
-rw-r--r--src/arrow/c_glib/arrow-flight-glib/common.cpp1467
-rw-r--r--src/arrow/c_glib/arrow-flight-glib/common.h268
-rw-r--r--src/arrow/c_glib/arrow-flight-glib/common.hpp63
-rw-r--r--src/arrow/c_glib/arrow-flight-glib/meson.build82
-rw-r--r--src/arrow/c_glib/arrow-flight-glib/server.cpp724
-rw-r--r--src/arrow/c_glib/arrow-flight-glib/server.h144
-rw-r--r--src/arrow/c_glib/arrow-flight-glib/server.hpp38
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);