Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.
 
 
 
 
 
 

311 rindas
8.0 KiB

  1. # Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
  2. # MIT License. See license.txt
  3. from __future__ import unicode_literals
  4. import webnotes
  5. session = webnotes.session
  6. sql = webnotes.conn.sql
  7. out = webnotes.response
  8. from webnotes.utils import cint
  9. import webnotes.defaults
  10. def get_sql_tables(q):
  11. if q.find('WHERE') != -1:
  12. tl = q.split('FROM')[1].split('WHERE')[0].split(',')
  13. elif q.find('GROUP BY') != -1:
  14. tl = q.split('FROM')[1].split('GROUP BY')[0].split(',')
  15. else:
  16. tl = q.split('FROM')[1].split('ORDER BY')[0].split(',')
  17. return [t.strip().strip('`')[3:] for t in tl]
  18. def get_parent_dt(dt):
  19. pdt = ''
  20. if sql('select name from `tabDocType` where istable=1 and name="%s"' % dt):
  21. import webnotes.model.meta
  22. return webnotes.model.meta.get_parent_dt(dt)
  23. return pdt
  24. def get_sql_meta(tl):
  25. std_columns = {
  26. 'owner':('Owner', '', '', '100'),
  27. 'creation':('Created on', 'Date', '', '100'),
  28. 'modified':('Last modified on', 'Date', '', '100'),
  29. 'modified_by':('Modified By', '', '', '100')
  30. }
  31. meta = {}
  32. for dt in tl:
  33. meta[dt] = std_columns.copy()
  34. # for table doctype, the ID is the parent id
  35. pdt = get_parent_dt(dt)
  36. if pdt:
  37. meta[dt]['parent'] = ('ID', 'Link', pdt, '200')
  38. # get the field properties from DocField
  39. res = sql("select fieldname, label, fieldtype, options, width from tabDocField where parent='%s'" % dt)
  40. for r in res:
  41. if r[0]:
  42. meta[dt][r[0]] = (r[1], r[2], r[3], r[4]);
  43. # name
  44. meta[dt]['name'] = ('ID', 'Link', dt, '200')
  45. return meta
  46. def add_match_conditions(q, tl):
  47. sl = []
  48. ur = webnotes.user.get_roles()
  49. for dt in tl:
  50. s = getmatchcondition(dt, ur)
  51. if s:
  52. sl.append(s)
  53. # insert the conditions
  54. if sl:
  55. condition_st = q.find('WHERE')!=-1 and ' AND ' or ' WHERE '
  56. condition_end = q.find('ORDER BY')!=-1 and 'ORDER BY' or 'LIMIT'
  57. condition_end = q.find('GROUP BY')!=-1 and 'GROUP BY' or condition_end
  58. if q.find('ORDER BY')!=-1 or q.find('LIMIT')!=-1 or q.find('GROUP BY')!=-1: # if query continues beyond conditions
  59. q = q.split(condition_end)
  60. q = q[0] + condition_st + '(' + ' OR '.join(sl) + ') ' + condition_end + q[1]
  61. else:
  62. q = q + condition_st + '(' + ' OR '.join(sl) + ')'
  63. return q
  64. def getmatchcondition(dt, ur):
  65. res = sql("SELECT `role`, `match` FROM tabDocPerm WHERE parent = '%s' AND (`read`=1) AND permlevel = 0" % dt)
  66. cond = []
  67. for r in res:
  68. if r[0] in ur: # role applicable to user
  69. if r[1]:
  70. if ":" in r[1]:
  71. keys = r[1].split(":")
  72. else:
  73. keys = [r[1], r[1]]
  74. for d in webnotes.defaults.get_user_default_as_list(keys[0]) or ["** No Match **"]:
  75. cond.append('`tab%s`.`%s`="%s"' % (dt, r[1], d))
  76. else:
  77. return ''
  78. return ' OR '.join(cond)
  79. def exec_report(code, res, colnames=[], colwidths=[], coltypes=[], coloptions=[], filter_values={}, query='', from_export=0):
  80. col_idx, i, out, style, header_html, footer_html, page_template = {}, 0, None, [], '', '', ''
  81. for c in colnames:
  82. col_idx[c] = i
  83. i+=1
  84. # load globals (api)
  85. from webnotes import *
  86. from webnotes.utils import *
  87. from webnotes.model.doc import *
  88. set = webnotes.conn.set
  89. sql = webnotes.conn.sql
  90. get_value = webnotes.conn.get_value
  91. convert_to_lists = webnotes.conn.convert_to_lists
  92. NEWLINE = '\n'
  93. exec str(code)
  94. if out!=None:
  95. res = out
  96. return res, style, header_html, footer_html, page_template
  97. def guess_type(m):
  98. """
  99. Returns fieldtype depending on the MySQLdb Description
  100. """
  101. import MySQLdb
  102. if m in MySQLdb.NUMBER:
  103. return 'Currency'
  104. elif m in MySQLdb.DATE:
  105. return 'Date'
  106. else:
  107. return 'Data'
  108. def build_description_simple():
  109. colnames, coltypes, coloptions, colwidths = [], [], [], []
  110. for m in webnotes.conn.get_description():
  111. colnames.append(m[0])
  112. coltypes.append(guess_type[m[0]])
  113. coloptions.append('')
  114. colwidths.append('100')
  115. return colnames, coltypes, coloptions, colwidths
  116. def build_description_standard(meta, tl):
  117. desc = webnotes.conn.get_description()
  118. colnames, coltypes, coloptions, colwidths = [], [], [], []
  119. # merged metadata - used if we are unable to
  120. # get both the table name and field name from
  121. # the description - in case of joins
  122. merged_meta = {}
  123. for d in meta:
  124. merged_meta.update(meta[d])
  125. for f in desc:
  126. fn, dt = f[0], ''
  127. if '.' in fn:
  128. dt, fn = fn.split('.')
  129. if (not dt) and merged_meta.get(fn):
  130. # no "AS" given, find type from merged description
  131. desc = merged_meta[fn]
  132. colnames.append(desc[0] or fn)
  133. coltypes.append(desc[1] or '')
  134. coloptions.append(desc[2] or '')
  135. colwidths.append(desc[3] or '100')
  136. elif meta.get(dt,{}).has_key(fn):
  137. # type specified for a multi-table join
  138. # usually from Report Builder
  139. desc = meta[dt][fn]
  140. colnames.append(desc[0] or fn)
  141. coltypes.append(desc[1] or '')
  142. coloptions.append(desc[2] or '')
  143. colwidths.append(desc[3] or '100')
  144. else:
  145. # nothing found
  146. # guess
  147. colnames.append(fn)
  148. coltypes.append(guess_type(f[1]))
  149. coloptions.append('')
  150. colwidths.append('100')
  151. return colnames, coltypes, coloptions, colwidths
  152. @webnotes.whitelist()
  153. def runquery(q='', ret=0, from_export=0):
  154. import webnotes.utils
  155. formatted = cint(webnotes.form_dict.get('formatted'))
  156. # CASE A: Simple Query
  157. # --------------------
  158. if webnotes.form_dict.get('simple_query') or webnotes.form_dict.get('is_simple'):
  159. if not q: q = webnotes.form_dict.get('simple_query') or webnotes.form_dict.get('query')
  160. if q.split()[0].lower() != 'select':
  161. raise Exception, 'Query must be a SELECT'
  162. as_dict = cint(webnotes.form_dict.get('as_dict'))
  163. res = sql(q, as_dict = as_dict, as_list = not as_dict, formatted=formatted)
  164. # build colnames etc from metadata
  165. colnames, coltypes, coloptions, colwidths = [], [], [], []
  166. # CASE B: Standard Query
  167. # -----------------------
  168. else:
  169. if not q: q = webnotes.form_dict.get('query')
  170. tl = get_sql_tables(q)
  171. meta = get_sql_meta(tl)
  172. q = add_match_conditions(q, tl)
  173. webnotes
  174. # replace special variables
  175. q = q.replace('__user', session['user'])
  176. q = q.replace('__today', webnotes.utils.nowdate())
  177. res = sql(q, as_list=1, formatted=formatted)
  178. colnames, coltypes, coloptions, colwidths = build_description_standard(meta, tl)
  179. # run server script
  180. # -----------------
  181. style, header_html, footer_html, page_template = '', '', '', ''
  182. out['colnames'] = colnames
  183. out['coltypes'] = coltypes
  184. out['coloptions'] = coloptions
  185. out['colwidths'] = colwidths
  186. out['header_html'] = header_html
  187. out['footer_html'] = footer_html
  188. out['page_template'] = page_template
  189. if style:
  190. out['style'] = style
  191. # just the data - return
  192. if ret==1:
  193. return res
  194. out['values'] = res
  195. # return num of entries
  196. qm = webnotes.form_dict.get('query_max') or ''
  197. if qm and qm.strip():
  198. if qm.split()[0].lower() != 'select':
  199. raise Exception, 'Query (Max) must be a SELECT'
  200. if not webnotes.form_dict.get('simple_query'):
  201. qm = add_match_conditions(qm, tl)
  202. out['n_values'] = webnotes.utils.cint(sql(qm)[0][0])
  203. @webnotes.whitelist()
  204. def runquery_csv():
  205. global out
  206. # run query
  207. res = runquery(from_export = 1)
  208. q = webnotes.form_dict.get('query')
  209. rep_name = webnotes.form_dict.get('report_name')
  210. if not webnotes.form_dict.get('simple_query'):
  211. # Report Name
  212. if not rep_name:
  213. rep_name = get_sql_tables(q)[0]
  214. if not rep_name: rep_name = 'DataExport'
  215. # Headings
  216. heads = []
  217. rows = [[rep_name], out['colnames']] + out['values']
  218. from cStringIO import StringIO
  219. import csv
  220. f = StringIO()
  221. writer = csv.writer(f)
  222. for r in rows:
  223. # encode only unicode type strings and not int, floats etc.
  224. writer.writerow(map(lambda v: isinstance(v, unicode) and v.encode('utf-8') or v, r))
  225. f.seek(0)
  226. out['result'] = unicode(f.read(), 'utf-8')
  227. out['type'] = 'csv'
  228. out['doctype'] = rep_name
  229. def add_limit_to_query(query, args):
  230. """
  231. Add limit condition to query
  232. can be used by methods called in listing to add limit condition
  233. """
  234. if args.get('limit_page_length'):
  235. query += """
  236. limit %(limit_start)s, %(limit_page_length)s"""
  237. import webnotes.utils
  238. args['limit_start'] = webnotes.utils.cint(args.get('limit_start'))
  239. args['limit_page_length'] = webnotes.utils.cint(args.get('limit_page_length'))
  240. return query, args