void FE_Utils::create_uses_multiple_stuff (AST_Component *c, AST_Uses *u, const char *prefix) { ACE_CString struct_name (prefix); if (!struct_name.empty ()) { struct_name += '_'; } struct_name += u->local_name ()->get_string (); struct_name += "Connection"; Identifier struct_id (struct_name.c_str ()); UTL_ScopedName sn (&struct_id, 0); // In case this call comes from the backend. We // will pop the scope before returning. idl_global->scopes ().push (c); AST_Structure *connection = idl_global->gen ()->create_structure (&sn, 0, 0); struct_id.destroy (); /// If the field type is a param holder, we want /// to use the lookup to create a fresh one, /// since the field will own it and destroy it. UTL_ScopedName *fn = u->uses_type ()->name (); AST_Decl *d = idl_global->root ()->lookup_by_name (fn, true, false); AST_Type *ft = AST_Type::narrow_from_decl (d); Identifier object_id ("objref"); UTL_ScopedName object_name (&object_id, 0); AST_Field *object_field = idl_global->gen ()->create_field (ft, &object_name, AST_Field::vis_NA); (void) DeclAsScope (connection)->fe_add_field (object_field); object_id.destroy (); Identifier local_id ("Cookie"); UTL_ScopedName local_name (&local_id, 0); Identifier module_id ("Components"); UTL_ScopedName scoped_name (&module_id, &local_name); d = c->lookup_by_name (&scoped_name, true); local_id.destroy (); module_id.destroy (); if (d == 0) { // This would happen if we haven't included Components.idl. idl_global->err ()->lookup_error (&scoped_name); return; } AST_ValueType *cookie = AST_ValueType::narrow_from_decl (d); Identifier cookie_id ("ck"); UTL_ScopedName cookie_name (&cookie_id, 0); AST_Field *cookie_field = idl_global->gen ()->create_field (cookie, &cookie_name, AST_Field::vis_NA); (void) DeclAsScope (connection)->fe_add_field (cookie_field); cookie_id.destroy (); (void) c->fe_add_structure (connection); ACE_CDR::ULong bound = 0; AST_Expression *bound_expr = idl_global->gen ()->create_expr (bound, AST_Expression::EV_ulong); AST_Sequence *sequence = idl_global->gen ()->create_sequence (bound_expr, connection, 0, 0, 0); ACE_CString seq_string (struct_name); seq_string += 's'; Identifier seq_id (seq_string.c_str ()); UTL_ScopedName seq_name (&seq_id, 0); AST_Typedef *connections = idl_global->gen ()->create_typedef (sequence, &seq_name, 0, 0); seq_id.destroy (); (void) c->fe_add_typedef (connections); // In case this call comes from the backend. idl_global->scopes ().pop (); }
// DB2 identity options in GENERATED ALWAYS or BY DEFAULT AS IDENTITY bool SqlParser::ParseDb2GeneratedClause(Token *create, Token *table_name, Token *column, Token *generated, Token **id_col, Token **id_start, Token **id_inc, bool *id_default) { if(generated == NULL) return false; Token *always = GetNextWordToken("ALWAYS", L"ALWAYS", 6); Token *by = NULL; Token *default_ = NULL; if(always == NULL) { by = GetNextWordToken("BY", L"BY", 2); default_ = GetNextWordToken("DEFAULT", L"DEFAULT", 7); if(id_default != NULL) *id_default = true; } else { if(id_default != NULL) *id_default = false; } Token *as = GetNextWordToken("AS", L"AS", 2); Token *identity = GetNextWordToken("IDENTITY", L"IDENTITY", 8); // Identity parameters are optional Token *open = GetNextCharToken('(', L'('); Token *close = NULL; Token *start_with = NULL; Token *increment_by = NULL; while(true) { bool exists = false; if(open == NULL) break; Token *option = GetNextToken(); if(option == NULL) break; // START WITH if(option->Compare("START", L"START", 5) == true) { /*Token *with */ (void) GetNextWordToken("WITH", L"WITH", 4); start_with = GetNextNumberToken(); exists = true; continue; } else // INCREMENT BY if(option->Compare("INCREMENT", L"INCREMENT", 9) == true) { /*Token *by */ (void) GetNextWordToken("BY", L"BY", 2); increment_by = GetNextNumberToken(); exists = true; continue; } else // MINVALUE if(option->Compare("MINVALUE", L"MINVALUE", 8) == true) { /*Token *value */ (void) GetNextNumberToken(); exists = true; continue; } else // MAXVALUE if(option->Compare("MAXVALUE", L"MAXVALUE", 8) == true) { /*Token *value */ (void) GetNextNumberToken(); exists = true; continue; } else // NO CYCLE and NO ORDER if(option->Compare("NO", L"NO", 2) == true) { /*Token *attr */ (void) GetNextToken(); exists = true; continue; } else // CACHE if(option->Compare("CACHE", L"CACHE", 5) == true) { /*Token *value */ (void) GetNextNumberToken(); exists = true; continue; } else // CYCLE if(option->Compare("CYCLE", L"CYCLE", 5) == true) { exists = true; continue; } else // Looks like comma is optional if(option->Compare(',', L',') == true) { exists = true; continue; } PushBack(option); break; } if(open != NULL) close = GetNextCharToken(')', L')'); // IDENTITY(start, inc) in SQL Server if(_target == SQL_SQL_SERVER) { Token::Change(generated, "IDENTITY(", L"IDENTITY(", 9); AppendCopy(generated, start_with); if(increment_by != NULL) { Append(generated, ", ", L", ", 2); AppendCopy(generated, increment_by); } Append(generated, ")", L")", 1); if(always != NULL) Token::Remove(always, close); else Token::Remove(by, close); } else // Use a sequence and DEFAULT nextval for PostgreSQL and Greenplum if(_target == SQL_POSTGRESQL || _target == SQL_GREENPLUM) { TokenStr seq_name(table_name); AppendIdentifier(seq_name, "_seq", L"_seq", 4); // Generate CREATE SEQUENCE before CREATE TABLE Prepend(create, "CREATE SEQUENCE ", L"CREATE SEQUENCE ", 16); PrependNoFormat(create, &seq_name); if(start_with != NULL) { Prepend(create, " START WITH ", L" START WITH ", 12); PrependCopy(create, start_with); } if(increment_by != NULL) { Prepend(create, " INCREMENT BY ", L" INCREMENT BY ", 14); PrependCopy(create, increment_by); } Prepend(create, ";\n\n", L";\n\n", 3); // Generate DEFAULT nextval('tablename_seq') clause Token::Change(generated, "DEFAULT ", L"DEFAULT ", 8); Append(generated, "nextval ('", L"nextval ('", 10); AppendNoFormat(generated, &seq_name); Append(generated, "')", L"')", 2); if(always != NULL) Token::Remove(always, close); else Token::Remove(by, close); } else // Remove for other databases if(_target != SQL_DB2) { Token::Remove(generated); Token::Remove(always); Token::Remove(by, default_); Token::Remove(as, identity); Token::Remove(open, close); } if(id_col != NULL) *id_col = column; if(id_start != NULL) *id_start = start_with; if(id_inc != NULL) *id_inc = increment_by; return true; }