Skip to content

Commit

Permalink
ARROW-14637: [GLib][Ruby] Add support for initializing S3 APIs explic…
Browse files Browse the repository at this point in the history
…itly

Ruby API: Arrow.s3_initialize(log_level: :trace)
  • Loading branch information
kou committed Nov 9, 2021
1 parent 412da89 commit 2e3ba5a
Show file tree
Hide file tree
Showing 7 changed files with 293 additions and 3 deletions.
177 changes: 174 additions & 3 deletions c_glib/arrow-glib/file-system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ G_BEGIN_DECLS
*
* #GArrowHDFSFileSystem is a class for HDFS-backed file system.
*
* #GArrowS3GlobalOptions is a class for options to initialize S3 APIs.
*
* #GArrowS3FileSystem is a class for S3-backed file system.
*/

Expand All @@ -72,10 +74,10 @@ enum {

G_DEFINE_TYPE_WITH_PRIVATE(GArrowFileInfo, garrow_file_info, G_TYPE_OBJECT)

#define GARROW_FILE_INFO_GET_PRIVATE(obj) \
#define GARROW_FILE_INFO_GET_PRIVATE(object) \
static_cast<GArrowFileInfoPrivate *>( \
garrow_file_info_get_instance_private( \
GARROW_FILE_INFO(obj)))
garrow_file_info_get_instance_private( \
GARROW_FILE_INFO(object)))

static void
garrow_file_info_finalize(GObject *object)
Expand Down Expand Up @@ -1364,6 +1366,168 @@ garrow_hdfs_file_system_class_init(GArrowHDFSFileSystemClass *klass)
}


typedef struct GArrowS3GlobalOptionsPrivate_ {
arrow::fs::S3GlobalOptions options;
} GArrowS3GlobalOptionsPrivate;

enum {
PROP_S3_GLOBAL_OPTIONS_LOG_LEVEL = 1,
};

G_DEFINE_TYPE_WITH_PRIVATE(GArrowS3GlobalOptions,
garrow_s3_global_options,
G_TYPE_OBJECT)

#define GARROW_S3_GLOBAL_OPTIONS_GET_PRIVATE(object) \
static_cast<GArrowS3GlobalOptionsPrivate *>( \
garrow_s3_global_options_get_instance_private( \
GARROW_S3_GLOBAL_OPTIONS(object)))

static void
garrow_s3_global_options_finalize(GObject *object)
{
auto priv = GARROW_S3_GLOBAL_OPTIONS_GET_PRIVATE(object);
priv->options.~S3GlobalOptions();
G_OBJECT_CLASS(garrow_s3_global_options_parent_class)->finalize(object);
}

static void
garrow_s3_global_options_set_property(GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
auto arrow_options =
garrow_s3_global_options_get_raw(GARROW_S3_GLOBAL_OPTIONS(object));

switch (prop_id) {
case PROP_S3_GLOBAL_OPTIONS_LOG_LEVEL:
arrow_options->log_level =
static_cast<arrow::fs::S3LogLevel>(g_value_get_enum(value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
}
}

static void
garrow_s3_global_options_get_property(GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
auto arrow_options =
garrow_s3_global_options_get_raw(GARROW_S3_GLOBAL_OPTIONS(object));

switch (prop_id) {
case PROP_S3_GLOBAL_OPTIONS_LOG_LEVEL:
g_value_set_enum(value,
static_cast<GArrowS3LogLevel>(arrow_options->log_level));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
}
}

static void
garrow_s3_global_options_init(GArrowS3GlobalOptions *object)
{
auto priv = GARROW_S3_GLOBAL_OPTIONS_GET_PRIVATE(object);
new(&priv->options) arrow::fs::S3GlobalOptions;
}

static void
garrow_s3_global_options_class_init(GArrowS3GlobalOptionsClass *klass)
{
GParamSpec *spec;

auto gobject_class = G_OBJECT_CLASS(klass);

gobject_class->finalize = garrow_s3_global_options_finalize;
gobject_class->set_property = garrow_s3_global_options_set_property;
gobject_class->get_property = garrow_s3_global_options_get_property;

arrow::fs::S3GlobalOptions options{arrow::fs::S3LogLevel::Fatal};

/**
* GArrowS3GlobalOptions:log-level:
*
* The log level of S3 APIs.
*
* Since: 7.0.0
*/
spec = g_param_spec_enum("log-level",
"Log level",
"The log level of S3 APIs",
GARROW_TYPE_S3_LOG_LEVEL,
static_cast<GArrowS3LogLevel>(options.log_level),
static_cast<GParamFlags>(G_PARAM_READWRITE |
G_PARAM_CONSTRUCT));
g_object_class_install_property(gobject_class,
PROP_S3_GLOBAL_OPTIONS_LOG_LEVEL,
spec);
}

/**
* garrow_s3_global_options_new:
*
* Returns: A newly created #GArrowS3GlobalOptions.
*
* Since: 7.0.0
*/
GArrowS3GlobalOptions *
garrow_s3_global_options_new(void)
{
return GARROW_S3_GLOBAL_OPTIONS(
g_object_new(GARROW_TYPE_S3_GLOBAL_OPTIONS, NULL));
}


/**
* garrow_s3_initialize:
* @options: (nullable): Options to initialize the S3 APIs.
* @error: (nullable): Return location for a #GError or %NULL.
*
* Normally, you don't need to call this function because the S3 APIs
* are initialized with the default options automatically. If you want
* to call this function, you must call this function before you use
* any #GArrowS3FileSystem related APIs.
*
* Returns: %TRUE on success, %FALSE on error.
*
* Since: 7.0.0
*/
gboolean
garrow_s3_initialize(GArrowS3GlobalOptions *options,
GError **error)
{
auto arrow_options = garrow_s3_global_options_get_raw(options);
return garrow::check(error,
arrow::fs::InitializeS3(*arrow_options),
"[s3][initialize]");
}

/**
* garrow_s3_finalize:
* @error: (nullable): Return location for a #GError or %NULL.
*
* Finalize the S3 APIs.
*
* Returns: %TRUE on success, %FALSE on error.
*
* Since: 7.0.0
*/
gboolean
garrow_s3_finalize(GError **error)
{
return garrow::check(error,
arrow::fs::FinalizeS3(),
"[s3][finalize]");
}


G_DEFINE_TYPE(GArrowS3FileSystem,
garrow_s3_file_system,
GARROW_TYPE_FILE_SYSTEM)
Expand Down Expand Up @@ -1448,3 +1612,10 @@ garrow_slow_file_system_new_raw(
"base-file-system", base_file_system,
NULL));
}

arrow::fs::S3GlobalOptions *
garrow_s3_global_options_get_raw(GArrowS3GlobalOptions *options)
{
auto priv = GARROW_S3_GLOBAL_OPTIONS_GET_PRIVATE(options);
return &(priv->options);
}
50 changes: 50 additions & 0 deletions c_glib/arrow-glib/file-system.h
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,56 @@ struct _GArrowHDFSFileSystemClass
};


/**
* GArrowS3LogLevel:
* @GARROW_S3_LOG_LEVEL_OFF: Off.
* @GARROW_S3_LOG_LEVEL_FATAL: Fatal. This is the default.
* @GARROW_S3_LOG_LEVEL_ERROR: Error.
* @GARROW_S3_LOG_LEVEL_WARN: Warn.
* @GARROW_S3_LOG_LEVEL_INFO: Info.
* @GARROW_S3_LOG_LEVEL_DEBUG: Debug.
* @GARROW_S3_LOG_LEVEL_TRACE: Trace.
*
* They are corresponding to `arrow::fs::S3LogLevel` values.
*
* Since: 7.0.0
*/
typedef enum {
GARROW_S3_LOG_LEVEL_OFF,
GARROW_S3_LOG_LEVEL_FATAL,
GARROW_S3_LOG_LEVEL_ERROR,
GARROW_S3_LOG_LEVEL_WARN,
GARROW_S3_LOG_LEVEL_INFO,
GARROW_S3_LOG_LEVEL_DEBUG,
GARROW_S3_LOG_LEVEL_TRACE,
} GArrowS3LogLevel;


#define GARROW_TYPE_S3_GLOBAL_OPTIONS (garrow_s3_global_options_get_type())
G_DECLARE_DERIVABLE_TYPE(GArrowS3GlobalOptions,
garrow_s3_global_options,
GARROW,
S3_GLOBAL_OPTIONS,
GObject)
struct _GArrowS3GlobalOptionsClass
{
GObjectClass parent_class;
};

GARROW_AVAILABLE_IN_7_0
GArrowS3GlobalOptions *
garrow_s3_global_options_new(void);


GARROW_AVAILABLE_IN_7_0
gboolean
garrow_s3_initialize(GArrowS3GlobalOptions *options,
GError **error);
GARROW_AVAILABLE_IN_7_0
gboolean
garrow_s3_finalize(GError **error);


#define GARROW_TYPE_S3_FILE_SYSTEM (garrow_s3_file_system_get_type())
G_DECLARE_DERIVABLE_TYPE(GArrowS3FileSystem,
garrow_s3_file_system,
Expand Down
3 changes: 3 additions & 0 deletions c_glib/arrow-glib/file-system.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,6 @@ garrow_slow_file_system_new_raw(
std::shared_ptr<arrow::fs::FileSystem> *arrow_file_system,
GArrowFileSystem *base_file_system);


arrow::fs::S3GlobalOptions *
garrow_s3_global_options_get_raw(GArrowS3GlobalOptions *options);
23 changes: 23 additions & 0 deletions c_glib/arrow-glib/version.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,15 @@
# define GARROW_UNAVAILABLE(major, minor) G_UNAVAILABLE(major, minor)
#endif

/**
* GARROW_VERSION_7_0:
*
* You can use this macro value for compile time API version check.
*
* Since: 7.0.0
*/
#define GARROW_VERSION_7_0 G_ENCODE_VERSION(7, 0)

/**
* GARROW_VERSION_6_0:
*
Expand Down Expand Up @@ -274,6 +283,20 @@

#define GARROW_AVAILABLE_IN_ALL

#if GARROW_VERSION_MIN_REQUIRED >= GARROW_VERSION_7_0
# define GARROW_DEPRECATED_IN_7_0 GARROW_DEPRECATED
# define GARROW_DEPRECATED_IN_7_0_FOR(function) GARROW_DEPRECATED_FOR(function)
#else
# define GARROW_DEPRECATED_IN_7_0
# define GARROW_DEPRECATED_IN_7_0_FOR(function)
#endif

#if GARROW_VERSION_MAX_ALLOWED < GARROW_VERSION_7_0
# define GARROW_AVAILABLE_IN_7_0 GARROW_UNAVAILABLE(7, 0)
#else
# define GARROW_AVAILABLE_IN_7_0
#endif

#if GARROW_VERSION_MIN_REQUIRED >= GARROW_VERSION_6_0
# define GARROW_DEPRECATED_IN_6_0 GARROW_DEPRECATED
# define GARROW_DEPRECATED_IN_6_0_FOR(function) GARROW_DEPRECATED_FOR(function)
Expand Down
4 changes: 4 additions & 0 deletions c_glib/doc/arrow-glib/arrow-glib-docs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,10 @@
<title>Index of deprecated API</title>
<xi:include href="xml/api-index-deprecated.xml"><xi:fallback /></xi:include>
</index>
<index id="api-index-7-0-0" role="7.0.0">
<title>Index of new symbols in 7.0.0</title>
<xi:include href="xml/api-index-7.0.0.xml"><xi:fallback /></xi:include>
</index>
<index id="api-index-6-0-0" role="6.0.0">
<title>Index of new symbols in 6.0.0</title>
<xi:include href="xml/api-index-6.0.0.xml"><xi:fallback /></xi:include>
Expand Down
1 change: 1 addition & 0 deletions ruby/red-arrow/lib/arrow/loader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ def require_libraries
require "arrow/record-batch-reader"
require "arrow/record-batch-stream-reader"
require "arrow/rolling-window"
require "arrow/s3-global-options"
require "arrow/scalar"
require "arrow/schema"
require "arrow/slicer"
Expand Down
38 changes: 38 additions & 0 deletions ruby/red-arrow/lib/arrow/s3-global-options.rb
Original file line number Diff line number Diff line change
@@ -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.

module Arrow
class S3GlobalOptions
class << self
# @api private
def try_convert(value)
case value
when Hash
options = new
value.each do |k, v|
setter = :"#{k}="
return unless options.respond_to?(setter)
options.__send__(setter, v)
end
options
else
nil
end
end
end
end
end

0 comments on commit 2e3ba5a

Please sign in to comment.