Skip to content

Repo Old

Denis Istratov edited this page Jul 28, 2023 · 1 revision

You can use Repo.builder() to create the repository you need.

Binary repository

This repository requires the least effort to initialize it.

You need only class, that implements Serializable and contains fields that types are primitive or implements Serializable

For example:

@Data
class User implements Serializable {
    private static final long serialVersionUID = 6529685098267757690L;
    private final String name;
    private int age;
    private List<String> children;
}

Usage of builder:

MutableRepo<String, User> repo = Repo.<String, User> builder()
        .folder(File("data")
        .binary()
        .build();

Warning! This method can be quite unstable! It is not recommended to use :(

Also it is recommended to set the serialVersionUID to the class as it was done in the example:

private static final long serialVersionUID = 6529685098267757690L;

Serializator repository

To use this type of repository, you must create your own implementation of CommonSerializer.

For example:

public record Purchase(int idOnForum,
                       String command,
                       String[] allowedServers,
                       String[] allowedWorlds,
                       XMaterial icon) {}
                     
public class PurchaseSerializer implements CommonSerializer<Purchase> {
    @Override
    public String serialize(Purchase purchase) {
        return purchase.idOnForum() +
                "\n" +
                purchase.command() +
                "\n" +
                String.join(",", purchase.allowedServers()) +
                "\n" +
                String.join(",", purchase.allowedWorlds()) +
                "\n" +
                purchase.icon().parseMaterial().name();
    }

    @Override
    public Purchase deserialize(String s) {
        String[] args = s.split("\n");
        return new Purchase(
                Integer.parseInt(args[0]),
                args[1],
                args[2].split(","),
                args[3].split(","),
                XMaterial.valueOf(args[4])
        );
    }
}

Now you can create repo using builder:

MutableRepo<String, User> repo = Repo.<String, User> builder()
        .folder(File("data")
        .serializer(new PurchaseSerializer())
        .build();

Schema repo

If you need a complete customization of the process of saving to memory (for example, if you want to use a database), then you can create a class that implements SchemaStrategy and use the builder from the example.

//using mysql class from https://github.com/Huskehhh/MySQL
@Data
class User {
    private final int id;
    private final String name;
    private int age;
}

@RequiredArgsConstructor
class UserSchema implements SchemaStrategy<Integer, User> {
    private final MySQL mysql;

    @Override
    public void init() {
        mysql.query("CREATE TABLE IF NOT EXISTS table (" +
                "id INT AUTO_INCREMENT PRIMARY KEY," +
                "name VARCHAR(25) NOT NULL," +
                "age INT NOT NULL" +
                ");");
    }

    @Override
    public void close() {
        mySQL.closeConnection();
    }

    @Override
    public Collection<User> all() {
        List<User> result = new ArrayList<>();
        mysql.query("SELECT * from table;",results->{
            if(results != null)
            while(results.next()){
                result.add(new User(
                        results.getInt("id"),
                        results.getString("name"),
                        results.getInt("age")
                ));
            }
        });
        return result;
    }

    @Override
    public User get(Integer key) {
        mysql.query("SELECT * from table WHERE id = "+key+";",results->{
            if(results != null)
                if(results.next()){
                    return new User(
                            results.getInt("id"),
                            results.getString("name"),
                            results.getInt("age")
                    );
                }
        });
        throw new RuntimeException("not found");
    }

    @Override
    public void insert(Integer key, User value) {
        mysql.update("INSERT INTO `table` (`id`, `name`, `age`) VALUES ('"+key+"','"+
                value.getName()
                +"',"+
                value.getAge()
                +");");

    }

    @Override
    public void remove(Integer key) {
        mysql.query("DELETE FROM table WHERE id =" + key + ";");
    }
}

Creating repo:

MySQL mysql = ...;
Repo.<Integer, User> builder().
                .schema(new UserSchema(mysql))
                .build();

Customizing builder

In addition to directly installing the repository folder, you can:

//A) Set name of dir (the path to it is the root folder of the program)
Repo.builder()
        .folder("data-dir")
        .serializer(new PurchaseSerializer())
        .build();


//B) Set bukkit plugin and name of dir (the path to it is the folder of your bukkit plugin)
@Override
public void onEnable() {
    Repo.builder()
            .folder("data-dir")
            .plugin(this)
            .serializer(new PurchaseSerializer())
            .build();
}


//C) Set only plugin (the folder name "saved-data-carcadex" will be used in plugin folder)
@Override
public void onEnable() {
    Repo.builder()
            .plugin(this)
            .serializer(new PurchaseSerializer())
            .build();
}


//D) implementation (the folder name "saved-data-carcadex" will be used in root folder)
Repo.builder().serializer(new PurchaseSerializer()).build();

You can set repo autoupdate:

Repo.builder()
          .autoupdate(1000*60*60*10) //in miliseconds
          .serializer(new PurchaseSerializer())
          .build();

You can set repo as synchronized or use concurrent Map for cache (do not use it both, choose one):

Repo.builder()
          .sync()
          .concurrent()
          .serializer(new PurchaseSerializer())
          .build();

You can set logger for repo:

Repo.builder()
          .logging() //Default slf4j logger
          /* .logging(org.slf4j.Logger) other logger
             .debugLogging(org.slf4j.Logger) only on debug enable logger
             or else .debugLogging() using default slf4j logger
          */
          .serializer(new PurchaseSerializer())
          .build();

YamlRepo

Implementation of immutable repo. Takes data from a file in YAML markup. Requires implementing ParseStrategy#fromYaml(FileConfiguration) to get the parse from the file.

For example:

Repo<String, List<Integer>> capacity = new YamlRepo<>(
    new File(getDataFolder(), "capacity.yml"),
    this,
    conf -> conf.getKeys(false).stream().collect(Collectors.toMap(
        value -> value,
        conf::getIntegerList))
);

Clone this wiki locally