%PDF- %PDF-
Direktori : /proc/thread-self/root/usr/lib/python2.7/site-packages/salt/sdb/ |
Current File : //proc/thread-self/root/usr/lib/python2.7/site-packages/salt/sdb/sqlite3.py |
# -*- coding: utf-8 -*- ''' SQLite sdb Module :maintainer: SaltStack :maturity: New :platform: all This module allows access to sqlite3 using an ``sdb://`` URI Like all sdb modules, the sqlite3 module requires a configuration profile to be configured in either the minion or master configuration file. This profile requires very little. For example: .. code-block:: yaml mysqlite: driver: sqlite3 database: /tmp/sdb.sqlite table: sdb create_table: True The ``driver`` refers to the sqlite3 module, ``database`` refers to the sqlite3 database file. ``table`` is the table within the db that will hold keys and values (defaults to ``sdb``). The database and table will be created if they do not exist. Advanced Usage: =============== Instead of a table name, it is possible to provide custom SQL statements to create the table(s) and get and set values. .. code-block: yaml myadvanced driver: sqlite3 database: /tmp/sdb-advanced.sqlite create_statements: - "CREATE TABLE advanced (a text, b text, c blob, d blob)" - "CREATE INDEX myidx ON advanced (a)" get_query: "SELECT d FROM advanced WHERE a=:key" set_query: "INSERT OR REPLACE INTO advanced (a, d) VALUES (:key, :value)" ''' from __future__ import absolute_import, print_function, unicode_literals # Import python libs import logging import codecs try: import sqlite3 HAS_SQLITE3 = True except ImportError: HAS_SQLITE3 = False # Import salt libs from salt.ext import six # Import third party libs import msgpack DEFAULT_TABLE = 'sdb' log = logging.getLogger(__name__) __func_alias__ = { 'set_': 'set' } def __virtual__(): ''' Only load if sqlite3 is available. ''' if not HAS_SQLITE3: return False return True def _quote(s, errors='strict'): encodable = s.encode('utf-8', errors).decode('utf-8') nul_index = encodable.find('\x00') if nul_index >= 0: error = UnicodeEncodeError('NUL-terminated utf-8', encodable, nul_index, nul_index + 1, 'NUL not allowed') error_handler = codecs.lookup_error(errors) replacement, _ = error_handler(error) encodable = encodable.replace('\x00', replacement) return '"' + encodable.replace('"', '""') + '"' def _connect(profile): db = profile['database'] table = None conn = sqlite3.connect(db) cur = conn.cursor() stmts = profile.get('create_statements') table = profile.get('table', DEFAULT_TABLE) idx = _quote(table + '_idx') table = _quote(table) try: if stmts: for sql in stmts: cur.execute(sql) elif profile.get('create_table', True): cur.execute(('CREATE TABLE {0} (key text, ' 'value blob)').format(table)) cur.execute(('CREATE UNIQUE INDEX {0} ON {1} ' '(key)').format(idx, table)) except sqlite3.OperationalError: pass return (conn, cur, table) def set_(key, value, profile=None): ''' Set a key/value pair in sqlite3 ''' if not profile: return False conn, cur, table = _connect(profile) if six.PY2: value = buffer(msgpack.packb(value)) else: value = memoryview(msgpack.packb(value)) q = profile.get('set_query', ('INSERT OR REPLACE INTO {0} VALUES ' '(:key, :value)').format(table)) conn.execute(q, {'key': key, 'value': value}) conn.commit() return True def get(key, profile=None): ''' Get a value from sqlite3 ''' if not profile: return None _, cur, table = _connect(profile) q = profile.get('get_query', ('SELECT value FROM {0} WHERE ' 'key=:key'.format(table))) res = cur.execute(q, {'key': key}) res = res.fetchone() if not res: return None return msgpack.unpackb(res[0])