package er.indexing.example; import java.io.File; import java.io.IOException; import java.math.BigDecimal; import java.sql.SQLException; import java.util.Enumeration; import java.util.Random; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.webobjects.eoaccess.EOAdaptorChannel; import com.webobjects.eoaccess.EODatabaseContext; import com.webobjects.eoaccess.EOModel; import com.webobjects.eoaccess.EOModelGroup; import com.webobjects.eoaccess.EOSQLExpression; import com.webobjects.eoaccess.EOSchemaGeneration; import com.webobjects.eoaccess.EOSynchronizationFactory; import com.webobjects.eoaccess.EOUtilities; import com.webobjects.eocontrol.EOEditingContext; import com.webobjects.foundation.NSArray; import com.webobjects.foundation.NSDictionary; import com.webobjects.foundation.NSForwardException; import com.webobjects.foundation.NSMutableArray; import com.webobjects.foundation.NSMutableDictionary; import com.webobjects.foundation.NSTimestamp; import er.extensions.eof.ERXEC; import er.extensions.foundation.ERXFileUtilities; import er.extensions.foundation.ERXProperties; import er.extensions.jdbc.ERXJDBCUtilities; import er.extensions.jdbc.ERXSQLHelper; import er.indexing.ERIndexing; import er.indexing.example.eof.Asset; import er.indexing.example.eof.AssetGroup; import er.indexing.example.eof.Tag; public class DataCreator { private EOEditingContext ec; private static final Logger log = LoggerFactory.getLogger(DataCreator.class); public static void main(String[] args) { new DataCreator().createAll(); } private NSDictionary optionsWithPrimaryKeySupportDisabled(NSDictionary options) { NSMutableDictionary mutableOptions = options.mutableClone(); mutableOptions.setObjectForKey("NO", EOSchemaGeneration.CreatePrimaryKeySupportKey); mutableOptions.setObjectForKey("NO", EOSchemaGeneration.DropPrimaryKeySupportKey); return mutableOptions.immutableClone(); } private void createPrimaryKeySupportForModel(EOModel eomodel, EOAdaptorChannel channel, EOSynchronizationFactory syncFactory) { try { // AK: the (Object) cast is needed, because in 5.4 new NSArray(obj) // != new NSArray(array). NSArray pkSupportExpressions = syncFactory.primaryKeySupportStatementsForEntityGroups(new NSArray((Object) eomodel.entities())); Enumeration enumeration = pkSupportExpressions.objectEnumerator(); while (enumeration.hasMoreElements()) { EOSQLExpression expression = (EOSQLExpression) enumeration.nextElement(); channel.evaluateExpression(expression); } } catch (Exception e) { } } private void createTables(boolean dropTables) { for (Enumeration e = EOModelGroup.defaultGroup().models().objectEnumerator(); e.hasMoreElements();) { final EOModel eomodel = (EOModel) e.nextElement(); EODatabaseContext dbc = EOUtilities.databaseContextForModelNamed(ec, eomodel.name()); dbc.lock(); try { EOAdaptorChannel channel = dbc.availableChannel().adaptorChannel(); if (eomodel.adaptorName().contains("JDBC")) { EOSynchronizationFactory syncFactory = (EOSynchronizationFactory) channel.adaptorContext().adaptor().synchronizationFactory(); ERXSQLHelper helper = ERXSQLHelper.newSQLHelper(channel); NSDictionary options = helper.defaultOptionDictionary(true, dropTables); // Primary key support creation throws an unwanted exception // if // EO_PK_TABLE already // exists (e.g. in case of MySQL), so we add pk support in a // stand-alone step options = optionsWithPrimaryKeySupportDisabled(options); createPrimaryKeySupportForModel(eomodel, channel, syncFactory); String sqlScript = syncFactory.schemaCreationScriptForEntities(eomodel.entities(), options); log.info("Creating tables: {}", eomodel.name()); ERXJDBCUtilities.executeUpdateScript(channel, sqlScript, true); } } catch (SQLException ex) { log.error("Can't update", ex); } finally { dbc.unlock(); } } } NSMutableArray<Asset> assets = new NSMutableArray<>(); NSMutableArray<AssetGroup> groups = new NSMutableArray<>(); NSMutableArray<Tag> tags = new NSMutableArray<>(); NSArray<String> words = new NSArray<>(); public void createAll() { createTables(); clearIndex(); createDummyData(); } public void clearIndex() { ERIndexing.indexing().clear(); } public void createTables() { ec = ERXEC.newEditingContext(); ec.lock(); try { boolean dropTables = ERXProperties.booleanForKeyWithDefault("dropTables", true); createTables(dropTables); } finally { ec.unlock(); } } public void createDummyData() { ec = ERXEC.newEditingContext(); ec.lock(); try { doCreateDummyData(); } finally { ec.unlock(); } } private int randomInt(int max) { return new Random().nextInt(max); } private <T> T randomObject(NSArray<T> array) { return array.objectAtIndex(randomInt(array.count())); } private String randomWord() { return randomObject(words); } private String randomText(int max) { StringBuilder content = new StringBuilder(); while (true) { String nextWord = randomWord(); if ((content.length() + nextWord.length() + 1) < max) { content.append(nextWord).append(' '); } else { break; } } return content.toString(); } private Tag randomTag() { return randomObject(tags); } private AssetGroup randomAssetGroup() { return randomObject(groups); } private BigDecimal randomPrice() { return BigDecimal.valueOf((double) randomInt(10000) / (double) 100).setScale(2, BigDecimal.ROUND_DOWN); } private NSTimestamp randomTime() { return new NSTimestamp(randomInt((int) (System.currentTimeMillis() / 1000)) * 1000); } private void doCreateDummyData() { try { log.info("load"); String wordFile = ERXFileUtilities.stringFromFile(new File("/usr/share/dict/words")); words = NSArray.componentsSeparatedByString(wordFile, "\n"); log.info("loaded words: {}", words.count()); int MAX = 100; int MAX_ASSETS = MAX * 10; for (int i = 0; i < MAX; i++) { Tag tag = Tag.clazz.createAndInsertObject(ec); tag.setName(randomWord()); tags.addObject(tag); } log.info("created tags: {}", tags.count()); for (int i = 0; i < MAX; i++) { AssetGroup group = AssetGroup.clazz.createAndInsertObject(ec); group.setName(randomWord()); groups.addObject(group); } log.info("created groups: {}", groups.count()); for (int i = 0; i < MAX_ASSETS; i++) { Asset asset = Asset.clazz.createAndInsertObject(ec); asset.setAssetGroup(randomAssetGroup()); asset.setCreationDate(randomTime()); asset.setUserCount((long) randomInt(10000)); asset.setPrice(randomPrice()); for (int j = 0; j < 10; j++) { asset.addToTags(randomTag()); } asset.setContent(randomText(1000)); asset.setGenericInfo(randomText(1000)); assets.addObject(asset); } log.info("created assets: {}", assets.count()); ec.saveChanges(); log.info("fin: {}", words.count()); } catch (IOException e) { throw NSForwardException._runtimeExceptionForThrowable(e); } } }