Database - noobmobile/GroovyBukkitAPI GitHub Wiki
Databases
GroovyBukkitAPI uses norm. Just call useDatabase() on your enable() and you'll be ready to use it.
@Entity
@Inject
@Table(name = "groovyusers")
class User {
@Id
String name
int blocks
}
def onBreak = { BlockBreakEvent e ->
def user = main.database().where("name=?", e.player.name).first(User)
user.setBlocks(user.getBlocks() + 1)
e.player.sendMessage("$user.blocks")
main.database().upsert(user)
}
Method Injections
GroovyBukkitAPI already injects to you the following methods into your domain objects:
MyObject.findByProperty()e.g.:User.findByName(name)MyObject.findAllByProperty()e.g.:User.findAllByBlocks(blocks)MyObject.findAll()e.g.:User.findAll()MyObject.save()e.g.:user.save()MyObject.delete()e.g.:user.delete()MyObject.topXProperty()pseudo-regex:(top|order|orderBy)(number?)(asc|desc?)(by?)(property)(if Desc or Asc is specificied, default is Desc) e.g:
User.topKills() // order by kills desc, no limit
User.top10Kills() // order by kills, desc, limit 10
User.top50AscKills() // order by kills, asc, limit 50
User.order20AscByDeaths() // order by deaths, asc, limit 20
User.orderByAscDeaths() // order by deaths, asc, no limit
def onBreak = { BlockBreakEvent e ->
def user = User.findByName(e.player.name) ?: new User(name: e.player.name)
user.setBlocks(user.getBlocks() + 1)
e.player.sendMessage("$user.blocks")
user.save()
}
Be careful to call all these methods in async.
Converters
GroovyBukkitAPI automatically provides to you the following converters:
ItemStackLocationMap
So you don't need to use @Convert from javax. But if you want to use, no problems, nOrm will handle to you.
@Entity
@Inject
@Table(name = "groovyusers")
class User {
@Id
String name
int blocks
Map<String, Integer> kills
Location lastSeen
@Convert(converter = MyAttributeConverter.class)
CustomThing customThing
}
Database config
It'll be generated a database.yml with the following configurations:
database:
type: MYSQL // Avaliable: SQLITE, MYSQL
host: localhost
port: '3306'
user: admin
password: ''
database: test
Cache
It's not recommended query/update database all time, specially on Bukkit, where we have 20 ticks per second (this can lead to thousands of database operations easily)
@ToString
@Entity
@Inject
@Table(name = "groovymachines")
class Machine {
@CacheOptions(loadAllOnEnable = true, saveAllOnDisable = true)
static final Cache<Location, Machine> CACHE = new Cache<>(Machine, { it.location })
@Id
Location location
String owner
int timesClicked
}
def onInteract = { PlayerInteractEvent e ->
if (!e.hasBlock()) return
if (!e.hasItem() || e.getItem().getType() != Material.STICK) return
def clicked = e.getClickedBlock().getLocation()
def player = e.player
def machine = Machine.CACHE.getCached(clicked)
?: new Machine(owner: player.name, location: clicked)
machine.timesClicked++
player.sendMessage("$machine")
machine.cache() // if not cached, cache it
}
Cache Options
First, let's explain the Cache constructor:
static final Cache<Location, Machine> CACHE = new Cache<>(Machine, { it.location })
The first parameter it's our domain object class, the second one is its key.
@CacheOptions
loadAllOnEnable()- load all objects into cache ononEnable(), default falsesaveAllOnDisable()- save all cached objects ononDisable(), default trueautoSave()- save all cached objects periodically, default trueautoSaveDelay()- the delay of our autosave in minutes, default 30loadOnJoin()- load a object into cache if is found a object with the key being the player's name, default false (ONLY FOR PLAYERS) (Useful forUser)saveOnQuit()- same as above, default false