# -*- coding: utf-8 -*-
"""
rhodecode.lib.db_manage
~~~~~~~~~~~~~~~~~~~~~~~
Database creation, and setup module for RhodeCode. Used for creation
of database as well as for migration operations
:created_on: Apr 10, 2010
:author: marcink
:copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
:license: GPLv3, see COPYING for more details.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
import sys
import uuid
import logging
from os.path import dirname as dn, join as jn
from rhodecode import __dbversion__
from rhodecode.model import meta
from rhodecode.model.user import UserModel
from rhodecode.lib.utils import ask_ok
from rhodecode.model import init_model
from rhodecode.model.db import User, Permission, RhodeCodeUi, \
RhodeCodeSetting, UserToPerm, DbMigrateVersion, RepoGroup,\
UserRepoGroupToPerm
from sqlalchemy.engine import create_engine
from rhodecode.model.repos_group import ReposGroupModel
log = logging.getLogger(__name__)
class DbManage(object):
def __init__(self, log_sql, dbconf, root, tests=False):
self.dbname = dbconf.split('/')[-1]
self.tests = tests
self.root = root
self.dburi = dbconf
self.log_sql = log_sql
self.db_exists = False
self.init_db()
def init_db(self):
engine = create_engine(self.dburi, echo=self.log_sql)
init_model(engine)
self.sa = meta.Session
def create_tables(self, override=False):
def create_tables(self, override=False, defaults={}):
Create a auth database
quiet = defaults.get('quiet')
log.info("Any existing database is going to be destroyed")
if self.tests:
if self.tests or quiet:
destroy = True
else:
destroy = ask_ok('Are you sure to destroy old database ? [y/n]')
if not destroy:
sys.exit()
if destroy:
meta.Base.metadata.drop_all()
checkfirst = not override
meta.Base.metadata.create_all(checkfirst=checkfirst)
log.info('Created tables for %s' % self.dbname)
def set_db_version(self):
ver = DbMigrateVersion()
ver.version = __dbversion__
ver.repository_id = 'rhodecode_db_migrations'
ver.repository_path = 'versions'
self.sa.add(ver)
log.info('db version set to: %s' % __dbversion__)
def upgrade(self):
Upgrades given database schema to given revision following
all needed steps, to perform the upgrade
from rhodecode.lib.dbmigrate.migrate.versioning import api
from rhodecode.lib.dbmigrate.migrate.exceptions import \
DatabaseNotControlledError
if 'sqlite' in self.dburi:
print (
'********************** WARNING **********************\n'
'Make sure your version of sqlite is at least 3.7.X. \n'
'Earlier versions are known to fail on some migrations\n'
'*****************************************************\n'
)
upgrade = ask_ok('You are about to perform database upgrade, make '
'sure You backed up your database before. '
'Continue ? [y/n]')
if not upgrade:
sys.exit('Nothing done')
repository_path = jn(dn(dn(dn(os.path.realpath(__file__)))),
'rhodecode/lib/dbmigrate')
db_uri = self.dburi
try:
curr_version = api.db_version(db_uri, repository_path)
msg = ('Found current database under version'
' control with version %s' % curr_version)
except (RuntimeError, DatabaseNotControlledError):
curr_version = 1
msg = ('Current database is not under version control. Setting'
' as version %s' % curr_version)
api.version_control(db_uri, repository_path, curr_version)
print (msg)
if curr_version == __dbversion__:
sys.exit('This database is already at the newest version')
#======================================================================
# UPGRADE STEPS
class UpgradeSteps(object):
Those steps follow schema versions so for example schema
for example schema with seq 002 == step_2 and so on.
def __init__(self, klass):
self.klass = klass
def step_0(self):
# step 0 is the schema upgrade, and than follow proper upgrades
print ('attempting to do database upgrade to version %s' \
% __dbversion__)
api.upgrade(db_uri, repository_path, __dbversion__)
print ('Schema upgrade completed')
def step_1(self):
pass
def step_2(self):
print ('Patching repo paths for newer version of RhodeCode')
self.klass.fix_repo_paths()
print ('Patching default user of RhodeCode')
self.klass.fix_default_user()
log.info('Changing ui settings')
self.klass.create_ui_settings()
rhodecode.websetup
~~~~~~~~~~~~~~~~~~
Weboperations and setup for rhodecode
:created_on: Dec 11, 2010
from rhodecode.config.environment import load_environment
from rhodecode.lib.db_manage import DbManage
from rhodecode.model.meta import Session
def setup_app(command, conf, vars):
"""Place any commands to setup rhodecode here"""
dbconf = conf['sqlalchemy.db1.url']
dbmanage = DbManage(log_sql=True, dbconf=dbconf, root=conf['here'],
tests=False)
dbmanage.create_tables(override=True)
dbmanage.create_tables(override=True, defaults=command.options.__dict__)
dbmanage.set_db_version()
opts = dbmanage.config_prompt(None, defaults=command.options.__dict__)
dbmanage.create_settings(opts)
dbmanage.create_default_user()
dbmanage.admin_prompt(defaults=command.options.__dict__)
dbmanage.create_permissions()
dbmanage.populate_default_permissions()
Session.commit()
load_environment(conf.global_conf, conf.local_conf, initial=True)
Status change: