sfAlchemy.py

Go to the documentation of this file.
00001 # SalesForce Alchemy - provides an ORM-type interface for SalesForce via pyax and pyax_utils.
00002 
00003 import os, sys
00004 import random
00005 
00006 from vyperlogix.classes.MagicObject import MagicObject2
00007 
00008 from vyperlogix.sf.sf import SalesForceQuery
00009 from vyperlogix.sf.abstract import SalesForceAbstract
00010 from vyperlogix.wx.pyax.SalesForceLoginModel import SalesForceLoginModel
00011 
00012 from vyperlogix import misc
00013 from vyperlogix.misc import _utils
00014 from vyperlogix.hash import lists
00015 
00016 from vyperlogix.daemon.daemon import Log
00017 
00018 from vyperlogix.classes.SmartObject import SmartFuzzyObject
00019 
00020 __copyright__ = """\
00021 (c). Copyright 1990-2008, Vyper Logix Corp., All Rights Reserved.
00022 
00023 Published under Creative Commons License 
00024 (http://creativecommons.org/licenses/by-nc/3.0/) 
00025 restricted to non-commercial educational use only., 
00026 
00027 See also: http://www.VyperLogix.com and http://www.pypi.info for details.
00028 
00029 THE AUTHOR VYPER LOGIX CORP DISCLAIMS ALL WARRANTIES WITH REGARD TO
00030 THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
00031 FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
00032 INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
00033 FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
00034 NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
00035 WITH THE USE OR PERFORMANCE OF THIS SOFTWARE !
00036 
00037 USE AT YOUR OWN RISK.
00038 """
00039 
00040 class SalesForceObjectException(Exception):
00041     def __init__(self, value):
00042         self.parameter = value
00043     def __str__(self):
00044         return repr(self.parameter)
00045         
00046 class SalesForceFieldException(Exception):
00047     def __init__(self, value):
00048         self.parameter = value
00049     def __str__(self):
00050         return repr(self.parameter)
00051         
00052 class SalesForceParmException(Exception):
00053     def __init__(self, value):
00054         self.parameter = value
00055     def __str__(self):
00056         return repr(self.parameter)
00057         
00058 class SalesForceOrderByException(Exception):
00059     def __init__(self, value):
00060         self.parameter = value
00061     def __str__(self):
00062         return repr(self.parameter)
00063         
00064 class SalesForceAlchemy(MagicObject2,SalesForceAbstract):
00065     def __init__(self,username=None,password=None,token=None):
00066         # Note: SalesForceAbstract.__init__() appears below where it should... never mind about doing anything about it here.
00067         self.__username__ = username
00068         self.__password__ = password
00069         self.__token__ = token
00070         self.__endPoint__ = None
00071         self.__sfLoginModel__ = None
00072         self.__api_version__ = 14
00073         self.__types__ = lists.HashedFuzzyLists2()
00074         self.__objectStack__ = []
00075         self.__fieldsStack__ = []
00076         self.__filterStack__ = []
00077         self.__orderByStack__ = []
00078         self.__quoted__ = lambda val:"'" if (not str(val).isdigit()) else ''
00079         
00080         self.__reset_magic__() # This is basically the init method for MagicObject2...
00081         
00082     def __tokenize_password__(self):
00083         if (misc.isString(self.__token__)):
00084             self.__password__ = str(self.__password__) + self.__token__
00085             self.__token__ = None
00086 
00087     def api_version():
00088         doc = "api_version - default is 14.0 however any valid value works so long as SalesForce supports it."
00089         def fget(self):
00090             return self.__api_version__
00091         def fset(self, api_version):
00092             self.__api_version__ = _utils.only_float_digits(str(api_version))
00093         return locals()
00094     api_version = property(**api_version())
00095 
00096     def lastError():
00097         doc = "lastError property"
00098         def fget(self):
00099             return self.__sfLoginModel__.lastError
00100         return locals()
00101     lastError = property(**lastError())
00102 
00103     def isLoggedIn():
00104         doc = "isLoggedIn property"
00105         def fget(self):
00106             return self.__sfLoginModel__.isLoggedIn
00107         return locals()
00108     isLoggedIn = property(**isLoggedIn())
00109     
00110     def __make_soql__(self):
00111         where_clause = []
00112         while (len(self.__filterStack__) > 0):
00113             aFilter = self.__filterStack__.pop()[0]
00114             aClause = ' and '.join(['%s.%s=%s%s%s' % (self.object_prefix,k,self.__quoted__(v),v,self.__quoted__(v)) for k,v in aFilter.iteritems()])
00115             if (len(aClause) > 0):
00116                 where_clause.append()
00117         if (len(where_clause) > 0):
00118             where_clause = ['(%s)' % (where) for where in where_clause]
00119         order_by_clause = []
00120         while (len(self.__orderByStack__) > 0):
00121             item = self.__orderByStack__.pop()[0]
00122             if (item in self.description.fieldnames):
00123                 order_by_clause.append('%s.%s' % (self.object_prefix,item))
00124                 break
00125             else:
00126                 raise SalesForceOrderByException('Cannot use the field named "%s" in an ORDER BY clause for SalesForce Object named "%s".' % (item,self.object_name))
00127         if (len(order_by_clause) == 1):
00128             order_by_clause.insert(0,'')
00129         from_clause = ' FROM %s %s%s' % (self.object_name,self.object_prefix,' WHERE %s' % (' and '.join(where_clause)) if (len(where_clause) > 0) else '')
00130         soql = 'SELECT %s%s%s' % (', '.join(self.names),from_clause,' ORDER BY '.join(order_by_clause) if (len(order_by_clause) > 0) else '')
00131         soql_count = 'SELECT COUNT()%s' % (from_clause)
00132         return soql,soql_count
00133     
00134     def __getattr__(self,name):
00135         t = self.__types__[name]
00136         if (t is not None):
00137             self.__objectStack__.append(t)
00138             return self
00139         return super(SalesForceAlchemy, self).__getattr__(name)
00140     
00141     def __call__(self,*args,**kwargs):
00142         super(SalesForceAlchemy, self).__call__(*args,**kwargs)
00143         n = self.n.pop()
00144         a = list(args)
00145         a.append(kwargs)
00146         if (n == 'endPoint'):
00147             self.__endPoint__ = a
00148         elif (n == 'login'):
00149             self.__tokenize_password__()
00150             self.__sfLoginModel__ = SalesForceLoginModel(username=self.__username__,password=self.__password__)
00151             if (isinstance(self.__endPoint__,list)):
00152                 self.__sfLoginModel__.api_version = self.__api_version__
00153                 self.__endPoint__ = self.__endPoint__[0] if (len(self.__endPoint__) > 0) else 'www.salesforce.com'
00154             if (self.__endPoint__.find('://') == -1):
00155                 self.__endPoint__ = self.__sfLoginModel__.get_endpoint(end_point=self.__endPoint__)
00156             self.__sfLoginModel__.perform_login(end_point=self.__endPoint__)
00157             if (self.isLoggedIn):
00158                 for t in self.__sfLoginModel__.sfdc.describe_global_response['types']:
00159                     self.__types__[t] = t
00160                 #self.__sfQuery__ = SalesForceQuery(self.__sfLoginModel__)
00161                 SalesForceAbstract.__init__(self, SalesForceQuery(self.__sfLoginModel__))
00162         elif (n == 'username'):
00163             self.__username__ = a[0] if (len(a) > 0) else ''
00164         elif (n == 'password'):
00165             self.__password__ = a[0] if (len(a) > 0) else ''
00166         elif (n == 'token'):
00167             self.__token__ = a[0] if (len(a) > 0) else ''
00168         elif (n == 'fields'):
00169             self.__fieldsStack__.append(a)
00170         elif (n == 'filter'):
00171             self.__filterStack__.append(a)
00172         elif (n == 'order_by'):
00173             self.__orderByStack__.append(a)
00174         elif (n == 'all') or (n == 'count'):
00175             try:
00176                 object_name = self.__objectStack__.pop()
00177             except IndexError:
00178                 raise SalesForceObjectException("Required Object Name was not present.  Object Name must appear like this (sf.case.fields('*').filter(Id='value-of-Id').order_by('Name').all()) with each Object Name being present in the target SalesForce Org.")
00179             fieldsStack_copy = misc.copy(self.__fieldsStack__)
00180             filterStack_copy = misc.copy(self.__filterStack__)
00181             orderByStack_copy = misc.copy(self.__orderByStack__)
00182             self.object_name = object_name
00183             self.canonicalizeNames(self.__fieldsStack__)
00184             soql,soql_count = self.__make_soql__()
00185             results_count = self.sf_query(soql_count)
00186             if (n == 'count'):
00187                 if (kwargs.has_key('debug')) and (kwargs['debug']):
00188                     return soql,soql_count,results_count[0]
00189                 else:
00190                     return results_count[0]
00191             else:
00192                 _callback = None
00193                 if (kwargs.has_key('callback')) and (callable(kwargs['callback'])):
00194                     _callback = kwargs['callback']
00195                 if (int(results_count[0].size[0]) > 1):
00196                     f = self.fields_by_(name='idlookup',value='true')
00197                     if (f is not None):
00198                         l = [_f for _f in f if (_f.has_key('name')) and (_f['name'].find('Id') > -1)]
00199                         if (len(l) == 0):
00200                             l = random.choice(f)
00201                         l = l[0] if (isinstance(l,list)) and (len(l) > 0) else l
00202                         self.__filterStack__ = filterStack_copy
00203                         self.__orderByStack__ = orderByStack_copy
00204                         self.namesCanonicalized([l['name']])
00205                         soql,soql_count = self.__make_soql__()
00206                         records = self.sf_query(soql)
00207                         for rec in records:
00208                             self.__fieldsStack__ = fieldsStack_copy
00209                             self.__filterStack__ = filterStack_copy
00210                             self.__orderByStack__ = orderByStack_copy
00211                             self.canonicalizeNames(self.__fieldsStack__)
00212                             pass
00213                         pass
00214                     pass
00215                 elif (kwargs.has_key('debug')) and (kwargs['debug']):
00216                     return soql,soql_count,results_count[0]
00217                 else:
00218                     records = self.sf_query(soql)
00219                     if (callable(_callback)):
00220                         for rec in records:
00221                             _callback(rec)
00222                     return records
00223         self.__reset_magic__()
00224         return self
00225 
00226 if (__name__ == '__main__'):
00227     import sys
00228     print >>sys.stdout, __copyright__
00229     print >>sys.stderr, __copyright__
00230 
00231     _root_ = r'Z:\python projects\molten_in_django'
00232     _logPath_ = os.path.join(_root_,'%s.log' % (os.path.basename(os.path.splitext(sys.argv[0])[0])))
00233     logger = Log(open(_logPath_,mode='a'))
00234     
00235     from maglib.salesforce.auth import credentials
00236     from maglib.salesforce.auth import magma_molten_passphrase
00237     
00238     _use_staging = False
00239     __sf_account__ = credentials(magma_molten_passphrase,0 if (not _use_staging) else 1)
00240     
00241     #sf = SalesForceAlchemy(username=__sf_account__['username'],password=__sf_account__['password']).endPoint('www.salesforce.com').login()
00242     #print 'isLoggedIn=%s' % (sf.isLoggedIn)
00243     #if (not sf.isLoggedIn):
00244         #print 'lastError=%s' % (sf.lastError)
00245     
00246     sf = SalesForceAlchemy().username(__sf_account__['username']).password(__sf_account__['password']).endPoint('www.salesforce.com').login()
00247     print 'isLoggedIn=%s' % (sf.isLoggedIn)
00248     if (not sf.isLoggedIn):
00249         print 'lastError=%s' % (sf.lastError)
00250 
00251     #results = sf.case.fields('*').filter(Id='500300000035KA4AAM').order_by('Id').all(debug=1)
00252     #print results
00253     
00254     #results = sf.case.fields('*').filter(Id='500300000035KA4AAM').order_by('Id').count()
00255     #print results
00256     
00257     #results = sf.case.fields('*').filter(Id='500300000035KA4AAM').order_by('Id').count(debug=1)
00258     #print results
00259     
00260     #results = sf.case.fields('*').filter(Id='500300000035KA4AAM').order_by('Id').all()
00261     #print results
00262 
00263     results = sf.account.fields('*').filter().order_by('Id').all()
00264     print results
00265 
00266     def aCallback(rec):
00267         pass
00268     
00269     results = sf.account.fields('*').filter().order_by('Id').all(callback=aCallback)
00270     print results
00271 
00272     results = sf.account.fields('*').filter().order_by('Id').iteritems()
00273     print results
00274 
00275     
00276 

© Copyright 2008-2009 Vyper Logix Corp., All Right Reserved; If you reference this document or any part of this document you must use the citation verbatim (including the link) "© Copyright 2008-2009 Vyper Logix Corp., All Right Reserved."

Notice: This source code contained in this document is NOT open source and is NOT being distributed as open source.

122,241 lines of code and growing...