summaryrefslogtreecommitdiffstats
path: root/src/arrow/c_glib/arrow-glib/field.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/arrow/c_glib/arrow-glib/field.cpp')
-rw-r--r--src/arrow/c_glib/arrow-glib/field.cpp441
1 files changed, 441 insertions, 0 deletions
diff --git a/src/arrow/c_glib/arrow-glib/field.cpp b/src/arrow/c_glib/arrow-glib/field.cpp
new file mode 100644
index 000000000..1bb2dd181
--- /dev/null
+++ b/src/arrow/c_glib/arrow-glib/field.cpp
@@ -0,0 +1,441 @@
+/*
+ * 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/data-type.hpp>
+#include <arrow-glib/error.hpp>
+#include <arrow-glib/field.hpp>
+#include <arrow-glib/internal-hash-table.hpp>
+
+#include <arrow/c/bridge.h>
+
+G_BEGIN_DECLS
+
+/**
+ * SECTION: field
+ * @short_description: Field class
+ *
+ * #GArrowField is a class for field. Field is metadata of a
+ * column. It has name, data type (#GArrowDataType) and nullable
+ * information of the column.
+ */
+
+typedef struct GArrowFieldPrivate_ {
+ std::shared_ptr<arrow::Field> field;
+ GArrowDataType *data_type;
+} GArrowFieldPrivate;
+
+enum {
+ PROP_FIELD = 1,
+ PROP_DATA_TYPE
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE(GArrowField,
+ garrow_field,
+ G_TYPE_OBJECT)
+
+#define GARROW_FIELD_GET_PRIVATE(obj) \
+ static_cast<GArrowFieldPrivate *>( \
+ garrow_field_get_instance_private( \
+ GARROW_FIELD(obj)))
+
+static void
+garrow_field_dispose(GObject *object)
+{
+ auto priv = GARROW_FIELD_GET_PRIVATE(object);
+
+ if (priv->data_type) {
+ g_object_unref(priv->data_type);
+ priv->data_type = nullptr;
+ }
+
+ G_OBJECT_CLASS(garrow_field_parent_class)->dispose(object);
+}
+
+static void
+garrow_field_finalize(GObject *object)
+{
+ auto priv = GARROW_FIELD_GET_PRIVATE(object);
+
+ priv->field.~shared_ptr();
+
+ G_OBJECT_CLASS(garrow_field_parent_class)->finalize(object);
+}
+
+static void
+garrow_field_set_property(GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ auto priv = GARROW_FIELD_GET_PRIVATE(object);
+
+ switch (prop_id) {
+ case PROP_FIELD:
+ priv->field =
+ *static_cast<std::shared_ptr<arrow::Field> *>(g_value_get_pointer(value));
+ break;
+ case PROP_DATA_TYPE:
+ priv->data_type = GARROW_DATA_TYPE(g_value_dup_object(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+garrow_field_init(GArrowField *object)
+{
+ auto priv = GARROW_FIELD_GET_PRIVATE(object);
+ new(&priv->field) std::shared_ptr<arrow::Field>;
+}
+
+static void
+garrow_field_class_init(GArrowFieldClass *klass)
+{
+ auto gobject_class = G_OBJECT_CLASS(klass);
+
+ gobject_class->dispose = garrow_field_dispose;
+ gobject_class->finalize = garrow_field_finalize;
+ gobject_class->set_property = garrow_field_set_property;
+
+ GParamSpec *spec;
+ spec = g_param_spec_pointer("field",
+ "Field",
+ "The raw std::shared<arrow::Field> *",
+ static_cast<GParamFlags>(G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property(gobject_class, PROP_FIELD, spec);
+
+ spec = g_param_spec_object("data-type",
+ "Data type",
+ "The data type",
+ GARROW_TYPE_DATA_TYPE,
+ static_cast<GParamFlags>(G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property(gobject_class, PROP_DATA_TYPE, spec);
+}
+
+/**
+ * garrow_field_import:
+ * @c_abi_schema: (not nullable): A `struct ArrowSchema *`.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Returns: (transfer full) (nullable): An imported #GArrowField on success,
+ * %NULL on error.
+ *
+ * You don't need to release the passed `struct ArrowSchema *`,
+ * even if this function reports an error.
+ *
+ * Since: 6.0.0
+ */
+GArrowField *
+garrow_field_import(gpointer c_abi_schema, GError **error)
+{
+ auto arrow_field_result =
+ arrow::ImportField(static_cast<ArrowSchema *>(c_abi_schema));
+ if (garrow::check(error, arrow_field_result, "[field][import]")) {
+ return garrow_field_new_raw(&(*arrow_field_result), nullptr);
+ } else {
+ return NULL;
+ }
+}
+
+/**
+ * garrow_field_new:
+ * @name: The name of the field.
+ * @data_type: The data type of the field.
+ *
+ * Returns: A newly created #GArrowField.
+ */
+GArrowField *
+garrow_field_new(const gchar *name,
+ GArrowDataType *data_type)
+{
+ auto arrow_data_type = garrow_data_type_get_raw(data_type);
+ auto arrow_field = std::make_shared<arrow::Field>(name, arrow_data_type);
+ return garrow_field_new_raw(&arrow_field, data_type);
+}
+
+/**
+ * garrow_field_new_full:
+ * @name: The name of the field.
+ * @data_type: The data type of the field.
+ * @nullable: Whether null may be included or not.
+ *
+ * Returns: A newly created #GArrowField.
+ */
+GArrowField *
+garrow_field_new_full(const gchar *name,
+ GArrowDataType *data_type,
+ gboolean nullable)
+{
+ auto arrow_field =
+ std::make_shared<arrow::Field>(name,
+ garrow_data_type_get_raw(data_type),
+ nullable);
+ return garrow_field_new_raw(&arrow_field, data_type);
+}
+
+/**
+ * garrow_field_export:
+ * @field: A #GArrowField.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Returns: (transfer full) (nullable): An exported #GArrowField as
+ * `struct ArrowStruct *` on success, %NULL on error.
+ *
+ * It should be freed with the `ArrowSchema::release` callback then
+ * g_free() when no longer needed.
+ *
+ * Since: 6.0.0
+ */
+gpointer
+garrow_field_export(GArrowField *field, GError **error)
+{
+ const auto arrow_field = garrow_field_get_raw(field);
+ auto c_abi_schema = g_new(ArrowSchema, 1);
+ auto status = arrow::ExportField(*arrow_field, c_abi_schema);
+ if (garrow::check(error, status, "[field][export]")) {
+ return c_abi_schema;
+ } else {
+ g_free(c_abi_schema);
+ return NULL;
+ }
+}
+
+/**
+ * garrow_field_get_name:
+ * @field: A #GArrowField.
+ *
+ * Returns: The name of the field.
+ */
+const gchar *
+garrow_field_get_name(GArrowField *field)
+{
+ const auto arrow_field = garrow_field_get_raw(field);
+ return arrow_field->name().c_str();
+}
+
+/**
+ * garrow_field_get_data_type:
+ * @field: A #GArrowField.
+ *
+ * Returns: (transfer none): The data type of the field.
+ */
+GArrowDataType *
+garrow_field_get_data_type(GArrowField *field)
+{
+ auto priv = GARROW_FIELD_GET_PRIVATE(field);
+ return priv->data_type;
+}
+
+/**
+ * garrow_field_is_nullable:
+ * @field: A #GArrowField.
+ *
+ * Returns: Whether the filed may include null or not.
+ */
+gboolean
+garrow_field_is_nullable(GArrowField *field)
+{
+ const auto arrow_field = garrow_field_get_raw(field);
+ return arrow_field->nullable();
+}
+
+/**
+ * garrow_field_equal:
+ * @field: A #GArrowField.
+ * @other_field: A #GArrowField to be compared.
+ *
+ * Returns: %TRUE if both of them have the same data, %FALSE
+ * otherwise.
+ */
+gboolean
+garrow_field_equal(GArrowField *field,
+ GArrowField *other_field)
+{
+ const auto arrow_field = garrow_field_get_raw(field);
+ const auto arrow_other_field = garrow_field_get_raw(other_field);
+ return arrow_field->Equals(arrow_other_field);
+}
+
+/**
+ * garrow_field_to_string:
+ * @field: A #GArrowField.
+ *
+ * Returns: The string representation of the field.
+ */
+gchar *
+garrow_field_to_string(GArrowField *field)
+{
+ const auto arrow_field = garrow_field_get_raw(field);
+ return g_strdup(arrow_field->ToString().c_str());
+}
+
+/**
+ * garrow_field_to_string_metadata:
+ * @field: A #GArrowField.
+ * @show_metadata: Whether include metadata or not.
+ *
+ * Returns: The string representation of the field.
+ *
+ * It should be freed with g_free() when no longer needed.
+ *
+ * Since: 3.0.0
+ */
+gchar *
+garrow_field_to_string_metadata(GArrowField *field, gboolean show_metadata)
+{
+ const auto arrow_field = garrow_field_get_raw(field);
+ return g_strdup(arrow_field->ToString(show_metadata).c_str());
+}
+
+/**
+ * garrow_field_has_metadata:
+ * @field: A #GArrowField.
+ *
+ * Returns: %TRUE if the field has metadata, %FALSE otherwise.
+ *
+ * Since: 3.0.0
+ */
+gboolean
+garrow_field_has_metadata(GArrowField *field)
+{
+ const auto arrow_field = garrow_field_get_raw(field);
+ return arrow_field->HasMetadata();
+}
+
+/**
+ * garrow_field_get_metadata:
+ * @field: A #GArrowField.
+ *
+ * Returns: (element-type utf8 utf8) (nullable) (transfer full): The
+ * metadata in the field.
+ *
+ * It should be freed with g_hash_table_unref() when no longer needed.
+ *
+ * Since: 3.0.0
+ */
+GHashTable *
+garrow_field_get_metadata(GArrowField *field)
+{
+ const auto arrow_field = garrow_field_get_raw(field);
+ if (!arrow_field->HasMetadata()) {
+ return NULL;
+ }
+
+ auto arrow_metadata = arrow_field->metadata();
+ auto metadata = g_hash_table_new(g_str_hash, g_str_equal);
+ const auto n = arrow_metadata->size();
+ for (int64_t i = 0; i < n; ++i) {
+ g_hash_table_insert(metadata,
+ const_cast<gchar *>(arrow_metadata->key(i).c_str()),
+ const_cast<gchar *>(arrow_metadata->value(i).c_str()));
+ }
+ return metadata;
+}
+
+/**
+ * garrow_field_with_metadata:
+ * @field: A #GArrowField.
+ * @metadata: (element-type utf8 utf8): A new associated metadata.
+ *
+ * Returns: (transfer full): The new field with the given metadata.
+ *
+ * Since: 3.0.0
+ */
+GArrowField *
+garrow_field_with_metadata(GArrowField *field,
+ GHashTable *metadata)
+{
+ const auto arrow_field = garrow_field_get_raw(field);
+ auto arrow_metadata = garrow_internal_hash_table_to_metadata(metadata);
+ auto arrow_new_field = arrow_field->WithMetadata(arrow_metadata);
+ return garrow_field_new_raw(&arrow_new_field,
+ garrow_field_get_data_type(field));
+}
+
+/**
+ * garrow_field_with_merged_metadata:
+ * @field: A #GArrowField.
+ * @metadata: (element-type utf8 utf8): An additional associated metadata.
+ *
+ * Returns: (transfer full): The new field that also has the given
+ * metadata. If both of the existing metadata and the given metadata
+ * have the same keys, the values in the given metadata are used.
+ *
+ * Since: 3.0.0
+ */
+GArrowField *
+garrow_field_with_merged_metadata(GArrowField *field,
+ GHashTable *metadata)
+{
+ const auto arrow_field = garrow_field_get_raw(field);
+ auto arrow_metadata = garrow_internal_hash_table_to_metadata(metadata);
+ auto arrow_new_field = arrow_field->WithMergedMetadata(arrow_metadata);
+ return garrow_field_new_raw(&arrow_new_field,
+ garrow_field_get_data_type(field));
+}
+
+/**
+ * garrow_field_remove_metadata:
+ * @field: A #GArrowField.
+ *
+ * Returns: (transfer full): The new field that doesn't have metadata.
+ *
+ * Since: 3.0.0
+ */
+GArrowField *
+garrow_field_remove_metadata(GArrowField *field)
+{
+ const auto arrow_field = garrow_field_get_raw(field);
+ auto arrow_new_field = arrow_field->RemoveMetadata();
+ return garrow_field_new_raw(&arrow_new_field,
+ garrow_field_get_data_type(field));
+}
+
+G_END_DECLS
+
+GArrowField *
+garrow_field_new_raw(std::shared_ptr<arrow::Field> *arrow_field,
+ GArrowDataType *data_type)
+{
+ bool data_type_need_unref = false;
+ if (!data_type) {
+ auto arrow_data_type = (*arrow_field)->type();
+ data_type = garrow_data_type_new_raw(&arrow_data_type);
+ data_type_need_unref = true;
+ }
+ auto field = GARROW_FIELD(g_object_new(GARROW_TYPE_FIELD,
+ "field", arrow_field,
+ "data-type", data_type,
+ NULL));
+ if (data_type_need_unref) {
+ g_object_unref(data_type);
+ }
+ return field;
+}
+
+std::shared_ptr<arrow::Field>
+garrow_field_get_raw(GArrowField *field)
+{
+ auto priv = GARROW_FIELD_GET_PRIVATE(field);
+ return priv->field;
+}