Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/MariaDB/storage/mroonga/vendor/groonga/plugins/functions/   (MariaDB Server Version 8.1-8.4©)  Datei vom 1.9.2026 mit Größe 11 kB image not shown  

Quelle  time.c   Sprache: C

 

/* -*- c-basic-offset: 2 -*- */
/*
  Copyright(C) 2016 Brazil

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License version 2.1 as published by the Free Software Foundation.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1335  USA
*/


#ifdef GRN_EMBEDDED
#  define GRN_PLUGIN_FUNCTION_TAG functions_time
#endif

#include <groonga/plugin.h>

#include <math.h>

typedef enum {
  GRN_TIME_CLASSIFY_UNIT_SECOND,
  GRN_TIME_CLASSIFY_UNIT_MINUTE,
  GRN_TIME_CLASSIFY_UNIT_HOUR,
  GRN_TIME_CLASSIFY_UNIT_DAY,
  GRN_TIME_CLASSIFY_UNIT_WEEK,
  GRN_TIME_CLASSIFY_UNIT_MONTH,
  GRN_TIME_CLASSIFY_UNIT_YEAR
} grn_time_classify_unit;

static grn_obj *
func_time_classify_raw(grn_ctx *ctx,
                       int n_args,
                       grn_obj **args,
                       grn_user_data *user_data,
                       const char *function_name,
                       grn_time_classify_unit unit)
{
  grn_obj *time;
  uint32_t interval_raw = 1;
  grn_obj *classed_time;
  grn_bool accept_interval = GRN_TRUE;

  switch (unit) {
  case GRN_TIME_CLASSIFY_UNIT_SECOND :
  case GRN_TIME_CLASSIFY_UNIT_MINUTE :
  case GRN_TIME_CLASSIFY_UNIT_HOUR :
    accept_interval = GRN_TRUE;
    break;
  case GRN_TIME_CLASSIFY_UNIT_DAY :
  case GRN_TIME_CLASSIFY_UNIT_WEEK :
    accept_interval = GRN_FALSE;
    break;
  case GRN_TIME_CLASSIFY_UNIT_MONTH :
  case GRN_TIME_CLASSIFY_UNIT_YEAR :
    accept_interval = GRN_TRUE;
    break;
  }

  if (accept_interval) {
    if (!(n_args == 1 || n_args == 2)) {
      GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
                       "%s(): "
                       "wrong number of arguments (%d for 1..2)",
                       function_name,
                       n_args);
      return NULL;
    }
  } else {
    if (n_args != 1) {
      GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
                       "%s(): "
                       "wrong number of arguments (%d for 1)",
                       function_name,
                       n_args);
      return NULL;
    }
  }

  time = args[0];
  if (!(time->header.type == GRN_BULK &&
        time->header.domain == GRN_DB_TIME)) {
    grn_obj inspected;

    GRN_TEXT_INIT(&inspected, 0);
    grn_inspect(ctx, &inspected, time);
    GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
                     "%s(): "
                     "the first argument must be a time: "
                     "<%.*s>",
                     function_name,
                     (int)GRN_TEXT_LEN(&inspected),
                     GRN_TEXT_VALUE(&inspected));
    GRN_OBJ_FIN(ctx, &inspected);
    return NULL;
  }

  if (n_args == 2) {
    grn_obj *interval;
    grn_obj casted_interval;

    interval = args[1];
    if (!(interval->header.type == GRN_BULK &&
          grn_type_id_is_number_family(ctx, interval->header.domain))) {
      grn_obj inspected;

      GRN_TEXT_INIT(&inspected, 0);
      grn_inspect(ctx, &inspected, interval);
      GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
                       "%s(): "
                       "the second argument must be a number: "
                       "<%.*s>",
                       function_name,
                       (int)GRN_TEXT_LEN(&inspected),
                       GRN_TEXT_VALUE(&inspected));
      GRN_OBJ_FIN(ctx, &inspected);
      return NULL;
    }

    GRN_VALUE_FIX_SIZE_INIT(&casted_interval, 0, GRN_DB_UINT32);
    grn_obj_cast(ctx, interval, &casted_interval, GRN_FALSE);
    interval_raw = GRN_UINT32_VALUE(&casted_interval);
    GRN_OBJ_FIN(ctx, &casted_interval);

    if (interval_raw == 0) {
      grn_obj inspected;

      GRN_TEXT_INIT(&inspected, 0);
      grn_inspect(ctx, &inspected, interval);
      GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
                       "%s(): "
                       "the second argument must not be zero: "
                       "<%.*s>",
                       function_name,
                       (int)GRN_TEXT_LEN(&inspected),
                       GRN_TEXT_VALUE(&inspected));
      GRN_OBJ_FIN(ctx, &inspected);
      return NULL;
    }
  }

  {
    int64_t time_raw;
    struct tm tm;
    int64_t classed_time_raw;

    time_raw = GRN_TIME_VALUE(time);
    if (!grn_time_to_tm(ctx, time_raw, &tm)) {
      return NULL;
    }

    switch (unit) {
    case GRN_TIME_CLASSIFY_UNIT_SECOND :
      tm.tm_sec = (tm.tm_sec / interval_raw) * interval_raw;
      break;
    case GRN_TIME_CLASSIFY_UNIT_MINUTE :
      tm.tm_min = (tm.tm_min / interval_raw) * interval_raw;
      tm.tm_sec = 0;
      break;
    case GRN_TIME_CLASSIFY_UNIT_HOUR :
      tm.tm_hour = (tm.tm_hour / interval_raw) * interval_raw;
      tm.tm_min = 0;
      tm.tm_sec = 0;
      break;
    case GRN_TIME_CLASSIFY_UNIT_DAY :
      tm.tm_hour = 0;
      tm.tm_min = 0;
      tm.tm_sec = 0;
      break;
    case GRN_TIME_CLASSIFY_UNIT_WEEK :
      if ((tm.tm_mday - tm.tm_wday) >= 0) {
        tm.tm_mday -= tm.tm_wday;
      } else {
        int n_underflowed_mday = -(tm.tm_mday - tm.tm_wday);
        int mday;
        int max_mday = 31;

        if (tm.tm_mon == 0) {
          tm.tm_year--;
          tm.tm_mon = 11;
        } else {
          tm.tm_mon--;
        }

        for (mday = max_mday; mday > n_underflowed_mday; mday--) {
          int64_t unused;
          tm.tm_mday = mday;
          if (grn_time_from_tm(ctx, &unused, &tm)) {
            break;
          }
        }
        tm.tm_mday -= n_underflowed_mday;
      }
      tm.tm_hour = 0;
      tm.tm_min = 0;
      tm.tm_sec = 0;
      break;
    case GRN_TIME_CLASSIFY_UNIT_MONTH :
      tm.tm_mon = (tm.tm_mon / interval_raw) * interval_raw;
      tm.tm_mday = 1;
      tm.tm_hour = 0;
      tm.tm_min = 0;
      tm.tm_sec = 0;
      break;
    case GRN_TIME_CLASSIFY_UNIT_YEAR :
      tm.tm_year = (((1900 + tm.tm_year) / interval_raw) * interval_raw) - 1900;
      tm.tm_mon = 0;
      tm.tm_mday = 1;
      tm.tm_hour = 0;
      tm.tm_min = 0;
      tm.tm_sec = 0;
      break;
    }

    if (!grn_time_from_tm(ctx, &classed_time_raw, &tm)) {
      return NULL;
    }

    classed_time = grn_plugin_proc_alloc(ctx,
                                         user_data,
                                         time->header.domain,
                                         0);
    if (!classed_time) {
      return NULL;
    }
    GRN_TIME_SET(ctx, classed_time, classed_time_raw);

    return classed_time;
  }
}

static grn_obj *
func_time_classify_second(grn_ctx *ctx, int n_args, grn_obj **args,
                          grn_user_data *user_data)
{
  return func_time_classify_raw(ctx,
                                n_args,
                                args,
                                user_data,
                                "time_classify_second",
                                GRN_TIME_CLASSIFY_UNIT_SECOND);
}

static grn_obj *
func_time_classify_minute(grn_ctx *ctx, int n_args, grn_obj **args,
                          grn_user_data *user_data)
{
  return func_time_classify_raw(ctx,
                                n_args,
                                args,
                                user_data,
                                "time_classify_minute",
                                GRN_TIME_CLASSIFY_UNIT_MINUTE);
}

static grn_obj *
func_time_classify_hour(grn_ctx *ctx, int n_args, grn_obj **args,
                        grn_user_data *user_data)
{
  return func_time_classify_raw(ctx,
                                n_args,
                                args,
                                user_data,
                                "time_classify_hour",
                                GRN_TIME_CLASSIFY_UNIT_HOUR);
}

static grn_obj *
func_time_classify_day(grn_ctx *ctx, int n_args, grn_obj **args,
                       grn_user_data *user_data)
{
  return func_time_classify_raw(ctx,
                                n_args,
                                args,
                                user_data,
                                "time_classify_day",
                                GRN_TIME_CLASSIFY_UNIT_DAY);
}

static grn_obj *
func_time_classify_week(grn_ctx *ctx, int n_args, grn_obj **args,
                        grn_user_data *user_data)
{
  return func_time_classify_raw(ctx,
                                n_args,
                                args,
                                user_data,
                                "time_classify_week",
                                GRN_TIME_CLASSIFY_UNIT_WEEK);
}

static grn_obj *
func_time_classify_month(grn_ctx *ctx, int n_args, grn_obj **args,
                         grn_user_data *user_data)
{
  return func_time_classify_raw(ctx,
                                n_args,
                                args,
                                user_data,
                                "time_classify_month",
                                GRN_TIME_CLASSIFY_UNIT_MONTH);
}

static grn_obj *
func_time_classify_year(grn_ctx *ctx, int n_args, grn_obj **args,
                        grn_user_data *user_data)
{
  return func_time_classify_raw(ctx,
                                n_args,
                                args,
                                user_data,
                                "time_classify_year",
                                GRN_TIME_CLASSIFY_UNIT_YEAR);
}

grn_rc
GRN_PLUGIN_INIT(grn_ctx *ctx)
{
  return ctx->rc;
}

grn_rc
GRN_PLUGIN_REGISTER(grn_ctx *ctx)
{
  grn_rc rc = GRN_SUCCESS;

  grn_proc_create(ctx,
                  "time_classify_second", -1,
                  GRN_PROC_FUNCTION,
                  func_time_classify_second,
                  NULL, NULL, 0, NULL);
  grn_proc_create(ctx,
                  "time_classify_minute", -1,
                  GRN_PROC_FUNCTION,
                  func_time_classify_minute,
                  NULL, NULL, 0, NULL);
  grn_proc_create(ctx,
                  "time_classify_hour", -1,
                  GRN_PROC_FUNCTION,
                  func_time_classify_hour,
                  NULL, NULL, 0, NULL);
  grn_proc_create(ctx,
                  "time_classify_day", -1,
                  GRN_PROC_FUNCTION,
                  func_time_classify_day,
                  NULL, NULL, 0, NULL);
  grn_proc_create(ctx,
                  "time_classify_week", -1,
                  GRN_PROC_FUNCTION,
                  func_time_classify_week,
                  NULL, NULL, 0, NULL);
  grn_proc_create(ctx,
                  "time_classify_month", -1,
                  GRN_PROC_FUNCTION,
                  func_time_classify_month,
                  NULL, NULL, 0, NULL);
  grn_proc_create(ctx,
                  "time_classify_year", -1,
                  GRN_PROC_FUNCTION,
                  func_time_classify_year,
                  NULL, NULL, 0, NULL);

  return rc;
}

grn_rc
GRN_PLUGIN_FIN(grn_ctx *ctx)
{
  return GRN_SUCCESS;
}

Messung V0.5 in Prozent
C=100 H=98 G=98

¤ Dauer der Verarbeitung: 0.15 Sekunden  (vorverarbeitet am  2026-10-08) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.