Skip to content

Instantly share code, notes, and snippets.

@monopolly
Created October 16, 2016 15:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save monopolly/2384c3d628177b625dc086e3c32288e5 to your computer and use it in GitHub Desktop.
Save monopolly/2384c3d628177b625dc086e3c32288e5 to your computer and use it in GitHub Desktop.
#!/usr/bin/tarantool
------------------------------------- Импортируем встроенные библиотеки ------------------------------------------
json = require('json')
yaml = require('yaml')
fiber = require('fiber')
msgpack = require('msgpack')
-------------------------------------------------- Конфиг базы ------------------------------------------------------
dir = 'dbtest'
os.execute("mkdir " .. dir) --создаем директорию если ее нет
box.cfg {
listen = 3301,
snapshot_period = 3600, --раз в час
snapshot_count = 10, --количество
slab_alloc_arena = 1.6, -- 1.6 Гб памяти для базы
work_dir = dir -- место куда тарантул будет складывать все, базу, xlogs
}
---------------------------------------------------- Доступ --------------------------------------------------------
box.schema.user.create('user1', {if_not_exists = true, password = '12345'}) --создаем пользователей
box.schema.user.create('user2', {if_not_exists = true, password = '12345'})
box.schema.user.grant('guest', 'read, write, execute', 'universe', nil, {if_not_exists=true, password = '12345'})
----------------------------------------- Маленькие и полезные утилитки --------------------------------------------
function Q(data) return print(yaml.encode(data)) end -- для удобства отображения таблиц в разработке
function time() return fiber.time64() end -- время в формате Unixtime nano = 1476627462302740
function js(data) return json.encode(data) end -- делает из таблицы json
function help() return docs end -- показывает помощь, перед этим нужно ее создать в docs
----------------------------------------------- Инициализация базы -------------------------------------------------
function init(db)
local newdb = {}
--смотрим сколько у нас будет таблиц
for name, list in pairs(db) do
--создаем таблицу
newdb[name] = {}
--создаем список соответствий
map = {} maplist = {} mapmap = {}
for i = 1, #list do
local item = list[i]
map[item.tag] = {num = i, type = item.type, default = item.default, index = item.index}
maplist[i] = item.tag
mapmap[item.tag] = i
end
--создаем спейс в тарантуле (таблицу)
--можно поиграться добавить engine если нужно
--по дефолту ngine = 'memtx'
newdb[name].db = box.schema.space.create(name, {if_not_exists = true})
--создаем индексы для таблицы из нашего списка
for i = 1, #list do
local field = list[i]
if field.index then
--если у в индексе несколько полей
--конвертируем названия например 'login' в формат тарантула {2, 'string'}
if field.parts then
--если есть прописанные части индекса
parts = {}
for _, partname in pairs(field.parts) do
table.insert(parts, map[partname].num)
table.insert(parts, map[partname].type)
end
field.parts = parts
else
--если нет прописанных частей, берем текущее поле
field.parts = {i, field.type}
end
--создаем индекс в спейсе
newdb[name].db:create_index(field.index, {if_not_exists = true, unique = field.unique, parts = field.parts})
end
end
--сохраняем наши таблицы соответствий
newdb[name].map = mapmap
newdb[name].list = maplist
end
return newdb
end
---------------------------------------------------- База данных --------------------------------------------------------
--к этой таблице мы будем потом обращаться из процедур
--назвал ее db, но можно как угодно;)
db = {}
--создаем таблицы
db.users = {
-- индексы
-- то есть обязательные поля
-- для индекса обязательно указывать название index = 'login'
-- если индекс составной, то тип нужно указывать и у тех полей которые в индексе
-- type: string, unsigned, int и тд (смотрите в официальной документации)
{ tag = 'id' , type='string' , index = 'primary' , unique = true},
{ tag = 'login' , type='string' , index = 'login' , unique = true},
{ tag = 'creds' , type='string' , index = 'creds' , parts = {'provider', 'key'} , unique = true},
-- обычные поля
{ tag = 'provider' , type='string'},
{ tag = 'key' , type='string'},
{ tag = 'token' , type='string'},
{ tag = 'name' , type='string'},
{ tag = 'about' , type='string'}
}
db.jobs = {
-- индексы
{ tag = 'id' , type='string' , index = 'primary' , unique = true },
{ tag = 'owner' , type='string' , index = 'owner' , unique = false },
-- поля
{ tag = 'provider' , type='string'},
{ tag = 'key' , type='string'},
{ tag = 'token' , type='string'},
{ tag = 'name' , type='string'},
{ tag = 'about' , type='string'}
}
db.followers = {
-- индексы
{ tag = 'id' , type='string' , index = 'primary' , unique = true },
{ tag = 'owner' , type='string' , index = 'owner' , unique = false },
--обычные поля
{ tag = 'provider' , type='string' , default = ""},
{ tag = 'key' , type='string' , default = ""},
{ tag = 'token' , type='string' , default = ""},
{ tag = 'name' , type='string' , default = ""},
{ tag = 'about' , type='string' , default = ""}
}
--------------------------------------------------- Поехали -------------------------------------------------------
--инициализируем нашу базу
db = init(db)
--смотрим работает или нет
Q(db.jobs.db:select{})
Q(db.jobs.map['owner'])
Q(db.jobs.list[5])
--например функция для апдейтов любой таблицы
function update(dbname, key, value)
return db[dbname].db:update({id}, {{'=', db[dbname].map[key], value}})
end
--вообшем это все помогает здорово экономить время на рутинные дела)
--чтобы потестировать нужно поставить себе тарантул
--сохранить этот темплейт например как test.lua
--в терминале запустить
--> tarantool test.lua
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment