Projet

Général

Profil

0004-add-management-command-convert_to_sql-20410.patch

Christophe Siraut, 21 juin 2018 12:28

Télécharger (6,23 ko)

Voir les différences:

Subject: [PATCH 4/4] add management command convert_to_sql (#20410)

 tests/test_convert_to_sql.py                  | 54 ++++++++++++++++-
 wcs/ctl/management/commands/convert_to_sql.py | 85 +++++++++++++++++++++++++++
 2 files changed, 138 insertions(+), 1 deletion(-)
 create mode 100644 wcs/ctl/management/commands/convert_to_sql.py
tests/test_convert_to_sql.py
1
import os
1 2
import pytest
2 3
from django.core.management import get_commands
3 4
from django.core.management import call_command
5
from django.core.management.base import CommandError
6
from qommon.publisher import get_publisher_class
7
from test_api import local_user
8
from test_configure_connection import pub
9
from test_configure_connection import cursor
10
from test_configure_connection import database
4 11

  
5 12

  
6 13
def test_command_exists():
7
   assert 'convert_to_sql' in get_commands()
14
    assert 'convert_to_sql' in get_commands()
15

  
16

  
17
def test_unknown_publisher_fails():
18
    with pytest.raises(CommandError) as excinfo:
19
        call_command('convert_to_sql', '-d', 'unknown.net',
20
                     '--database', 'foobar')
21
    assert excinfo.value.message == 'unknown tenant'
22

  
23

  
24
def test_already_migrated_fails(pub):
25
    if pub.is_using_postgresql():
26
        with pytest.raises(CommandError) as excinfo:
27
            call_command('convert_to_sql', '-d', 'example.net',
28
                         '--database', 'foobar')
29
        assert excinfo.value.message == 'tenant already using postgresql'
30

  
31

  
32
def test_migration(pub, database):
33
    if not pub.is_using_postgresql():
34
        assert 'postgresql' not in pub.cfg
35
        call_command('convert_to_sql', '-d', 'example.net',
36
                     '--database', database)
37
        pub.set_config()
38
        assert 'postgresql' in pub.cfg
39

  
40

  
41
def test_data_migrated(pub, database, local_user):
42
    if pub.is_using_postgresql():
43
        return
44

  
45
    pub.load_site_options()
46
    assert not pub.site_options.has_option('options', 'postgresql')
47
    call_command('convert_to_sql', '-d', 'example.net', '--database', database)
48
    pub.load_site_options()
49
    assert pub.site_options.has_option('options', 'postgresql')
50

  
51
    # Open a new publisher, to ensure we use postgresql
52
    # not sure if this is needed
53
    publisher_class = get_publisher_class()
54
    publisher = publisher_class.create_publisher()
55
    publisher.app_dir = os.path.join(publisher.app_dir, 'example.net')
56
    publisher.set_config()
57
    assert publisher.site_options.has_option('options', 'postgresql')
58
    assert len(
59
        publisher.user_class.get_users_with_name_identifier('0123456789')) == 1
wcs/ctl/management/commands/convert_to_sql.py
1
from django.core.management.base import CommandError
2
from wcs.ctl.management.commands import configure_connection
3
import sys
4
from wcs import sql
5
from wcs.users import User
6
from wcs.formdef import FormDef
7
import traceback
8

  
9

  
10
class Command(configure_connection.Command):
11

  
12
    def handle(self, **options):
13

  
14
        if self.publisher.is_using_postgresql():
15
            raise CommandError('tenant already using postgresql')
16

  
17
        self.setup_connection(**options)
18
        sql.get_connection_and_cursor(new=True)
19
        self.store_users()
20
        self.store_forms()
21
        self.publisher.write_cfg()
22
        self.enable()
23
        self.publisher.cleanup()
24

  
25
    def store_users(self):
26
        errors = []
27
        print('converting users')
28
        sql.do_user_table()
29
        for i, user_id in enumerate(User.keys()):
30
            user = User.get(user_id)
31
            user.__class__ = sql.SqlUser
32
            try:
33
                user.store()
34
            except AssertionError:
35
                errors.append((user, traceback.format_exc()))
36
        sql.SqlUser.fix_sequences()
37

  
38
        if errors:
39
            error_log = open('error_user.log', 'w')
40
            for user, trace in errors:
41
                error_log.write('user_id {}'.format(user.id))
42
                error_log.write(trace)
43
                error_log.write('-'*80)
44
            error_log.close()
45
            print('There were some errors, see error_user.log for details.')
46

  
47
    def store_forms(self):
48
        errors = []
49
        for formdef in FormDef.select():
50
            print('converting %s' % formdef.name)
51
            sql.do_formdef_tables(formdef, rebuild_views=True,
52
                                  rebuild_global_views=True)
53
            data_class = formdef.data_class(mode='files')
54

  
55
            # load all objects a first time, to allow the migrate() code to be
56
            # run and the eventual changes properly saved.
57
            for id in data_class.keys():
58
                formdata = data_class.get(id)
59
            delattr(sys.modules['formdef'], formdef.url_name.title())
60

  
61
            # once this is done, reload and store everything in postgresql
62
            sql_data_class = formdef.data_class(mode='sql')
63
            for i, id in enumerate(data_class.keys()):
64
                formdata = data_class.get(id)
65
                formdata._formdef = formdef
66
                formdata._evolution = formdata.evolution
67
                formdata.__class__ = sql_data_class
68
                try:
69
                    formdata.store()
70
                except AssertionError:
71
                    errors.append((formdata, traceback.format_exc()))
72
            sql_data_class.fix_sequences()
73

  
74
        sql.do_tracking_code_table()
75
        sql.do_session_table()
76
        sql.do_meta_table()
77

  
78
        if errors:
79
            error_log = open('error_formdata.log', 'w')
80
            for formdata, trace in errors:
81
                error_log.write('{} {}'.format(formdata.fromdef, formdata.id))
82
                error_log.write(trace)
83
                error_log.write('-'*80)
84
            error_log.close()
85
            print('There were some errors, see error_formdata.log.')
0
-