Local Storage

Why Local Storage?

Local storage can be used to store information. The nice thing about this feature is that it can be used very dynamically: You get to use one table and you are the one that specifies what the table structure is. Further, Local Storage can be (and should be) used by intra gossip, which creates another dimension to P2P widgets.

How to use?

Local Storage for Tribler Widgets is possible by supporting 1 database table per widget, where the widget must specify the structure. It does so by initializing the _localstorage_structure variable within the widget class:

class widget(widgets.tribler_widget):



    _localstorage_structure = [("mynumber","integer pkey"), ("mytext","text")]

The _localstorage_structure variable is of list of tuples where the first entry is the name of the database table column and the second entry the strings identifying the column type. Possible types are: integer, text, numeric. After the column type, column which are part of the primary key should get "pkey" behind it, just like the mynumber column.

Database initialisation

When a local storage structure is specified, the widget runtime will set the _db variable of the widget (which is otherwise and on failure: None).

CAUTION however: the _db variable is initialised AFTER the __init__ method.

To do any database initialisation, implement the OnPostInit function, which will have the _db variable initialized:


    def OnPostInit(self):

        first_ten = self._db.getAll(("mynumber", "mytext"),limit=10, order_by = "mynumber DESC")

        # TODO: now initialize the GUI with these values...



Using the Local Storage API

The following functions are supported by the _db Database Handler:

    # insert one record

    def insert(self, commit=True, **kw):       

        

    #insert many records. Values is a list of tuples, keys a list of column names

    def insertMany(self, values, keys=None, commit=True):        



    # same as insert but ignores if record is already there

    def insertOrIgnore(self, commit=True, **kw):       

        

    # same as insertMany but ignores records that already exist

    def insertOrIgnoreMany(self, values, keys=None, commit=True):        

        

    # update a record. where is a valid SQL WHERE expression.

    def update(self, where=None, commit=True, **argv): 

        

    # delete a record. where is a valid SQL WHERE expression, but optional. keyword arguments may also specify exact matches,

    def delete(self, commit=True, where=None, **kw):    



    # retrieve one record. value_name is either a column name or a tuple of multiple column names.

    def getOne(self, value_name, where=None, conj='and', **kw):

    

    # retrieve multiple records

    def getAll(self, value_name, where=None, group_by=None, having=None, order_by=None, limit=None, offset=None, conj='and', **kw):



    

examples:

    self._db.insert(True,mynumber=23, mytext="hello")



    list_of_tuples = [(23,"foo"), (50,"bar"), (66, "miep")]

    self._db.insertMany(list_of_tuples)

    self._db.update("mynumber = 23", mynumber=10)

    self._db.delete(mynumber=10)                    # delete where mynumber =10

    self._db.delete("mynumber<=10", mytext="foo")   # delete where mynumber <= 10 AND mytext = 'foo'

    self._db.delete("mynumber<=10 or mytext='foo' ")   # delete where mynumber <= 10 OR mytext = 'foo'



    pairs = self._db.getAll(("mynumber", "mytext"),limit=10, order_by = "mynumber DESC")

    max = self._db.getOne("MAX(*)")