예제 #1
0
class LancamentoAddCommand(object):
    def __init__(self):
        self._conta_dao = Inject('conta dao')
        self._lancamento_dao = Inject('lancamento dao')

    def lancamento_parser_created_handler(self, lancamento_parser):
        parser = lancamento_parser.add_parser(
            'add', aliases=['a'], help='Adiciona um novo lançamento')
        parser.set_defaults(event='lancamento_add_command')

        parser.add_argument('origem')
        parser.add_argument('destino')
        parser.add_argument('valor', type=currency.parse)
        parser.add_argument('--data',
                            '-d',
                            type=date_converter.parse,
                            default=date.today())
        parser.add_argument('--observacao', '-o', required=False)

    def lancamento_add_command_handler(self, args):
        contas_not_found = []

        origem = self._conta_dao.by_name(args.origem)
        if not origem:
            contas_not_found += ['origem']

        destino = self._conta_dao.by_name(args.destino)
        if not destino:
            contas_not_found += ['destino']

        if len(contas_not_found) > 0:
            return 'conta_not_found', {'contas': contas_not_found}
        else:
            lancamento = Lancamento()

            lancamento.data = args.data
            lancamento.origem = origem
            lancamento.destino = destino
            lancamento.valor = args.valor
            lancamento.observacao = args.observacao

            self._lancamento_dao.insert(lancamento)

            return 'ok', {'lancamento': lancamento}

    def lancamento_add_command_ok_handler(self, lancamento):
        observacao = lancamento.observacao if lancamento.observacao else ''

        print('Lançamento criado: {} {} {} {} {}'.format(
            lancamento.data, lancamento.origem.nome, lancamento.destino.nome,
            lancamento.valor, observacao))

    def lancamento_add_command_conta_not_found_handler(self, contas):
        plural_suffix = 's' if len(contas) > 0 else ''

        contas_str = ', '.join(contas)

        print('Conta{} não encontrada{0}: {}'.format(plural_suffix,
                                                     contas_str))
예제 #2
0
    def __init__(self):
        self._connection = Inject('database connection')
        self._conta_dao = Inject('conta dao')
        self._produto_dao = Inject('produto dao')
        self._fornecedor_dao = Inject('fornecedor dao')
        self._lancamento_dao = Inject('lancamento dao')

        self._unknown_contas = None
        self._unknown_produtos = None
        self._unknown_fornecedores = None
예제 #3
0
class ContaListCommand(object):

    def __init__(self):
        self._dao = Inject('conta dao')

    @staticmethod
    def conta_parser_created_handler(conta_parser):
        conta_parser.add_parser("list", aliases=['l', 'ls'], help="Lista as contas existentes").set_defaults(
            event='conta_list_command')

    def conta_list_command_handler(self, args):
        contas = self._dao.list()

        return 'ok', {'contas': contas}

    def conta_list_command_ok_handler(self, contas):
        factory = TablePrinterFactory()

        factory.string_column().of_attr('nome').add()
        factory.string_column().of_attr('descricao').title('Descrição').add()
        factory.string_column().of_attr('propriedades').add()

        printer = factory.create()

        printer.print(contas)
예제 #4
0
class LancamentoListCommand(object):
    def __init__(self):
        self._dao = Inject('lancamento dao')

    def lancamento_parser_created_handler(self, lancamento_parser):
        parser = lancamento_parser.add_parser(
            'list', aliases=['ls'], help='Lista os lançamentos existentes')

        parser.set_defaults(event='lancamento_list_command')

        # TODO
        # parser.add_argument('-f', '--filter', type=str, help='Filter to be applied')
        # parser.add_argument('-b', '--balance', action='store_true', help='Calculate the balances for each line')

    def lancamento_list_command_handler(self, args):
        lancamentos = self._dao.list_with_contas()

        return 'ok', {'lancamentos': lancamentos}

    def lancamento_list_command_ok_handler(self, lancamentos):
        factory = TablePrinterFactory()

        factory.date_column().of_attr('data').add()
        factory.string_column().of_attr('origem.nome').add()
        factory.string_column().of_attr('destino.nome').add()
        factory.currency_column().of_attr('valor').add()
        factory.string_column().of_attr('observacao').title('Observação').add()

        printer = factory.create()

        printer.print(lancamentos)
예제 #5
0
class DatabaseDumpCommand(object):

    def __init__(self):
        self._logger = Inject('logger')
        self._connection = Inject('database connection')
        self._config = Inject('app configuration')
        self._git = Inject('fdc git wrapper')

    def database_parser_created_handler(self, db_parser):
        db_parser.add_parser("dump", help="Dump database.db to database.dump").set_defaults(
            event='database_dump_command')

        # TODO Flag to skip specific git steps (or all of then)

    def database_dump_command_handler(self, args):
        with open(self._config['fdc.dump_full_path'], 'w') as file:
            for line in self._connection.iterdump():
                file.write('%s\n' % line)

        self._git.add(self._config['fdc.dump_full_path'])

        self._git.commit('--message', 'Automatic database dump')

        self._git.push()

        return 'ok'

    def database_dump_command_ok_handler(self):
        print('Database contents dumped')
예제 #6
0
class ContaAddCommand(object):

    def __init__(self):
        self._dao = Inject('conta dao')

    @staticmethod
    def conta_parser_created_handler(conta_parser):
        conta_add_parser = conta_parser.add_parser('add', aliases=['a'], help='Adiciona uma nova conta')
        conta_add_parser.set_defaults(event='conta_add_command')

        conta_add_parser.add_argument("-c", "--contabilizavel", default=False, action="store_true",
                                      help="Marca a nova conta como contabilizável (o saldo é calculado nas listagens)")
        conta_add_parser.add_argument("--df", "--fechamento", help="Data de fechamento da conta")

        conta_add_parser.add_argument("nome", help="Nome da conta a ser criada")

    def conta_add_command_handler(self, args):
        conta = Conta()

        conta.nome = args.nome
        if args.contabilizavel:
            conta.propriedades += 'contabilizável'

        if hasattr(args, "fechamento"):
            conta.fechamento = args.fechamento

        self._dao.insert(conta)

        return 'ok', conta

    def conta_add_command_ok_handler(self, conta):
        message = 'Conta "{}"'.format(conta.nome)

        if conta.propriedades != '':
            message += ' com as propriedades "{}"'.format(conta.propriedades)

        message += " criada."

        print(message)
예제 #7
0
class ConnectionFactory(object):
    def __init__(self):
        self._configs = Inject('app configuration')
        self._logger = Inject('logger')

    @staticmethod
    def get_external_resources():
        return [{
            'name': 'database connection',
            'creator': ConnectionFactory.create_connection
        }]

    def create_connection(self):
        # TODO Make this more generic, should not use fdc keys here!
        self._logger.debug('Connecting to database at {}...',
                           self._configs['fdc.db_full_path'])

        connection = sqlite3.connect(self._configs['fdc.db_full_path'])

        sqlite3.register_adapter(decimal.Decimal, lambda d: str(d))
        sqlite3.register_converter('decimal', lambda s: decimal.Decimal(s))

        return connection
예제 #8
0
class LancamentoBalanceHandler(object):
    def __init__(self):
        self._lancamento_dao = Inject('lancamento dao')

    def lancamento_balance_command_handler(self, args):
        # TODO Limit this by date
        lancamentos = self._lancamento_dao.list_with_contas()

        lancamentos_per_day = self._group_lancamentos_per_day(lancamentos)

        saldos = dict()
        balance = dict()

        for data, lancamentos in lancamentos_per_day.items():
            for lancamento in lancamentos:
                self._update_balance(balance, lancamento.origem,
                                     -lancamento.valor)

                self._update_balance(balance, lancamento.destino,
                                     lancamento.valor)

            saldos[data] = dict(balance)

        contas = list(set(balance.keys()))

        contas.sort()

        return 'ok', {'saldos': saldos, 'contas': contas}

    def _group_lancamentos_per_day(self, lancamentos):
        lancamentos_per_day = {}

        for lancamento in lancamentos:
            day_lancamentos = lancamentos_per_day.setdefault(
                lancamento.data, [])

            day_lancamentos.append(lancamento)

        return lancamentos_per_day

    def _update_balance(self, diario, conta, valor):
        if 'contabilizável' in conta.propriedades:
            saldo = diario.setdefault(conta.nome, Decimal(0))

            saldo += Decimal(valor) / Decimal(100)

            diario[conta.nome] = saldo
예제 #9
0
class ImportCSVCommand(object):

    def __init__(self):
        self._connection = Inject('database connection')
        self._conta_dao = Inject('conta dao')
        self._produto_dao = Inject('produto dao')
        self._fornecedor_dao = Inject('fornecedor dao')
        self._lancamento_dao = Inject('lancamento dao')

        self._unknown_contas = None
        self._unknown_produtos = None
        self._unknown_fornecedores = None

    @staticmethod
    def import_parser_created_handler(import_parser):
        import_csv_parser = import_parser.add_parser('csv', help='Importa um arquivo .csv')
        import_csv_parser.set_defaults(event='import_csv_command')

        import_csv_parser.add_argument('-c', '--confirm', action='store_true',
                                       help='Confirma a importação, caso contrário apenas mostra em tela o que será importado')
        import_csv_parser.add_argument("filename", help="Nome do arquivo que será importado")

    def import_csv_command_handler(self, args):
        source = open(args.filename, 'r')

        self._unknown_contas = set()
        self._unknown_produtos = set()
        self._unknown_fornecedores = set()

        ok = True

        lancamentos = []

        try:
            for self._i, self._line in enumerate(source):
                fields_array = self._get_fields_array()

                if not self._validate(fields_array, lambda f: len(f) >= 4, None,
                                      'every line must have at least 4 fields'):
                    continue

                fields = self._get_fields(fields_array)

                ok &= self._validate_fields(*fields)

                if ok:
                    lancamento = self._make_lancamento(*fields)

                    if args.confirm:
                        self._lancamento_dao.insert(lancamento)
                    else:
                        lancamentos.append(lancamento)

        except Exception:
            self._connection.rollback()
            raise

        if ok:
            if args.confirm:
                self._connection.commit()

                return 'imported', {'filename': args.filename}
            else:
                return 'simulated', {'filename': args.filename, 'lancamentos': lancamentos}

        else:
            if args.confirm:
                self._connection.rollback()

            return 'error', {'filename': args.filename, 'unknown_contas': self._unknown_contas,
                             'unknown_produtos': self._unknown_produtos,
                             'unknown_fornecedores': self._unknown_fornecedores}

    def _get_fields_array(self):
        if self._line.endswith('\n'):
            self._line = self._line[:-1]

        fields = self._line.split(';')

        return fields

    def _validate(self, data, validator, validation_fail_callback, message):
        if not validator(data):
            print('[ERROR] Line {}: {}'.format(self._i + 1, message.format(data)))

            if validation_fail_callback:
                validation_fail_callback()

            return False

        return True

    def _get_fields(self, fields_array):
        data = fields_array[0]
        origem = fields_array[1]
        destino = fields_array[2]
        valor = fields_array[3]

        observacoes = self._get(fields_array, 4)
        produto = self._get(fields_array, 5)
        quantidade = self._get(fields_array, 6)
        fornecedor = self._get(fields_array, 7)

        return data, origem, destino, valor, observacoes, produto, quantidade, fornecedor

    def _validate_fields(self, data, origem, destino, valor, observacoes, produto, quantidade, fornecedor):
        ok = self._validate(data, self._data_ok, None, 'date "{{}}" is not in format "{}"'.format(_CSV_DATE_FORMAT))

        ok &= self._validate(origem, self._conta_dao.by_name, lambda: self._unknown_contas.add(origem),
                             'origem "{}" doesnt exists')

        ok &= self._validate(destino, self._conta_dao.by_name, lambda: self._unknown_contas.add(destino),
                             'destino "{}" doesnt exists')

        ok &= self._validate(valor, self._valor_ok, None, 'valor "{}" is not in valid format')

        if produto:
            ok &= self._validate(produto, self._produto_dao.by_name, lambda: self._unknown_produtos.add(produto),
                                 'produto "{}" not found')

        if quantidade:
            ok &= self._validate(quantidade, self._is_float, None, 'quantidade "{}" is not a float value')

        if fornecedor:
            ok &= self._validate(fornecedor, self._fornecedor_dao.by_name,
                                 lambda: self._unknown_fornecedores.add(fornecedor), 'fornecedor "{}" not found')

        return ok

    def _make_lancamento(self, data, origem, destino, valor, observacoes, produto, quantidade, fornecedor):
        lancamento = Lancamento()

        # TODO Extract a formatter from the following two lines
        lancamento.data = datetime.strftime(datetime.strptime(data, _CSV_DATE_FORMAT), _SQLITE_DATE_FORMAT)
        lancamento.valor = int(valor.replace('.', ''))
        lancamento.origem = self._conta_dao.by_name(origem)
        lancamento.destino = self._conta_dao.by_name(destino)
        lancamento.observacoes = observacoes
        lancamento.produto = self._produto_dao.by_name(produto) if produto else None
        lancamento.quantidade = quantidade
        lancamento.fornecedor = self._fornecedor_dao.by_name(fornecedor) if fornecedor else None

        return lancamento

    @staticmethod
    def _get(fields, index, default=None):
        return fields[index] if len(fields) >= index + 1 else default

    @staticmethod
    def _data_ok(value):
        try:
            datetime.strptime(value, _CSV_DATE_FORMAT)

            return True
        except ValueError:
            return False

    @staticmethod
    def _valor_ok(valor):
        try:
            # TODO Internacionalize this to work with , for decimal point!
            Decimal(valor)
            return True
        except InvalidOperation:
            return False

    @staticmethod
    def _is_float(value):
        try:
            float(value)
            return True
        except ValueError:
            return False

    @staticmethod
    def import_csv_command_imported_handler(filename):
        print('Arquivo "{}" importado com sucesso!'.format(filename))

    @staticmethod
    def import_csv_command_simulated_handler(filename, lancamentos):
        print('Simulated import for file "{}" (use --confirm to actually import), would create lancamentos:'.format(
            filename))

        for lancamento in lancamentos:
            print(ImportCSVCommand._make_lancamento_string(lancamento))

    @staticmethod
    def _make_lancamento_string(lancamento):
        values = list()

        values.append(str(lancamento.data))
        values.append(str(lancamento.origem))
        values.append(str(lancamento.destino))
        values.append(str(lancamento.valor))
        values.append(str(lancamento.observacoes)) if lancamento.observacoes else None
        values.append(str(lancamento.produto)) if lancamento.produto else None
        values.append(str(lancamento.quantidade)) if lancamento.quantidade else None
        values.append(str(lancamento.fornecedor)) if lancamento.fornecedor else None

        return '; '.join(values)

    @staticmethod
    def import_csv_command_error_handler(filename, unknown_contas, unknown_produtos, unknown_fornecedores):
        print('Erros importando arquivo "{}"!'.format(filename))
        print()

        ImportCSVCommand._print_array('Contas desconhecidas:', unknown_contas)
        ImportCSVCommand._print_array('Produtos desconhecidos:', unknown_produtos)
        ImportCSVCommand._print_array('Fornecedores desconhecidos:', unknown_fornecedores)

    @staticmethod
    def _print_array(message, array):
        if len(array) == 0:
            return

        print(message)

        for conta in array:
            print(conta)

        print()
예제 #10
0
class DatabaseRestoreCommand(object):
    def __init__(self):
        self._config = Inject('app configuration')
        self._logger = Inject('logger')
        self._git = Inject('fdc git wrapper')

    def database_parser_created_handler(self, db_parser):
        db_parser.add_parser("restore",
                             help="Restore fdc.dump to fdc.db").set_defaults(
                                 event='database_restore_command')

        # TODO A flag to skip git pull
        # TODO A flag to rename existing database
        # TODO A parameter to change dump file location
        # TODO A parameter to change database to be restored
        # TODO A parameter to disable git pull

    def database_restore_command_handler(self, args):
        self._git.pull()

        # FIXME This will become huge after some time.....
        restore_database_script = self._get_database_restore_script()

        if not restore_database_script:
            return 'dump_file_not_found'

        connection = self._prepare_connection()

        # FIXME Rollback on error
        connection.executescript(restore_database_script)

        connection.commit()

        connection.close()

        return 'ok'

    def _get_database_restore_script(self):
        if not os.path.isfile(self._config['fdc.dump_full_path']):
            return None

        file = open(self._config['fdc.dump_full_path'], 'r')

        script = file.read()

        file.close

        return script

    def _prepare_connection(self):
        if os.path.isfile(self._config['fdc.db_full_path']):
            os.remove(self._config['fdc.db_full_path'])

        return di_container.get_resource('database connection')

    def database_restore_command_dump_file_not_found_handler(self):
        print('Dump file not found at "{}". Nothing to do.'.format(
            self._config['fdc.db_full_path']))

    def database_restore_command_ok_handler(self):
        print('Dump file at "{}" restored into database "{}" successfully.'.
              format(self._config['fdc.dump_full_path'],
                     self._config['fdc.db_full_path']))
예제 #11
0
 def __init__(self):
     self._config = Inject('app configuration')
     self._logger = Inject('logger')
     self._git = Inject('fdc git wrapper')
예제 #12
0
 def __init__(self):
     self._dependency = Inject('transient_dependency')
예제 #13
0
 def __init__(self):
     self._configs = Inject('app configuration')
     self._logger = Inject('logger')
예제 #14
0
 def __init__(self):
     self._was_set = Inject('dependency_of_external_dependency_was_set')
예제 #15
0
 def __init__(self):
     self._conta_dao = Inject('conta dao')
     self._lancamento_dao = Inject('lancamento dao')
예제 #16
0
 def __init__(self):
     self._lancamento_dao = Inject('lancamento dao')
예제 #17
0
 def __init__(self):
     self._dao = Inject('conta dao')
예제 #18
0
 def __init__(self, entity_class, metadata):
     self._connection = Inject('database connection')
     self._logger = Inject('logger')
     self._entity_class = entity_class
     self._metadata = metadata
예제 #19
0
class FDCInitCommand(object):
    def __init__(self):
        self._configs = Inject('app configuration')
        self._git = Inject('fdc git wrapper')
        self._logger = Inject('logger')

    def database_parser_created_handler(self, db_parser):
        db_parser.add_parser(
            "init",
            help=
            "Inicializa a pasta do FDC e o banco de dados com uma estrutura vazia. Se houver um banco de dados já "
            "existente o mesmo será excluído e reiniciado.").set_defaults(
                event='database_init_command')

    def database_init_command_handler(self, args):
        # TODO Verificar se o arquivo de banco de dados é um SQLITE válido!

        self._ensure_fdc_folder_exists()

        self._ensure_fdc_folder_is_git_repository()

        self._ensure_database_structure_with_no_data()

        return 'ok'

    def _ensure_fdc_folder_exists(self):
        if not os.path.isdir(self._configs['fdc.folder']):
            self._logger.info('Creating fdc folder at "{}"',
                              self._configs['fdc.folder'])
            os.makedirs(self._configs['fdc.folder'], exist_ok=True)
        else:
            self._logger.info('fdc folder found at "{}"',
                              self._configs['fdc.folder'])

    def _ensure_fdc_folder_is_git_repository(self):
        if not self._git.is_repository():
            self._logger.info(
                'Git repository not found at fdc folder, creating it...')
            if not self._git.init():
                raise FDCInitializationException(
                    'Error initializing git repository at "{}"',
                    self._git.repository_folder)

    def _ensure_database_structure_with_no_data(self):
        if os.path.isfile(self._configs['fdc.db_full_path']):
            self._logger.warn('Database file "{}" found, removing it...',
                              self._configs['fdc.db_full_path'])
            os.remove(self._configs['fdc.db_full_path'])

        connection = di_container.get_resource('database connection')

        # TODO Create these tables via controller events to centralize table handling in specialized classes

        self._logger.debug('Creating table "Conta"...')
        connection.executescript('create table Conta ('
                                 '  nome text not null,'
                                 '  descricao text,'
                                 '  data_aquisicao date,'
                                 '  propriedades text not null,'
                                 '  observacao text);')

        self._logger.debug('Creating table "Cotacao"...')
        connection.executescript('create table Cotacao ('
                                 '  data date not null,'
                                 '  moeda text not null,'
                                 '  valor integer not null);')

        self._logger.debug('Creating table "Orcamento"...')
        connection.executescript('create table Orcamento ('
                                 '  nome text not null,'
                                 '  descricao text not null);')

        self._logger.debug('Creating table "OrcamentoLancamento"...')
        connection.executescript('create table OrcamentoLancamento ('
                                 '  orcamento not null references Orcamento,'
                                 '  regra_data_vencimento text not null,'
                                 '  origem_padrao not null references Conta,'
                                 '  destino_padrao not null references Conta,'
                                 '  valor_padrao integer not null,'
                                 '  cotacao_moeda text,'
                                 '  regra_cotacao_data text,'
                                 '  regra_periodo_referencia text not null,'
                                 '  produto references Produto,'
                                 '  quantidade integer,'
                                 '  observacao text);')

        self._logger.debug('Creating table "Lancamento"...')
        connection.executescript('create table Lancamento ('
                                 '  data date not null,'
                                 '  origem references Conta not null,'
                                 '  destino references Conta not null,'
                                 '  valor integer not null,'
                                 '  cotacao references Cotacao,'
                                 '  referencia_inicio text,'
                                 '  referencia_fim text,'
                                 '  realizado boolean not null default false,'
                                 '  produto references Produto,'
                                 '  fornecedor references Fornecedor,'
                                 '  quantidade integer,'
                                 '  observacao text);')

        self._logger.debug('Creating table "Produto"...')
        connection.executescript('create table Produto ('
                                 '  nome text not null,'
                                 '  medida text,'
                                 '  unidade text);')

        self._logger.debug('Creating table "Fornecedor"...')
        connection.executescript('create table Fornecedor ('
                                 '  nome text not null);')

        # TODO Handle errors

    def database_init_command_ok_handler(self):
        print('Structure created successfully')
예제 #20
0
 def __init__(self):
     self._external_dependency = Inject('external_dependency')
예제 #21
0
 def __init__(self):
     self._dependency = Inject('dependency_name')
예제 #22
0
 def __init__(self):
     self._dependency = Inject('dependency which doesnt exists')
예제 #23
0
class Main(object):
    def __init__(self):
        self._logger = Inject('logger')
        self._configs = Inject('app configuration')

    def main(self):
        packages = [
            'commons',
            'di_container',
            __package__ + '.commons',
            __package__ + '.conta',
            __package__ + '.database',
            __package__ + '.import',
            'fdc.lancamento',
            'fdc.produto',
            'fdc.fornecedor',
        ]

        di_container.load_resources(packages)
        controller.load_listeners(packages)

        di_container.inject_resources(self)

        self._logger.info('Loaded resources and listeners from packages: {}',
                          packages)

        self._logger.debug('Using configurations: {}', self._configs.dump())

        args = self.parse_command_line()

        self._logger.info('Command line parsed: {}', args)

        event_results = controller.event(args.event,
                                         inject_dependencies=True,
                                         args=args)

        for result in event_results:
            self._logger.info(
                'Calling front end for "{}" with data "{}, {}" due to status "{}"',
                args.event, result.kwdata, result.data, result.status)

            # inject_dependencies parameter put first
            event_args = True, *result.data

            controller.event(args.event + '_' + result.status, *event_args,
                             **result.kwdata)

    def parse_command_line(self):
        parser = argparse.ArgumentParser()

        subparsers = parser.add_subparsers()

        controller.event('root_parser_created', root_parser=subparsers)

        args = parser.parse_args()

        if not hasattr(args, "event"):
            parser.print_help()
            parser.exit(0, "No arguments supplied\n")
        else:
            return args
예제 #24
0
class AbstractDao(object):
    def __init__(self, entity_class, metadata):
        self._connection = Inject('database connection')
        self._logger = Inject('logger')
        self._entity_class = entity_class
        self._metadata = metadata

    def new_builder(self, kind):
        if kind == 'SELECT':
            return SelectBuilder(self._metadata)
        else:
            return None

    def get_single(self, where=None, *values):
        list = self.list(where, *values)

        return list[0] if len(list) > 0 else None

    def list(self, where=None, *values):
        cursor = self._create_select_cursor((), where, *values)

        entity_list = self._load_cursor(cursor)

        cursor.close()

        return entity_list

    def exists(self, where, *values):
        cursor = self._create_select_cursor(('count(*)', ), where, *values)

        count = cursor.fetchone()[0]

        return count > 0

    def _create_select_cursor(self, fields=(), where=None, *values):
        builder = self.new_builder('SELECT')

        builder.where = where

        builder.fields(*fields) if len(fields) > 0 else None

        query = builder.build()

        return self._connection.execute(query, values)

    def _load_cursor(self, cursor):
        entity_list = []
        for row in cursor:
            entity = self._load_row(row)

            entity_list.append(entity)
        return entity_list

    def _load_row(self, row):
        entity_values = {}

        for i, field_name in enumerate(self._metadata.fields):
            value = row[i]

            entity_values[field_name] = value

        return SimpleNamespace(**entity_values)

    def insert(self, entity):
        builder = InsertBuilder(self._metadata)

        sql = builder.build()

        # TODO Essa recuperação de valores é responsabilidade do InsertBuilder
        values = self._get_field_values(entity)

        self._logger.debug('Running "{}" with values "{}"', sql, values)

        self._connection.execute(sql, values)

        self._connection.commit()

    def _get_field_values(self, entity):
        t = ()

        for field in self._metadata.fields:
            if field == 'rowid':
                continue

            value = getattr(entity, field, None)

            if hasattr(value, 'rowid'):
                t += value.rowid,
            else:
                t += value,

        return t
예제 #25
0
 def __init__(self):
     self._configs = Inject('app configuration')
     self._verbosity_level = None
예제 #26
0
 def __init__(self):
     self._dependency_with_transient = Inject('dependency_with_transient')