Create test data
For creating test data for the sample database, one may use the OSI script as shown below. Comment on the example you will find in the subtopic OSI Script comments . After creating the Sample project, one may simply call OSI.sh (LINUX) or OSI.cmd (Windows), which have been generated to the project directory. When generating other projects, the generated scripts have to be revised in order to check file location for the called .osi script file.
Dictionary and database are expected in the project root directory. Otherwise, DICTIONARY and DATABASE have to be updated in the script file.
When calling the script, a new database will be created at the location defined in DATABASE in the script. Before rerunning the script, the database should be deleted, since the script is not prepared for being called repeatedly.
In order to change the amount of data to be created, one may modify the script slightly (see also comments). The number of persons to be created can be passed as parameter in the CreatePersons( person_count ) function call. The default is 1000.
The dictionary must exist at the location specified in the script file for DICTIONARY . The script contains several Message() calls that write protocol information to the console. The protocols listed in the Linux and Windows specification are the output from the tests running on our test machine.
DICTIONARY='Sample.dev';
DATABASE='Sample.dat';
bool main ( ) {
VARIABLES
global int comp_count = 5;
PROCESS
CreateCompanies();
CreatePersons();
InitCollections();
AssignChildren();
}
void CreateCompanies ( ) {
VARIABLES
int comp_number = 0;
int count = 0;
int car_counts[5];
string key;
SET<Company> &companies = Company;
SET<Car> &cars = companies.cars;
PROCESS
// create 5 companies
Message("Starting company transaction: " + (string)Time() );
companies.objectSpace.beginTransaction();
SystemClass::RandomNumbers(car_counts,20); // initialize number of cars per company between 0 and
companies.insert("My company");
companies.insert("Your company");
companies.insert("NO company");
companies.insert("Any company");
companies.insert("Best company");
comp_count = companies.count;
while ( comp_number < comp_count ) {
companies.get(comp_number);
count = 0;
while ( count < car_counts[comp_number] ) {
key = 'C' + (string)comp_number + '-' + (string)(++count);
cars.insert(key);
}
++comp_number; // only prefix operators are supported
}
Message("Storing company transaction: " + (string)Time() );
companies.objectSpace.commitTransaction;
Message("Stopping company transaction: " + (string)Time() );
}
void CreatePersons ( int person_count = 1000 ) {
VARIABLES
int count = 0;
SET<Person> &persons = Person::Persons;
PROCESS
Message("Starting person transaction: " + (string)Time() );
persons.objectSpace.beginTransaction();
while ( count < person_count )
persons.insert('P' + (string)(++count)).SetAttributes();
Message("Storing person transaction: " + (string)Time() );
persons.objectSpace.commitTransaction;
Message("Stopping persons transaction: " + (string)Time() );
}
void Person::SetAttributes ( ) {
VARIABLES
int count = 0;
int number;
int comp_number = 0;
int first_name_letters[10];
int last_name_letters[5];
int years;
int months;
int days;
string upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string lower = "abcdefghijklmnopqrstuvwxyz";
PROCESS
// initialize gender
SystemClass::RandomNumbers(number,2);
sex = number + 1; // 1: male, 2:female
// initialize birth date
SystemClass::RandomNumbers(years,100);
SystemClass::RandomNumbers(months,12);
SystemClass::RandomNumbers(days,28);
birth_date = (string)(years + 1910) + '-' + (string)(months + 1) + '-' + (string)(days + 1);
// initialize family state
SystemClass::RandomNumbers(number,2);
if ( age >= 18 ) // initial value is false
married = number;
// init first first name
count = 0;
SystemClass::RandomNumbers(first_name_letters,26);
first_name[0] += upper.subString(first_name_letters[0],1);
while ( ++count < 10 ) // number of random letters in first_name_letters
first_name[0] += lower.subString(first_name_letters[count],1);
// init last name
count = 0;
SystemClass::RandomNumbers(last_name_letters,26);
name += upper.subString(last_name_letters[0],1);
// while ( ++count < 5 ) // number of random letters in last_name_letters
while ( ++count < last_name_letters.propertyDefinition.collectionSize ) // number of random letters in last_name_letters
name += lower.subString(last_name_letters[count],1);
save();
// initialize employee
if ( age >= 16 && age < 65 ) {
RandomNumbers(comp_number,comp_count);
RandomNumbers(number,9500);
Company.get(comp_number).employees.insert(pid).{ income = number + 500; };
}
}
void InitCollections ( ) {
VARIABLES
global set<Person> &f20 &= Person::Persons;
global set<Person> &f40 &= Person::Persons;
global set<Person> &f60 &= Person::Persons;
global set<Person> &f80 &= Person::Persons;
global set<Person> &f100 &= Person::Persons;
global set<Person> &m20 &= Person::Persons;
global set<Person> &m40 &= Person::Persons;
global set<Person> &m60 &= Person::Persons;
global set<Person> &m80 &= Person::Persons;
global set<Person> &m100 &= Person::Persons;
global set<Person> &c10 &= Person::Persons;
global set<Person> &c30 &= Person::Persons;
global set<Person> &c50 &= Person::Persons;
global set<Person> &c70 &= Person::Persons;
PROCESS
// set filter for global male and feemale collections by age
f20.filter('age <= 20 && sex == "female"');
f40.filter('age > 20 && age <= 40 && sex == "female"');
f60.filter('age > 40 && age <= 60 && sex == "female"');
f80.filter('age > 60 && age <= 80 && sex == "female"');
f100.filter('age > 80 && age <= 100 && sex == "female"');
m20.filter('age > 20 && sex == "male"');
m40.filter('age > 20 && age <= 40 && sex == "male"');
m60.filter('age > 40 && age <= 60 && sex == "male"');
m80.filter('age > 60 && age <= 80 && sex == "male"');
m100.filter('age > 80 && age <= 100 && sex == "male"');
c10.filter('age <= 10');
c10.first(); // locate first
c30.filter('age > 10 && age <= 30');
c30.first(); // locate first
c50.filter('age > 30 && age <= 50');
c50.first(); // locate first
c70.filter('age > 50 && age <= 70');
c70.first(); // locate first
}
bool AssignChildren ( ) {
VARIABLES
set<Person> &father;
int age_group = 100;
PROCESS
Message("Create child/parent relations: " + (string)Time() );
while ( age_group > 20 ) {
switch ( age_group ) {
case 100 : father &= f100;
break;
case 80 : father &= f80;
break;
case 60 : father &= f60;
break;
case 40 : father &= f40;
break;
}
if ( father.next() ) {
father.AssignChild(age_group);
} else
age_group -= 20;
}
Message("Created: " + (string)Time() );
}
bool Person::AssignChild ( int age_group ) {
VARIABLES
set<Person> &mother;
set<Person> &child;
int child_count;
int cage_group = 100;
PROCESS
SystemClass::RandomNumbers(child_count,7);
if ( !child_count )
leave;
while ( age_group > 20 ) {
switch ( age_group ) {
case 100 : mother &= m100;
break;
case 80 : mother &= m80;
break;
case 60 : mother &= m60;
break;
case 40 : mother &= m40;
break;
}
if ( !mother.next ) {
age_group -= 20;
} else
break;
}
while ( child_count > 0 && age_group >= 40) {
--child_count;
switch ( age_group ) {
case 100: child &= c70;
break;
case 80 : child &= c50;
break;
case 60 : child &= c30;
break;
case 40 : child &= c10;
break;
}
if ( !child.located ) {
age_group -= 20;
continue;
} else {
children.insertReference(child);
if ( mother.located )
mother.children.insertReference(child);
child.next();
}
}
}