blob: 2c2c36e74bb4c16b49327087eb5b61058e42d368 [file] [log] [blame]
/*
* 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/enums.h>
#include <arrow-glib/error.hpp>
#include <arrow-glib/file-system.hpp>
#include <arrow-glib/input-stream.hpp>
#include <arrow-glib/local-file-system.h>
#include <arrow-glib/output-stream.hpp>
G_BEGIN_DECLS
/**
* SECTION: file-system
* @section_id: file-system-classes
* @title: File system classes
* @include: arrow-glib/arrow-glib.h
*
* #GArrowFileInfo is a class for information for a file system entry.
*
* #GArrowFileSelector is a class for a selector for file system APIs.
*
* #GArrowFileSystem is an interface for file system.
*
* #GArrowSubTreeFileSystem is a delegator to another file system that is
* a logical view of a subtree of a file system, such as a directory in
* a local file system.
*
* #GArrowSlowFileSystem is a delegator to another file system.
* This inserts latencies at various points.
*
* #GArrowMockFileSystem is a class for mock file system that holds
* its contents in memory.
*
* #GArrowHDFSFileSystem is a class for HDFS-backed file system.
*
* #GArrowS3FileSystem is a class for S3-backed file system.
*/
/* arrow::fs::FileInfo */
typedef struct GArrowFileInfoPrivate_ {
arrow::fs::FileInfo file_info;
} GArrowFileInfoPrivate;
enum {
PROP_FILE_INFO_TYPE = 1,
PROP_FILE_INFO_PATH,
PROP_FILE_INFO_BASE_NAME,
PROP_FILE_INFO_DIR_NAME,
PROP_FILE_INFO_EXTENSION,
PROP_FILE_INFO_SIZE,
PROP_FILE_INFO_MTIME,
};
G_DEFINE_TYPE_WITH_PRIVATE(GArrowFileInfo, garrow_file_info, G_TYPE_OBJECT)
#define GARROW_FILE_INFO_GET_PRIVATE(obj) \
static_cast<GArrowFileInfoPrivate *>( \
garrow_file_info_get_instance_private( \
GARROW_FILE_INFO(obj)))
static void
garrow_file_info_finalize(GObject *object)
{
auto priv = GARROW_FILE_INFO_GET_PRIVATE(object);
priv->file_info.~FileInfo();
G_OBJECT_CLASS(garrow_file_info_parent_class)->finalize(object);
}
static void
garrow_file_info_set_property(GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
auto arrow_file_info = garrow_file_info_get_raw(GARROW_FILE_INFO(object));
switch (prop_id) {
case PROP_FILE_INFO_TYPE:
{
auto arrow_file_type =
static_cast<arrow::fs::FileType>(g_value_get_enum(value));
arrow_file_info->set_type(arrow_file_type);
}
break;
case PROP_FILE_INFO_PATH:
arrow_file_info->set_path(g_value_get_string(value));
break;
case PROP_FILE_INFO_SIZE:
arrow_file_info->set_size(g_value_get_int64(value));
break;
case PROP_FILE_INFO_MTIME:
{
const gint64 mtime = g_value_get_int64(value);
const arrow::fs::TimePoint::duration duration(mtime);
arrow_file_info->set_mtime(arrow::fs::TimePoint(duration));
}
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
}
}
static void
garrow_file_info_get_property(GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
const auto arrow_file_info =
garrow_file_info_get_raw(GARROW_FILE_INFO(object));
switch (prop_id) {
case PROP_FILE_INFO_TYPE:
{
const auto arrow_file_type = arrow_file_info->type();
const auto file_type = static_cast<GArrowFileType>(arrow_file_type);
g_value_set_enum(value, file_type);
}
break;
case PROP_FILE_INFO_PATH:
g_value_set_string(value, arrow_file_info->path().c_str());
break;
case PROP_FILE_INFO_BASE_NAME:
g_value_set_string(value, arrow_file_info->base_name().c_str());
break;
case PROP_FILE_INFO_DIR_NAME:
g_value_set_string(value, arrow_file_info->dir_name().c_str());
break;
case PROP_FILE_INFO_EXTENSION:
g_value_set_string(value, arrow_file_info->extension().c_str());
break;
case PROP_FILE_INFO_SIZE:
g_value_set_int64(value, arrow_file_info->size());
break;
case PROP_FILE_INFO_MTIME:
{
const auto arrow_mtime = arrow_file_info->mtime();
const auto mtime = arrow_mtime.time_since_epoch().count();
g_value_set_int64(value, mtime);
}
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
}
}
static void
garrow_file_info_init(GArrowFileInfo *object)
{
auto priv = GARROW_FILE_INFO_GET_PRIVATE(object);
new(&priv->file_info) arrow::fs::FileInfo;
}
static void
garrow_file_info_class_init(GArrowFileInfoClass *klass)
{
GParamSpec *spec;
auto gobject_class = G_OBJECT_CLASS(klass);
gobject_class->finalize = garrow_file_info_finalize;
gobject_class->set_property = garrow_file_info_set_property;
gobject_class->get_property = garrow_file_info_get_property;
auto info = arrow::fs::FileInfo();
/**
* GArrowFileInfo:type:
*
* The type of the entry.
*
* Since: 0.17.0
*/
spec = g_param_spec_enum("type",
"Type",
"The type of the entry",
GARROW_TYPE_FILE_TYPE,
GARROW_FILE_TYPE_UNKNOWN,
static_cast<GParamFlags>(G_PARAM_READWRITE));
g_object_class_install_property(gobject_class, PROP_FILE_INFO_TYPE, spec);
/**
* GArrowFileInfo:path:
*
* The full file path in the file system.
*
* Since: 0.17.0
*/
spec = g_param_spec_string("path",
"Path",
"The full file path",
info.path().c_str(),
static_cast<GParamFlags>(G_PARAM_READWRITE));
g_object_class_install_property(gobject_class, PROP_FILE_INFO_PATH, spec);
/**
* GArrowFileInfo:base-name:
*
* The file base name (component after the last directory separator).
*
* Since: 0.17.0
*/
spec = g_param_spec_string("base-name",
"Base name",
"The file base name",
info.base_name().c_str(),
static_cast<GParamFlags>(G_PARAM_READABLE));
g_object_class_install_property(gobject_class,
PROP_FILE_INFO_BASE_NAME,
spec);
/**
* GArrowFileInfo:dir-name:
*
* The directory base name (component before the file base name).
*
* Since: 0.17.0
*/
spec = g_param_spec_string("dir-name",
"Directory name",
"The directory base name",
info.dir_name().c_str(),
static_cast<GParamFlags>(G_PARAM_READABLE));
g_object_class_install_property(gobject_class,
PROP_FILE_INFO_DIR_NAME,
spec);
/**
* GArrowFileInfo:extension:
*
* The file extension (excluding the dot).
*
* Since: 0.17.0
*/
spec = g_param_spec_string("extension",
"Extension",
"The file extension",
info.extension().c_str(),
static_cast<GParamFlags>(G_PARAM_READABLE));
g_object_class_install_property(gobject_class,
PROP_FILE_INFO_EXTENSION,
spec);
/**
* GArrowFileInfo:size:
*
* The size in bytes, if available
* Only regular files are guaranteed to have a size.
*
* Since: 0.17.0
*/
spec = g_param_spec_int64("size",
"Size",
"The size in bytes",
arrow::fs::kNoSize,
INT64_MAX,
info.size(),
static_cast<GParamFlags>(G_PARAM_READWRITE));
g_object_class_install_property(gobject_class, PROP_FILE_INFO_SIZE, spec);
/**
* GArrowFileInfo:mtime:
*
* The time of last modification, if available.
*
* Since: 0.17.0
*/
spec = g_param_spec_int64("mtime",
"Last modified time",
"The time of last modification",
arrow::fs::kNoTime.time_since_epoch().count(),
INT64_MAX,
info.mtime().time_since_epoch().count(),
static_cast<GParamFlags>(G_PARAM_READWRITE));
g_object_class_install_property(gobject_class, PROP_FILE_INFO_MTIME, spec);
}
/**
* garrow_file_info_new:
*
* Returns: A newly created #GArrowFileInfo.
*
* Since: 0.17.0
*/
GArrowFileInfo *
garrow_file_info_new(void)
{
return GARROW_FILE_INFO(g_object_new(GARROW_TYPE_FILE_INFO, NULL));
}
/**
* garrow_file_info_equal:
* @file_info: A #GArrowFileInfo.
* @other_file_info: A #GArrowFileInfo to be compared.
*
* Returns: %TRUE if both of them have the same data, %FALSE
* otherwise.
*
* Since: 0.17.0
*/
gboolean
garrow_file_info_equal(GArrowFileInfo *file_info,
GArrowFileInfo *other_file_info)
{
const auto arrow_file_info = garrow_file_info_get_raw(file_info);
const auto arrow_other_file_info = garrow_file_info_get_raw(other_file_info);
return arrow_file_info->Equals(*arrow_other_file_info);
}
/**
* garrow_file_info_is_file:
* @file_info: A #GArrowFileInfo.
*
* Returns: %TRUE if the entry is a file, %FALSE otherwise.
*
* Since: 0.17.0
*/
gboolean
garrow_file_info_is_file(GArrowFileInfo *file_info)
{
const auto arrow_file_info = garrow_file_info_get_raw(file_info);
return arrow_file_info->IsFile();
}
/**
* garrow_file_info_is_dir
* @file_info: A #GArrowFileInfo.
*
* Returns: %TRUE if the entry is a directory, %FALSE otherwise.
*
* Since: 0.17.0
*/
gboolean
garrow_file_info_is_dir(GArrowFileInfo *file_info)
{
const auto arrow_file_info = garrow_file_info_get_raw(file_info);
return arrow_file_info->IsDirectory();
}
/**
* garrow_file_info_to_string:
* @file_info: A #GArrowFileInfo.
*
* Returns: The string representation of the file statistics.
*
* It should be freed with g_free() when no longer needed.
*
* Since: 0.17.0
*/
gchar *
garrow_file_info_to_string(GArrowFileInfo *file_info)
{
const auto arrow_file_info = garrow_file_info_get_raw(file_info);
return g_strdup(arrow_file_info->ToString().c_str());
}
/* arrow::fs::FileSelector */
typedef struct GArrowFileSelectorPrivate_ {
arrow::fs::FileSelector file_selector;
} GArrowFileSelectorPrivate;
enum {
PROP_FILE_SELECTOR_BASE_DIR = 1,
PROP_FILE_SELECTOR_ALLOW_NOT_FOUND,
PROP_FILE_SELECTOR_RECURSIVE,
PROP_FILE_SELECTOR_MAX_RECURSION
};
G_DEFINE_TYPE_WITH_PRIVATE(GArrowFileSelector, garrow_file_selector, G_TYPE_OBJECT)
#define GARROW_FILE_SELECTOR_GET_PRIVATE(obj) \
static_cast<GArrowFileSelectorPrivate *>( \
garrow_file_selector_get_instance_private( \
GARROW_FILE_SELECTOR(obj)))
static void
garrow_file_selector_finalize(GObject *object)
{
auto priv = GARROW_FILE_SELECTOR_GET_PRIVATE(object);
priv->file_selector.~FileSelector();
G_OBJECT_CLASS(garrow_file_selector_parent_class)->finalize(object);
}
static void
garrow_file_selector_set_property(GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
auto priv = GARROW_FILE_SELECTOR_GET_PRIVATE(object);
switch (prop_id) {
case PROP_FILE_SELECTOR_BASE_DIR:
priv->file_selector.base_dir = g_value_get_string(value);
break;
case PROP_FILE_SELECTOR_ALLOW_NOT_FOUND:
priv->file_selector.allow_not_found = g_value_get_boolean(value);
break;
case PROP_FILE_SELECTOR_RECURSIVE:
priv->file_selector.recursive = g_value_get_boolean(value);
break;
case PROP_FILE_SELECTOR_MAX_RECURSION:
priv->file_selector.max_recursion = g_value_get_int(value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
}
}
static void
garrow_file_selector_get_property(GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
auto priv = GARROW_FILE_SELECTOR_GET_PRIVATE(object);
switch (prop_id) {
case PROP_FILE_SELECTOR_BASE_DIR:
g_value_set_string(value, priv->file_selector.base_dir.c_str());
break;
case PROP_FILE_SELECTOR_ALLOW_NOT_FOUND:
g_value_set_boolean(value, priv->file_selector.allow_not_found);
break;
case PROP_FILE_SELECTOR_RECURSIVE:
g_value_set_boolean(value, priv->file_selector.recursive);
break;
case PROP_FILE_SELECTOR_MAX_RECURSION:
g_value_set_int(value, priv->file_selector.max_recursion);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
}
}
static void
garrow_file_selector_init(GArrowFileSelector *object)
{
auto priv = GARROW_FILE_SELECTOR_GET_PRIVATE(object);
new(&priv->file_selector) arrow::fs::FileSelector;
}
static void
garrow_file_selector_class_init(GArrowFileSelectorClass *klass)
{
GParamSpec *spec;
auto gobject_class = G_OBJECT_CLASS(klass);
gobject_class->finalize = garrow_file_selector_finalize;
gobject_class->set_property = garrow_file_selector_set_property;
gobject_class->get_property = garrow_file_selector_get_property;
auto file_selector = arrow::fs::FileSelector();
/**
* GArrowFileSelector:base-dir:
*
* The directory in which to select files.
* If the path exists but doesn't point to a directory, this should
* be an error.
*
* Since: 0.17.0
*/
spec = g_param_spec_string("base-dir",
"Base dir",
"The directory in which to select files",
file_selector.base_dir.c_str(),
static_cast<GParamFlags>(G_PARAM_READWRITE));
g_object_class_install_property(gobject_class,
PROP_FILE_SELECTOR_BASE_DIR,
spec);
/**
* GArrowFileSelector:allow-not-found:
*
* The behavior if `base_dir` isn't found in the file system.
* If false, an error is returned. If true, an empty selection is returned.
*
* Since: 0.17.0
*/
spec = g_param_spec_boolean("allow-not-found",
"Allow not found",
"The behavior if `base_dir` isn't found in the file system",
file_selector.allow_not_found,
static_cast<GParamFlags>(G_PARAM_READWRITE));
g_object_class_install_property(gobject_class,
PROP_FILE_SELECTOR_ALLOW_NOT_FOUND,
spec);
/**
* GArrowFileSelector:recursive:
*
* Whether to recurse into subdirectories.
*
* Since: 0.17.0
*/
spec = g_param_spec_boolean("recursive",
"Recursive",
"Whether to recurse into subdirectories",
file_selector.recursive,
static_cast<GParamFlags>(G_PARAM_READWRITE));
g_object_class_install_property(gobject_class,
PROP_FILE_SELECTOR_RECURSIVE,
spec);
/**
* GArrowFileSelector:max-recursion:
*
* The maximum number of subdirectories to recurse into.
*
* Since: 0.17.0
*/
spec = g_param_spec_int("max-recursion",
"Max recursion",
"The maximum number of subdirectories to recurse into",
0,
INT32_MAX,
file_selector.max_recursion,
static_cast<GParamFlags>(G_PARAM_READWRITE));
g_object_class_install_property(gobject_class,
PROP_FILE_SELECTOR_MAX_RECURSION,
spec);
}
/* arrow::fs::FileSystem */
typedef struct GArrowFileSystemPrivate_ {
std::shared_ptr<arrow::fs::FileSystem> file_system;
} GArrowFileSystemPrivate;
enum {
PROP_FILE_SYSTEM = 1
};
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE(GArrowFileSystem,
garrow_file_system,
G_TYPE_OBJECT)
#define GARROW_FILE_SYSTEM_GET_PRIVATE(obj) \
static_cast<GArrowFileSystemPrivate *>( \
garrow_file_system_get_instance_private( \
GARROW_FILE_SYSTEM(obj)))
static void
garrow_file_system_finalize(GObject *object)
{
auto priv = GARROW_FILE_SYSTEM_GET_PRIVATE(object);
priv->file_system.~shared_ptr();
G_OBJECT_CLASS(garrow_file_system_parent_class)->finalize(object);
}
static void
garrow_file_system_set_property(GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
auto priv = GARROW_FILE_SYSTEM_GET_PRIVATE(object);
switch (prop_id) {
case PROP_FILE_SYSTEM:
priv->file_system =
*static_cast<std::shared_ptr<arrow::fs::FileSystem> *>(g_value_get_pointer(value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
}
}
static void
garrow_file_system_init(GArrowFileSystem *object)
{
auto priv = GARROW_FILE_SYSTEM_GET_PRIVATE(object);
new(&priv->file_system) std::shared_ptr<arrow::fs::FileSystem>;
}
static void
garrow_file_system_class_init(GArrowFileSystemClass *klass)
{
GParamSpec *spec;
auto gobject_class = G_OBJECT_CLASS(klass);
gobject_class->finalize = garrow_file_system_finalize;
gobject_class->set_property = garrow_file_system_set_property;
spec = g_param_spec_pointer("file-system",
"FileSystem",
"The raw std::shared<arrow::fs::FileSystem> *",
static_cast<GParamFlags>(G_PARAM_WRITABLE |
G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property(gobject_class, PROP_FILE_SYSTEM, spec);
}
/**
* garrow_file_system_create:
* @uri: An URI to specify file system with options. If you only have an
* absolute path, g_filename_to_uri() will help you.
* @error: (nullable): Return location for a #GError or %NULL.
*
* This is a factory function to create a specific #GArrowFileSystem
* object.
*
* Returns: (nullable) (transfer full): The newly created file system
* that is an object of a subclass of #GArrowFileSystem.
*
* Since: 3.0.0
*/
GArrowFileSystem *
garrow_file_system_create(const gchar *uri, GError **error)
{
auto arrow_file_system_result = arrow::fs::FileSystemFromUri(uri);
if (garrow::check(error,
arrow_file_system_result,
"[file-system][create]")) {
auto arrow_file_system = *arrow_file_system_result;
return garrow_file_system_new_raw(&arrow_file_system);
} else {
return NULL;
}
}
/**
* garrow_file_system_get_type_name:
* @file_system: A #GArrowFileSystem.
*
* Returns: The name of file system type.
*
* It should be freed with g_free() when no longer needed.
*
* Since: 0.17.0
*/
gchar *
garrow_file_system_get_type_name(GArrowFileSystem *file_system)
{
auto arrow_file_system = garrow_file_system_get_raw(file_system);
const auto &type_name = arrow_file_system->type_name();
return g_strndup(type_name.data(), type_name.size());
}
/**
* garrow_file_system_get_file_info:
* @file_system: A #GArrowFileSystem.
* @path: The path of the target.
* @error: (nullable): Return location for a #GError or %NULL.
*
* Get information for the given target.
*
* Any symlink is automatically dereferenced, recursively.
* A non-existing or unreachable file returns an OK status and has
* a #GArrowFileType of value %GARROW_FILE_TYPE_NOT_FOUND.
* An error status indicates a truly exceptional condition
* (low-level I/O error, etc.).
*
* Returns: (nullable) (transfer full): A #GArrowFileInfo.
*
* Since: 0.17.0
*/
GArrowFileInfo *
garrow_file_system_get_file_info(GArrowFileSystem *file_system,
const gchar *path,
GError **error)
{
auto arrow_file_system = garrow_file_system_get_raw(file_system);
auto arrow_result = arrow_file_system->GetFileInfo(path);
if (garrow::check(error, arrow_result, "[file-system][get-file-info]")) {
const auto &arrow_file_info = *arrow_result;
return garrow_file_info_new_raw(arrow_file_info);
} else {
return NULL;
}
}
static inline GList *
garrow_file_infos_new(arrow::Result<std::vector<arrow::fs::FileInfo>>&& arrow_result,
GError **error,
const gchar *context)
{
if (garrow::check(error, arrow_result, context)) {
auto arrow_file_infos = *arrow_result;
GList *file_infos = NULL;
for (auto arrow_file_info : arrow_file_infos) {
auto file_info = garrow_file_info_new_raw(arrow_file_info);
file_infos = g_list_prepend(file_infos, file_info);
}
return g_list_reverse(file_infos);
} else {
return NULL;
}
}
/**
* garrow_file_system_get_file_infos_paths:
* @file_system: A #GArrowFileSystem.
* @paths: (array length=n_paths): The paths of the targets.
* @n_paths: The number of items in @paths.
* @error: (nullable): Return location for a #GError or %NULL.
*
* Get information same as garrow_file_system_get_file_info()
* for the given many targets at once.
*
* Returns: (element-type GArrowFileInfo) (transfer full):
* A list of #GArrowFileInfo.
*
* Since: 0.17.0
*/
GList *
garrow_file_system_get_file_infos_paths(GArrowFileSystem *file_system,
const gchar **paths,
gsize n_paths,
GError **error)
{
auto arrow_file_system = garrow_file_system_get_raw(file_system);
std::vector<std::string> arrow_paths;
for (gsize i = 0; i < n_paths; ++i) {
arrow_paths.push_back(paths[i]);
}
return garrow_file_infos_new(arrow_file_system->GetFileInfo(arrow_paths),
error,
"[file-system][get-file-infos][paths]");
}
/**
* garrow_file_system_get_file_infos_selector:
* @file_system: A #GArrowFileSystem.
* @file_selector: A #GArrowFileSelector.
* @error: (nullable): Return location for a #GError or %NULL.
*
* Get information same as garrow_file_system_get_file_info()
* according to a selector.
*
* The selector's base directory will not be part of the results,
* even if it exists.
*
* Returns: (element-type GArrowFileInfo) (transfer full):
* A list of #GArrowFileInfo.
*
* Since: 0.17.0
*/
GList *
garrow_file_system_get_file_infos_selector(GArrowFileSystem *file_system,
GArrowFileSelector *file_selector,
GError **error)
{
auto arrow_file_system = garrow_file_system_get_raw(file_system);
const auto &arrow_file_selector =
GARROW_FILE_SELECTOR_GET_PRIVATE(file_selector)->file_selector;
return garrow_file_infos_new(arrow_file_system->GetFileInfo(arrow_file_selector),
error,
"[file-system][get-file-infos][selector]");
}
/**
* garrow_file_system_create_dir:
* @file_system: A #GArrowFileSystem.
* @path: The paths of the directory.
* @recursive: Whether creating directory recursively or not.
* @error: (nullable): Return location for a #GError or %NULL.
*
* Create a directory and subdirectories.
* This function succeeds if the directory already exists.
*
* Returns: %TRUE on success, %FALSE if there was an error.
*
* Since: 0.17.0
*/
gboolean
garrow_file_system_create_dir(GArrowFileSystem *file_system,
const gchar *path,
gboolean recursive,
GError **error)
{
auto arrow_file_system = garrow_file_system_get_raw(file_system);
auto status = arrow_file_system->CreateDir(path, recursive);
return garrow::check(error, status, "[file-system][create-dir]");
}
/**
* garrow_file_system_delete_dir:
* @file_system: A #GArrowFileSystem.
* @path: The paths of the directory.
* @error: (nullable): Return location for a #GError or %NULL.
*
* Delete a directory and its contents, recursively.
*
* Returns: %TRUE on success, %FALSE if there was an error.
*
* Since: 0.17.0
*/
gboolean
garrow_file_system_delete_dir(GArrowFileSystem *file_system,
const gchar *path,
GError **error)
{
auto arrow_file_system = garrow_file_system_get_raw(file_system);
auto status = arrow_file_system->DeleteDir(path);
return garrow::check(error, status, "[file-system][delete-dir]");
}
/**
* garrow_file_system_delete_dir_contents:
* @file_system: A #GArrowFileSystem.
* @path: The paths of the directory.
* @error: (nullable): Return location for a #GError or %NULL.
*
* Delete a directory's contents, recursively. Like
* garrow_file_system_delete_dir(), but doesn't delete the directory
* itself. Passing an empty path (`""`) will wipe the entire file
* system tree.
*
* Returns: %TRUE on success, %FALSE if there was an error.
*
* Since: 0.17.0
*/
gboolean
garrow_file_system_delete_dir_contents(GArrowFileSystem *file_system,
const gchar *path,
GError **error)
{
auto arrow_file_system = garrow_file_system_get_raw(file_system);
auto status = arrow_file_system->DeleteDirContents(path);
return garrow::check(error, status, "[file-system][delete-dir-contents]");
}
/**
* garrow_file_system_delete_file:
* @file_system: A #GArrowFileSystem.
* @path: The paths of the file to be delete.
* @error: (nullable): Return location for a #GError or %NULL.
*
* Delete a file.
*
* Returns: %TRUE on success, %FALSE if there was an error.
*
* Since: 0.17.0
*/
gboolean
garrow_file_system_delete_file(GArrowFileSystem *file_system,
const gchar *path,
GError **error)
{
auto arrow_file_system = garrow_file_system_get_raw(file_system);
auto status = arrow_file_system->DeleteFile(path);
return garrow::check(error, status, "[file-system][delete-file]");
}
/**
* garrow_file_system_delete_files:
* @file_system: A #GArrowFileSystem.
* @paths: (array length=n_paths):
* The paths of the files to be delete.
* @n_paths: The number of items in @paths.
* @error: (nullable): Return location for a #GError or %NULL.
*
* Delete many files.
*
* Returns: %TRUE on success, %FALSE if there was an error.
*
* Since: 0.17.0
*/
gboolean
garrow_file_system_delete_files(GArrowFileSystem *file_system,
const gchar **paths,
gsize n_paths,
GError **error)
{
auto arrow_file_system = garrow_file_system_get_raw(file_system);
std::vector<std::string> arrow_paths;
arrow_paths.reserve(n_paths);
for (gsize i = 0; i < n_paths; ++i) {
arrow_paths.emplace_back(paths[i]);
}
auto status = arrow_file_system->DeleteFiles(arrow_paths);
return garrow::check(error, status, "[file-system][delete-files]");
}
/**
* garrow_file_system_move:
* @file_system: A #GArrowFileSystem.
* @src: The path of the source file.
* @dest: The path of the destination.
* @error: (nullable): Return location for a #GError or %NULL.
*
* Move / rename a file or a directory.
* If the destination exists:
* - if it is a non-empty directory, an error is returned
* - otherwise, if it has the same type as the source, it is replaced
* - otherwise, behavior is unspecified (implementation-dependent).
*
* Returns: %TRUE on success, %FALSE if there was an error.
*
* Since: 0.17.0
*/
gboolean
garrow_file_system_move(GArrowFileSystem *file_system,
const gchar *src,
const gchar *dest,
GError **error)
{
auto arrow_file_system = garrow_file_system_get_raw(file_system);
auto status = arrow_file_system->Move(src, dest);
return garrow::check(error, status, "[file-system][move]");
}
/**
* garrow_file_system_copy_file:
* @file_system: A #GArrowFileSystem.
* @src: The path of the source file.
* @dest: The path of the destination.
* @error: (nullable): Return location for a #GError or %NULL.
*
* Copy a file.
* If the destination exists and is a directory, an error is returned.
* Otherwise, it is replaced.
*
* Returns: %TRUE on success, %FALSE if there was an error.
*
* Since: 0.17.0
*/
gboolean
garrow_file_system_copy_file(GArrowFileSystem *file_system,
const gchar *src,
const gchar *dest,
GError **error)
{
auto arrow_file_system = garrow_file_system_get_raw(file_system);
auto status = arrow_file_system->CopyFile(src, dest);
return garrow::check(error, status, "[file-system][copy-file]");
}
/**
* garrow_file_system_open_input_stream:
* @file_system: A #GArrowFileSystem.
* @path: The path of the input stream.
* @error: (nullable): Return location for a #GError or %NULL.
*
* Open an input stream for sequential reading.
*
* Returns: (nullable) (transfer full): A newly created
* #GArrowInputStream.
*
* Since: 0.17.0
*/
GArrowInputStream *
garrow_file_system_open_input_stream(GArrowFileSystem *file_system,
const gchar *path,
GError **error)
{
auto arrow_file_system = garrow_file_system_get_raw(file_system);
auto arrow_input_stream = arrow_file_system->OpenInputStream(path);
if (garrow::check(error,
arrow_input_stream,
"[file-system][open-input-stream]")) {
return garrow_input_stream_new_raw(&(*arrow_input_stream));
} else {
return NULL;
}
}
/**
* garrow_file_system_open_input_file:
* @file_system: A #GArrowFileSystem.
* @path: The path of the input file.
* @error: (nullable): Return location for a #GError or %NULL.
*
* Open an input file for random access reading.
*
* Returns: (nullable) (transfer full): A newly created
* #GArrowSeekableInputStream.
*
* Since: 0.17.0
*/
GArrowSeekableInputStream *
garrow_file_system_open_input_file(GArrowFileSystem *file_system,
const gchar *path,
GError **error)
{
auto arrow_file_system = garrow_file_system_get_raw(file_system);
auto arrow_random_access_file = arrow_file_system->OpenInputFile(path);
if (garrow::check(error,
arrow_random_access_file,
"[file-system][open-input-file]")) {
return garrow_seekable_input_stream_new_raw(&(*arrow_random_access_file));
} else {
return NULL;
}
}
/**
* garrow_file_system_open_output_stream:
* @file_system: A #GArrowFileSystem.
* @path: The path of the output stream.
* @error: (nullable): Return location for a #GError or %NULL.
*
* Open an output stream for sequential writing.
* If the target already exists, the existing data is truncated.
*
* Returns: (nullable) (transfer full): A newly created
* #GArrowOutputStream.
*
* Since: 0.17.0
*/
GArrowOutputStream *
garrow_file_system_open_output_stream(GArrowFileSystem *file_system,
const gchar *path,
GError **error)
{
auto arrow_file_system = garrow_file_system_get_raw(file_system);
auto arrow_output_stream = arrow_file_system->OpenOutputStream(path);
if (garrow::check(error,
arrow_output_stream,
"[file-system][open-output-stream]")) {
return garrow_output_stream_new_raw(&(*arrow_output_stream));
} else {
return NULL;
}
}
/**
* garrow_file_system_open_append_stream:
* @file_system: A #GArrowFileSystem.
* @path: The path of the output stream.
* @error: (nullable): Return location for a #GError or %NULL.
*
* Open an output stream for appending.
* If the target doesn't exist, a new empty file is created.
*
* Returns: (nullable) (transfer full): A newly created #GArrowOutputStream
* for appending.
*
* Since: 0.17.0
*/
GArrowOutputStream *
garrow_file_system_open_append_stream(GArrowFileSystem *file_system,
const gchar *path,
GError **error)
{
auto arrow_file_system = garrow_file_system_get_raw(file_system);
auto arrow_output_stream = arrow_file_system->OpenAppendStream(path);
if (garrow::check(error,
arrow_output_stream,
"[file-system][open-append-stream]")) {
return garrow_output_stream_new_raw(&(*arrow_output_stream));
} else {
return NULL;
}
}
/* arrow::fs::SubTreeFileSystem */
typedef struct GArrowSubTreeFileSystemPrivate_ {
GArrowFileSystem *base_file_system;
} GArrowSubTreeFileSystemPrivate;
enum {
PROP_BASE_FILE_SYSTEM = 1,
};
G_DEFINE_TYPE_WITH_PRIVATE(GArrowSubTreeFileSystem,
garrow_sub_tree_file_system,
GARROW_TYPE_FILE_SYSTEM)
#define GARROW_SUB_TREE_FILE_SYSTEM_GET_PRIVATE(object) \
static_cast<GArrowSubTreeFileSystemPrivate *>( \
garrow_sub_tree_file_system_get_instance_private( \
GARROW_SUB_TREE_FILE_SYSTEM(object)))
static void
garrow_sub_tree_file_system_dispose(GObject *object)
{
auto priv = GARROW_SUB_TREE_FILE_SYSTEM_GET_PRIVATE(object);
if (priv->base_file_system) {
g_object_unref(priv->base_file_system);
priv->base_file_system = NULL;
}
G_OBJECT_CLASS(garrow_sub_tree_file_system_parent_class)->dispose(object);
}
static void
garrow_sub_tree_file_system_set_property(GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
auto priv = GARROW_SUB_TREE_FILE_SYSTEM_GET_PRIVATE(object);
switch (prop_id) {
case PROP_BASE_FILE_SYSTEM:
priv->base_file_system = GARROW_FILE_SYSTEM(g_value_dup_object(value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
}
}
static void
garrow_sub_tree_file_system_get_property(GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
auto priv = GARROW_SUB_TREE_FILE_SYSTEM_GET_PRIVATE(object);
switch (prop_id) {
case PROP_BASE_FILE_SYSTEM:
g_value_set_object(value, priv->base_file_system);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
}
}
static void
garrow_sub_tree_file_system_init(GArrowSubTreeFileSystem *file_system)
{
}
static void
garrow_sub_tree_file_system_class_init(GArrowSubTreeFileSystemClass *klass)
{
auto gobject_class = G_OBJECT_CLASS(klass);
gobject_class->dispose = garrow_sub_tree_file_system_dispose;
gobject_class->set_property = garrow_sub_tree_file_system_set_property;
gobject_class->get_property = garrow_sub_tree_file_system_get_property;
GParamSpec *spec;
spec = g_param_spec_object("base-file-system",
"Base file system",
"The base GArrowFileSystem",
GARROW_TYPE_FILE_SYSTEM,
static_cast<GParamFlags>(G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property(gobject_class, PROP_BASE_FILE_SYSTEM, spec);
}
/**
* garrow_sub_tree_file_system_new:
* @base_path: A base path of the sub tree file system.
* @base_file_system: A #GArrowFileSystem as the base file system.
*
* Returns: (transfer full): A newly created #GArrowSubTreeFileSystem.
*
* Since: 0.17.0
*/
GArrowSubTreeFileSystem *
garrow_sub_tree_file_system_new(const gchar *base_path,
GArrowFileSystem *base_file_system)
{
auto arrow_base_file_system = garrow_file_system_get_raw(base_file_system);
auto arrow_sub_tree_file_system =
std::static_pointer_cast<arrow::fs::FileSystem>(
std::make_shared<arrow::fs::SubTreeFileSystem>(base_path,
arrow_base_file_system));
return garrow_sub_tree_file_system_new_raw(&arrow_sub_tree_file_system,
base_file_system);
}
/* arrow::fs::SlowFileSystem */
typedef struct GArrowSlowFileSystemPrivate_ {
GArrowFileSystem *base_file_system;
} GArrowSlowFileSystemPrivate;
G_DEFINE_TYPE_WITH_PRIVATE(GArrowSlowFileSystem,
garrow_slow_file_system,
GARROW_TYPE_FILE_SYSTEM)
#define GARROW_SLOW_FILE_SYSTEM_GET_PRIVATE(object) \
static_cast<GArrowSlowFileSystemPrivate *>( \
garrow_slow_file_system_get_instance_private( \
GARROW_SLOW_FILE_SYSTEM(object)))
static void
garrow_slow_file_system_dispose(GObject *object)
{
auto priv = GARROW_SLOW_FILE_SYSTEM_GET_PRIVATE(object);
if (priv->base_file_system) {
g_object_unref(priv->base_file_system);
priv->base_file_system = NULL;
}
G_OBJECT_CLASS(garrow_slow_file_system_parent_class)->dispose(object);
}
static void
garrow_slow_file_system_set_property(GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
auto priv = GARROW_SLOW_FILE_SYSTEM_GET_PRIVATE(object);
switch (prop_id) {
case PROP_BASE_FILE_SYSTEM:
priv->base_file_system = GARROW_FILE_SYSTEM(g_value_dup_object(value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
}
}
static void
garrow_slow_file_system_get_property(GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
auto priv = GARROW_SLOW_FILE_SYSTEM_GET_PRIVATE(object);
switch (prop_id) {
case PROP_BASE_FILE_SYSTEM:
g_value_set_object(value, priv->base_file_system);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
}
}
static void
garrow_slow_file_system_init(GArrowSlowFileSystem *file_system)
{
}
static void
garrow_slow_file_system_class_init(GArrowSlowFileSystemClass *klass)
{
auto gobject_class = G_OBJECT_CLASS(klass);
gobject_class->dispose = garrow_slow_file_system_dispose;
gobject_class->set_property = garrow_slow_file_system_set_property;
gobject_class->get_property = garrow_slow_file_system_get_property;
GParamSpec *spec;
spec = g_param_spec_object("base-file-system",
"Base file system",
"The base GArrowFileSystem",
GARROW_TYPE_FILE_SYSTEM,
static_cast<GParamFlags>(G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property(gobject_class, PROP_BASE_FILE_SYSTEM, spec);
}
/**
* garrow_slow_file_system_new_average_latency:
* @base_file_system: A #GArrowFileSystem as the base file system.
* @average_latency: The average value of the latency.
*
* The latency is normally distributed with a standard deviation of
* @average_latency * 0.1.
*
* The random seed is given by the default random device.
*
* Returns: (transfer full): A newly created #GArrowSlowFileSystem.
*
* Since: 0.17.0
*/
GArrowSlowFileSystem *
garrow_slow_file_system_new_average_latency(GArrowFileSystem *base_file_system,
gdouble average_latency)
{
auto arrow_base_file_system = garrow_file_system_get_raw(base_file_system);
auto arrow_slow_file_system =
std::static_pointer_cast<arrow::fs::FileSystem>(
std::make_shared<arrow::fs::SlowFileSystem>(arrow_base_file_system,
average_latency));
return garrow_slow_file_system_new_raw(&arrow_slow_file_system,
base_file_system);
}
/**
* garrow_slow_file_system_new_average_latency_and_seed:
* @base_file_system: A #GArrowFileSystem as the base file system.
* @average_latency: The average value of the latency.
* @seed: A random seed.
*
* The latency is normally distributed with a standard deviation of
* @average_latency * 0.1.
*
* Returns: (transfer full): A newly created #GArrowSlowFileSystem.
*
* Since: 0.17.0
*/
GArrowSlowFileSystem *
garrow_slow_file_system_new_average_latency_and_seed(GArrowFileSystem *base_file_system,
gdouble average_latency,
gint32 seed)
{
auto arrow_base_file_system = garrow_file_system_get_raw(base_file_system);
auto arrow_slow_file_system =
std::static_pointer_cast<arrow::fs::FileSystem>(
std::make_shared<arrow::fs::SlowFileSystem>(arrow_base_file_system,
average_latency,
seed));
return garrow_slow_file_system_new_raw(&arrow_slow_file_system,
base_file_system);
}
G_DEFINE_TYPE(GArrowMockFileSystem,
garrow_mock_file_system,
GARROW_TYPE_FILE_SYSTEM)
static void
garrow_mock_file_system_init(GArrowMockFileSystem *file_system)
{
}
static void
garrow_mock_file_system_class_init(GArrowMockFileSystemClass *klass)
{
}
G_DEFINE_TYPE(GArrowHDFSFileSystem,
garrow_hdfs_file_system,
GARROW_TYPE_FILE_SYSTEM)
static void
garrow_hdfs_file_system_init(GArrowHDFSFileSystem *file_system)
{
}
static void
garrow_hdfs_file_system_class_init(GArrowHDFSFileSystemClass *klass)
{
}
G_DEFINE_TYPE(GArrowS3FileSystem,
garrow_s3_file_system,
GARROW_TYPE_FILE_SYSTEM)
static void
garrow_s3_file_system_init(GArrowS3FileSystem *file_system)
{
}
static void
garrow_s3_file_system_class_init(GArrowS3FileSystemClass *klass)
{
}
G_END_DECLS
GArrowFileInfo *
garrow_file_info_new_raw(const arrow::fs::FileInfo &arrow_file_info)
{
auto file_info = garrow_file_info_new();
GARROW_FILE_INFO_GET_PRIVATE(file_info)->file_info = arrow_file_info;
return file_info;
}
arrow::fs::FileInfo *
garrow_file_info_get_raw(GArrowFileInfo *file_info)
{
auto priv = GARROW_FILE_INFO_GET_PRIVATE(file_info);
return &(priv->file_info);
}
GArrowFileSystem *
garrow_file_system_new_raw(
std::shared_ptr<arrow::fs::FileSystem> *arrow_file_system)
{
const auto &type_name = (*arrow_file_system)->type_name();
GType file_system_type = GARROW_TYPE_FILE_SYSTEM;
if (type_name == "local") {
file_system_type = GARROW_TYPE_LOCAL_FILE_SYSTEM;
} else if (type_name == "hdfs") {
file_system_type = GARROW_TYPE_HDFS_FILE_SYSTEM;
} else if (type_name == "s3") {
file_system_type = GARROW_TYPE_S3_FILE_SYSTEM;
} else if (type_name == "mock") {
file_system_type = GARROW_TYPE_MOCK_FILE_SYSTEM;
}
return GARROW_FILE_SYSTEM(g_object_new(file_system_type,
"file-system", arrow_file_system,
NULL));
}
std::shared_ptr<arrow::fs::FileSystem>
garrow_file_system_get_raw(GArrowFileSystem *file_system)
{
auto priv = GARROW_FILE_SYSTEM_GET_PRIVATE(file_system);
return priv->file_system;
}
GArrowSubTreeFileSystem *
garrow_sub_tree_file_system_new_raw(
std::shared_ptr<arrow::fs::FileSystem> *arrow_file_system,
GArrowFileSystem *base_file_system)
{
return GARROW_SUB_TREE_FILE_SYSTEM(
g_object_new(GARROW_TYPE_SUB_TREE_FILE_SYSTEM,
"file-system", arrow_file_system,
"base-file-system", base_file_system,
NULL));
}
GArrowSlowFileSystem *
garrow_slow_file_system_new_raw(
std::shared_ptr<arrow::fs::FileSystem> *arrow_file_system,
GArrowFileSystem *base_file_system)
{
return GARROW_SLOW_FILE_SYSTEM(
g_object_new(GARROW_TYPE_SLOW_FILE_SYSTEM,
"file-system", arrow_file_system,
"base-file-system", base_file_system,
NULL));
}