~sidnei/storm/mssql-support

« back to all changes in this revision

Viewing changes to storm/store.py

  • Committer: Gustavo Niemeyer
  • Date: 2007-08-07 23:15:09 UTC
  • mfrom: (156.1.8 preset-primary-key)
  • Revision ID: gustavo@niemeyer.net-20070807231509-iw58uiygzuef5wth
Merged preset-primary-key branch [r=radix,jkakar] [f=126080]

This branch introduces a new hook which allows backends to modify
variables which are part of the primary key of an object before
they are inserted in the database.  Also, lazy values may now be
used in the primary key, which means that it's possible to set these
primary variables to SQL expressions if needed.

Other minor changes include an optimization in Result: it will
preset the raw cursor's arraysize to a better value if it's found
to be 1.  Result.__iter__() was also fixed to parse rows through
the from_database hook.

Show diffs side-by-side

added added

removed removed

Lines of Context:
321
321
            del obj_info["store"]
322
322
 
323
323
        elif pending is PENDING_ADD:
324
 
            columns = []
325
 
            variables = []
326
 
 
327
 
            for column in cls_info.columns:
328
 
                variable = obj_info.variables[column]
329
 
                if variable.is_defined():
330
 
                    columns.append(column)
331
 
                    variables.append(variable)
332
 
                else:
333
 
                    lazy_value = variable.get_lazy()
334
 
                    if isinstance(lazy_value, Expr):
335
 
                        columns.append(column)
336
 
                        variables.append(lazy_value)
337
 
 
338
 
            expr = Insert(columns, variables, cls_info.table)
 
324
 
 
325
            # Give a chance to the backend to process primary variables.
 
326
            self._connection.preset_primary_key(cls_info.primary_key,
 
327
                                                obj_info.primary_vars)
 
328
 
 
329
            changes = self._get_changes_map(obj_info, True)
 
330
 
 
331
            expr = Insert(changes, cls_info.table,
 
332
                          primary_columns=cls_info.primary_key,
 
333
                          primary_variables=obj_info.primary_vars)
339
334
 
340
335
            result = self._connection.execute(expr)
341
336
 
356
351
            cached_primary_vars = obj_info["primary_vars"]
357
352
            primary_key_idx = cls_info.primary_key_idx
358
353
 
359
 
            changes = {}
360
 
            for column in cls_info.columns:
361
 
                variable = obj_info.variables[column]
362
 
                if variable.has_changed():
363
 
                    if variable.is_defined():
364
 
                        changes[column] = variable
365
 
                    else:
366
 
                        lazy_value = variable.get_lazy()
367
 
                        if isinstance(lazy_value, Expr):
368
 
                            changes[column] = lazy_value
 
354
            changes = self._get_changes_map(obj_info)
369
355
 
370
356
            if changes:
371
357
                expr = Update(changes,
386
372
 
387
373
        obj_info.event.emit("flushed")
388
374
 
 
375
    def _get_changes_map(self, obj_info, adding=False):
 
376
        """Return a {column: variable} dictionary suitable for inserts/updates.
 
377
 
 
378
        @param obj_info: ObjectInfo to inspect for changes.
 
379
        @param adding: If true, any defined variables will be considered
 
380
                       a change and included in the returned map.
 
381
        """
 
382
        cls_info = obj_info.cls_info
 
383
        changes = {}
 
384
        select_variables = []
 
385
        for column in cls_info.columns:
 
386
            variable = obj_info.variables[column]
 
387
            if adding or variable.has_changed():
 
388
                if variable.is_defined():
 
389
                    changes[column] = variable
 
390
                else:
 
391
                    lazy_value = variable.get_lazy()
 
392
                    if isinstance(lazy_value, Expr):
 
393
                        if id(column) in cls_info.primary_key_idx:
 
394
                            select_variables.append(variable) # See below.
 
395
                            changes[column] = variable
 
396
                        else:
 
397
                            changes[column] = lazy_value
 
398
 
 
399
        # If we have any expressions in the primary variables, we
 
400
        # have to resolve them now so that we have the identity of
 
401
        # the inserted object available later.
 
402
        if select_variables:
 
403
            resolve_expr = Select([variable.get_lazy()
 
404
                                   for variable in select_variables])
 
405
            result = self._connection.execute(resolve_expr)
 
406
            for variable, value in zip(select_variables, result.get_one()):
 
407
                result.set_variable(variable, value)
 
408
 
 
409
        return changes
 
410
 
389
411
    def _fill_missing_values(self, obj_info, primary_vars, result=None,
390
412
                             checkpoint=True, replace_lazy=False):
391
413
        """Query retrieve from the database any missing values in obj_info.