~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/js/js.cc

  • Committer: Henrik Ingo
  • Date: 2011-09-21 20:52:28 UTC
  • mto: This revision was merged to the branch mainline in revision 2439.
  • Revision ID: henrik.ingo@avoinelama.fi-20110921205228-56l0x31iedgnmolp
Arguments that are of type DATETIME are now created as JavaScript
Date objects. Needed to export the Temporal family of classes
to be able to compute unix timestamp value with set_epoch_seconds().

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
#include <drizzled/error.h>
24
24
#include <drizzled/plugin/function.h>
25
25
#include <drizzled/function/str/strfunc.h>
 
26
#include <drizzled/temporal.h>
26
27
 
27
28
#include <v8.h>
28
29
#define JS_ENGINE "v8"
71
72
};
72
73
 
73
74
/**
74
 
 * Extracts a C string from a V8 Utf8Value
 
75
 * @brief Extracts a C string from a V8 Utf8Value
75
76
 * 
76
77
 * Idea copied from v8 sources, samples/shell.cc. Makes code easier to read than
77
78
 * (char *)(*utf8value)
116
117
}
117
118
 
118
119
/**
119
 
 * Implements js() - execute JavaScript code
 
120
 * @brief Implements js() - execute JavaScript code
120
121
 * 
121
122
 * @todo datetime and row_result types are not yet handled
122
123
 * @todo Some of the v8 stuff should be done in initialize()
190
191
    } else if ( args[n]->result_type() == REAL_RESULT || args[n]->result_type() == DECIMAL_RESULT ) {
191
192
      a->Set( n-1, v8::Number::New(args[n]->val_real() ) );
192
193
    } else if ( true || args[n]->result_type() == STRING_RESULT ) {
193
 
      // Default to creating string values in JavaScript
194
 
      a->Set( n-1, v8::String::New(args[n]->val_str(str)->c_str() ) );
 
194
      if ( args[n]->is_datetime() ) {
 
195
        // DATE/TIME values are also STRING_RESULT, make them a Date type in v8
 
196
        // Now we need to get the unix timestamp integer, surprisingly tricky...
 
197
        // TODO: This should really be just args[n]->get_epoch_seconds(). I need to write a separate patch for Item class one of these days.
 
198
        type::Time ltime;
 
199
        Timestamp temporal;
 
200
        args[n]->get_date(ltime, 0);
 
201
        temporal.set_years(ltime.year);
 
202
        temporal.set_months(ltime.month);
 
203
        temporal.set_days(ltime.day);
 
204
        temporal.set_hours(ltime.hour);
 
205
        temporal.set_minutes(ltime.minute);
 
206
        temporal.set_seconds(ltime.second);
 
207
        temporal.set_epoch_seconds();
 
208
        if (temporal.is_valid())
 
209
        {
 
210
          time_t tmp;
 
211
          temporal.to_time_t(tmp);
 
212
          // Pay attention, Ecmascript defines a date as *milliseconds* since unix epoch
 
213
          // Also, on platforms where time_t is 32 bit, we need explicit cast to 64 bit integer
 
214
          a->Set( n-1, v8::Date::New(((uint64_t)tmp)*1000) );
 
215
        } else {
 
216
          a->Set( n-1, v8::String::New(args[n]->val_str(str)->c_str() ) );
 
217
        }
 
218
      } else {
 
219
        // Default to creating string values in JavaScript
 
220
        a->Set( n-1, v8::String::New(args[n]->val_str(str)->c_str() ) );
 
221
      }
195
222
    }
196
223
    // If user has given a name to the arguments, pass these as global variables
197
224
    if( ! args[n]->is_autogenerated_name ) {
198
225
      if( args[n]->result_type() == INT_RESULT ){
199
226
        if( args[n]->is_unsigned() ) {
200
 
          context->Global()->Set( v8::String::New(args[n]->name ), v8::Integer::NewFromUnsigned( (uint32_t) args[n]->val_uint() ) );
 
227
          context->Global()->Set( v8::String::New( args[n]->name ), v8::Integer::NewFromUnsigned( (uint32_t) args[n]->val_uint() ) );
201
228
        } else {
202
 
          context->Global()->Set( v8::String::New(args[n]->name ), v8::Integer::New((int32_t)args[n]->val_int() ) );
 
229
          context->Global()->Set( v8::String::New( args[n]->name ), v8::Integer::New((int32_t)args[n]->val_int() ) );
203
230
        }
204
231
      } else if ( args[n]->result_type() == REAL_RESULT || args[n]->result_type() == DECIMAL_RESULT ) {
205
 
        context->Global()->Set( v8::String::New(args[n]->name ), v8::Number::New(args[n]->val_real() ) );
 
232
        context->Global()->Set( v8::String::New( args[n]->name ), v8::Number::New(args[n]->val_real() ) );
206
233
      } else if ( true || args[n]->result_type() == STRING_RESULT ) {
207
 
        context->Global()->Set( v8::String::New(args[n]->name ), v8::String::New(args[n]->val_str(str)->c_str() ) );
 
234
      if ( args[n]->is_datetime() ) {
 
235
        // DATE/TIME values are also STRING_RESULT, make them a Date type in v8
 
236
        // Now we need to get the unix timestamp integer, surprisingly tricky...
 
237
        // TODO: This should really be just args[n]->get_epoch_seconds(). I need to write a separate patch for Item class one of these days.
 
238
        type::Time ltime;
 
239
        Timestamp temporal;
 
240
        args[n]->get_date(ltime, 0);
 
241
        temporal.set_years(ltime.year);
 
242
        temporal.set_months(ltime.month);
 
243
        temporal.set_days(ltime.day);
 
244
        temporal.set_hours(ltime.hour);
 
245
        temporal.set_minutes(ltime.minute);
 
246
        temporal.set_seconds(ltime.second);
 
247
        temporal.set_epoch_seconds();
 
248
        if (temporal.is_valid())
 
249
        {
 
250
          time_t tmp;
 
251
          temporal.to_time_t(tmp);
 
252
          // Pay attention, Ecmascript defines a date as *milliseconds* since unix epoch
 
253
          // Also, on platforms where time_t is 32 bit, we need explicit cast to 64 bit integer
 
254
          context->Global()->Set( v8::String::New( args[n]->name ), v8::Date::New(((uint64_t)tmp)*1000) );
 
255
        } else {
 
256
          context->Global()->Set( v8::String::New( args[n]->name ), v8::String::New(args[n]->val_str(str)->c_str() ) );
 
257
        }
 
258
      } else {
 
259
        context->Global()->Set( v8::String::New( args[n]->name ), v8::String::New(args[n]->val_str(str)->c_str() ) );
 
260
      }
208
261
      }
209
262
    }
210
263
  }