Sequence.py :  » Development » SnapLogic » snaplogic » components » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Development » SnapLogic 
SnapLogic » snaplogic » components » Sequence.py
# $SnapHashLicense:
# 
# SnapLogic - Open source data services
# 
# Copyright (C) 2008 - 2009, SnapLogic, Inc.  All rights reserved.
# 
# See http://www.snaplogic.org for more information about
# the SnapLogic project. 
# 
# This program is free software, distributed under the terms of
# the GNU General Public License Version 2. See the LEGAL file
# at the top of the source tree.
# 
# "SnapLogic" is a trademark of SnapLogic, Inc.
# 
# 
# $

#    $Id: Sequence.py 10330 2009-12-24 22:13:38Z grisha $

"""
Sequence component and resource definition.

This component allows the creation of resources that add a generated sequence number column to input
records. Currently this sequence is not persistent across pipeline runs. This means that everytime
a pipeline is run, the sequence will start from the number stored in the resource at creation time. Also,
pipelines which share a sequence will not receive unique numbers between the two. For example, if /pipe1 and
/pipe2 are both pipelines that contain sequence /seq1, when both pipelines are run (either concurrently or
separately), they will each receive the same sequence 1, 2, 3, ....

These shortcomings will be addressed at a later time.

"""

__docformat__ = "epytext en"

from decimal import Decimal
from snaplogic.common.data_types import Record
from snaplogic.common import version_info
from snaplogic.cc.component_api import ComponentAPI
import snaplogic.cc.prop as prop
from snaplogic import components
from snaplogic.common.snap_exceptions import *
from snaplogic.snapi_base import keys
from snaplogic.common.data_types import SnapNumber

# Public names 
__all__ = [ "Sequence" ]


class Sequence(ComponentAPI):
    """
    The sequence generating component.

    """
    
    api_version = '1.0'
    component_version = '1.1'
    
    capabilities = {
        ComponentAPI.CAPABILITY_INPUT_VIEW_LOWER_LIMIT    : 1,
        ComponentAPI.CAPABILITY_INPUT_VIEW_UPPER_LIMIT    : 1,
        ComponentAPI.CAPABILITY_OUTPUT_VIEW_LOWER_LIMIT   : 1,
        ComponentAPI.CAPABILITY_OUTPUT_VIEW_UPPER_LIMIT   : 1,
        ComponentAPI.CAPABILITY_ALLOW_PASS_THROUGH        : True
    }
    
    component_description = "Generates a sequence from a starting value with a specified step."
    component_label       = "Sequence"
    component_doc_uri     = "https://www.snaplogic.org/trac/wiki/Documentation/%s/ComponentRef/Sequence" % \
                                                        version_info.doc_uri_version


    def create_resource_template(self):
        """
        Create Sequence resource definition template. It consists of:

        InitialValue:   The value where the sequence starts.
        StepValue:      The increase per step.

        """
        self.set_property_def('InitialValue', 
                              prop.SimpleProp("InitialValue", 
                                              SnapNumber, 
                                              "The start value of the sequence.",
                                              None, 
                                              True))
        self.set_property_def('StepValue',    
                              prop.SimpleProp("StepValue",    
                                              SnapNumber, 
                                              "The increase of the sequence output per step.",
                                              None, 
                                              True))

        # Set some defaults
        self.set_property_value('InitialValue', 1)
        self.set_property_value('StepValue',    1)

        # Predefine the input view with no fields, pass-through = True, modifiable=False
        self.add_record_input_view_def('Input1', (), 'Sequence input view', False)

        # Predefine the output view with 1 field, modifiable=False and propagate the pass through fields
        self.add_record_output_view_def('Output1',
                                        (('Value', SnapNumber, "Sequence value"),),
                                        'Sequence output view', 
                                        False)
        self.set_output_view_pass_through('Output1', ["Input1",])

    def validate(self, err_obj):
        """
        Validate the input/output views for correctness.

        Generic validation handles checking the property values for presence and correctness.

        """

        # Generic constraint validation has already checked that we have
        # the correct number of input and output views but here we check
        # that the input view has no fields and the output view has only 1 
        # field of type number.
        input_views  = self.list_input_view_names()
        output_views = self.list_output_view_names()

        # Confirm that the input view has exactly only zero fields
        if len(self.get_input_view_def(input_views[keys.SINGLE_VIEW])[keys.VIEW_FIELDS]) != 0:
            err_obj.get_input_view_err().set_message("Input view may not contain any fields. All input fields must be pass through.")

        # Confirm that the output view has exactly only one field defined
        if len(self.get_output_view_def(output_views[keys.SINGLE_VIEW])[keys.VIEW_FIELDS]) != 1:
            err_obj.get_output_view_err().set_message("There must be exactly one field in the output view.")
        else:
            # And it's type must be number
            output_view_desc = self.get_output_view_def(output_views[keys.SINGLE_VIEW])
            if output_view_desc['fields'][0][keys.FIELD_TYPE] != SnapNumber:
                err_obj.get_output_view_err().set_message("Sequence component output field type must be '%s'." % SnapNumber)


    def execute(self, input_views, output_views):
        """
        Processing the input records.

        """
        try:
            output_view = output_views.values()[keys.SINGLE_VIEW] 
        except IndexError:
            raise SnapComponentError("No output view connected.")
        try: 
            input_view = input_views.values()[keys.SINGLE_VIEW]
        except IndexError:
            raise SnapComponentError("No input view connected.")       

        # Getting properties and views and doing some sanity checking.
        try:
            current_value = self.get_property_value('InitialValue')
            step_value    = self.get_property_value('StepValue')
            
            if type(current_value) != Decimal:
                current_value = Decimal(current_value)
                
            if type(step_value) != Decimal:
                step_value = Decimal(step_value)
        except Exception, e:
            self.elog(e)
            raise SnapComponentError("Cannot get proper numerical value for one of the properties.")

        # Pre-create the output record object
        out_rec = output_view.create_record()
        ofname  = out_rec.field_names[0]

        # Start the processing loop
        record = input_view.read_record()
        while record is not None:
            out_rec[ofname] = current_value
            current_value += step_value
            out_rec.transfer_pass_through_fields(record)
            output_view.write_record(out_rec)
            record = input_view.read_record()

        output_view.completed()

    def upgrade_1_0_to_1_1(self):
        """
        No-op upgrade only to change component doc URI during the upgrade
        which will be by cc_info before calling this method.
        
        """
        pass
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.