To use GDBMS in a project it's necessary to include GDBMS in its classpath. If a third party driver is going to be used, it's needed its jar to be in the classpath too. GDBMS depends on other projects and a list of those dependencies can be found here and the actual jars can be found here.
We can perform read/write operations in a data set through the DataSource interface. Since the 2.0 version it's quite easy to get a DataSource instance, we have to follow this steps:
–Create a DataSourceFactory.
–Get the DataSource instance.
This step is common to any data source. We need to create a DataSourceFactory instance:
DataSourceFactory factory = new DataSourceFactory();
There are several ways to obtain a DataSource instance to access the data. First, the data source can be registered by name in the DataSourceFactory and the instance can be retrieved by that name. It's also possible to execute a SQL instruction over the registered data sources. Even it's possible to store to disk the information of an existing instance and create the instance from that information later. But the easiest way to get a DataSource instance is by calling the getAlphanumericDataSource() or getSpatialDataSource(). There are several methods with that name, the one we'll choose will depend on the type of source we want to access.
No matter the way, the DataSource is registered by a name in the DataSource factory. It's possible to remove the DataSource registration by calling its remove method. It has no efect on the DataSource but its name is no longer registered in the DataSourceFactory so no more instances can be obtained.
DataSource source = factory.getAlphanumericDataSource("file.csv");
source.remove();
It's even possible to execute SQL queries against registered DataSources:
DataSource source = factory.getAlphanumericDataSource("file.csv");
DataSource filtered = factory.executeSQL("select * from " + source.getName() + " where name='fernando'");
If the file is an alphanumeric one we will use the getAlphanumericDataSource(File file) method:
AlphanumericDataSource ds = factory.getAlphanumericDataSource(“person.csv");
The following code opens a shapefile called points.shp:
SpatialDataSource sds = factory.getSpatialDataSource(“points.shp");
Objects can also be a data source if they implement either the AlphanumericObjectDriver or SpatialObjectDriver interface. To get a DataSource instance that accesses the information of an object we proceed in the same way than before:
FakeObjectDriver driver = new FakeObjectDriver();
AlphanumericDataSource ds = factory.createDataSource(driver);
This one registers an object with a spatial field:
FakeSpatialObjectDriver driver = new FakeSpatialObjectDriver();
SpatialDataSource ds = factory.createDataSource(driver);
FakeObjectDriver y FakeSpatialObjectDriver are object drivers located in the com.hardcode.gdbms.engine.data package. They are only suitable to examples, unit and functional tests and so on.
There are two methods to get a DataSource instance that accesses a database.
This code registers an alphanumeric database table:
DBSource source = new DBSource(null, 0, basedir + "/src/test/resources/testdb", "sa", "", "persona", "jdbc:hsqldb:file");
AlphanumericDataSource ds = factory.createDataSource(source);
This one is for spatial database tables:
DBSource source = new DBSource(“127.0.0.1”, 5432, “testdb", "root", "", "polygons", "jdbc:postgresql");
AlphanumericDataSource ds = factory.createDataSource(source);
The read capabilities for a DataSource are:
Get a field value.
Get the names of the fields.
Get the index of a field by his name.
Get the number of rows.
Get all the values of a row.
Get the geometry type (only SpatialDataSource)
Get the index of the spatial field (only SpatialDataSource).
To get the value of a specified field at a specified row the getFieldValue() method has to be used.
source.start();
String v = source.getString(1, "name");
int i = source.getInt(1, "age");
...
source.stop();
This gets the value of field called "name" at the second row.
To perform this operation the DataSource.getFieldNames() method is used.
source.start();
String[] nombres = source.getFieldNames();
source.stop();
The method DataSource.getFieldIndexByName(String name) returns the index of the specified field.
source.start();
int index = source.getFieldIndexByName(“campo”);
source.stop();
It's possible to obtain the row number by calling the DataSource.getRowCount() method.
source.start();
long rows = source.getRowCount();
source.stop();
source.start();
Value[] valores = source.getRow(0);
source.stop();
SpatialDataSource spatial = (SpatialDataSource) source;
int type = spatial.getGeometryType();
SpatialDataSource spatial = (SpatialDataSource) source;
int spatialIndex = spatial.getSpatialFieldIndex();
These are the writing operations available to through the DataSource interface:
Set a field value.
Insert an empty row.
Insert a filled row.
Row deletion.
Undo/Redo.
source.setFieldValue(0, 0, ValueFactory.createValue("valor"));
source.setString(0, 0, "valor");
source.setInt(0, "age", 25);
It's possible to insert a row at the end of the DataSource by calling DataSource.insertEmptyRow().
source.insertEmptyRow();
AlphanumericDataSource alpha = (AlphanumericDataSource) source;
alpha.insertEmptyRowAt(0);
Value[] values = new Value[] {ValueFactory.createValue("valor1"), ValueFactory.createValue(1) };
source.insertFilledRow(values);
As the previous case to insert a row at a specified position a casting has to be done:
SpatialDataSource spatial = (SpatialDataSource) source;
Value[] valores = new Value[] {ValueFactory.createValue("valor1"), ValueFactory.createValue(1)};
spatial.insertFilledRowAt(0, valores);
SpatialDataSource spatial = (SpatialDataSource) source;
spatial.deleteRow(0);
To enable undo capabilities to a DataSource it has to be retrieved this way:
DataSource source = factory.createRandomDataSource(nombre, DataSourceFactory.UNDOABLE);After it, the DataSource.undo() and DataSource.redo() methods can be called only when there is an operation to undo or redo. It can be known by calling canUndo() and canRedo().
DataSource source = factory.executeSQL("select name from persona;");
DataSource source2 = factory.executeSQL("select * from " + source.getName() + " order by name asc;");
evaluate(Value[] args). This methods has the actual function code.
getName(). Returns the name of the function which will be used n the SQL statement.
isAggregate(). True if it's an aggregate function(max, min, count), false otherwise.
factory.executeSQL(“select max(age) from person; ”);
factory.executeSQL(“select sum(lenght(name)) from persona; ”);
cloneFunction(). Returns a new instance of the function.
FunctionManager.addFunction(new MyFunction());
Where MyFunction is an implementation of the Function interfaz.
Once registered it can be executed instructions like this one:
factory.executeSQL(“select myFunction(name) from persona;”);
Metadata m = ds.getDataSourceMetadata();
for (int i = 0; i < m.getFieldCount(); i++) {
System.out.println(m.getFieldName(i) + ": " + m.getFieldType(i));
}
DefaultDriverMetadata ddm = new DefaultDriverMetadata();
ddm.addField("text", "VARCHAR", new String[]{"LENGTH"}, new String[]{"5"});
ddm.addField("int", "TINYINT");
ddm.addField("decimal", "DECIMAL", new String[]{"SCALE", "PRECISION"}, new String[]{"5", "3"});
DBSource dbsd = new DBSource("www.myhost.com", 1234, "testdb", "user", "password", "new_table");
SourceCreation sc = new DBSourceCreation("GDBMS HSQLDB driver", dbsd, ddm);
dsf.createDataSource(sc);
dsf.addDataSource(new DBTableSourceDefinition("newDataSource", dbsd, "GDBMS HSQLDB driver"));
DataSource d = dsf.createRandomDataSource("newDataSource");
d.start();
...
d.stop();
DataSource d1 = dsf.createRandomDataSource("existingDataSource");
d1.start();
DefaultDriverMetadata ddm = d1.getDriverMetadata();
d1.stop();
DBSource dbsd = new DBSource("www.myhost.com", 1234, "testdb", "user", "password", "new_table");
SourceCreation sc = new DBSourceCreation("GDBMS HSQLDB driver", dbsd, ddm);
dsf.createDataSource(sc);
dsf.addDataSource(new DBTableSourceDefinition("newDataSource", dbsd, "GDBMS HSQLDB driver"));
DataSource d = dsf.createRandomDataSource("newDataSource");
d.start();
...
d.stop();