Beispiel #1
0
int
create_table(){
  NdbDictionary::Dictionary* dict = g_ndb->getDictionary();
  assert(dict);
  if(g_paramters[P_CREATE].value){
    g_ndb->getDictionary()->dropTable(g_tablename);
    const NdbDictionary::Table * pTab = NDBT_Tables::getTable(g_tablename);
    assert(pTab);
    NdbDictionary::Table copy = * pTab;
    copy.setLogging(false);
    if(dict->createTable(copy) != 0){
      g_err << "Failed to create table: " << g_tablename << endl;
      return -1;
    }

    NdbDictionary::Index x(g_indexname);
    x.setTable(g_tablename);
    x.setType(NdbDictionary::Index::OrderedIndex);
    x.setLogging(false);
    for (unsigned k = 0; k < copy.getNoOfColumns(); k++){
      if(copy.getColumn(k)->getPrimaryKey()){
	x.addColumnName(copy.getColumn(k)->getName());
      }
    }

    if(dict->createIndex(x) != 0){
      g_err << "Failed to create index: " << endl;
      return -1;
    }
  }
  g_table = dict->getTable(g_tablename);
  g_index = dict->getIndex(g_indexname, g_tablename);
  assert(g_table);
  assert(g_index);

  if(g_paramters[P_CREATE].value)
  {
    int rows = g_paramters[P_ROWS].value;
    HugoTransactions hugoTrans(* g_table);
    if (hugoTrans.loadTable(g_ndb, rows)){
      g_err.println("Failed to load %s with %d rows", 
		    g_table->getName(), rows);
      return -1;
    }
  }
  
  return 0;
}
Beispiel #2
0
int
NDBT_TestSuite::createHook(Ndb* ndb, NdbDictionary::Table& tab, int when)
{
  if (when == 0) {
    if (diskbased) 
    {
      for (int i = 0; i < tab.getNoOfColumns(); i++) 
      {
        NdbDictionary::Column* col = tab.getColumn(i);
        if (! col->getPrimaryKey()) 
	{
          col->setStorageType(NdbDictionary::Column::StorageTypeDisk);
        }
      }
    }
    else if (temporaryTables)
    {
      tab.setTemporary(true);
      tab.setLogging(false);
    }
    
    if (tsname != NULL) {
      tab.setTablespaceName(tsname);
    }
  }
  return 0;
}
Beispiel #3
0
Handle<Object> GetTableCall::buildDBIndex(const NdbDictionary::Index *idx) {
  HandleScope scope;
  
  Local<Object> obj = NdbDictIndexEnv.newWrapper();
  wrapPointerInObject(idx, NdbDictIndexEnv, obj);

  obj->Set(String::NewSymbol("name"), String::New(idx->getName()));
  obj->Set(String::NewSymbol("isUnique"),     
           Boolean::New(idx->getType() == NdbDictionary::Index::UniqueHashIndex),
           ReadOnly);
  obj->Set(String::NewSymbol("isOrdered"),
           Boolean::New(idx->getType() == NdbDictionary::Index::OrderedIndex),
           ReadOnly);
  
  /* Loop over the columns of the key. 
     Build the "columns" array and the "record" object, then set both.
  */  
  int ncol = idx->getNoOfColumns();
  Local<Array> idx_columns = Array::New(ncol);
  DEBUG_PRINT("Creating Index Record (%s)", idx->getName());
  Record * idx_record = new Record(arg0->dict, ncol);
  for(int i = 0 ; i < ncol ; i++) {
    const char *colName = idx->getColumn(i)->getName();
    const NdbDictionary::Column *col = ndb_table->getColumn(colName);
    idx_columns->Set(i, v8::Int32::New(col->getColumnNo()));
    idx_record->addColumn(col);
  }
  idx_record->completeIndexRecord(idx);
  obj->Set(String::NewSymbol("record"), Record_Wrapper(idx_record), ReadOnly);
  obj->Set(String::NewSymbol("columnNumbers"), idx_columns);
  
  return scope.Close(obj);
}
Beispiel #4
0
/* 
DBIndex = {
  name             : ""    ,  // Index name; undefined for PK 
  isPrimaryKey     : true  ,  // true for PK; otherwise undefined
  isUnique         : true  ,  // true or false
  isOrdered        : true  ,  // true or false; can scan if true
  columnNumbers    : []    ,  // an ordered array of column numbers
};
*/
Handle<Object> GetTableCall::buildDBIndex_PK() {
  HandleScope scope;
  
  Local<Object> obj = Object::New();

  obj->Set(String::NewSymbol("isPrimaryKey"), Boolean::New(true), ReadOnly);
  obj->Set(String::NewSymbol("isUnique"),     Boolean::New(true), ReadOnly);
  obj->Set(String::NewSymbol("isOrdered"),    Boolean::New(false), ReadOnly);

  /* Loop over the columns of the key. 
     Build the "columnNumbers" array and the "record" object, then set both.
  */  
  int ncol = ndb_table->getNoOfPrimaryKeys();
  DEBUG_PRINT("Creating Primary Key Record");
  Record * pk_record = new Record(arg0->dict, ncol);
  Local<Array> idx_columns = Array::New(ncol);
  for(int i = 0 ; i < ncol ; i++) {
    const char * col_name = ndb_table->getPrimaryKey(i);
    const NdbDictionary::Column * col = ndb_table->getColumn(col_name);
    pk_record->addColumn(col);
    idx_columns->Set(i, v8::Int32::New(col->getColumnNo()));
  }
  pk_record->completeTableRecord(ndb_table);

  obj->Set(String::NewSymbol("columnNumbers"), idx_columns);
  obj->Set(String::NewSymbol("record"), Record_Wrapper(pk_record), ReadOnly);
 
  return scope.Close(obj);
}
Beispiel #5
0
Handle<Object> GetTableCall::buildDBIndex(const NdbDictionary::Index *idx) {
  EscapableHandleScope scope(isolate);

  Local<Object> obj = NdbDictIndexEnv.newWrapper();
  wrapPointerInObject(idx, NdbDictIndexEnv, obj);

  SET_RO_PROPERTY(obj, SYMBOL(isolate, "name"), String::NewFromUtf8(isolate, idx->getName()));
  SET_RO_PROPERTY(obj, SYMBOL(isolate, "isPrimaryKey"), Boolean::New(isolate, false));
  SET_RO_PROPERTY(obj, SYMBOL(isolate, "isUnique"),
                Boolean::New(isolate, idx->getType() == NdbDictionary::Index::UniqueHashIndex));
  SET_RO_PROPERTY(obj, SYMBOL(isolate, "isOrdered"),
                Boolean::New(isolate, idx->getType() == NdbDictionary::Index::OrderedIndex));
  
  /* Loop over the columns of the key. 
     Build the "columns" array and the "record" object, then set both.
  */  
  int ncol = idx->getNoOfColumns();
  Local<Array> idx_columns = Array::New(isolate, ncol);
  DEBUG_PRINT("Creating Index Record (%s)", idx->getName());
  Record * idx_record = new Record(dict, ncol);
  for(int i = 0 ; i < ncol ; i++) {
    const char *colName = idx->getColumn(i)->getName();
    const NdbDictionary::Column *col = ndb_table->getColumn(colName);
    idx_columns->Set(i, v8::Int32::New(isolate, col->getColumnNo()));
    idx_record->addColumn(col);
  }
  idx_record->completeIndexRecord(idx);
  SET_RO_PROPERTY(obj, SYMBOL(isolate, "record"), Record_Wrapper(idx_record));
  obj->Set(SYMBOL(isolate, "columnNumbers"), idx_columns);
  
  return scope.Escape(obj);
}
Beispiel #6
0
/* 
DBIndex = {
  name             : ""    ,  // Index name
  isPrimaryKey     : true  ,  // true for PK; otherwise undefined
  isUnique         : true  ,  // true or false
  isOrdered        : true  ,  // true or false; can scan if true
  columnNumbers    : []    ,  // an ordered array of column numbers
};
*/
Handle<Object> GetTableCall::buildDBIndex_PK() {
  EscapableHandleScope scope(isolate);
  
  Local<Object> obj = Object::New(isolate);

  SET_RO_PROPERTY(obj, SYMBOL(isolate, "name"), String::NewFromUtf8(isolate, "PRIMARY_KEY"));
  SET_RO_PROPERTY(obj, SYMBOL(isolate, "isPrimaryKey"), Boolean::New(isolate, true));
  SET_RO_PROPERTY(obj, SYMBOL(isolate, "isUnique"),     Boolean::New(isolate, true));
  SET_RO_PROPERTY(obj, SYMBOL(isolate, "isOrdered"),    Boolean::New(isolate, false));

  /* Loop over the columns of the key. 
     Build the "columnNumbers" array and the "record" object, then set both.
  */  
  int ncol = ndb_table->getNoOfPrimaryKeys();
  DEBUG_PRINT("Creating Primary Key Record");
  Record * pk_record = new Record(dict, ncol);
  Local<Array> idx_columns = Array::New(isolate, ncol);
  for(int i = 0 ; i < ncol ; i++) {
    const char * col_name = ndb_table->getPrimaryKey(i);
    const NdbDictionary::Column * col = ndb_table->getColumn(col_name);
    pk_record->addColumn(col);
    idx_columns->Set(i, v8::Int32::New(isolate, col->getColumnNo()));
  }
  pk_record->completeTableRecord(ndb_table);

  obj->Set(SYMBOL(isolate, "columnNumbers"), idx_columns);
  SET_RO_PROPERTY(obj, SYMBOL(isolate, "record"), Record_Wrapper(pk_record));

  return scope.Escape(obj);
}
int
create_table() {
    NdbDictionary::Dictionary* dict = g_ndb->getDictionary();
    assert(dict);
    if(g_paramters[P_CREATE].value) {
        const NdbDictionary::Table * pTab = NDBT_Tables::getTable(g_table);
        assert(pTab);
        NdbDictionary::Table copy = * pTab;
        copy.setLogging(false);
        if(dict->createTable(copy) != 0) {
            g_err << "Failed to create table: " << g_table << endl;
            return -1;
        }

        NdbDictionary::Index x(g_ordered);
        x.setTable(g_table);
        x.setType(NdbDictionary::Index::OrderedIndex);
        x.setLogging(false);
        for (unsigned k = 0; k < copy.getNoOfColumns(); k++) {
            if(copy.getColumn(k)->getPrimaryKey()) {
                x.addColumn(copy.getColumn(k)->getName());
            }
        }

        if(dict->createIndex(x) != 0) {
            g_err << "Failed to create index: " << endl;
            return -1;
        }

        x.setName(g_unique);
        x.setType(NdbDictionary::Index::UniqueHashIndex);
        if(dict->createIndex(x) != 0) {
            g_err << "Failed to create index: " << endl;
            return -1;
        }
    }
    g_tab = dict->getTable(g_table);
    g_i_unique = dict->getIndex(g_unique, g_table);
    g_i_ordered = dict->getIndex(g_ordered, g_table);
    assert(g_tab);
    assert(g_i_unique);
    assert(g_i_ordered);
    return 0;
}
static int
g_create_hook(Ndb* ndb, NdbDictionary::Table& tab, int when, void* arg)
{
  if (when == 0) {
    if (g_diskbased) {
      for (int i = 0; i < tab.getNoOfColumns(); i++) {
        NdbDictionary::Column* col = tab.getColumn(i);
        if (! col->getPrimaryKey()) {
          col->setStorageType(NdbDictionary::Column::StorageTypeDisk);
        }
      }
    }
    if (g_tsname != NULL) {
      tab.setTablespaceName(g_tsname);
    }
  }
  return 0;
}
Beispiel #9
0
NDBT_ResultRow::NDBT_ResultRow(const NdbDictionary::Table& tab,
			       char attrib_delimiter)
  : cols(0), names(NULL), data(NULL), m_ownData(false), m_table(tab)
{
  ad[0] = attrib_delimiter;
  ad[1] = 0;

  if (tab.getObjectStatus() == NdbDictionary::Object::Retrieved)
  {
    cols  = tab.getNoOfColumns();
    names = new char *       [cols];
    data  = new NdbRecAttr * [cols];
  
    for(int i = 0; i<cols; i++){
      names[i] = new char[255];
      strcpy(names[i], tab.getColumn(i)->getName());
    }  
  }
}
Beispiel #10
0
/*
 * ForeignKeyMetadata = {
  name             : ""    ,  // Constraint name
  columnNames      : null  ,  // an ordered array of column numbers
  targetTable      : ""    ,  // referenced table name
  targetDatabase   : ""    ,  // referenced database name
  targetColumnNames: null  ,  // an ordered array of target column names
};
*/
Handle<Object> GetTableCall::buildDBForeignKey(const NdbDictionary::ForeignKey *fk) {
  HandleScope scope;
  DictionaryNameSplitter localSplitter;
  Local<Object> js_fk = Object::New();

  localSplitter.splitName(fk->getName());  // e.g. "12/20/fkname"
  js_fk->Set(String::NewSymbol("name"), String::New(localSplitter.part3));

  // get child column names
  unsigned int childColumnCount = fk->getChildColumnCount();
  Local<Array> fk_child_column_names = Array::New(childColumnCount);
  for (unsigned i = 0; i < childColumnCount; ++i) {
    int columnNumber = fk->getChildColumnNo(i);
    const NdbDictionary::Column * column = ndb_table->getColumn(columnNumber);
    fk_child_column_names->Set(i, String::New(column->getName()));
  }
  js_fk->Set(String::NewSymbol("columnNames"), fk_child_column_names);

  // get parent table (which might be in a different database)
  const char * fk_parent_name = fk->getParentTable();
  localSplitter.splitName(fk_parent_name);
  const char * parent_db_name = localSplitter.part1;
  const char * parent_table_name = localSplitter.part3;
  js_fk->Set(String::NewSymbol("targetTable"), String::New(parent_table_name));
  js_fk->Set(String::NewSymbol("targetDatabase"), String::New(parent_db_name));
  ndb->setDatabaseName(parent_db_name);
  const NdbDictionary::Table * parent_table = dict->getTable(parent_table_name);
  ndb->setDatabaseName(dbName);

  // get parent column names
  unsigned int parentColumnCount = fk->getParentColumnCount();
  Local<Array> fk_parent_column_names = Array::New(parentColumnCount);
  for (unsigned i = 0; i < parentColumnCount; ++i) {
    int columnNumber = fk->getParentColumnNo(i);
    const NdbDictionary::Column * column = parent_table->getColumn(columnNumber);
    fk_parent_column_names->Set(i, String::New( column->getName()));
  }
  js_fk->Set(String::NewSymbol("targetColumnNames"), fk_parent_column_names);

  return scope.Close(js_fk);
}
Beispiel #11
0
int
create_table(){
  NdbDictionary::Dictionary* dict = g_ndb->getDictionary();
  assert(dict);
  if(g_paramters[P_CREATE].value){
    g_ndb->getDictionary()->dropTable(g_tablename);
    const NdbDictionary::Table * pTab = NDBT_Tables::getTable(g_tablename);
    assert(pTab);
    NdbDictionary::Table copy = * pTab;
    copy.setLogging(false);
    if(dict->createTable(copy) != 0){
      g_err << "Failed to create table: " << g_tablename << endl;
      return -1;
    }

    NdbDictionary::Index x(g_indexname);
    x.setTable(g_tablename);
    x.setType(NdbDictionary::Index::OrderedIndex);
    x.setLogging(false);
    for (unsigned k = 0; k < (unsigned) copy.getNoOfColumns(); k++){
      if(copy.getColumn(k)->getPrimaryKey()){
	x.addColumnName(copy.getColumn(k)->getName());
      }
    }

    if(dict->createIndex(x) != 0){
      g_err << "Failed to create index: " << endl;
      return -1;
    }
  }
  g_table = dict->getTable(g_tablename);
  g_index = dict->getIndex(g_indexname, g_tablename);
  assert(g_table);
  assert(g_index);

  /* Obtain NdbRecord instances for the table and index */
  {
    NdbDictionary::RecordSpecification spec[ NDB_MAX_ATTRIBUTES_IN_TABLE ];
    
    Uint32 offset=0;
    Uint32 cols= g_table->getNoOfColumns();
    for (Uint32 colNum=0; colNum<cols; colNum++)
    {
      const NdbDictionary::Column* col= g_table->getColumn(colNum);
      Uint32 colLength= col->getLength();
      
      spec[colNum].column= col;
      spec[colNum].offset= offset;

      offset+= colLength;

      spec[colNum].nullbit_byte_offset= offset++;
      spec[colNum].nullbit_bit_in_byte= 0;
    }
  
    g_table_record= dict->createRecord(g_table,
                                       &spec[0],
                                       cols,
                                       sizeof(NdbDictionary::RecordSpecification));

    assert(g_table_record);
  }
  {
    NdbDictionary::RecordSpecification spec[ NDB_MAX_ATTRIBUTES_IN_TABLE ];
    
    Uint32 offset=0;
    Uint32 cols= g_index->getNoOfColumns();
    for (Uint32 colNum=0; colNum<cols; colNum++)
    {
      /* Get column from the underlying table */
      // TODO : Add this mechanism to dict->createRecord
      // TODO : Add NdbRecord queryability methods so that an NdbRecord can
      // be easily built and later used to read out data.
      const NdbDictionary::Column* col= 
        g_table->getColumn(g_index->getColumn(colNum)->getName());
      Uint32 colLength= col->getLength();
      
      spec[colNum].column= col;
      spec[colNum].offset= offset;

      offset+= colLength;

      spec[colNum].nullbit_byte_offset= offset++;
      spec[colNum].nullbit_bit_in_byte= 0;
    }
  
    g_index_record= dict->createRecord(g_index,
                                       &spec[0],
                                       cols,
                                       sizeof(NdbDictionary::RecordSpecification));

    assert(g_index_record);
  }


  if(g_paramters[P_CREATE].value)
  {
    int rows = g_paramters[P_ROWS].value;
    HugoTransactions hugoTrans(* g_table);
    if (hugoTrans.loadTable(g_ndb, rows)){
      g_err.println("Failed to load %s with %d rows", 
		    g_table->getName(), rows);
      return -1;
    }
  }
  
  return 0;
}
Beispiel #12
0
/* doAsyncCallback() runs in the main thread.  We don't want it to block.
   TODO: verify whether any IO is done 
         by checking WaitMetaRequestCount at the start and end.
*/    
void GetTableCall::doAsyncCallback(Local<Object> ctx) {
  HandleScope scope;  
  DEBUG_PRINT("GetTableCall::doAsyncCallback: return_val %d", return_val);

  /* User callback arguments */
  Handle<Value> cb_args[2];
  cb_args[0] = Null();
  cb_args[1] = Null();
  
  /* TableMetadata = {
      database         : ""    ,  // Database name
      name             : ""    ,  // Table Name
      columns          : []    ,  // ordered array of DBColumn objects
      indexes          : []    ,  // array of DBIndex objects 
      partitionKey     : []    ,  // ordered array of column numbers in the partition key
    };
  */    
  if(ndb_table && ! return_val) {

    Local<Object> table = NdbDictTableEnv.newWrapper();
    wrapPointerInObject(ndb_table, NdbDictTableEnv, table);

    // database
    table->Set(String::NewSymbol("database"), String::New(arg1));
    
    // name
    table->Set(String::NewSymbol("name"), String::New(ndb_table->getName()));
    
    // columns
    Local<Array> columns = Array::New(ndb_table->getNoOfColumns());
    for(int i = 0 ; i < ndb_table->getNoOfColumns() ; i++) {
      Handle<Object> col = buildDBColumn(ndb_table->getColumn(i));
      columns->Set(i, col);
    }
    table->Set(String::NewSymbol("columns"), columns);

    // indexes (primary key & secondary) 
    Local<Array> js_indexes = Array::New(idx_list.count + 1);
    js_indexes->Set(0, buildDBIndex_PK());                   // primary key
    for(unsigned int i = 0 ; i < idx_list.count ; i++) {   // secondary indexes
      const NdbDictionary::Index * idx =
        arg0->dict->getIndex(idx_list.elements[i].name, arg2);


      js_indexes->Set(i+1, buildDBIndex(idx));
    }    
    table->Set(String::NewSymbol("indexes"), js_indexes, ReadOnly);

    // partitionKey
    
  
    // Table Record (implementation artifact; not part of spec)
    DEBUG_PRINT("Creating Table Record");
    Record * rec = new Record(arg0->dict, ndb_table->getNoOfColumns());
    for(int i = 0 ; i < ndb_table->getNoOfColumns() ; i++) {
      rec->addColumn(ndb_table->getColumn(i));
    }
    rec->completeTableRecord(ndb_table);

    table->Set(String::NewSymbol("record"), Record_Wrapper(rec));    
    
    // User Callback
    cb_args[1] = table;
  }
  else {
    cb_args[0] = String::New(arg0->dict->getNdbError().message);
  }
  
  callback->Call(ctx, 2, cb_args);
}
Beispiel #13
0
/* doAsyncCallback() runs in the main thread.  We don't want it to block.
   TODO: verify whether any IO is done 
         by checking WaitMetaRequestCount at the start and end.
*/    
void GetTableCall::doAsyncCallback(Local<Object> ctx) {
  const char *tableName;
  HandleScope scope;  
  DEBUG_PRINT("GetTableCall::doAsyncCallback: return_val %d", return_val);

  /* User callback arguments */
  Handle<Value> cb_args[2];
  cb_args[0] = Null();
  cb_args[1] = Null();
  
  /* TableMetadata = {
      database         : ""    ,  // Database name
      name             : ""    ,  // Table Name
      columns          : []    ,  // ordered array of DBColumn objects
      indexes          : []    ,  // array of DBIndex objects 
      partitionKey     : []    ,  // ordered array of column numbers in the partition key
    };
  */    
  if(ndb_table && ! return_val) {

    Local<Object> table = NdbDictTableEnv.newWrapper();
    const NdbDictionary::Table * js_ndb_table = ndb_table;
    wrapPointerInObject(js_ndb_table, NdbDictTableEnv, table);

    // database
    table->Set(String::NewSymbol("database"), String::New(arg1));
    
    // name
    tableName = ndb_table->getName();
    table->Set(String::NewSymbol("name"), String::New(tableName));

    // partitionKey
    int nPartitionKeys = 0;
    Handle<Array> partitionKeys = Array::New();
    table->Set(String::NewSymbol("partitionKey"), partitionKeys);
    
    // columns
    Local<Array> columns = Array::New(ndb_table->getNoOfColumns());
    for(int i = 0 ; i < ndb_table->getNoOfColumns() ; i++) {
      const NdbDictionary::Column *ndb_col = ndb_table->getColumn(i);
      Handle<Object> col = buildDBColumn(ndb_col);
      columns->Set(i, col);
      if(ndb_col->getPartitionKey()) { /* partition key */
        partitionKeys->Set(nPartitionKeys++, String::New(ndb_col->getName()));
      }
    }
    table->Set(String::NewSymbol("columns"), columns);

    // indexes (primary key & secondary) 
    Local<Array> js_indexes = Array::New(idx_list.count + 1);
    js_indexes->Set(0, buildDBIndex_PK());                   // primary key
    for(unsigned int i = 0 ; i < idx_list.count ; i++) {   // secondary indexes
      const NdbDictionary::Index * idx =
        dict->getIndex(idx_list.elements[i].name, arg2);
      js_indexes->Set(i+1, buildDBIndex(idx));
    }    
    table->Set(String::NewSymbol("indexes"), js_indexes, ReadOnly);
  
    // Table Record (implementation artifact; not part of spec)
    DEBUG_PRINT("Creating Table Record");
    Record * rec = new Record(dict, ndb_table->getNoOfColumns());
    for(int i = 0 ; i < ndb_table->getNoOfColumns() ; i++) {
      rec->addColumn(ndb_table->getColumn(i));
    }
    rec->completeTableRecord(ndb_table);

    table->Set(String::NewSymbol("record"), Record_Wrapper(rec));    

    // foreign keys (only foreign keys for which this table is the child)
    // now create the javascript foreign key metadata objects for dictionary objects cached earlier
    Local<Array> js_fks = Array::New(fk_count);

    int fk_number = 0;
    for(unsigned int i = 0 ; i < fk_list.count ; i++) {
      NdbDictionary::ForeignKey fk;
      if (fk_list.elements[i].type == NdbDictionary::Object::ForeignKey) {
        const char * fk_name = fk_list.elements[i].name;
        int fkGetCode = dict->getForeignKey(fk, fk_name);
        DEBUG_PRINT("getForeignKey for %s returned %i", fk_name, fkGetCode);
        // see if the foreign key child table is this table
        if(splitNameMatchesDbAndTable(fk.getChildTable())) {
          // the foreign key child table is this table; build the fk object
          DEBUG_PRINT("Adding foreign key for %s at %i", fk.getName(), fk_number);
          js_fks->Set(fk_number++, buildDBForeignKey(&fk));
        }
      }
    }
    table->Set(String::NewSymbol("foreignKeys"), js_fks, ReadOnly);

    // Autoincrement Cache Impl (also not part of spec)
    if(per_table_ndb) {
      table->Set(String::NewSymbol("per_table_ndb"), Ndb_Wrapper(per_table_ndb));
    }
    
    // User Callback
    cb_args[1] = table;
  }
  else {
    cb_args[0] = NdbError_Wrapper(* ndbError);
  }
  
  callback->Call(ctx, 2, cb_args);
}
Beispiel #14
0
/* doAsyncCallback() runs in the main thread.  We don't want it to block.
   TODO: verify whether any IO is done 
         by checking WaitMetaRequestCount at the start and end.
*/    
void GetTableCall::doAsyncCallback(Local<Object> ctx) {
  const char *ndbTableName;
  EscapableHandleScope scope(isolate);
  DEBUG_PRINT("GetTableCall::doAsyncCallback: return_val %d", return_val);

  /* User callback arguments */
  Handle<Value> cb_args[2];
  cb_args[0] = Null(isolate);
  cb_args[1] = Null(isolate);
  
  /* TableMetadata = {
      database         : ""    ,  // Database name
      name             : ""    ,  // Table Name
      columns          : []    ,  // ordered array of DBColumn objects
      indexes          : []    ,  // array of DBIndex objects 
      partitionKey     : []    ,  // ordered array of column numbers in the partition key
      sparseContainer  : null     // default column for sparse fields
    };
  */    
  if(ndb_table && ! return_val) {
    Local<Object> table = NdbDictTableEnv.wrap(ndb_table)->ToObject();

    // database
    table->Set(SYMBOL(isolate, "database"), String::NewFromUtf8(isolate, arg1));
    
    // name
    ndbTableName = ndb_table->getName();
    table->Set(SYMBOL(isolate, "name"), String::NewFromUtf8(isolate, ndbTableName));

    // partitionKey
    int nPartitionKeys = 0;
    Handle<Array> partitionKeys = Array::New(isolate);
    table->Set(SYMBOL(isolate, "partitionKey"), partitionKeys);

    // sparseContainer
    table->Set(SYMBOL(isolate,"sparseContainer"), Null(isolate));

    // columns
    Local<Array> columns = Array::New(isolate, ndb_table->getNoOfColumns());
    for(int i = 0 ; i < ndb_table->getNoOfColumns() ; i++) {
      const NdbDictionary::Column *ndb_col = ndb_table->getColumn(i);
      Handle<Object> col = buildDBColumn(ndb_col);
      columns->Set(i, col);
      if(ndb_col->getPartitionKey()) { /* partition key */
        partitionKeys->Set(nPartitionKeys++, String::NewFromUtf8(isolate, ndb_col->getName()));
      }
      if(     ! strcmp(ndb_col->getName(), "SPARSE_FIELDS")
          && ( (! strncmp(getColumnType(ndb_col), "VARCHAR", 7)
                  && (getEncoderCharsetForColumn(ndb_col)->isUnicode))
              || (   ! strncmp(getColumnType(ndb_col), "VARBINARY", 9)
                  || ! strncmp(getColumnType(ndb_col), "JSON", 4))))
      {
        table->Set(SYMBOL(isolate,"sparseContainer"),
                   String::NewFromUtf8(isolate, ndb_col->getName()));
      }
    }
    table->Set(SYMBOL(isolate, "columns"), columns);

    // indexes (primary key & secondary) 
    Local<Array> js_indexes = Array::New(isolate, idx_list.count + 1);
    js_indexes->Set(0, buildDBIndex_PK());                   // primary key
    for(unsigned int i = 0 ; i < idx_list.count ; i++) {   // secondary indexes
      const NdbDictionary::Index * idx =
        dict->getIndex(idx_list.elements[i].name, arg2);
      js_indexes->Set(i+1, buildDBIndex(idx));
    }    
    SET_RO_PROPERTY(table, SYMBOL(isolate, "indexes"), js_indexes);

    // foreign keys (only foreign keys for which this table is the child)
    // now create the javascript foreign key metadata objects for dictionary objects cached earlier
    Local<Array> js_fks = Array::New(isolate, fk_count);

    int fk_number = 0;
    for(unsigned int i = 0 ; i < fk_list.count ; i++) {
      NdbDictionary::ForeignKey fk;
      if (fk_list.elements[i].type == NdbDictionary::Object::ForeignKey) {
        const char * fk_name = fk_list.elements[i].name;
        int fkGetCode = dict->getForeignKey(fk, fk_name);
        DEBUG_PRINT("getForeignKey for %s returned %i", fk_name, fkGetCode);
        // see if the foreign key child table is this table
        if(splitNameMatchesDbAndTable(fk.getChildTable())) {
          // the foreign key child table is this table; build the fk object
          DEBUG_PRINT("Adding foreign key for %s at %i", fk.getName(), fk_number);
          js_fks->Set(fk_number++, buildDBForeignKey(&fk));
        }
      }
    }
    SET_RO_PROPERTY(table, SYMBOL(isolate, "foreignKeys"), js_fks);

    // Autoincrement Cache Impl (also not part of spec)
    if(per_table_ndb) {
      table->Set(SYMBOL(isolate, "per_table_ndb"), Ndb_Wrapper(per_table_ndb));
    }
    
    // User Callback
    cb_args[1] = table;
  }
  else {
    cb_args[0] = NdbError_Wrapper(* ndbError);
  }
  
  ToLocal(& callback)->Call(ctx, 2, cb_args);
}