package org.reldb.rel.v0.storage.relvars.external.accdb;
import java.io.File;
import java.io.IOException;
import org.reldb.rel.exceptions.ExceptionSemantic;
import org.reldb.rel.v0.generator.Generator;
import org.reldb.rel.v0.generator.SelectAttributes;
import org.reldb.rel.v0.storage.RelDatabase;
import org.reldb.rel.v0.storage.relvars.RelvarCustomMetadata;
import org.reldb.rel.v0.storage.relvars.RelvarExternal;
import org.reldb.rel.v0.storage.relvars.RelvarGlobal;
import org.reldb.rel.v0.storage.relvars.RelvarHeading;
import org.reldb.rel.v0.storage.relvars.external.CSVLineParse;
import org.reldb.rel.v0.storage.relvars.external.ColumnName;
import org.reldb.rel.v0.storage.tables.TableExternal.DuplicateHandling;
import org.reldb.rel.v0.types.Heading;
import org.reldb.rel.v0.types.builtin.TypeCharacter;
import org.reldb.rel.v0.types.builtin.TypeInteger;
import com.healthmarketscience.jackcess.Column;
import com.healthmarketscience.jackcess.Database;
import com.healthmarketscience.jackcess.DatabaseBuilder;
import com.healthmarketscience.jackcess.Table;
public class RelvarACCDBMetadata extends RelvarCustomMetadata {
public static final long serialVersionUID = 0;
private String connectionString;
private String fileSpec; // "c:\\users\\me\\mydb.accdb"
private String table; // "mytable"
// var myvar external accdb "c:\\users\\me\\mydb.accdb,mytable";
private DuplicateHandling duplicates;
public static RelvarHeading getHeading(RelDatabase database, String spec, DuplicateHandling duplicates) {
String[] values = CSVLineParse.parseTrimmed(spec);
if (values.length != 2)
throw new ExceptionSemantic("RS0472: Invalid arguments. Expected: FILE, TABLE but got " + spec);
String fileSpec = values[0];
String table = values[1];
Database db = null;
try {
db = DatabaseBuilder.open(new File(fileSpec));
Table tableData = db.getTable(table);
Heading heading = new Heading();
if (duplicates == DuplicateHandling.DUP_COUNT)
heading.add("_DUP_COUNT", TypeInteger.getInstance());
else if (duplicates == DuplicateHandling.AUTOKEY)
heading.add("_AUTOKEY", TypeInteger.getInstance());
for (Column column: tableData.getColumns())
heading.add(ColumnName.cleanName(column.getName()), TypeCharacter.getInstance());
RelvarHeading relvarHeading = new RelvarHeading(heading);
if (duplicates == DuplicateHandling.AUTOKEY) {
SelectAttributes keyAttribute = new SelectAttributes();
keyAttribute.add("_AUTOKEY");
relvarHeading.addKey(keyAttribute);
}
return relvarHeading;
} catch (IOException e) {
throw new ExceptionSemantic("RS0473: Unable to open " + fileSpec + " table " + table + ": " + e.toString());
} finally {
if (db != null)
try {
db.close();
} catch (IOException e) {
}
}
}
@Override
public String getSourceDefinition() {
return "EXTERNAL ACCDB \"" + fileSpec.replace('\\', '/') + "," + table + "\" " + duplicates;
}
public RelvarACCDBMetadata(RelDatabase database, String owner, String spec, DuplicateHandling duplicates) {
super(database, getHeading(database, spec, duplicates), owner);
String[] values = CSVLineParse.parseTrimmed(spec);
fileSpec = values[0];
table = values[1];
this.duplicates = duplicates;
connectionString = spec;
}
public void checkTableExistence() {
Database db = null;
try {
db = DatabaseBuilder.open(new File(fileSpec));
db.getTable(table);
} catch (IOException e) {
throw new ExceptionSemantic("RS0474: Table " + table + " no longer exists.");
} finally {
if (db != null)
try {
db.close();
} catch (IOException e) {
}
}
}
@Override
public RelvarGlobal getRelvar(String name, RelDatabase database) {
checkTableExistence();
return new RelvarExternal(name, database, new Generator(database, System.out), this, duplicates);
}
@Override
public void dropRelvar(RelDatabase database) {
}
public String getConnectionString() {
return connectionString;
}
public String getFileSpec() {
return fileSpec;
}
public String getTable() {
return table;
}
@Override
public String tableClassName() {
return "TableACCDB";
}
@Override
public String getType() {
return "ACCDB";
}
}