Search the FirstSpirit Knowledge Base
Mittels folgendem Schnippels finde ich alle Felder in Datenbank-Templates die zwar mehrsprachig sind aber bei denen nicht für alle existierenden Sprachen ein Feld existiert.
Es werden also zum Beispiel bei einem zweisprachigen Projekt das vor kurzem eine neue Sprache hinzugefügt hat alle mehrsprachigen Felder gelistet da bei diesen das Feld für die neue Sprache fehlt.
TemplateStoreRoot templateStore = (TemplateStoreRoot) storeAgent.getStore(Store.Type.TEMPLATESTORE);
Schemes schemes = templateStore.getSchemes();
for (Schema s : schemes.getChildren(Schema.class)) {
for (TableTemplate t : s.getChildren(TableTemplate.class)) {
TableTemplate.Mapping[] mappings = t.getMappings();
for (TableTemplate.Mapping m : mappings) {
if (!m.isLanguageDependent()) {
continue;
}
for (Language l : context.getProject().getLanguages()) {
Attribute a = m.getDBAttribute(l.getAbbreviation());
if (a == null) {
System.out.println(t.getName() +"," + m.getName()+ "," + l.getName());
}
}
}
}
}
Ich würde nun gerne an der Stelle des println die fehlenden Felder hinzufügen und auch gleich mappen.
Hat da jemand Hinweise, Ideen oder Ähnliches?
Viele Grüße,
Michael
Den Trick mit der XML kenne ich. Allerdings würde ich die Felder gerne automatisch anlegen.
Die Tabellenspalte habe ich nun soweit anlegen können. Mir fehlt aber noch das Mapping.
Die Klasse TableTemplate.Mapping hat eine Methode getDBAttribute aber keine um mein neu erstelltes SimpleAttribute zu setzen.
Wie gehe ich denn vor um das Mapping anzulegen ?
EDIT: Ich habe es hingekriegt. Falls einer das gleiche Problem hat hier der Quelltext:
public class CreateFieldsNewLanguage {
private ClientScriptContext context;
private Language masterLang;
private static final Pattern reName = Pattern.compile("^([^_]+)_.{2}$");
private String getOriginalDatabaseFieldName(TableTemplate.Mapping mapping) throws Exception {
Attribute master = mapping.getDBAttribute(masterLang.getAbbreviation());
if (master == null) {
throw new Exception("Field " + mapping.getName() + " does not have master language mapping");
}
Matcher m = reName.matcher(master.getName());
if (!m.matches()) {
throw new Exception("Field " + mapping.getName() + " has DB field " + master.getName() + " which does not conform to naming convention of $name_$abbreviationoflangunage");
}
return m.group(1);
}
private void addMissingFields(TableTemplate t, EntityType type) throws Exception {
try {
t.setLock(true, false);
TableTemplate.Mapping[] mappings = t.getMappings();
for (TableTemplate.Mapping mapping : mappings) {
if (!mapping.isLanguageDependent()) {
continue;
}
for (Language l : context.getProject().getLanguages()) {
Attribute a = mapping.getDBAttribute(l.getAbbreviation());
if (a != null) {
continue;
}
String dbname;
try {
dbname = getOriginalDatabaseFieldName(mapping);
} catch(Exception e) {
context.logError(e.getMessage());
continue;
}
String masterName = dbname + "_" + masterLang.getAbbreviation();
if (!type.isSimpleAttribute(masterName)) {
context.logInfo(t.getName() + "," + mapping.getName() + "," + l.getName() + " is missing but not simple attribute (composed not supported)");
continue;
}
String newName = dbname + "_" + l.getAbbreviation();
if (!type.containsAttribute(newName)) {
context.logInfo(t.getName() + "," + mapping.getName() + "," + l.getName() + "-> creating " + newName);
SimpleAttribute ma = (SimpleAttribute) type.getAttribute(masterName);
SimpleAttribute na = type.createSimpleAttribute(newName, ma.getType());
Column col = ma.getColumn().clone();
col.setName(newName);
na.setColumn(col);
}
context.logInfo(t.getName() + "," + mapping.getName() + "," + l.getName() + "-> mapping " + newName);
mapping.setAttributeReference(new String[]{newName}, l.getAbbreviation(), true);
}
}
t.setMappings(mappings);
t.save("", false);
} finally {
t.setLock(false, false);
}
}
public void run(ClientScriptContext context) throws Exception {
this.context = context;
this.masterLang = context.getProject().getMasterLanguage();
TemplateStoreRoot templateStore = context.getUserService().getStore(Store.Type.TEMPLATESTORE, false);
Schemes schemes = templateStore.getSchemes();
for (Schema s : schemes.getChildren(Schema.class)) {
if(s.isReadOnly()) {
continue;
}
try {
s.setLock(true, false);
Session osess = s.getSession(false);
de.espirit.or.schema.Schema os = osess.getSchema();
for (TableTemplate t : s.getChildren(TableTemplate.class)) {
addMissingFields(t, os.getEntityType(t.getEntityType().getName()));
}
osess.syncSchemaWithDB(os, false);
s.setOrSchema(os);
s.save("", false);
} finally {
s.setLock(false, false);
}
}
}
}
Benutzung ist:
new CreateFieldsNewLanguage().run(context);
Falls jemand Verbesserungsvorschlage und/oder Kritik hat bitte melden.
Hallo Michael,
ich fürchte, da gibt es keinen einfachen Weg über die API. Zumindest fällt mir keiner ein.
Eine ähnliche Frage findest Du in Sprachabhängige Spalten nach Hinzufügen einer Sprache. Dort verweise ich auf ein Blogposting, in dem ein alternativer Weg beschrieben wird.
Viele Grüße
Donato
Den Trick mit der XML kenne ich. Allerdings würde ich die Felder gerne automatisch anlegen.
Die Tabellenspalte habe ich nun soweit anlegen können. Mir fehlt aber noch das Mapping.
Die Klasse TableTemplate.Mapping hat eine Methode getDBAttribute aber keine um mein neu erstelltes SimpleAttribute zu setzen.
Wie gehe ich denn vor um das Mapping anzulegen ?
EDIT: Ich habe es hingekriegt. Falls einer das gleiche Problem hat hier der Quelltext:
public class CreateFieldsNewLanguage {
private ClientScriptContext context;
private Language masterLang;
private static final Pattern reName = Pattern.compile("^([^_]+)_.{2}$");
private String getOriginalDatabaseFieldName(TableTemplate.Mapping mapping) throws Exception {
Attribute master = mapping.getDBAttribute(masterLang.getAbbreviation());
if (master == null) {
throw new Exception("Field " + mapping.getName() + " does not have master language mapping");
}
Matcher m = reName.matcher(master.getName());
if (!m.matches()) {
throw new Exception("Field " + mapping.getName() + " has DB field " + master.getName() + " which does not conform to naming convention of $name_$abbreviationoflangunage");
}
return m.group(1);
}
private void addMissingFields(TableTemplate t, EntityType type) throws Exception {
try {
t.setLock(true, false);
TableTemplate.Mapping[] mappings = t.getMappings();
for (TableTemplate.Mapping mapping : mappings) {
if (!mapping.isLanguageDependent()) {
continue;
}
for (Language l : context.getProject().getLanguages()) {
Attribute a = mapping.getDBAttribute(l.getAbbreviation());
if (a != null) {
continue;
}
String dbname;
try {
dbname = getOriginalDatabaseFieldName(mapping);
} catch(Exception e) {
context.logError(e.getMessage());
continue;
}
String masterName = dbname + "_" + masterLang.getAbbreviation();
if (!type.isSimpleAttribute(masterName)) {
context.logInfo(t.getName() + "," + mapping.getName() + "," + l.getName() + " is missing but not simple attribute (composed not supported)");
continue;
}
String newName = dbname + "_" + l.getAbbreviation();
if (!type.containsAttribute(newName)) {
context.logInfo(t.getName() + "," + mapping.getName() + "," + l.getName() + "-> creating " + newName);
SimpleAttribute ma = (SimpleAttribute) type.getAttribute(masterName);
SimpleAttribute na = type.createSimpleAttribute(newName, ma.getType());
Column col = ma.getColumn().clone();
col.setName(newName);
na.setColumn(col);
}
context.logInfo(t.getName() + "," + mapping.getName() + "," + l.getName() + "-> mapping " + newName);
mapping.setAttributeReference(new String[]{newName}, l.getAbbreviation(), true);
}
}
t.setMappings(mappings);
t.save("", false);
} finally {
t.setLock(false, false);
}
}
public void run(ClientScriptContext context) throws Exception {
this.context = context;
this.masterLang = context.getProject().getMasterLanguage();
TemplateStoreRoot templateStore = context.getUserService().getStore(Store.Type.TEMPLATESTORE, false);
Schemes schemes = templateStore.getSchemes();
for (Schema s : schemes.getChildren(Schema.class)) {
if(s.isReadOnly()) {
continue;
}
try {
s.setLock(true, false);
Session osess = s.getSession(false);
de.espirit.or.schema.Schema os = osess.getSchema();
for (TableTemplate t : s.getChildren(TableTemplate.class)) {
addMissingFields(t, os.getEntityType(t.getEntityType().getName()));
}
osess.syncSchemaWithDB(os, false);
s.setOrSchema(os);
s.save("", false);
} finally {
s.setLock(false, false);
}
}
}
}
Benutzung ist:
new CreateFieldsNewLanguage().run(context);
Falls jemand Verbesserungsvorschlage und/oder Kritik hat bitte melden.
Hallo zusammen,
im Rahmen eines Kundenprojekts haben wir dieses Skript eingesetzt.
Folgendes muss angepasst werden:
Hi Jessica,
postet das angepasste Script doch, oder noch besser, packt es auf Github (wenn der ursprüngliche Urheber damit einverstanden ist) 🙂
Ein Solches Feature fehlt in FS sowieso schon immer und jeder baut es sich irgendwie selbst.
Grüße
Sandro
Hallo Sandra,
ich lad es einfach hier hoch. wir haben das Skript bzw. die Skripte nicht "schön" gemacht, sondern nur, dass es funktioniert.
Wichtig ist dabei die Skripte in der folgenden Reihenfolge auszuführen:
1. add_language_schema
2. add_table
1) ADD_LANGUAGE_SCHEMA
import de.espirit.firstspirit.access.Language;
import de.espirit.firstspirit.access.store.Store;
import de.espirit.firstspirit.access.store.templatestore.Schema;
import de.espirit.firstspirit.access.store.templatestore.Schemes;
import de.espirit.firstspirit.access.store.templatestore.TableTemplate;
import de.espirit.firstspirit.access.store.templatestore.TemplateStoreRoot;
import de.espirit.firstspirit.access.store.templatestore.TableTemplate.Mapping;
import de.espirit.or.Session;
import de.espirit.or.schema.Attribute;
import de.espirit.or.schema.Column;
import de.espirit.or.schema.EntityType;
import de.espirit.or.schema.SimpleAttribute;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
private Language masterLang;
private static final Pattern reName = Pattern.compile("^(.+)_[a-zA-Z]{2}$");
private String getOriginalDatabaseFieldName(TableTemplate.Mapping mapping) throws Exception {
Attribute master = mapping.getDBAttribute(context.getProject().getMasterLanguage().getAbbreviation());
if (master == null) {
throw new Exception("Field " + mapping.getName() + " does not have master language mapping");
}
Matcher m = reName.matcher(master.getName());
if (!m.matches()) {
throw new Exception("Field " + mapping.getName() + " has DB field " + master.getName() + " which does not conform to naming convention of $name_$abbreviationoflangunage");
}
return m.group(1);
}
private void addMissingFields(TableTemplate t, EntityType type, Session osess, de.espirit.or.schema.Schema os, Schema s) throws Exception {
try {
t.setLock(true, false);
context.logInfo("Locking '" + t.getUid() + "'");
mappings = t.getMappings();
for (TableTemplate.Mapping mapping: mappings) {
if (!mapping.isLanguageDependent()) {
context.logInfo("Mapping '" + mapping.getName() + "' of '" + t.getUid() + "' is not language dependent! -> skipping");
Attribute master = mapping.getDBAttribute(context.getProject().getMasterLanguage().getAbbreviation());
if (master == null) {
context.logError("Field " + mapping.getName() + " does not have master language mapping");
continue;
}
String masterName = master.getName();
for (Language l: context.getProject().getLanguages()) {
if (mapping.getDBAttribute(l.getAbbreviation()) == null) {
mapping.setAttributeReference(new String[] {
masterName
}, l.getAbbreviation(), false);
context.logInfo(t.getName() + "," + mapping.getName() + "," + l.getName() + " -> mapping " + masterName + " [lang. independent]");
}
}
continue;
}
for (Language l: context.getProject().getLanguages()) {
Attribute a = mapping.getDBAttribute(l.getAbbreviation());
if (a != null) {
continue;
}
String dbname;
try {
dbname = getOriginalDatabaseFieldName(mapping);
} catch (Exception e) {
context.logError(e.getMessage());
continue;
}
String masterName = dbname + "_" + context.getProject().getMasterLanguage().getAbbreviation();
if (!type.isSimpleAttribute(masterName)) {
context.logInfo(t.getName() + "," + mapping.getName() + "," + l.getName() + " is missing but not simple attribute (composed not supported)");
continue;
}
String newName = dbname + "_" + l.getAbbreviation();
if (!type.containsAttribute(newName)) {
context.logInfo(t.getName() + "," + mapping.getName() + "," + l.getName() + "-> creating " + newName + " [attribute not in entity]");
SimpleAttribute ma = (SimpleAttribute) type.getAttribute(masterName);
SimpleAttribute na = type.createSimpleAttribute(newName, ma.getType());
Column col = ma.getColumn().clone();
col.setName(newName);
na.setColumn(col);
}
context.logInfo(t.getName() + "," + mapping.getName() + "," + l.getName() + "-> mapping " + newName);
mapping.setAttributeReference(new String[] {
newName
}, l.getAbbreviation(), true);
}
}
t.setMappings(mappings);
//t.save("", false);
} finally {
context.logInfo("Unlocking '" + t.getUid() + "'");
t.setLock(false, false);
}
}
public void run(context) throws Exception {
this.masterLang = context.getProject().getMasterLanguage();
TemplateStoreRoot templateStore = (TemplateStoreRoot) context.getUserService().getStore(Store.Type.TEMPLATESTORE, false);
Schemes schemes = templateStore.getSchemes();
for (Schema s: schemes.getChildren(Schema.class)) {
context.logInfo("- - - - - - - - - - - - ");
context.logInfo("Schema: '" + s.getUid() + "'");
if (s.isReadOnly()) {
continue;
}
try {
context.logInfo("Locking '" + s.getUid() + "'");
s.setLock(true, false);
Session osess = s.getSession(false);
de.espirit.or.schema.Schema os = osess.getSchema();
for (TableTemplate t: s.getChildren(TableTemplate.class)) {
addMissingFields(t, os.getEntityType(t.getEntityType().getName()), osess, os, s);
}
osess.syncSchemaWithDB(os, false);
s.setOrSchema(os);
s.save("", false);
} finally {
context.logInfo("Unlocking '" + s.getUid() + "'");
s.setLock(false, false);
s.refresh();
s.setLock(true, false);
s.save("", false);
s.setLock(false, false);
}
context.logInfo("- - - - - - - - - - - - ");
context.logInfo(" ");
}
}
run(context);
2) ADD_LANGUAGE_TABLE
import de.espirit.firstspirit.access.Language;
import de.espirit.firstspirit.access.store.Store;
import de.espirit.firstspirit.access.store.templatestore.Schema;
import de.espirit.firstspirit.access.store.templatestore.Schemes;
import de.espirit.firstspirit.access.store.templatestore.TableTemplate;
import de.espirit.firstspirit.access.store.templatestore.TemplateStoreRoot;
import de.espirit.firstspirit.access.store.templatestore.TableTemplate.Mapping;
import de.espirit.or.Session;
import de.espirit.or.schema.Attribute;
import de.espirit.or.schema.Column;
import de.espirit.or.schema.EntityType;
import de.espirit.or.schema.SimpleAttribute;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
private Language masterLang;
private static final Pattern reName = Pattern.compile("^(.+)_[a-zA-Z]{2}$");
private String getOriginalDatabaseFieldName(TableTemplate.Mapping mapping) throws Exception {
Attribute master = mapping.getDBAttribute(context.getProject().getMasterLanguage().getAbbreviation());
if (master == null) {
throw new Exception("Field " + mapping.getName() + " does not have master language mapping");
}
Matcher m = reName.matcher(master.getName());
if (!m.matches()) {
throw new Exception("Field " + mapping.getName() + " has DB field " + master.getName() + " which does not conform to naming convention of $name_$abbreviationoflangunage");
}
return m.group(1);
}
private void addMissingFields(TableTemplate t, EntityType type, Session osess, de.espirit.or.schema.Schema os, Schema s) throws Exception {
try {
t.setLock(true, false);
context.logInfo("Locking '" + t.getUid() + "'");
mappings = t.getMappings();
for (TableTemplate.Mapping mapping: mappings) {
if (!mapping.isLanguageDependent()) {
context.logInfo("Mapping '" + mapping.getName() + "' of '" + t.getUid() + "' is not language dependent! -> skipping");
Attribute master = mapping.getDBAttribute(context.getProject().getMasterLanguage().getAbbreviation());
if (master == null) {
context.logError("Field " + mapping.getName() + " does not have master language mapping");
continue;
}
String masterName = master.getName();
for (Language l: context.getProject().getLanguages()) {
if (mapping.getDBAttribute(l.getAbbreviation()) == null) {
mapping.setAttributeReference(new String[] {
masterName
}, l.getAbbreviation(), false);
context.logInfo(t.getName() + "," + mapping.getName() + "," + l.getName() + " -> mapping " + masterName + " [lang. independent]");
}
}
continue;
}
for (Language l: context.getProject().getLanguages()) {
Attribute a = mapping.getDBAttribute(l.getAbbreviation());
if (a != null) {
continue;
}
String dbname;
try {
dbname = getOriginalDatabaseFieldName(mapping);
} catch (Exception e) {
context.logError(e.getMessage());
continue;
}
String masterName = dbname + "_" + context.getProject().getMasterLanguage().getAbbreviation();
if (!type.isSimpleAttribute(masterName)) {
context.logInfo(t.getName() + "," + mapping.getName() + "," + l.getName() + " is missing but not simple attribute (composed not supported)");
continue;
}
String newName = dbname + "_" + l.getAbbreviation();
if (!type.containsAttribute(newName)) {
context.logInfo(t.getName() + "," + mapping.getName() + "," + l.getName() + "-> creating " + newName + " [attribute not in entity]");
SimpleAttribute ma = (SimpleAttribute) type.getAttribute(masterName);
SimpleAttribute na = type.createSimpleAttribute(newName, ma.getType());
Column col = ma.getColumn().clone();
col.setName(newName);
na.setColumn(col);
}
context.logInfo(t.getName() + "," + mapping.getName() + "," + l.getName() + "-> mapping " + newName);
mapping.setAttributeReference(new String[] {
newName
}, l.getAbbreviation(), true);
}
}
t.setMappings(mappings);
t.save("", false);
} finally {
context.logInfo("Unlocking '" + t.getUid() + "'");
t.setLock(false, false);
}
}
public void run(context) throws Exception {
this.masterLang = context.getProject().getMasterLanguage();
TemplateStoreRoot templateStore = (TemplateStoreRoot) context.getUserService().getStore(Store.Type.TEMPLATESTORE, false);
Schemes schemes = templateStore.getSchemes();
for (Schema s: schemes.getChildren(Schema.class)) {
context.logInfo("- - - - - - - - - - - - ");
context.logInfo("Schema: '" + s.getUid() + "'");
if (s.isReadOnly()) {
continue;
}
try {
context.logInfo("Locking '" + s.getUid() + "'");
s.setLock(true, false);
Session osess = s.getSession(false);
de.espirit.or.schema.Schema os = osess.getSchema();
for (TableTemplate t: s.getChildren(TableTemplate.class)) {
addMissingFields(t, os.getEntityType(t.getEntityType().getName()), osess, os, s);
}
osess.syncSchemaWithDB(os, false);
s.setOrSchema(os);
//s.save("", false);
} finally {
context.logInfo("Unlocking '" + s.getUid() + "'");
s.setLock(false, false);
s.refresh();
s.setLock(true, false);
//s.save("", false);
s.setLock(false, false);
}
context.logInfo("- - - - - - - - - - - - ");
context.logInfo(" ");
}
}
run(context);
TemplateStoreRoot templateStore = (TemplateStoreRoot) storeAgent.getStore(Store.Type.TEMPLATESTORE); Schemes schemes = templateStore.getSchemes(); for (Schema s : schemes.getChildren(Schema.class)) { for (TableTemplate t : s.getChildren(TableTemplate.class)) { TableTemplate.Mapping[] mappings = t.getMappings(); for (TableTemplate.Mapping m : mappings) { if (!m.isLanguageDependent()) { continue; } for (Language l : context.getProject().getLanguages()) { Attribute a = m.getDBAttribute(l.getAbbreviation()); if (a == null) { System.out.println(t.getName() +"," + m.getName()+ "," + l.getName()); } } } } }
SandrO meinte ich! Sorry!
Bin ich gewohnt 😉
Hallo Jessica.
Die beigefügten Skripte unterscheiden sich aber von einander nicht viel. Oder verstehe ich was falsch?
Viele Grüße,
Olga