Skip to content

An API that can help you easily create and manage your databases locally or online

Notifications You must be signed in to change notification settings

pepiillo99/DatabaseAPI

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

37 Commits
 
 
 
 
 
 
 
 

Repository files navigation

DatabaseAPI

This API is a help to create your database more easily and simply.

First of all, it will be necessary to create the database configuration, this will be separated by two types, MySQL and SQLite. For the MySQL configuration we will use the following arguments in the DatabaseConfiguration constructor:

MySQL

DatabaseConfiguration(String ip, int port, String user, String password) { // mysql

SQLite (local file)

DatabaseConfiguration(boolean generateIdentifiers, File dataFolder) { // sql

For this example we will use SQLite, which has no bearing on the functionality of the API.

DatabaseConfiguration dbConfig = new DatabaseConfiguration(true, new File("C:\Users\youruser\Desktop"));

With this, with each database registered in the API, a name.db file will be created (ONLY IN THE CASE OF USING SQLITE)

Next it will be necessary to create the API instance, it is abstract and we must add the necessary methods. In addition, it will also be necessary to add the configuration created previously.

DatabaseAPI databaseAPI = new DatabaseAPI(configuration) {
    @Override
    public void log(String name, String message) {
        System.out.println("[" + name + "]: " + message); // here you print with your log system...
    }
    @Override
    public boolean isPlayerOnline(UUID uuid) {
        return yoursystem.getPlayer(uuid) != null; // this you need return if player is online (for internal actions)
    }
    @Override
    public void kickPlayer(UUID uuid, String message) {
        yoursystem.getPlayer(uuid).kick(message); // this method is used to kick a player in the event that loading/saving returned an error.
    }         
};

When generating the API instance, we will automatically create two databases PlayerDatabase and ServerDatabase you can use any of these databases to your liking, but you can also create your own database. For this it will be necessary to create a class extending it from Database, for example we will create the TestDatabase database.

import me.pepe.DatabaseAPI.DatabaseManager.Types.Database;

public class TestDatabase extends Database {
    public TestDatabase() {
        super("TestDatabase"); // name of database
    }
}

Once the extended Database class is created, it will be necessary to register the database to the API, using the DatabaseManager we will register the database which we must initialize.

DatabaseManager dbManager = databaseAPI.getDatabaseManager();
dbManager.registerDatabase(new TestDatabase());
Database testdb = dbManager.getDatabase(TestDatabase.class);

As we have seen in the previous code, the databases in the API are saved using their own class as an identifier.

It is time to integrate tables in our database, for this, as before with the database itself, it will be necessary to create a class per table. Before continuing, I suppose you have noticed that the database has a built-in system for players, this is geared towards videogames or client systems. In the event that your software does not contain players or clients, you should not worry, this is completely separated in the code and does not imply any extra consumption.

The explanation of the client/player oriented API is at the end.

Once here it is important to know the types of tables.

  • DatabaseTable: It is the parent class, from which we can create the different types of tables. It is a basic table with its key and its attributes, to get a tuple we will use its key.
  • TableDatabaseMultiKeys: It extends from TableDatabase, it refers to its name, all the attributes can be used as "key", but it was really created thinking that its key was a number and that this auto incremented automatically as tuples are added. When trying to search for data in said table, it can return several tuples depending on the search method we use.

To make a good example of this type of table, we are going to save the contacts of a contact book, saving only the phone number and the name of the contact...

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;

import me.pepe.DatabaseAPI.DatabaseManager.DatabaseKeyType;
import me.pepe.DatabaseAPI.DatabaseManager.Databases.ServerDataDatabase;
import me.pepe.DatabaseAPI.DatabaseManager.Tables.DatabaseTable;
import me.pepe.DatabaseAPI.DatabaseManager.Types.Database;

public class ContactsTable extends DatabaseTable<ServerDataDatabase> { // on extends you need indicate which database you will use
    private int number = 0; // key...
    private String name = ""; // is important define default values...
    public ContactsTable(int number, Database database) {
        // (tableName, keyName, DatabaseType, database)
        super("ContactsTable", "number", DatabaseKeyType.INT, database);
        this.number = number;
    }
    @Override
    public Object keySerialize() { // you can change Object to Integer...
        return number;
    }
    @Override
    public HashMap<String, Object> serialize(HashMap<String, Object> map) {
        // As the telephone number is the key to the table, it will not be necessary to save it. (supposedly this will never change)
        map.put("name", name);
        return map;
    }
    @Override
    public void deserialize(ResultSet result) throws SQLException {
        // No need to enter primary key
        this.name = result.getString("name"); // we collect the name of the result and define it in our variable
    }
    @Override
    public void onLoad(boolean hasData) {
        System.out.println("Table " + getTableName() + " loaded hasData: " + hasData);
    }
    public int getNumber() {
        return number;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
        setSaved(false); // we define as the table is not saved
        save(true); // we save the table asynchromatically, in the case of not doing so (false) for the process to continue, you must wait for the database to be saved.
    }
}

And this code its for TableDatabaseMultiKeys:

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;

import me.pepe.DatabaseAPI.DatabaseManager.Types.Database;
import me.pepe.DatabaseAPI.DatabaseManager.Types.TableDatabaseMultiKeys;

public class ContactsTableMultiKeys extends TableDatabaseMultiKeys { // on extends you need indicate which database you will use
    private long id = 0;
    private int number = 0;
    private String name = "";
    public ContactsTableMultiKeys(int id, Database database) {
        super("ContactsMulti", "id", database);
        // Here the key is the id, by default extending from TableDatabaseMultiKeys you will know that it is a DatabaseKeyType.INT.
        this.id = id;
    }
    @Override
    public void buildKey(Long key) {
        this.id = key;
    }
    @Override
    protected void buildDatabase(ResultSet result) throws SQLException { // this you need define key (this method not call buildKey)
        this.id = result.getInt("id");
        this.number = result.getInt("number");
        this.name = result.getString("name");
    }
    @Override
    public Long keySerialize() { // i change Object to Integer
        return id;
    }
    @Override
    public HashMap<String, Object> serialize(HashMap mapp) { // here does not let you use the <String, Object> (although it is) I am working to fix this
        HashMap<String, Object> map = mapp; // temporaly fix
        map.put("number", number);
        map.put("name", name);
        return map;
    }
    @Override
    public void deserialize(ResultSet result) throws SQLException {
        this.number = result.getInt("number");
        this.name = result.getString("name");
    }
    public long getID() {
        return id;
    }
    public int getNumber() {
        return number;
    }
    public void setNumber(int number) {
        this.number = number;
        setSaved(false); // we define as the table is not saved
        save(true); // we save the table asynchromatically, in the case of not doing so (false) for the process to continue, you must wait for the database to be saved.
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
        setSaved(false); // we define as the table is not saved
        save(true); // we save the table asynchromatically, in the case of not doing so (false) for the process to continue, you must wait for the database to be saved.
    }
}

Here we have the example of the database using the DatabaseTable, when using it in this way our database will look like this:

+-----------+-------+
| number    | name  |
+-----------+-------+
| 666666666 | pepe  |
| 777777777 | maria |
| 888888888 | ana   |
+-----------+-------+

And this is the difference when using DatabaseTableMultiKeys:

+----+-----------+-------+
| id | number    | name  |
|----+-----------+-------+
| 1  | 666666666 | pepe  |
| 2  | 777777777 | maria |
| 3  | 888888888 | ana   |
+----+-----------+-------+

Now we know how to create our table and we know how it will be reflected in our database, it is time to register it in the API. To do this we must access the DatabaseManager which we have in the API instance, we previously saved it with the variable named databaseAPI

As we mentioned before we will register the tables in the following way:

DatabaseManager dbManager = databaseAPI.getDatabaseManager();
Database svDB = dbManager.getDatabase(ServerDataDatabase.class);
svDB.registerTable(databaseAPI, ContactsTable.class, new DatabaseTableInstance<Integer>() {
    @Override
    public DatabaseTable<ServerDataDatabase> newInstance(Integer key) {
        return new ContactsTable(key == null ? 0 : key, svDB); // the key to this table is a phone number, It can be null so in that case we will have to return default key (0)
    }       
});
svDB.registerTable(databaseAPI, ContactsTableMultiKeys.class, new DatabaseTableInstance<Integer>() {
    @Override
    public DatabaseTable<ServerDataDatabase> newInstance(Integer key) {
        return new ContactsTableMultiKeys(key == null ? 0 : key, svDB); // the key to this table is a phone number, It can be null so in that case we will have to return default key (0)
    }       
});

When we have passed this step, we will be able to use our database correctly, in fact we can execute this code and we will see that both the databases and the tables have been created. To continue, we are going to start by entering data into it.

*(For client/player system)

Table types available for client/player

  • PlayerDatabaseTable: It is the parent class, it will need the PlayerData of the client/player to be able to load/generate the data. It has an update method to update the data in the table, to execute this method it has a cooldown of 10 seconds so as not to saturate the database, although we will have the option of setting update priority so that it is always updated when using the method. We should not worry about the loss of data, because when downloading the PlayerData it will be saved automatically if it is not updated. From this class we can generate new table types for client/player.
  • SimplePlayerDatabaseTable: As its name indicates it is simply the child of PlayerDataDatabase.
  • MultiPlayerDatabaseTable: It is used to store the same data but in different sections, for example to store the statistics of a player in various game modes.

About

An API that can help you easily create and manage your databases locally or online

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages