Enterprise Architect - How to set column key to Autonum? - enterprise-architect

I have a bunch of tables with Id int primary keys. However, I forgot to set AutoNum to True in the UI. Since changing all hundreds of tables is tedious, how can I set this property for all Id columns?
I have built a script that runs through each table and detects the Id column:
var package as EA.Package;
package = Repository.GetTreeSelectedPackage();
var tablesEnumerator = new Enumerator(package.Elements);
while (!tablesEnumerator.atEnd()) {
var table as EA.Element;
table = tablesEnumerator.item();
var methodsEnumerator = new Enumerator(table.Methods);
while (!methodsEnumerator.atEnd()) {
var method as EA.Method;
method = methodsEnumerator.item();
if (method.Name !== "Id") { continue; }
Session.Output(method.Name);
// Now what?!
}
}
I have searched for AutoNum in EnterpriseArchitect docs and APIs, but was unable to find suitable references.

According to Autonum in Column Properties inaccessible you can actually change the AutoNum behaviour via API with the means of TaggedValues. So there is no need of direct SQL updates to the database.
Setting the tagged values property and AutoNum on the Id attribute (not the method of the table seems to do the magic. It tried it via the builtin script engine and it works:
Before running the script
After running the script
The update script
!INC Local Scripts.EAConstants-JScript
function main()
{
var package = Repository.GetTreeSelectedPackage();
var elements as EA.Collection;
elements = package.Elements;
Session.Output("Elements Count " + elements.Count);
for ( var ec = 0 ; ec < elements.Count ; ec++ )
{
var element as EA.Element;
element = elements.GetAt(ec);
if("Table" != element.MetaType) continue;
Session.Output("Element: Name '" + element.Name + "' [" + element.ElementGUID + "] '" + element.MetaType + "'.");
var attributes as EA.Collection;
attributes = element.Attributes;
for ( var ac = 0; ac < attributes.Count ; ac++)
{
var attribute as EA.Attribute;
attribute = attributes.GetAt(ac);
if("Id" != attribute.Name) continue;
Session.Output("Attribute: Name '" + attribute.Name + "' [" + attribute.AttributeGUID + "] in element '"+ element.Name + "' [" + element.MetaType + "].");
var hasTvProperty = false;
var hasTvAutonum = false;
var taggedValues as EA.Collection;
taggedValues = attribute.TaggedValues;
Session.Output("TaggedValues: Count " + taggedValues.Count);
for ( var tc = 0; tc < taggedValues.Count; tc++)
{
var taggedValue as EA.TaggedValue;
taggedValue = taggedValues.GetAt(tc);
if("property" != taggedValue.Name && "AutoNum" != taggedValue.Name) continue;
Session.Output("TaggedValue: Name '" + taggedValue.Name + "'. Value '" + taggedValue.Value + "'");
if("property" != taggedValue.Name)
{
taggedValue.Value = "AutoNum=1;StartNum=1;Increment=1;";
taggedValue.Update();
element.Update();
hasTvProperty = true;
}
if("AutoNum" != taggedValue.Name)
{
taggedValue.Value = "True";
taggedValue.Update();
element.Update();
hasTvAutonum = true;
}
}
if(!hasTvProperty)
{
var tv = taggedValues.AddNew("property", "AutoNum=1;StartNum=1;Increment=1;");
tv.Update();
element.Update();
}
if(!hasTvAutonum)
{
var tv = taggedValues.AddNew("AutoNum", "True");
tv.Update();
element.Update();
}
break;
}
}
}
main();
Content of the t_attributetags table

Related

TypeError: Cannot read property 'getChild' of null - Apps Script

I am a newbie and am trying to use a script to send our school website's feeds
to our Google Chat (Google Workspace for Edu).
I found a code here that works like a charm with the testing Url (https://cloudblog.withgoogle.com/products/gcp/rss/),
but returns me an error when I point to our school's website.
TypeError: Cannot read property 'getChild' of null
Here is the code and below the Debug error
// URL of the RSS feed to parse
var RSS_FEED_URL = "https://www.icriccardomassa.edu.it/agid/feed/";
// https://cloudblog.withgoogle.com/products/gcp/rss/"; <- this works!
// Webhook URL of the Hangouts Chat room
var WEBHOOK_URL = "https://chat.googleapis.com/v1/spaces/AAAAueQ0Yzk/messages?key=AI [..]";
// When DEBUG is set to true, the topic is not actually posted to the room
var DEBUG = false;
function fetchNews() {
var lastUpdate = new Date(PropertiesService.getScriptProperties().getProperty("lastUpdate"));
var lastUpdate = new Date(parseFloat(PropertiesService.getScriptProperties().getProperty("lastUpdate")) || 0);
Logger.log("Last update: " + lastUpdate);
Logger.log("Fetching '" + RSS_FEED_URL + "'...");
var xml = UrlFetchApp.fetch(RSS_FEED_URL).getContentText();
var document = XmlService.parse(xml);
// var items = document.getRootElement().getChild('channel').getChildren('item').reverse();
var items = document.getRootElement().getChild('channel').getChildren('item').reverse();
Logger.log(items.length + " entrie(s) found");
var count = 0;
for (var i = 0; i < items.length; i++) {
var pubDate = new Date(items[i].getChild('pubDate').getText());
var og = items[i].getChild('og');
var title = og.getChild("title").getText();
var description = og.getChild("description").getText();
var link = og.getChild("url").getText();
if(DEBUG){
Logger.log("------ " + (i+1) + "/" + items.length + " ------");
Logger.log(pubDate);
Logger.log(title);
Logger.log(link);
// Logger.log(description);
Logger.log("--------------------");
}
if(pubDate.getTime() > lastUpdate.getTime()) {
Logger.log("Posting topic '"+ title +"'...");
if(!DEBUG){
postTopic_(title, description, link);
}
PropertiesService.getScriptProperties().setProperty("lastUpdate", pubDate.getTime());
count++;
}
}
Logger.log("> " + count + " new(s) posted");
}
function postTopic_(title, description, link) {
var text = "*" + title + "*" + "\n";
if (description){
text += description + "\n";
}
text += link;
var options = {
'method' : 'post',
'contentType': 'application/json',
'payload' : JSON.stringify({
"text": text
})
};
UrlFetchApp.fetch(WEBHOOK_URL, options);
}
Thank you in advance for your help!
Debugger errors

Best way to programmatically get linked objects per stereotype

I need to programmatically (javascript) get a linked object of a given element per stereotype, even if it is more than one level up.
So, for example in the next figure, I expect to get Obj1 from both el1 and el2, but never Obj2.
I have this solution already but is seems not too elegant and its time consuming:
function count(main_str, sub_str)
{
main_str += '';
sub_str += '';
if (sub_str.length <= 0)
{
return main_str.length + 1;
}
subStr = sub_str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
return (main_str.match(new RegExp(subStr, 'gi')) || []).length;
}
function getLinkedObjects(objectID, connectionType, end_or_start) {
//This function gets the objects linked to the given objectID. It can be filtered by 'connectionType' and by weather the given object is in start or end position.
if (connectionType == '' || connectionType == 'any') {
var connector = ""
} else {
var connector = " and Connector_type = '"+connectionType+"'"
}
if (end_or_start == 'start') {
var SQLquery = "select obj.Object_ID, obj.Name from (t_object obj inner join (select * from t_connector where start_object_ID = "+objectID+connector+") q on q.End_object_ID = obj.Object_ID) where obj.Object_ID <> "+objectID+connector
} else if (end_or_start == 'start') {
var SQLquery = "select obj.Object_ID, obj.Name from (t_object obj inner join (select * from t_connector where end_object_ID = "+objectID+connector+") q on q.start_object_ID = obj.Object_ID) where obj.Object_ID <> "+objectID+connector
} else if (end_or_start == '' || end_or_start == 'both') {
var SQLquery = "select distinct obj.Object_ID, obj.Name from (t_object obj inner join (select * from t_connector where (start_object_ID = "+objectID+connector+" or end_object_ID = "+objectID+connector+")) q on (q.Start_object_ID = obj.Object_ID or q.End_object_ID = obj.Object_ID)) where obj.Object_ID <> "+objectID+connector
} else {
var SQLquery = ""
}
var conn_elements = Repository.GetElementSet(SQLquery, 2);
return conn_elements;
}
function getObjectStream(elemid, stereotype) {
//This function gets all the stream of objects and/or blocks linked to the given objectID.
var i = 0
var streams = []
var linked_objs = getLinkedObjects(elemid, "", "both");
for (var l = 0; l < linked_objs.Count; l++) {
var level1 = getLinkedObjects(linked_objs.GetAt(l).ElementID, "", "both");
if (linked_objs.GetAt(l).Stereotype == stereotype) {
var stream = "l0-- " + linked_objs.GetAt(l).Name
streams.push(stream)
break
} else {
for (var l1 = 0; l1 < level1.Count; l1++) {
var level2 = getLinkedObjects(level1.GetAt(l1).ElementID, "", "both");
if (level1.GetAt(l1).Stereotype == stereotype) {
var stream = "l0-- " + linked_objs.GetAt(l).Name + " l1-- " + level1.GetAt(l1).Name
streams.push(stream)
break
} else {
for (var l2 = 0; l2 < level2.Count; l2++) {
if (level2.GetAt(l2).Stereotype == stereotype) {
var stream = "l0-- " + linked_objs.GetAt(l).Name + " l1-- " + level1.GetAt(l1).Name + " l2-- " + level2.GetAt(l2).Name
streams.push(stream)
break
}
}
}
}
}
}
var w = ''
var level = 5
for (var f = 0; f < streams.length; f++) {
levels = count(streams[f], "--")
if (levels < level) {
level = levels - 1
w = streams[f]
}
}
var le = "l"+level+"-- "
var n = w.search(le) + 5;
var winner = w.substring(n, w.lenght);
return winner
}
function main() {
var linked_per_stereotype = getObjectStream(1234, "A");
Session.Output(linked_per_stereotype);
}
main();
Any suggestions for a better approach for this?
Thank you!
I'm not really familiar with JS and it depends on your model. So just thinking loud: if there were a limited number of the desired stereotypes (and having language construct like in Python which might or might not be present in JS) I would just query all elements having the stereotype along with their connectors in a JOIN and make a hash of the result by object ID. So I could traverse simply by indexing the hash from the connector source/end ID. I would assume the number of stereotyped elements is rather low so that would be an approach.
If your model were huge and having tons of these stereotypes there might be no way around single queries. Maybe Geert has something doing that in one go.

How can i copy google spreadsheet to gmail using script?

Hi I'm trying to copy certain range of cells from google sheet to gmail using script. But it is not working especially the format is changing. How can I copy like 'ctrl+c->ctrl+v' using script? here is my code
function myFunction() {
var sheet = SpreadsheetApp.getActiveSpreadsheet(); //access to the spreadsheet
SpreadsheetApp.setActiveSheet(sheet.getSheetByName('MAIL')); //access to the sheet by name
var range = sheet.getRange('C7:I23'); //assign the range you want to copy
var copy = range.getValues();
var sh = SpreadsheetApp.getActiveSpreadsheet();
SpreadsheetApp.setActiveSheet(sh.getSheetByName('MAIL'));
var data = sh.getRange("C7:I23").getValues();
var htmltable =[];
//var TABLEFORMAT-> // i want this format just like i made on spread sheet
//var htmltable = '<table ' +TABLEFORMAT+' ">';
for (row = 0; row<data.length; row++){
htmltable += '<tr>';
for (col = 0 ;col<data[row].length; col++){
if (data[row][col] === "" || 0) {
htmltable += '<td>' + ' ' +'</td>';
}
else if (row === 0) {
htmltable += '<th>' + data[row][col] + '</th>';
}
else {
htmltable += '<td>' + data[row][col] + '</td>';
}
}
htmltable += '</tr>';
}
htmltable += '</table>';
Logger.log(data);
Logger.log(htmltable);
var email_subject = "";
var my_email = "mail";
MailApp.sendEmail({
to: my_email,
subject: email_subject,
htmlBody: htmltable,
})}

Copy MongoDb indexes between databases

I am trying to copy mongo indexes between two environments. Checked the API and found no direct method of doing it. So I started writing a script that connects to one db, iterates over the collections, grabs indexes, mutates them (because getIndexes() and ensureIndex()) have different format), connects to the other db, wipes the indexes and copies the new ones in.
This all feels slightly over the top so I think that I must be missing something.
Any suggestions/good practices? Apart from having an index creation strategy.
Cheers!
Please run it on the database that you want to copy indexes.
db.getCollectionNames().forEach(function(collection) {
indexes = db[collection].getIndexes();
indexes.forEach(function (c) {
opt = ''
ixkey = JSON.stringify(c.key, null, 1).replace(/(\r\n|\n|\r)/gm,"")
ns = c.ns.substr(c.ns.indexOf(".") + 1, c.ns.length)
for (var key in c) {
if (key != 'key' && key != 'ns' && key != 'v') {
if (opt != '') { opt+= ','}
if (c.hasOwnProperty(key)) {
if (typeof(c[key]) == "string") {
opt += (key + ': "' + c[key] + '"')
} else {
opt+= (key + ": " + c[key])
}
}
}
}
if (opt != '') { opt = '{' + opt + '}'}
print ('db.' + ns + '.ensureIndex(' + ixkey + ','+ opt + ')')
})});
I've updated script of Adamo Tonete
db.getCollectionNames().forEach(function(col) {
var indexes = db[col].getIndexes();
indexes.forEach(function (c) {
var fields = '', result = '', options = {};
for (var i in c) {
if (i == 'key') {
fields = c[i];
} else if (i == 'name' && c[i] == '_id_') {
return;
} else if (i != 'name' && i != 'v' && i != 'ns') {
options[i] = c[i];
}
}
var fields = JSON.stringify(fields);
var options = JSON.stringify(options);
if (options == '{}') {
result = "db." + col + ".createIndex(" + fields + "); ";
} else {
result = "db." + col + ".createIndex(" + fields + ", " + options + "); ";
}
result = result
.replace(/{"floatApprox":-1,"top":-1,"bottom":-1}/ig, '-1')
.replace(/{"floatApprox":(-?\d+)}/ig, '$1')
.replace(/\{"\$numberLong":"(-?\d+)"\}/ig, '$1');
print(result);
});
});
Try with this script:
var i, c,
co_name, co_new,
co_old, co_old_i,
_db = db.getSiblingDB('logs'),
_colls = ['activity.games', 'activity.session', 'activity.social', 'activity.store'];
for (i in _colls){
co_name = _colls[i];
co_old = _db[co_name];
co_old_i = co_old.getIndexes();
if(co_old.count() > 0){
co_old.renameCollection(co_name + '.old');
_db.createCollection(co_name);
co_new = _db[co_name];
for(c in co_old_i){
co_new.ensureIndex(co_old_i[c].key);
}
}
}
https://gist.github.com/alejandrobernardis/8261327
Regards,
A
Here is a version to recreate them all with options, and with the new createIndex command instead of ensureIndex (since mongoDB 3.0). With that, it's very easy to copy (recreate) all indexes from one DB to another.
function createIndex2( coll, keys, options ) {
var ret = db[coll].createIndex(keys, options)
if (ret.createdCollectionAutomatically) print( "Collection " + coll + " was created")
if (ret.errmsg || (ret.note != "all indexes already exist" && ret.ok != 1)) {
ret.coll = coll
ret.keys = keys
ret.options = options
print(tojson(ret))
} else {
//print( "Everything normal", JSON.stringify(ret))
}
}
db.getCollectionInfos().forEach(function(coll) {
//print( JSON.stringify( coll ))
if (coll.type === "collection" ) {
db[coll.name].getIndexes().forEach(function(index) {
if ("_id_" !== index.name) {
//print( JSON.stringify( index ))
var indexKey = index.key // save the key, and transform index into the "options"
delete index.key
delete index.ns // namespace - not necessary
delete index.v // not necessary
index.background = true // optional: force background to be true
//native version: print("db." + coll.name + ".createIndex(" + JSON.stringify(indexKey) + ", " + JSON.stringify(index) + ")");
// this gives much more debug info
print("createIndex2(\"" + coll.name + "\", " + JSON.stringify(indexKey) + ", " + JSON.stringify(index) + ")");
}
});
}
});
The result looks like that if using the "native" version, otherwise, it will display only errors:
db.dishes.createIndex({"submenu":1},
{"name":"submenu_1","ns":"dishly.dishes","background":true})
db.dishes.createIndex({"loc":"2dsphere"},
{"name":"loc_2dsphere","ns":"dishly.dishes","2dsphereIndexVersion":3,"background":true})
db.dishes.createIndex({"rs":-1},
{"name":"rs_-1","ns":"dishly.dishes","partialFilterExpression":{"rs":{"$gte":3}},"background":true})
db.dishes.createIndex({"loc":"2d","type":1,"status":1,"FSid":1,"rs":-1},
{"name":"loc_2d_type_1_status_1_rs_-1","ns":"dishly.dishes","background":true,"partialFilterExpression":{"rs":{"$gte":2}}})
db.dishes.createIndex({"_fts":"text","_ftsx":1,"loc.0":1,"loc.1":1,"rs":-1},
{"name":"d2_menu_submenu_text__loc__rs","ns":"dishly.dishes","background":true,"weights":{"d2":1,"menu":1,"submenu":1},"default_language":"english","language_override":"language","textIndexVersion":3})

Using Jquery to dynamically create objects

I'm trying to dynamically create objects out of forms, but I want some reduntant elements to be ommitted, such as the submit.
The only problem is that my function won't omit these fields.
function form_to_json(formname) {
var obj = new Object();
var identity = "#" + formname + " input";
// Create JSON strings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
$(identity).each(function() {
if ($(this).val() != "Submit" || $(this).attr('name') != "password2") {
var propertyName = $(this).attr('name');
var propertyValue = $(this).val();
eval("obj." + propertyName + "='" + propertyValue + "'");
}
});
var jsonObj = JSON.stringify(obj);
return jsonObj;
}
The output spits out a nice little json object the only problem is it doesn't omit the form elements I'm asking it to.
Is it something to do with the selectors?
OK I just had a brainstorm and tried splitting up the if statement into two...
if ($(this).val() != "Submit") {
if ($(this).attr('name') != "password2") {
var propertyName = $(this).attr('name');
var propertyValue = $(this).val();
eval("obj." + propertyName + "='" + propertyValue + "'");
}
}
This did work.
You can do it in single if condition also. You just have to change OR condition to AND
if ($(this).val() != "Submit" && $(this).attr('name') != "password2") {