/* * 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 #include #include #include #include #include #include #include #include #include #include G_BEGIN_DECLS /** * SECTION: table * @section_id: GArrowTable * @title: GArrowTable * @short_description: Table class * @include: arrow-glib/arrow-glib.h * * #GArrowTableConcatenateOptions is a class for customizing * garrow_table_concatenate() behavior. * * #GArrowTable is a class for table. Table has zero or more * #GArrowChunkedArrays and zero or more records. * * #GArrowFeatherWriteProperties is a class to customize how to write * Feather data. */ typedef struct GArrowTableConcatenateOptionsPrivate_ { arrow::ConcatenateTablesOptions options; } GArrowTableConcatenateOptionsPrivate; enum { PROP_UNIFY_SCHEMAS = 1, PROP_PROMOTE_NULLABILITY, }; G_DEFINE_TYPE_WITH_PRIVATE(GArrowTableConcatenateOptions, garrow_table_concatenate_options, G_TYPE_OBJECT) #define GARROW_TABLE_CONCATENATE_OPTIONS_GET_PRIVATE(obj) \ static_cast( \ garrow_table_concatenate_options_get_instance_private( \ GARROW_TABLE_CONCATENATE_OPTIONS(obj))) static void garrow_table_concatenate_options_finalize(GObject *object) { auto priv = GARROW_TABLE_CONCATENATE_OPTIONS_GET_PRIVATE(object); priv->options.~ConcatenateTablesOptions(); G_OBJECT_CLASS(garrow_table_concatenate_options_parent_class)->finalize(object); } static void garrow_table_concatenate_options_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { auto priv = GARROW_TABLE_CONCATENATE_OPTIONS_GET_PRIVATE(object); switch (prop_id) { case PROP_UNIFY_SCHEMAS: priv->options.unify_schemas = g_value_get_boolean(value); break; case PROP_PROMOTE_NULLABILITY: priv->options.field_merge_options.promote_nullability = g_value_get_boolean(value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; } } static void garrow_table_concatenate_options_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { auto priv = GARROW_TABLE_CONCATENATE_OPTIONS_GET_PRIVATE(object); switch (prop_id) { case PROP_UNIFY_SCHEMAS: g_value_set_boolean(value, priv->options.unify_schemas); break; case PROP_PROMOTE_NULLABILITY: g_value_set_boolean(value, priv->options.field_merge_options.promote_nullability); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; } } static void garrow_table_concatenate_options_init(GArrowTableConcatenateOptions *object) { auto priv = GARROW_TABLE_CONCATENATE_OPTIONS_GET_PRIVATE(object); new(&(priv->options)) arrow::ConcatenateTablesOptions; } static void garrow_table_concatenate_options_class_init( GArrowTableConcatenateOptionsClass *klass) { auto gobject_class = G_OBJECT_CLASS(klass); gobject_class->finalize = garrow_table_concatenate_options_finalize; gobject_class->set_property = garrow_table_concatenate_options_set_property; gobject_class->get_property = garrow_table_concatenate_options_get_property; GParamSpec *spec; auto default_options = arrow::ConcatenateTablesOptions::Defaults(); /** * GArrowTableConcatenateOptions:unify-schemas: * * If true, the schemas of the tables will be first unified with * fields of the same name being merged, according to * #GArrowTableConcatenateOptions:promote-nullability, then each * table will be promoted to the unified schema before being * concatenated. * * Otherwise, all tables should have the same schema. Each column in * the output table is the result of concatenating the corresponding * columns in all input tables. * * Since: 6.0.0 */ spec = g_param_spec_boolean("unify-schemas", "Unify schemas", "Whether unifying schemas or not", default_options.unify_schemas, static_cast(G_PARAM_READWRITE)); g_object_class_install_property(gobject_class, PROP_UNIFY_SCHEMAS, spec); /** * GArrowTableConcatenateOptions:promote-nullability: * * If true, a #GArrowField of #GArrowNullDataType can be unified * with a #GArrowField of another type. The unified field will be of * the other type and become nullable. Nullability will be promoted * to the looser option (nullable if one is not nullable). * * Since: 6.0.0 */ spec = g_param_spec_boolean("promote-nullability", "Promote nullability", "Whether promoting nullability or not", default_options.field_merge_options.promote_nullability, static_cast(G_PARAM_READWRITE)); g_object_class_install_property(gobject_class, PROP_PROMOTE_NULLABILITY, spec); } /** * garrow_table_concatenate_options_new: * * Returns: A newly created #GArrowTableConcatenateOptions. * * Since: 6.0.0 */ GArrowTableConcatenateOptions * garrow_table_concatenate_options_new(void) { return GARROW_TABLE_CONCATENATE_OPTIONS( g_object_new(GARROW_TYPE_TABLE_CONCATENATE_OPTIONS, NULL)); } typedef struct GArrowTablePrivate_ { std::shared_ptr table; } GArrowTablePrivate; enum { PROP_TABLE = 1, }; G_DEFINE_TYPE_WITH_PRIVATE(GArrowTable, garrow_table, G_TYPE_OBJECT) #define GARROW_TABLE_GET_PRIVATE(obj) \ static_cast( \ garrow_table_get_instance_private( \ GARROW_TABLE(obj))) static void garrow_table_finalize(GObject *object) { auto priv = GARROW_TABLE_GET_PRIVATE(object); priv->table.~shared_ptr(); G_OBJECT_CLASS(garrow_table_parent_class)->finalize(object); } static void garrow_table_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { auto priv = GARROW_TABLE_GET_PRIVATE(object); switch (prop_id) { case PROP_TABLE: priv->table = *static_cast *>(g_value_get_pointer(value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; } } static void garrow_table_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { switch (prop_id) { default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; } } static void garrow_table_init(GArrowTable *object) { auto priv = GARROW_TABLE_GET_PRIVATE(object); new(&priv->table) std::shared_ptr; } static void garrow_table_class_init(GArrowTableClass *klass) { GObjectClass *gobject_class; GParamSpec *spec; gobject_class = G_OBJECT_CLASS(klass); gobject_class->finalize = garrow_table_finalize; gobject_class->set_property = garrow_table_set_property; gobject_class->get_property = garrow_table_get_property; spec = g_param_spec_pointer("table", "Table", "The raw std::shared_ptr *", static_cast(G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property(gobject_class, PROP_TABLE, spec); } /** * garrow_table_new_values: (skip) * @schema: The schema of the table. * @values: The values of the table. All values must be instance of * the same class. Available classes are #GArrowChunkedArray, * #GArrowArray and #GArrowRecordBatch. * @error: (nullable): Return location for a #GError or %NULL. * * Returns: (nullable): A newly created #GArrowTable or %NULL on error. * * Since: 0.12.0 */ GArrowTable * garrow_table_new_values(GArrowSchema *schema, GList *values, GError **error) { const auto context = "[table][new][values]"; auto arrow_schema = garrow_schema_get_raw(schema); std::vector> arrow_chunked_arrays; std::vector> arrow_arrays; std::vector> arrow_record_batches; for (GList *node = values; node; node = node->next) { if (GARROW_IS_CHUNKED_ARRAY(node->data)) { auto chunked_array = GARROW_CHUNKED_ARRAY(node->data); arrow_chunked_arrays.push_back(garrow_chunked_array_get_raw(chunked_array)); } else if (GARROW_IS_ARRAY(node->data)) { auto array = GARROW_ARRAY(node->data); arrow_arrays.push_back(garrow_array_get_raw(array)); } else if (GARROW_IS_RECORD_BATCH(node->data)) { auto record_batch = GARROW_RECORD_BATCH(node->data); arrow_record_batches.push_back(garrow_record_batch_get_raw(record_batch)); } else { g_set_error(error, GARROW_ERROR, GARROW_ERROR_INVALID, "%s: %s", context, "value must be one of " "GArrowChunkedArray, GArrowArray and GArrowRecordBatch"); return NULL; } } size_t n_types = 0; if (!arrow_chunked_arrays.empty()) { ++n_types; } if (!arrow_arrays.empty()) { ++n_types; } if (!arrow_record_batches.empty()) { ++n_types; } if (n_types > 1) { g_set_error(error, GARROW_ERROR, GARROW_ERROR_INVALID, "%s: %s", context, "all values must be the same objects of " "GArrowChunkedArray, GArrowArray or GArrowRecordBatch"); return NULL; } if (!arrow_chunked_arrays.empty()) { auto arrow_table = arrow::Table::Make(arrow_schema, std::move(arrow_chunked_arrays)); auto status = arrow_table->Validate(); if (garrow_error_check(error, status, context)) { return garrow_table_new_raw(&arrow_table); } else { return NULL; } } else if (!arrow_arrays.empty()) { auto arrow_table = arrow::Table::Make(arrow_schema, std::move(arrow_arrays)); auto status = arrow_table->Validate(); if (garrow_error_check(error, status, context)) { return garrow_table_new_raw(&arrow_table); } else { return NULL; } } else { auto maybe_table = arrow::Table::FromRecordBatches( arrow_schema, std::move(arrow_record_batches)); if (garrow::check(error, maybe_table, context)) { return garrow_table_new_raw(&(*maybe_table)); } else { return NULL; } } } /** * garrow_table_new_chunked_arrays: * @schema: The schema of the table. * @chunked_arrays: (array length=n_chunked_arrays): The chunked arrays of * the table. * @n_chunked_arrays: The number of chunked arrays. * @error: (nullable): Return location for a #GError or %NULL. * * Returns: (nullable): A newly created #GArrowTable or %NULL on error. * * Since: 0.15.0 */ GArrowTable * garrow_table_new_chunked_arrays(GArrowSchema *schema, GArrowChunkedArray **chunked_arrays, gsize n_chunked_arrays, GError **error) { auto arrow_schema = garrow_schema_get_raw(schema); std::vector> arrow_chunked_arrays; for (gsize i = 0; i < n_chunked_arrays; ++i) { auto arrow_chunked_array = garrow_chunked_array_get_raw(chunked_arrays[i]); arrow_chunked_arrays.push_back(arrow_chunked_array); } auto arrow_table = arrow::Table::Make(arrow_schema, arrow_chunked_arrays); auto status = arrow_table->Validate(); if (garrow_error_check(error, status, "[table][new][chunked-arrays]")) { return garrow_table_new_raw(&arrow_table); } else { return NULL; } } /** * garrow_table_new_arrays: * @schema: The schema of the table. * @arrays: (array length=n_arrays): The arrays of the table. * @n_arrays: The number of arrays. * @error: (nullable): Return location for a #GError or %NULL. * * Returns: (nullable): A newly created #GArrowTable or %NULL on error. * * Since: 0.12.0 */ GArrowTable * garrow_table_new_arrays(GArrowSchema *schema, GArrowArray **arrays, gsize n_arrays, GError **error) { auto arrow_schema = garrow_schema_get_raw(schema); std::vector> arrow_arrays; for (gsize i = 0; i < n_arrays; ++i) { arrow_arrays.push_back(garrow_array_get_raw(arrays[i])); } auto arrow_table = arrow::Table::Make(arrow_schema, arrow_arrays); auto status = arrow_table->Validate(); if (garrow_error_check(error, status, "[table][new][arrays]")) { return garrow_table_new_raw(&arrow_table); } else { return NULL; } } /** * garrow_table_new_record_batches: * @schema: The schema of the table. * @record_batches: (array length=n_record_batches): The record batches * that have data for the table. * @n_record_batches: The number of record batches. * @error: (nullable): Return location for a #GError or %NULL. * * Returns: (nullable): A newly created #GArrowTable or %NULL on error. * * Since: 0.12.0 */ GArrowTable * garrow_table_new_record_batches(GArrowSchema *schema, GArrowRecordBatch **record_batches, gsize n_record_batches, GError **error) { auto arrow_schema = garrow_schema_get_raw(schema); std::vector> arrow_record_batches; for (gsize i = 0; i < n_record_batches; ++i) { auto arrow_record_batch = garrow_record_batch_get_raw(record_batches[i]); arrow_record_batches.push_back(arrow_record_batch); } auto maybe_table = arrow::Table::FromRecordBatches(arrow_schema, arrow_record_batches); if (garrow::check(error, maybe_table, "[table][new][record-batches]")) { return garrow_table_new_raw(&(*maybe_table)); } else { return NULL; } } /** * garrow_table_equal: * @table: A #GArrowTable. * @other_table: A #GArrowTable to be compared. * * Returns: %TRUE if both of them have the same data, %FALSE * otherwise. * * Since: 0.4.0 */ gboolean garrow_table_equal(GArrowTable *table, GArrowTable *other_table) { const auto arrow_table = garrow_table_get_raw(table); const auto arrow_other_table = garrow_table_get_raw(other_table); return arrow_table->Equals(*arrow_other_table); } /** * garrow_table_equal_metadata: * @table: A #GArrowTable. * @other_table: A #GArrowTable to be compared. * @check_metadata: Whether to compare metadata. * * Returns: %TRUE if both of them have the same data, %FALSE * otherwise. * * Since: 0.17.0 */ gboolean garrow_table_equal_metadata(GArrowTable *table, GArrowTable *other_table, gboolean check_metadata) { const auto arrow_table = garrow_table_get_raw(table); const auto arrow_other_table = garrow_table_get_raw(other_table); return arrow_table->Equals(*arrow_other_table, check_metadata); } /** * garrow_table_get_schema: * @table: A #GArrowTable. * * Returns: (transfer full): The schema of the table. */ GArrowSchema * garrow_table_get_schema(GArrowTable *table) { const auto arrow_table = garrow_table_get_raw(table); auto arrow_schema = arrow_table->schema(); return garrow_schema_new_raw(&arrow_schema); } /** * garrow_table_get_column_data: * @table: A #GArrowTable. * @i: The index of the target column. If it's negative, index is * counted backward from the end of the columns. `-1` means the last * column. * * Returns: (nullable) (transfer full): The i-th column's data in the table. * * Since: 0.15.0 */ GArrowChunkedArray * garrow_table_get_column_data(GArrowTable *table, gint i) { const auto &arrow_table = garrow_table_get_raw(table); if (!garrow_internal_index_adjust(i, arrow_table->num_columns())) { return NULL; } auto arrow_column = arrow_table->column(i); return garrow_chunked_array_new_raw(&arrow_column); } /** * garrow_table_get_n_columns: * @table: A #GArrowTable. * * Returns: The number of columns in the table. */ guint garrow_table_get_n_columns(GArrowTable *table) { const auto arrow_table = garrow_table_get_raw(table); return arrow_table->num_columns(); } /** * garrow_table_get_n_rows: * @table: A #GArrowTable. * * Returns: The number of rows in the table. */ guint64 garrow_table_get_n_rows(GArrowTable *table) { const auto arrow_table = garrow_table_get_raw(table); return arrow_table->num_rows(); } /** * garrow_table_add_column: * @table: A #GArrowTable. * @i: The index of the new column. * @field: The field for the column to be added. * @chunked_array: The column data to be added. * @error: (nullable): Return location for a #GError or %NULL. * * Returns: (nullable) (transfer full): The newly allocated * #GArrowTable that has a new column or %NULL on error. * * Since: 0.15.0 */ GArrowTable * garrow_table_add_column(GArrowTable *table, guint i, GArrowField *field, GArrowChunkedArray *chunked_array, GError **error) { const auto arrow_table = garrow_table_get_raw(table); const auto arrow_field = garrow_field_get_raw(field); const auto arrow_chunked_array = garrow_chunked_array_get_raw(chunked_array); auto maybe_new_table = arrow_table->AddColumn(i, arrow_field, arrow_chunked_array); if (garrow::check(error, maybe_new_table, "[table][add-column]")) { return garrow_table_new_raw(&(*maybe_new_table)); } else { return NULL; } } /** * garrow_table_remove_column: * @table: A #GArrowTable. * @i: The index of the column to be removed. * @error: (nullable): Return location for a #GError or %NULL. * * Returns: (nullable) (transfer full): The newly allocated * #GArrowTable that doesn't have the column or %NULL on error. * * Since: 0.3.0 */ GArrowTable * garrow_table_remove_column(GArrowTable *table, guint i, GError **error) { const auto arrow_table = garrow_table_get_raw(table); auto maybe_new_table = arrow_table->RemoveColumn(i); if (garrow::check(error, maybe_new_table, "[table][remove-column]")) { return garrow_table_new_raw(&(*maybe_new_table)); } else { return NULL; } } /** * garrow_table_replace_column: * @table: A #GArrowTable. * @i: The index of the column to be replaced. * @field: The field for the new column. * @chunked_array: The newly added column data. * @error: (nullable): Return location for a #GError or %NULL. * * Returns: (nullable) (transfer full): The newly allocated * #GArrowTable that has @column as the @i-th column or %NULL on * error. * * Since: 0.15.0 */ GArrowTable * garrow_table_replace_column(GArrowTable *table, guint i, GArrowField *field, GArrowChunkedArray *chunked_array, GError **error) { const auto arrow_table = garrow_table_get_raw(table); const auto arrow_field = garrow_field_get_raw(field); const auto arrow_chunked_array = garrow_chunked_array_get_raw(chunked_array); auto maybe_new_table = arrow_table->SetColumn(i, arrow_field, arrow_chunked_array); if (garrow::check(error, maybe_new_table, "[table][replace-column]")) { return garrow_table_new_raw(&(*maybe_new_table)); } else { return NULL; } } /** * garrow_table_to_string: * @table: A #GArrowTable. * @error: (nullable): Return location for a #GError or %NULL. * * Returns: (nullable): * The formatted table content or %NULL on error. * * It should be freed with g_free() when no longer needed. * * Since: 0.12.0 */ gchar * garrow_table_to_string(GArrowTable *table, GError **error) { const auto arrow_table = garrow_table_get_raw(table); return g_strdup(arrow_table->ToString().c_str()); } /** * garrow_table_concatenate: * @table: A #GArrowTable. * @other_tables: (element-type GArrowTable): The tables to be concatenated. * @options: (nullable): The options to customize concatenation. * @error: (nullable): Return location for a #GError or %NULL. * * Returns: (nullable) (transfer full): The table concatenated vertically. * * Since: 0.14.0 */ GArrowTable * garrow_table_concatenate(GArrowTable *table, GList *other_tables, GArrowTableConcatenateOptions *options, GError **error) { auto arrow_table = garrow_table_get_raw(table); std::vector> arrow_tables = { arrow_table }; for (auto node = other_tables; node; node = g_list_next(node)) { auto arrow_other_table = garrow_table_get_raw(GARROW_TABLE(node->data)); arrow_tables.push_back(arrow_other_table); } auto arrow_options = arrow::ConcatenateTablesOptions::Defaults(); if (options) { auto options_priv = GARROW_TABLE_CONCATENATE_OPTIONS_GET_PRIVATE(options); arrow_options = options_priv->options; } auto arrow_concatenated_table_result = arrow::ConcatenateTables(arrow_tables, arrow_options); if (garrow::check(error, arrow_concatenated_table_result, "[table][concatenate]")) { auto arrow_concatenated_table = std::move(*arrow_concatenated_table_result); return garrow_table_new_raw(&arrow_concatenated_table); } else { return NULL; } } /** * garrow_table_slice: * @table: A #GArrowTable. * @offset: The offset of sub #GArrowTable. If the offset is negative, * the offset is counted from the last. * @length: The length of sub #GArrowTable. * * Returns: (transfer full): The sub #GArrowTable. It covers * only from `offset` to `offset + length` range. The sub * #GArrowTable shares values with the base * #GArrowTable. * * Since: 0.14.0 */ GArrowTable * garrow_table_slice(GArrowTable *table, gint64 offset, gint64 length) { const auto arrow_table = garrow_table_get_raw(table); if (offset < 0) { offset += arrow_table->num_rows(); } auto arrow_sub_table = arrow_table->Slice(offset, length); return garrow_table_new_raw(&arrow_sub_table); } /** * garrow_table_combine_chunks: * @table: A #GArrowTable. * @error: (nullable): Return location for a #GError or %NULL. * * Returns: (nullable) (transfer full): The #GArrowTable with * chunks combined, or %NULL on error. * * Since: 0.16.0 */ GArrowTable * garrow_table_combine_chunks(GArrowTable *table, GError **error) { const auto arrow_table = garrow_table_get_raw(table); auto maybe_new_table = arrow_table->CombineChunks(); if (garrow::check(error, maybe_new_table, "[table][combine-chunks]")) { return garrow_table_new_raw(&(*maybe_new_table)); } else { return NULL; } } typedef struct GArrowFeatherWritePropertiesPrivate_ { arrow::ipc::feather::WriteProperties properties; } GArrowFeatherWritePropertiesPrivate; enum { PROP_VERSION = 1, PROP_CHUNK_SIZE, PROP_COMPRESSION, PROP_COMPRESSION_LEVEL, }; G_DEFINE_TYPE_WITH_PRIVATE(GArrowFeatherWriteProperties, garrow_feather_write_properties, G_TYPE_OBJECT) #define GARROW_FEATHER_WRITE_PROPERTIES_GET_PRIVATE(obj) \ static_cast( \ garrow_feather_write_properties_get_instance_private( \ GARROW_FEATHER_WRITE_PROPERTIES(obj))) static void garrow_feather_write_properties_finalize(GObject *object) { auto priv = GARROW_FEATHER_WRITE_PROPERTIES_GET_PRIVATE(object); priv->properties.~WriteProperties(); G_OBJECT_CLASS(garrow_feather_write_properties_parent_class)->finalize(object); } static void garrow_feather_write_properties_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { auto priv = GARROW_FEATHER_WRITE_PROPERTIES_GET_PRIVATE(object); switch (prop_id) { case PROP_COMPRESSION: priv->properties.compression = static_cast(g_value_get_enum(value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; } } static void garrow_feather_write_properties_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { auto priv = GARROW_FEATHER_WRITE_PROPERTIES_GET_PRIVATE(object); switch (prop_id) { case PROP_COMPRESSION: g_value_set_enum(value, priv->properties.compression); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; } } static void garrow_feather_write_properties_init(GArrowFeatherWriteProperties *object) { auto priv = GARROW_FEATHER_WRITE_PROPERTIES_GET_PRIVATE(object); new(&priv->properties) arrow::ipc::feather::WriteProperties; priv->properties = arrow::ipc::feather::WriteProperties::Defaults(); } static void garrow_feather_write_properties_class_init(GArrowFeatherWritePropertiesClass *klass) { auto gobject_class = G_OBJECT_CLASS(klass); gobject_class->finalize = garrow_feather_write_properties_finalize; gobject_class->set_property = garrow_feather_write_properties_set_property; gobject_class->get_property = garrow_feather_write_properties_get_property; auto properties = arrow::ipc::feather::WriteProperties::Defaults(); GParamSpec *spec; // TODO: version // TODO: chunk_size /** * GArrowFeatherWriteProperties:compression: * * Compression type to use. Only * %GARROW_COMPRESSION_TYPE_UNCOMPRESSED, * %GARROW_COMPRESSION_TYPE_LZ4 and %GARROW_COMPRESSION_TYPE_ZSTD * are supported. The default compression is * %GARROW_COMPRESSION_TYPE_LZ4 if Apache Arrow C++ is built with * support for it, otherwise %GARROW_COMPRESSION_TYPE_UNCOMPRESSED. * %GARROW_COMPRESSION_TYPE_UNCOMPRESSED is set as the object * default here. * * Since: 0.17.0 */ spec = g_param_spec_enum("compression", "Compression", "The compression type to use", GARROW_TYPE_COMPRESSION_TYPE, properties.compression, static_cast(G_PARAM_READWRITE)); g_object_class_install_property(gobject_class, PROP_COMPRESSION, spec); // TODO: compression_level } /** * garrow_feather_write_properties_new: * * Returns: A newly created #GArrowFeatherWriteProperties. * * Since: 0.17.0 */ GArrowFeatherWriteProperties * garrow_feather_write_properties_new(void) { auto properties = g_object_new(GARROW_TYPE_FEATHER_WRITE_PROPERTIES, NULL); return GARROW_FEATHER_WRITE_PROPERTIES(properties); } /** * garrow_table_write_as_feather: * @table: A #GArrowTable. * @sink: The output. * @properties: (nullable): The properties for this write. * @error: (nullable): Return location for a #GError or %NULL. * * Writes the @table as Feather format data to the @sink. * * Returns: %TRUE on success, %FALSE if there was an error. * * Since: 0.17.0 */ gboolean garrow_table_write_as_feather(GArrowTable *table, GArrowOutputStream *sink, GArrowFeatherWriteProperties *properties, GError **error) { auto arrow_table = garrow_table_get_raw(table); auto arrow_sink = garrow_output_stream_get_raw(sink); arrow::Status status; if (properties) { auto arrow_properties = garrow_feather_write_properties_get_raw(properties); status = arrow::ipc::feather::WriteTable(*arrow_table, arrow_sink.get(), *arrow_properties); } else { status = arrow::ipc::feather::WriteTable(*arrow_table, arrow_sink.get()); } return garrow::check(error, status, "[feather-write-file]"); } G_END_DECLS GArrowTable * garrow_table_new_raw(std::shared_ptr *arrow_table) { auto table = GARROW_TABLE(g_object_new(GARROW_TYPE_TABLE, "table", arrow_table, NULL)); return table; } std::shared_ptr garrow_table_get_raw(GArrowTable *table) { auto priv = GARROW_TABLE_GET_PRIVATE(table); return priv->table; } arrow::ipc::feather::WriteProperties * garrow_feather_write_properties_get_raw(GArrowFeatherWriteProperties *properties) { auto priv = GARROW_FEATHER_WRITE_PROPERTIES_GET_PRIVATE(properties); return &(priv->properties); }