...
 
Commits (7)
......@@ -5,6 +5,7 @@ libgda 5.91.0
- GdaHandler now supports value transformation, if possible, before set it
- Ported almost all public API to use g_autoptr() and remove public private struct
- GdaHolder now is GdaAttributeManager free, replaced by GObect properties
- GdaTime ported to GDateTime, with improved time handling and defaulting to UTC time
- Fixed segfaults
- Fixed meta data generation engine
- Fixed PostgresSQL provider meta data generation integration
......@@ -1907,4 +1908,4 @@ libgda 0.8.100, 2002-01-06
- extended test suite with new connection tests (Gonzalo)
- fixed #67242 orbit-idl not generating files when IDL changes (Gonzalo)
- fixed lost-counter in data retrieval (Gonzalo)
\ No newline at end of file
......@@ -684,7 +684,7 @@ gdaui_data_cell_renderer_textual_start_editing (GtkCellRenderer *cell,
else
entry = gdaui_entry_string_new (priv->dh, priv->type, priv->options);
g_object_set (G_OBJECT (entry), "is-cell-renderer", TRUE, "actions", FALSE, NULL);
g_object_set (G_OBJECT (entry), "is-cell-renderer", TRUE, NULL);
if (OPTIMIZE) {
GValue *orig;
......
......@@ -109,7 +109,7 @@ gdaui_entry_common_time_class_init (GdauiEntryCommonTimeClass * class)
g_param_spec_boolean ("editing-canceled", NULL, NULL, FALSE,
G_PARAM_READABLE | G_PARAM_WRITABLE));
g_object_class_install_property (object_class, PROP_TYPE,
g_param_spec_uint ("type", NULL, NULL, 0, G_MAXUINT, GDA_TYPE_TIME,
g_param_spec_gtype ("type", "GType", "Entry GType handled", G_TYPE_NONE,
G_PARAM_WRITABLE | G_PARAM_READABLE));
}
......@@ -122,71 +122,6 @@ key_press_event_cb (GdauiEntryCommonTime *mgtim, GdkEventKey *key_event, G_GNUC_
return FALSE;
}
static glong
compute_tz_offset (struct tm *gmttm, struct tm *loctm)
{
if (! gmttm || !loctm)
return G_MAXLONG;
struct tm cgmttm, cloctm;
cgmttm = *gmttm;
cloctm = *loctm;
time_t lt, gt;
cgmttm.tm_isdst = 0;
cloctm.tm_isdst = 0;
lt = mktime (&cloctm);
if (lt == -1)
return G_MAXLONG;
gt = mktime (&cgmttm);
if (gt == -1)
return G_MAXLONG;
glong off;
off = lt - gt;
if ((off >= 24 * 3600) || (off <= - 24 * 3600))
return G_MAXLONG;
else
return off;
}
static gulong
compute_localtime_tz (void)
{
time_t val;
val = time (NULL);
glong tz = 0;
#ifdef HAVE_LOCALTIME_R
struct tm gmttm, loctm;
tzset ();
localtime_r ((const time_t *) &val, &loctm);
tz = compute_tz_offset (gmtime_r ((const time_t *) &val, &gmttm), &loctm);
#elif HAVE_LOCALTIME_S
struct tm gmttm, loctm;
if ((localtime_s (&loctm, (const time_t *) &val) == 0) &&
(gmtime_s (&gmttm, (const time_t *) &val) == 0)) {
tz = compute_tz_offset (&gmttm, &loctm);
}
#else
struct tm gmttm, loctm;
struct tm *ltm;
ltm = gmtime ((const time_t *) &val);
if (ltm) {
gmttm = *ltm;
ltm = localtime ((const time_t *) &val);
if (ltm) {
loctm = *ltm;
tz = compute_tz_offset (&gmttm, &loctm);
}
}
#endif
if (tz == G_MAXLONG)
tz = 0;
return tz;
}
static void
gdaui_entry_common_time_init (GdauiEntryCommonTime *mgtim)
{
......@@ -196,7 +131,9 @@ gdaui_entry_common_time_init (GdauiEntryCommonTime *mgtim)
priv->editing_canceled = FALSE;
priv->value_tz = 0; /* safe init value */
priv->value_fraction = 0; /* safe init value */
priv->displayed_tz = compute_localtime_tz ();
GDateTime *dt = g_date_time_new_now_local ();
priv->displayed_tz = (glong) g_date_time_get_utc_offset (dt);
g_date_time_unref (dt);
g_signal_connect (mgtim, "key-press-event",
G_CALLBACK (key_press_event_cb), NULL);
}
......@@ -239,7 +176,7 @@ gdaui_entry_common_time_set_property (GObject *object,
/* GdauiEntryCommonTimePrivate *priv = gdaui_entry_common_time_get_instance_private (mgtim); */
switch (param_id) {
case PROP_TYPE:
gdaui_data_entry_set_value_type (GDAUI_DATA_ENTRY (object), g_value_get_uint (value));
gdaui_data_entry_set_value_type (GDAUI_DATA_ENTRY (object), g_value_get_gtype (value));
break;
case PROP_EDITING_CANCELED:
TO_IMPLEMENT;
......@@ -265,7 +202,7 @@ gdaui_entry_common_time_get_property (GObject *object,
g_value_set_boolean (value, priv->editing_canceled);
break;
case PROP_TYPE:
g_value_set_uint (value, gdaui_data_entry_get_value_type (GDAUI_DATA_ENTRY (object)));
g_value_set_gtype (value, gdaui_data_entry_get_value_type (GDAUI_DATA_ENTRY (object)));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
......@@ -340,23 +277,11 @@ icon_press_cb (GtkEntry *entry, GtkEntryIconPosition icon_pos, GdkEvent *event,
}
if (unset) {
time_t now;
struct tm *stm;
now = time (NULL);
#ifdef HAVE_LOCALTIME_R
struct tm tmpstm;
stm = localtime_r (&now, &tmpstm);
#elif HAVE_LOCALTIME_S
struct tm tmpstm;
g_assert (localtime_s (&tmpstm, &now) == 0);
stm = &tmpstm;
#else
stm = localtime (&now);
#endif
year = stm->tm_year + 1900;
month = stm->tm_mon;
day = stm->tm_mday;
GDateTime *dt = g_date_time_new_now_local ();
year = g_date_time_get_year (dt);
month = g_date_time_get_month (dt);
day = g_date_time_get_day_of_month (dt);
g_date_time_unref (dt);
}
if (! unset) {
......@@ -457,17 +382,6 @@ date_day_selected_double_click (GtkCalendar *calendar, GdauiEntryCommonTime *mgt
gtk_widget_hide (priv->cal_popover);
}
static glong
fit_tz (glong tz)
{
tz = tz % 86400;
if (tz > 43200)
tz -= 86400;
else if (tz < -43200)
tz += 86400;
return tz;
}
static void entry_insert_func (GdauiFormattedEntry *fentry, gunichar insert_char, gint virt_pos, gpointer data);
static void
......@@ -589,7 +503,7 @@ real_set_value (GdauiEntryWrapper *mgwrap, const GValue *value)
const GdaTime *gtim;
GdaTime* copy;
gtim = gda_value_get_time (value);
priv->value_tz = fit_tz (gda_time_get_timezone (gtim));
priv->value_tz = gda_time_get_timezone (gtim);
priv->value_fraction = gda_time_get_fraction (gtim);
copy = gda_time_copy (gtim);
......@@ -622,7 +536,7 @@ real_set_value (GdauiEntryWrapper *mgwrap, const GValue *value)
GDateTime *gts;
GDateTime *copy;
gts = g_value_get_boxed (value);
priv->value_tz = fit_tz (g_date_time_get_utc_offset (gts) / 1000000);
priv->value_tz = g_date_time_get_utc_offset (gts);
priv->value_fraction = (glong) ((g_date_time_get_seconds (gts) - g_date_time_get_second (gts)) * 1000000);
gint itz = priv->displayed_tz;
......@@ -651,11 +565,10 @@ real_set_value (GdauiEntryWrapper *mgwrap, const GValue *value)
g_date_time_unref (copy);
}
}
else
gdaui_entry_set_text (GDAUI_ENTRY (priv->entry), NULL);
} else {
g_warning (_("Can't set value to entry: Invalid Data Type for Entry Wrapper Time"));
gdaui_entry_set_text (GDAUI_ENTRY (priv->entry), NULL);
}
else
g_assert_not_reached ();
}
static GValue *
......@@ -739,8 +652,11 @@ real_get_value (GdauiEntryWrapper *mgwrap)
*/
}
}
else
g_assert_not_reached ();
else {
g_warning (_("Can't get value from entry: Invalid Data Type for Entry Wrapper Time"));
gdaui_entry_set_text (GDAUI_ENTRY (priv->entry), NULL);
value = gda_value_new (G_TYPE_DATE);
}
if (!value) {
/* in case the gda_data_handler_get_value_from_str() returned an error because
......
......@@ -469,7 +469,7 @@ gdaui_data_cell_renderer_password_start_editing (GtkCellRenderer *cell,
entry = gdaui_entry_password_new (datacell->priv->dh, datacell->priv->type, datacell->priv->options);
g_object_set (G_OBJECT (entry), "is-cell-renderer", TRUE, "actions", FALSE, NULL);
g_object_set (G_OBJECT (entry), "is-cell-renderer", TRUE, NULL);
gdaui_data_entry_set_reference_value (GDAUI_DATA_ENTRY (entry), datacell->priv->value);
......
......@@ -847,10 +847,7 @@ reset_columns_in_xml_layout (GdauiRawGrid *grid, xmlNodePtr grid_node)
xmlChar *plugin;
plugin = xmlGetProp (child, BAD_CAST "plugin");
if (plugin && cdata->single_param) {
GValue *value;
value = gda_value_new_from_string ((gchar*) plugin, G_TYPE_STRING);
g_object_set (cdata->single_param, "plugin", value, NULL);
gda_value_free (value);
g_object_set (cdata->single_param, "plugin", plugin, NULL);
}
if (plugin)
xmlFree (plugin);
......
......@@ -3204,16 +3204,10 @@ _parse_iso8601_time (GdaTime *timegda, const gchar *value, gchar sep, glong time
gchar *stz = NULL;
gchar *fs = NULL;
gdouble seconds = 0.0;
glong fraction = 0.0;
/* https://en.wikipedia.org/wiki/ISO_8601 */
/* Any invalid Time Zone designator set time zone to local*/
GTimeZone *tz = g_time_zone_new_local ();
gda_time_set_timezone (timegda, g_time_zone_get_offset (tz, 0));
glong fraction = 0;
int h, m, s;
GTimeZone *tz;
gda_time_set_hour (timegda, 0);
gda_time_set_minute (timegda, 0);
gda_time_set_second (timegda, 0);
gda_time_set_fraction (timegda, 0);
if ((*value < '0') || (*value > '9'))
return FALSE;
......@@ -3225,7 +3219,7 @@ _parse_iso8601_time (GdaTime *timegda, const gchar *value, gchar sep, glong time
if (tmp > 23)
return FALSE;
}
gda_time_set_hour (timegda, tmp);
h = tmp;
if ((sep && *endptr != sep) || !*endptr)
return FALSE;
......@@ -3237,7 +3231,7 @@ _parse_iso8601_time (GdaTime *timegda, const gchar *value, gchar sep, glong time
if (tmp > 59)
return FALSE;
}
gda_time_set_minute (timegda, tmp);
m = tmp;
if ((sep && *endptr != sep) || !*endptr)
return FALSE;
......@@ -3251,22 +3245,21 @@ _parse_iso8601_time (GdaTime *timegda, const gchar *value, gchar sep, glong time
*out_endptr = stz;
return FALSE;
}
gda_time_set_second (timegda, (gint) seconds);
/* Strip fraction */
fraction = (glong) ((seconds - (gint) seconds) * 1000000);
g_free (fs);
gda_time_set_fraction (timegda, fraction);
tz = g_time_zone_new_local ();
if (stz != NULL) {
g_time_zone_unref (tz);
tz = g_time_zone_new (stz);
if (tz != NULL) {
gda_time_set_timezone (timegda, g_time_zone_get_offset (tz, 0));
if (tz == NULL) {
tz = g_time_zone_new_local ();
}
for (; *endptr; endptr++);
}
GDateTime *dt = g_date_time_new (tz, 1978, 1, 1, h, m, seconds);
gda_time_set_from_date_time (timegda, dt);
g_time_zone_unref (tz);
if (tz != NULL)
g_time_zone_unref (tz);
*out_endptr = endptr;
return TRUE;
}
......
......@@ -1445,126 +1445,24 @@ gda_numeric_get_string (const GdaNumeric *numeric)
static void
time_to_string (const GValue *src, GValue *dest)
{
GdaTime *gdatime;
g_return_if_fail (G_VALUE_HOLDS_STRING (dest) &&
GDA_VALUE_HOLDS_TIME (src));
gdatime = (GdaTime *) gda_value_get_time ((GValue *) src);
if (gdatime) {
GString *string;
string = g_string_new ("");
g_string_append_printf (string, "%02u:%02u:%02u",
gda_time_get_hour (gdatime),
gda_time_get_minute (gdatime),
gda_time_get_second (gdatime));
if (gda_time_get_fraction (gdatime) != 0)
g_string_append_printf (string, ".%lu", gda_time_get_fraction (gdatime));
if (gda_time_get_timezone (gdatime) != GDA_TIMEZONE_INVALID)
g_string_append_printf (string, "%+02d", (int) gda_time_get_timezone (gdatime) / 3600);
g_value_take_string (dest, string->str);
g_string_free (string, FALSE);
gchar *str = gda_value_stringify (src);
if (g_strcmp0 ("", str) == 0) {
g_value_set_string (dest, "00:00:00+0");
} else {
g_value_set_string (dest, str);
}
else
g_value_set_string (dest, "00:00:00");
g_free (str);
}
/* Transform a String GValue to a GdaTime from a string like "12:30:15+01" */
static void
string_to_time (const GValue *src, GValue *dest)
{
/* FIXME: add more checks*/
GdaTime *timegda;
const gchar *as_string;
const gchar *ptr;
g_return_if_fail (G_VALUE_HOLDS_STRING (src) &&
GDA_VALUE_HOLDS_TIME (dest));
as_string = g_value_get_string (src);
if (!as_string)
return;
timegda = gda_time_new ();
/* hour */
gda_time_set_timezone (timegda, GDA_TIMEZONE_INVALID);
ptr = as_string;
if ((*ptr >= '0') && (*ptr <= '9') &&
(*(ptr+1) >= '0') && (*(ptr+1) <= '9'))
gda_time_set_hour (timegda, (*ptr - '0') * 10 + *(ptr+1) - '0');
else {
gda_time_free (timegda);
return;
}
/* minute */
ptr += 2;
if (! *ptr) {
gda_time_free (timegda);
return;
}
if (*ptr == ':')
ptr++;
if ((*ptr >= '0') && (*ptr <= '9') &&
(*(ptr+1) >= '0') && (*(ptr+1) <= '9'))
gda_time_set_minute (timegda, (*ptr - '0') * 10 + *(ptr+1) - '0');
else{
gda_time_free (timegda);
return;
}
/* second */
ptr += 2;
gda_time_set_second (timegda, 0);
if (! *ptr) {
if ((gda_time_get_hour (timegda) <= 24) && (gda_time_get_minute (timegda) <= 60))
gda_value_set_time (dest, timegda);
gda_time_free (timegda);
return;
}
if (*ptr == ':')
ptr++;
if ((*ptr >= '0') && (*ptr <= '9') &&
(*(ptr+1) >= '0') && (*(ptr+1) <= '9'))
gda_time_set_second (timegda, (*ptr - '0') * 10 + *(ptr+1) - '0');
/* extra */
ptr += 2;
if (! *ptr) {
if ((gda_time_get_hour (timegda) <= 24) && (gda_time_get_minute (timegda) <= 60) &&
(gda_time_get_second (timegda) <= 60))
gda_value_set_time (dest, timegda);
gda_time_free (timegda);
return;
}
if (*ptr == '.') {
gulong fraction = 0;
ptr ++;
while (*ptr && (*ptr >= '0') && (*ptr <= '9')) {
fraction = fraction * 10 + *ptr - '0';
ptr++;
}
}
if ((*ptr == '+') || (*ptr == '-')) {
glong sign = (*ptr == '+') ? 1 : -1;
gda_time_set_timezone (timegda, 0);
while (*ptr && (*ptr >= '0') && (*ptr <= '9')) {
gda_time_set_timezone (timegda, gda_time_get_timezone (timegda) * 10 + sign * ((*ptr) - '0'));
ptr++;
}
gda_time_set_timezone (timegda, gda_time_get_timezone (timegda) * 3600);
}
/* checks */
if ((gda_time_get_hour (timegda) <= 24) || (gda_time_get_minute (timegda) <= 60) || (gda_time_get_second (timegda) <= 60))
gda_value_set_time (dest, timegda);
gda_time_free (timegda);
const gchar *str = g_value_get_string (src);
GdaTime *time = gda_time_new ();
gda_parse_iso8601_time (time, str);
g_value_set_boxed (dest, time);
gda_time_free (time);
}
/**
......@@ -1576,11 +1474,7 @@ string_to_time (const GValue *src, GValue *dest)
* @timezone: number of seconds added to the GMT timezone
*/
struct _GdaTime {
gushort hour;
gushort minute;
gushort second;
gulong fraction;
GTimeSpan timezone;
GDateTime *dt;
};
GType
......@@ -1609,19 +1503,9 @@ GdaTime*
gda_time_copy (const GdaTime* time)
{
GdaTime *src = (GdaTime*) time;
GdaTime *copy = NULL;
g_return_val_if_fail (src, NULL);
copy = g_new0 (GdaTime, 1);
copy->hour = src->hour;
copy->minute = src->minute;
copy->second = src->second;
copy->fraction = src->fraction;
copy->timezone = src->timezone;
return copy;
GdaTime *c = g_new0(GdaTime, 1);
c->dt = g_date_time_add_days (time->dt, 0);
return c;
}
/**
......@@ -1633,6 +1517,7 @@ gda_time_copy (const GdaTime* time)
void
gda_time_free (GdaTime* boxed)
{
g_date_time_unref (boxed->dt);
g_free (boxed);
}
......@@ -1659,14 +1544,80 @@ gda_value_take_time (GValue *value, GdaTime *time)
/**
* gda_time_new:
*
* Creates a new #GdaTime structure.
* Creates a new #GdaTime with time now local.
*
* Returns: (transfer full): a new #GdaTime structure
*/
GdaTime*
gda_time_new (void)
{
return g_new0 (GdaTime, 1);
GdaTime *t = g_new0 (GdaTime, 1);
t->dt = g_date_time_new_now_local ();
return t;
}
/**
* gda_time_to_string:
*
* Creates a string representation of a #GdaTime in local time
* with the timezone designation.
*
* Returns: (transfer full): a new string
* Since: 6.0
*/
gchar*
gda_time_to_string (GdaTime *time)
{
gchar *str;
GTimeZone *tz = g_time_zone_new_local ();
GDateTime *ndt = g_date_time_to_timezone (time->dt, tz);
str = g_date_time_format (ndt, "%H:%M:%S%:::z");
g_time_zone_unref (tz);
g_date_time_unref (ndt);
return str;
}
/**
* gda_time_to_string_local:
*
* Creates a string representation of a #GdaTime in local time
* without timezone designation.
*
* Returns: (transfer full): a new string
* Since: 6.0
*/
gchar*
gda_time_to_string_local (GdaTime *time)
{
gchar *str;
GTimeZone *tz = g_time_zone_new_local ();
GDateTime *ndt = g_date_time_to_timezone (time->dt, tz);
str = g_date_time_format (ndt, "%H:%M:%S");
g_time_zone_unref (tz);
g_date_time_unref (ndt);
return str;
}
/**
* gda_time_to_string_utc:
*
* Creates a string representation of a #GdaTime in UTC time
* with time zone indication.
*
* Returns: (transfer full): a new string
* Since: 6.0
*/
gchar*
gda_time_to_string_utc (GdaTime *time)
{
gchar *str;
GTimeZone *tz = g_time_zone_new_utc ();
GDateTime *ndt = g_date_time_to_timezone (time->dt, tz);
str = g_date_time_format (ndt, "%H:%M:%S%:::z");
g_time_zone_unref (tz);
g_date_time_unref (ndt);
return str;
}
/**
......@@ -1675,7 +1626,7 @@ gda_time_new (void)
* @minute: minutes
* @second: seconds
* @fraction: fraction of seconds
* @timezone: timezone used
* @timezone: timezone in seconds added to UTC
*
* Returns: (transfer full): the a new value storing a time
*/
......@@ -1683,13 +1634,82 @@ GdaTime*
gda_time_new_from_values (gushort hour, gushort minute, gushort second, gulong fraction, glong timezone)
{
GdaTime* time = g_new0 (GdaTime, 1);
time->hour = hour;
time->minute = minute;
time->second = second;
time->fraction = fraction;
time->timezone = timezone;
gda_time_set_from_values (time, hour, minute, second, fraction, timezone);
return time;
}
/**
* gda_time_set_from_values:
* @time: a #GdaTime object to set values to
* @hour: hours
* @minute: minutes
* @second: seconds
* @fraction: fraction of seconds
* @timezone: timezone in seconds added to UTC
*
* Returns: (transfer full): the a new value storing a time
* Since: 6.0
*/
void
gda_time_set_from_values (GdaTime *time, gushort hour, gushort minute, gushort second, gulong fraction, glong timezone)
{
gdouble seconds = 0.0;
gchar *sec = g_strdup_printf ("%d.%lu", second, fraction);
seconds = g_ascii_strtod (sec, NULL);
g_free (sec);
gint h = timezone / 3600;
gint m = (timezone - h * 3600) / 60;
gint s = (timezone - h * 3600 - m * 60);
gint sig = h;
if (m < 0) {
m = -1 * m;
}
if (s < 0) {
s = -1 * s;
}
if (h < 0) {
h = -1 * h;
}
gchar *stz = g_strdup_printf ("%s%02d:%02d:%02d", sig < 0 ? "-" : "+", h, m, s);
GTimeZone *tz = g_time_zone_new (stz);
g_free (stz);
time->dt = g_date_time_new (tz,
1970,
1,
1,
(gint) hour,
(gint) minute,
seconds);
}
/**
* gda_time_new_from_date_time:
* @dt: a #GDateTime to get time from
*
* Returns: (transfer full): the a new value storing a time
* Since: 6.0
*/
GdaTime*
gda_time_new_from_date_time (GDateTime *dt)
{
GdaTime* time = g_new0 (GdaTime, 1);
time->dt = g_date_time_add_days (dt, 0);
return time;
}
/**
* gda_time_set_from_date_time:
* @dt: a #GDateTime to get time from
*
* Returns: (transfer full): the a new value storing a time
* Since: 6.0
*/
void
gda_time_set_from_date_time (GdaTime *time, GDateTime *dt)
{
time->dt = g_date_time_add_days (dt, 0);
}
/**
* gda_time_get_hour:
* @time: a #GdaTime value to get hours from
......@@ -1700,7 +1720,7 @@ gushort
gda_time_get_hour (const GdaTime* time)
{
g_return_val_if_fail (time != NULL, 0);
return time->hour;
return (gushort) g_date_time_get_hour (time->dt);
}
/**
* gda_time_set_hour:
......@@ -1713,7 +1733,11 @@ void
gda_time_set_hour (GdaTime* time, gushort hour)
{
g_return_if_fail (time != NULL);
time->hour = hour;
gda_time_new_from_values (hour,
gda_time_get_minute (time),
gda_time_get_second (time),
gda_time_get_fraction (time),
gda_time_get_timezone (time));
}
/**
* gda_time_get_minute:
......@@ -1725,7 +1749,7 @@ gushort
gda_time_get_minute (const GdaTime* time)
{
g_return_val_if_fail (time != NULL, 0);
return time->minute;
return (gushort) g_date_time_get_minute (time->dt);
}
/**
* gda_time_set_minute:
......@@ -1738,7 +1762,11 @@ void
gda_time_set_minute (GdaTime* time, gushort minute)
{
g_return_if_fail (time != NULL);
time->minute = minute;
gda_time_new_from_values (gda_time_get_hour (time),
minute,
gda_time_get_second (time),
gda_time_get_fraction (time),
gda_time_get_timezone (time));
}
/**
* gda_time_get_second:
......@@ -1750,7 +1778,7 @@ gushort
gda_time_get_second (const GdaTime* time)
{
g_return_val_if_fail (time != NULL, 0);
return time->second;
return (gushort) g_date_time_get_second (time->dt);
}
/**
* gda_time_set_second:
......@@ -1763,7 +1791,11 @@ void
gda_time_set_second (GdaTime* time, gushort second)
{
g_return_if_fail (time != NULL);
time->second = second;
gda_time_new_from_values (gda_time_get_hour (time),
gda_time_get_minute (time),
second,
gda_time_get_fraction (time),
gda_time_get_timezone (time));
}
/**
* gda_time_get_fraction:
......@@ -1775,7 +1807,14 @@ gulong
gda_time_get_fraction (const GdaTime* time)
{
g_return_val_if_fail (time != NULL, 0);
return time->fraction;
gdouble v = g_date_time_get_seconds (time->dt) - g_date_time_get_second (time->dt);
gchar *str = g_strdup_printf ("%0.6f", v);
for (int i = 0; i < 2; i++) {
str[i] = ' ';
}
gulong f = (gulong) g_ascii_strtoll ((const gchar*) str, NULL, 10);
g_free (str);
return f;
}
/**
* gda_time_set_fraction:
......@@ -1788,7 +1827,11 @@ void
gda_time_set_fraction (GdaTime* time, gulong fraction)
{
g_return_if_fail (time != NULL);
time->fraction = fraction;
gda_time_new_from_values (gda_time_get_hour (time),
gda_time_get_minute (time),
gda_time_get_second (time),
fraction,
gda_time_get_timezone (time));
}
/**
* gda_time_get_timezone:
......@@ -1802,8 +1845,26 @@ glong
gda_time_get_timezone (const GdaTime* time)
{
g_return_val_if_fail (time != NULL, 0);
return time->timezone;
glong tz = (glong) (g_date_time_get_utc_offset (time->dt) / 1000000);
return tz;
}
/**
* gda_time_get_tz:
* @time: a #GdaTime value to get time zone from
*
* Returns a #GTimeZone in use in this @time.
*
* Since: 6.0
*/
GTimeZone*
gda_time_get_tz (const GdaTime* time)
{
g_return_val_if_fail (time != NULL, 0);
const gchar *stz = g_date_time_get_timezone_abbreviation (time->dt);
GTimeZone *tz = g_time_zone_new (stz);
return tz;
}
/**
* gda_time_set_timezone:
* @time: a #GdaTime value to set time zone to
......@@ -1815,7 +1876,11 @@ void
gda_time_set_timezone (GdaTime* time, glong timezone)
{
g_return_if_fail (time != NULL);
time->timezone = timezone;
gda_time_new_from_values (gda_time_get_hour (time),
gda_time_get_minute (time),
gda_time_get_second (time),
gda_time_get_fraction (time),
timezone);
}
/**
......@@ -1824,6 +1889,7 @@ gda_time_set_timezone (GdaTime* time, glong timezone)
*
* Returns: #TRUE if #GdaTime is valid; %FALSE otherwise.
*
* Deprecated: 6.0
* Since: 4.2
*/
gboolean
......@@ -1831,14 +1897,6 @@ gda_time_valid (const GdaTime *time)
{
g_return_val_if_fail (time, FALSE);
if ((time->hour > 23) ||
(time->minute > 59) ||
(time->second > 59))
return FALSE;
if ((time->fraction >= 1000000) ||
(time->timezone <= -12 * 3600) ||
(time->timezone >= 12 * 3600))
return FALSE;
return TRUE;
}
......@@ -1860,35 +1918,47 @@ gda_time_change_timezone (GdaTime *time, glong ntz)
{
g_return_if_fail (time);
g_return_if_fail (gda_time_valid (time));
g_return_if_fail ((ntz > - 12 * 3600) && (ntz < 12 * 3600));
if (time->timezone == ntz)
return;
if (time->timezone != GDA_TIMEZONE_INVALID) {
glong nsec;
nsec = time->hour * 3600 + time->minute * 60 + time->second - time->timezone + ntz;
if (nsec < 0)
nsec += 86400;
else if (nsec >= 86400)
nsec -= 86400;
/* hours */
gint n;
n = nsec / 3600;
time->hour = (gushort) n;
gint h = ntz / 3600;
gint m = (ntz - h * 3600) / 60;
gint s = (ntz - h * 3600 - m * 60);
gint sig = h;
if (m < 0) {
m = -1 * m;
}
if (s < 0) {
s = -1 * s;
}
if (h < 0) {
h = -1 * h;
}
gchar *stz = g_strdup_printf ("%s%02d:%02d:%02d", sig < 0 ? "-" : "+", h, m, s);
GTimeZone *tz = g_time_zone_new (stz);
g_free (stz);
GDateTime *ndt = time->dt;
time->dt = g_date_time_to_timezone (time->dt, tz);
g_date_time_unref (ndt);
}
/* minutes */
nsec -= n * 3600;
n = nsec / 60;
time->minute = (gushort) n;
/* seconds */
nsec -= n * 60;
time->second = (gushort) nsec;
}
/**
* gda_time_to_timezone:
* @time: a valid #GdaTime
* @ntz: a new #GTimeZone to use
*
* Translate @time's to give timezone
*
* Since: 6.0
*/
void
gda_time_to_timezone (GdaTime *time, GTimeZone *ntz)
{
g_return_if_fail (time);
g_return_if_fail (gda_time_valid (time));
time->timezone = ntz;
GDateTime *ndt = time->dt;
time->dt = g_date_time_to_timezone (time->dt, ntz);
g_date_time_unref (ndt);
}
/**
......@@ -2025,42 +2095,6 @@ gda_value_new_blob_from_file (const gchar *filename)
return value;
}
/*
* Warning: DOES NOT modify @gmttm and loctm
*
* Returns: the offset, or G_MAXLONG in case of error
*/
static glong
compute_tz_offset (struct tm *gmttm, struct tm *loctm)
{
if (! gmttm || !loctm)
return G_MAXLONG;
struct tm cgmttm, cloctm;
cgmttm = *gmttm;
cloctm = *loctm;
time_t lt, gt;
cgmttm.tm_isdst = 0;
cloctm.tm_isdst = 0;
lt = mktime (&cloctm);
if (lt == -1)
return G_MAXLONG;
gt = mktime (&cgmttm);
if (gt == -1)
return G_MAXLONG;
glong off;
off = lt - gt;
/*g_print ("%s(): %02d:%02d:%02d %d\n", __FUNCTION__,
loctm->tm_hour, loctm->tm_min, loctm->tm_sec, (gint) (off / 3600));*/
if ((off >= 24 * 3600) || (off <= - 24 * 3600))
return G_MAXLONG;
else
return off;
}
/**
* gda_value_new_date_time:
*
......@@ -2139,54 +2173,12 @@ gda_value_new_date_time_from_timet (time_t val)
GValue *
gda_value_new_time_from_timet (time_t val)
{
GValue *value = NULL;
struct tm *ltm = NULL;
glong tz = 0;
#ifdef HAVE_LOCALTIME_R
struct tm gmttm, loctm;
tzset ();
ltm = localtime_r ((const time_t *) &val, &loctm);
tz = compute_tz_offset (gmtime_r ((const time_t *) &val, &gmttm), &loctm);
if (tz == G_MAXLONG)
ltm = NULL;
#elif HAVE_LOCALTIME_S
struct tm gmttm, loctm;
if ((localtime_s (&loctm, (const time_t *) &val) == 0) &&
(gmtime_s (&gmttm, (const time_t *) &val) == 0)) {
tz = compute_tz_offset (&gmttm, &loctm);
if (tz != G_MAXLONG)
ltm = &loctm;
}
#else
struct tm gmttm, loctm;
ltm = gmtime ((const time_t *) &val);
if (ltm) {
gmttm = *ltm;
ltm = localtime ((const time_t *) &val);
if (ltm) {
loctm = *ltm;
tz = compute_tz_offset (&gmttm, &loctm);
if (tz == G_MAXLONG)
ltm = NULL;
}
}
#endif
if (ltm) {
GdaTime tim;
tim.hour = ltm->tm_hour;
tim.minute = ltm->tm_min;
tim.second = ltm->tm_sec;
tim.fraction = 0;
tim.timezone = tz;
value = g_new0 (GValue, 1);
gda_value_set_time (value, (const GdaTime *) &tim);
}
GValue *value = gda_value_new (GDA_TYPE_TIME);
GDateTime *dt = g_date_time_new_from_unix_local (val);
GdaTime *t = gda_time_new_from_date_time (dt);
gda_value_set_time (value, t);
return value;
return value;
}
/**
......@@ -2812,6 +2804,15 @@ gda_value_stringify (const GValue *value)
else
return g_strdup ("0000-00-00");
}
else if (g_type_is_a (type, GDA_TYPE_TIME)) {
GdaTime *gts;
gts = (GdaTime*) g_value_get_boxed (value);
if (gts != NULL) {
return gda_time_to_string_utc (gts);
} else {
return "00:00:00+0";
}
}
else if (g_type_is_a (type, G_TYPE_DATE_TIME)) {
GDateTime *ts;
ts = (GDateTime*) g_value_get_boxed (value);
......
......@@ -99,10 +99,13 @@ typedef struct _GdaTime GdaTime;
GType gda_time_get_type (void) G_GNUC_CONST;
GdaTime* gda_time_new (void);
GdaTime* gda_time_new_from_date_time (GDateTime *dt);
GdaTime* gda_time_new_from_values (gushort hour, gushort minute, gushort second, gulong fraction, glong timezone);
GdaTime* gda_time_copy (const GdaTime* time);
void gda_time_free (GdaTime* time);
void gda_time_set_from_date_time (GdaTime *time, GDateTime *dt);
void gda_time_set_from_values (GdaTime *time, gushort hour, gushort minute, gushort second, gulong fraction, glong timezone);
gushort gda_time_get_hour (const GdaTime* time);
void gda_time_set_hour (GdaTime* time, gushort hour);
gushort gda_time_get_minute (const GdaTime* time);
......@@ -111,11 +114,16 @@ gushort gda_time_get_second (const GdaTime* time);
void gda_time_set_second (GdaTime* time, gushort second);
gulong gda_time_get_fraction (const GdaTime *time);
void gda_time_set_fraction (GdaTime* time, gulong fraction);
GTimeZone* gda_time_get_tz (const GdaTime *time);
glong gda_time_get_timezone (const GdaTime *time);
void gda_time_set_timezone (GdaTime* time, glong timezone);
gboolean gda_time_valid (const GdaTime *time);
void gda_time_change_timezone (GdaTime *time, glong ntz);
void gda_time_to_timezone (GdaTime *time, GTimeZone *ntz);
gchar* gda_time_to_string (GdaTime *time);
gchar* gda_time_to_string_local (GdaTime *time);
gchar* gda_time_to_string_utc (GdaTime *time);
/**
* GdaBinary: (ref-func gda_binary_new) (unref-func gda_binary_free) (get-value-func gda_value_get_binary) (set-value-func gda_value_set_binary)
......
......@@ -535,20 +535,13 @@ gda_handler_time_get_sql_from_value (GdaDataHandler *iface, const GValue *value)
}
}
else if (type == GDA_TYPE_TIME) {
const GdaTime *tim;
GString *string;
string = g_string_new ("");
tim = gda_value_get_time ((GValue *) value);
g_string_append_c (string, '\'');
g_string_append_printf (string, "%02d:%02d:%02d",
gda_time_get_hour (tim),
gda_time_get_minute (tim),
gda_time_get_second (tim));
if (gda_time_get_timezone (tim) != GDA_TIMEZONE_INVALID)
g_string_append_printf (string, "%+02d",
(int) gda_time_get_timezone (tim) / 3600);
g_string_append_c (string, '\'');
retval = g_string_free (string, FALSE);
GdaTime *gdat;
gchar *str;
gdat = (GdaTime*) g_value_get_boxed ((GValue *) value);
str = gda_time_to_string_utc (gdat);
retval = g_strdup_printf ("'%s'", str);
g_free (str);
}
else if (g_type_is_a (type, G_TYPE_DATE_TIME)) {
GDateTime *gdats;
......@@ -556,52 +549,13 @@ gda_handler_time_get_sql_from_value (GdaDataHandler *iface, const GValue *value)
gdats = (GDateTime*) g_value_get_boxed ((GValue *) value);
if (gdats != NULL)
retval = g_date_time_format (gdats, "'%FT%H:%M:%S%:::z'");
else
retval = g_strdup ("NULL");
}
else if (type == G_TYPE_DATE_TIME) { // FIXME: Remove
GDateTime *ts;
GDate *vdate;
ts = g_value_get_boxed ((GValue *) value);
if (ts) {
gint y, m, d;
g_date_time_get_ymd (ts, &y, &m, &d);
vdate = g_date_new_dmy (d, m, y);
str = render_date_locale (vdate, hdl->sql_locale);
g_date_free (vdate);
if (str) {
GString *string;
string = g_string_new ("");
g_string_append_printf (string, "%02u:%02u:%02u",
g_date_time_get_hour (ts),
g_date_time_get_minute (ts),
g_date_time_get_second (ts));
if (g_date_time_get_microsecond (ts) != 0)
g_string_append_printf (string, ".%d", g_date_time_get_microsecond (ts));
GTimeSpan span;
span = g_date_time_get_utc_offset (ts);
if (span > 0)
g_string_append_printf (string, "+%02d",
(int) (span / G_TIME_SPAN_HOUR));
else
g_string_append_printf (string, "-%02d",
(int) (-span / G_TIME_SPAN_HOUR));
retval = g_strdup_printf ("'%sT%s'", str, string->str);
g_free (str);
g_string_free (string, TRUE);
}
else
retval = g_strdup ("NULL");
}
else
retval = g_strdup ("NULL");
}
else
g_assert_not_reached ();
else {
g_warning (_("Time data handler can create an SQL representation of a value not holding time type."));
retval = g_strdup ("NULL");
}
return retval;
}
......
......@@ -776,7 +776,7 @@ gda_sqlite_recordset_fetch_next (GdaDataSelect *model, GdaRow **prow, gint rownu
gda_data_select_add_exception (GDA_DATA_SELECT (model), lerror);
if (error)
g_propagate_error (error, g_error_copy (lerror));
return TRUE;
return FALSE;
}
*prow = fetch_next_sqlite_row (imodel, FALSE, error);
imodel->priv->tmp_row = *prow;
......
......@@ -608,8 +608,10 @@ static void
vcontext_free (VContext *context)
{
GObject *obj = g_weak_ref_get (&(context->context_object));
g_hash_table_remove (context->vtable->context.hash, obj);
g_object_unref (obj);
if (obj) {
g_hash_table_remove (context->vtable->context.hash, obj);
g_object_unref (obj);
}
if (context->context_data) {
g_array_free (context->context_data, TRUE);
context->context_data = NULL;
......
......@@ -151,7 +151,7 @@ gda_vconnection_hub_get_type (void)
* gda_vconnection_hub_add:
* @hub: a #GdaVconnectionHub connection
* @cnc: a #GdaConnection
* @ns: (nullable): a namespace, or %NULL
* @ns: a namespace, or %NULL
* @error: a place to store errors, or %NULL
*
* Make all the tables of @cnc appear as tables (of the same name) in the @hub connection.
......@@ -171,12 +171,19 @@ gda_vconnection_hub_add (GdaVconnectionHub *hub,
g_return_val_if_fail (GDA_IS_VCONNECTION_HUB (hub), FALSE);
g_return_val_if_fail (GDA_IS_CONNECTION (cnc), FALSE);
if (hc == NULL) {
g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
GDA_SERVER_PROVIDER_MISUSE_ERROR,
"%s", _("Namespace must be specified"));
return FALSE;
}
/* check for constraints */
hc = get_hub_cnc_by_ns (hub, ns);
if (hc && (hc->cnc != cnc)) {
g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
GDA_SERVER_PROVIDER_MISUSE_ERROR,
"%s", _("Namespace must be specified"));
_("There is already a namespace named '%s' in use with another connection"), ns);
return FALSE;
}
......@@ -186,16 +193,15 @@ gda_vconnection_hub_add (GdaVconnectionHub *hub,
if (!gda_connection_is_opened (cnc)) {
g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
GDA_SERVER_PROVIDER_MISUSE_ERROR,
"%s", _("Connection is closed"));
_("Connection was not added to virtual connection because it is closed"));
return FALSE;
}
/* actually adding @cnc */
hc = g_new (HubConnection, 1);
hc->hub = hub;
hc->cnc = cnc;
g_object_ref (cnc);
hc->ns = ns ? g_strdup (ns) : NULL;
hc->cnc = GDA_CONNECTION (g_object_ref (cnc));
hc->ns = g_strdup (ns);
if (!attach_hub_connection (hub, hc, error)) {
hub_connection_free (hc);
......@@ -240,6 +246,7 @@ gda_vconnection_hub_remove (GdaVconnectionHub *hub, GdaConnection *cnc, GError *
static HubConnection*
get_hub_cnc_by_ns (GdaVconnectionHub *hub, const gchar *ns)
{
g_return_val_if_fail (ns != NULL, NULL);
GSList *list;
for (list = hub->priv->hub_connections; list; list = list->next) {
if ((!ns && !((HubConnection*) list->data)->ns)||
......@@ -757,6 +764,7 @@ dict_table_create_model_func (GdaVconnectionDataModelSpec *spec, G_GNUC_UNUSED i
gint i;
GSList *list;
stmt = GDA_STATEMENT (idxStr);
g_assert (GDA_IS_STATEMENT (stmt));
if (! gda_statement_get_parameters (stmt, &params, NULL))
return NULL;
if (argc > 0) {
......
......@@ -112,7 +112,7 @@ do_a_test (GdaServerProvider *prov, GdaSqlParser *parser)
}
}
gchar *expected;
expected = "('@@@@@@@@@@T17:10:23+02', '16:09:22-3')";
expected = "('@@@@@@@@@@T17:10:23+02', '19:09:22+00')";
if (cnc)
sql = gda_connection_statement_to_sql (cnc, stmt, params, 0, NULL, &error);
else
......@@ -136,7 +136,7 @@ do_a_test (GdaServerProvider *prov, GdaSqlParser *parser)
}
g_free (sql);
expected = "('@@@@@@@@@@T15:10:23+00', '19:09:22')";
expected = "('@@@@@@@@@@T15:10:23+00', '19:09:22+00')";
if (cnc)
sql = gda_connection_statement_to_sql (cnc, stmt, params, GDA_STATEMENT_SQL_TIMEZONE_TO_GMT, NULL, &error);
else
......@@ -198,7 +198,7 @@ do_a_test (GdaServerProvider *prov, GdaSqlParser *parser)
goto endtest;
}
expected = "('@@@@@@@@@@T17:10:23+02', '16:09:22-3')";
expected = "('@@@@@@@@@@T17:10:23+02', '19:09:22+00')";
if (cnc)
sql = gda_connection_statement_to_sql (cnc, stmt, params, 0, NULL, &error);
else
......@@ -222,7 +222,7 @@ do_a_test (GdaServerProvider *prov, GdaSqlParser *parser)
}
g_free (sql);
expected = "('@@@@@@@@@@T15:10:23+00', '19:09:22')";
expected = "('@@@@@@@@@@T15:10:23+00', '19:09:22+00')";
if (cnc)
sql = gda_connection_statement_to_sql (cnc, stmt, params, GDA_STATEMENT_SQL_TIMEZONE_TO_GMT, NULL, &error);
else
......
......@@ -51,7 +51,7 @@ static void browser_window_class_init (BrowserWindowClass *klass);
static void browser_window_init (BrowserWindow *bwin);
static void browser_window_dispose (GObject *object);
static gboolean key_press_event (GtkWidget *widget, GdkEventKey *event);
static gboolean key_press_event (GtkWidget *widget, GdkEventKey *event, gpointer userdata);
static void transaction_status_changed_cb (TConnection *tcnc, BrowserWindow *bwin);
static void cnc_status_changed_cb (TConnection *tcnc, GdaConnectionStatus status, BrowserWindow *bwin);
......@@ -130,7 +130,6 @@ browser_window_class_init (BrowserWindowClass *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
widget_class->key_press_event = key_press_event;
parent_class = g_type_class_peek_parent (klass);
browser_window_signals[FULLSCREEN_CHANGED] =
......@@ -154,6 +153,7 @@ browser_window_init (BrowserWindow *bwin)
bwin->priv->pers_list = NULL;
bwin->priv->updating_transaction_status = FALSE;
bwin->priv->fullscreen = FALSE;
g_signal_connect (G_OBJECT (bwin), "key-press-event", G_CALLBACK (key_press_event), NULL);
}
static void
......@@ -630,7 +630,7 @@ change_perspective_cb (GSimpleAction *action, GVariant *state, gpointer data)
}
static gboolean
key_press_event (GtkWidget *widget, GdkEventKey *event)
key_press_event (GtkWidget *widget, GdkEventKey *event, gpointer userdata)
{
if ((event->keyval == GDK_KEY_Escape) &&
browser_window_is_fullscreen (BROWSER_WINDOW (widget))) {
......@@ -638,8 +638,7 @@ key_press_event (GtkWidget *widget, GdkEventKey *event)
return TRUE;
}
/* parent class */
return GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event);
return FALSE;
}
static void
......
......@@ -213,22 +213,18 @@ static void
create_layout (ConnectionBindingProperties *cprop)
{
GtkWidget *label, *hbox;
gchar *str;
GString *str;
GtkWidget *dcontents;
dcontents = gtk_dialog_get_content_area (GTK_DIALOG (cprop));
gtk_container_set_border_width (GTK_CONTAINER (dcontents), 10);
str = g_strdup_printf ("<b>%s:</b>\n<small>%s</small>",
_("Virtual connection's properties"),
_("The virtual connection you are about to define can bind tables "
"from an existing connection as well as bind a data set which will "
"appear as a table (importing CSV data for example). "
"You can add as many binds as needed"));
str = g_string_new (_("Virtual connection's properties."));
g_string_append (str, _("The virtual connection you are about to define can bind tables from an existing connection as well as bind a data set which will appear as a table (importing CSV data for example). You can add as many binds as needed"));
label = gtk_label_new ("");
gtk_label_set_markup (GTK_LABEL (label), str);
g_free (str);
gtk_label_set_markup (GTK_LABEL (label), str->str);
g_string_free (str, TRUE);
gtk_widget_set_halign (label, GTK_ALIGN_START);
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
gtk_box_pack_start (GTK_BOX (dcontents), label, FALSE, FALSE, 0);
......@@ -553,7 +549,8 @@ create_part_for_cnc (ConnectionBindingProperties *cprop, TVirtualConnectionPart
"SCHEMA", G_TYPE_STRING, cnc->table_schema);
holder = gda_holder_new (T_TYPE_CONNECTION, "CNC");
g_object_set (holder, "name", "Connection", "not-null", TRUE, NULL);
g_object_set (holder, "name", _("Connection"), "not-null", TRUE,
"description", _("Connection to get tables from in the schema"), NULL);
g_assert (gda_set_add_holder (set, holder));
g_value_set_object ((value = gda_value_new (T_TYPE_CONNECTION)), cnc->source_cnc);
......@@ -565,7 +562,7 @@ create_part_for_cnc (ConnectionBindingProperties *cprop, TVirtualConnectionPart
g_object_unref (holder);
holder = gda_set_get_holder (set, "SCHEMA");
g_object_set (holder, "name", "Schema",
g_object_set (holder, "name", _("Schema"),
"description", _("Name of the schema the\ntables will be in"), NULL);
form = gdaui_basic_form_new (set);
......
......@@ -3078,7 +3078,7 @@ extra_command_bind_cnc (ToolCommand *command, guint argc, const gchar **argv,
gda_connection_get_meta_store (virtual); /* force create of meta store */
/* add existing connections to virtual connection */
string = g_string_new (_("Bound connections are as:"));
string = g_string_new (_("Connections were bound as:"));
for (i = 1; i < nargv; i++) {
tcnc = t_connection_get_by_name (argv[i]);
if (tcnc) {
......
......@@ -533,7 +533,7 @@ t_connection_dispose (GObject *object)
tcnc->priv->dict_file_name = NULL;
}
TO_IMPLEMENT;
// FIXME: TO_IMPLEMENT;
/*
if (tcnc->priv->meta_store_signal)
gda_thread_wrapper_disconnect (tcnc->priv->wrapper,
......