Package skytools :: Module quoting
[frames] | no frames]

Source Code for Module skytools.quoting

  1  # quoting.py 
  2   
  3  """Various helpers for string quoting/unquoting.""" 
  4   
  5  import psycopg, urllib, re 
  6   
  7  #  
  8  # SQL quoting 
  9  # 
 10   
11 -def quote_literal(s):
12 """Quote a literal value for SQL. 13 14 Surronds it with single-quotes. 15 """ 16 17 if s == None: 18 return "null" 19 s = psycopg.QuotedString(str(s)) 20 return str(s)
21
22 -def quote_copy(s):
23 """Quoting for copy command.""" 24 25 if s == None: 26 return "\\N" 27 s = str(s) 28 s = s.replace("\\", "\\\\") 29 s = s.replace("\t", "\\t") 30 s = s.replace("\n", "\\n") 31 s = s.replace("\r", "\\r") 32 return s
33
34 -def quote_bytea_raw(s):
35 """Quoting for bytea parser.""" 36 37 if s == None: 38 return None 39 return s.replace("\\", "\\\\").replace("\0", "\\000")
40
41 -def quote_bytea_literal(s):
42 """Quote bytea for regular SQL.""" 43 44 return quote_literal(quote_bytea_raw(s))
45
46 -def quote_bytea_copy(s):
47 """Quote bytea for COPY.""" 48 49 return quote_copy(quote_bytea_raw(s))
50
51 -def quote_statement(sql, dict):
52 """Quote whose statement. 53 54 Data values are taken from dict. 55 """ 56 xdict = {} 57 for k, v in dict.items(): 58 xdict[k] = quote_literal(v) 59 return sql % xdict
60 61 # 62 # quoting for JSON strings 63 # 64 65 _jsre = re.compile(r'[\x00-\x1F\\/"]') 66 _jsmap = { "\b": "\\b", "\f": "\\f", "\n": "\\n", "\r": "\\r", 67 "\t": "\\t", "\\": "\\\\", '"': '\\"', 68 "/": "\\/", # to avoid html attacks 69 } 70
71 -def _json_quote_char(m):
72 c = m.group(0) 73 try: 74 return _jsmap[c] 75 except KeyError: 76 return r"\u%04x" % ord(c)
77
78 -def quote_json(s):
79 """JSON style quoting.""" 80 if s is None: 81 return "null" 82 return '"%s"' % _jsre.sub(_json_quote_char, s)
83 84 # 85 # Database specific urlencode and urldecode. 86 # 87
88 -def db_urlencode(dict):
89 """Database specific urlencode. 90 91 Encode None as key without '='. That means that in "foo&bar=", 92 foo is NULL and bar is empty string. 93 """ 94 95 elem_list = [] 96 for k, v in dict.items(): 97 if v is None: 98 elem = urllib.quote_plus(str(k)) 99 else: 100 elem = urllib.quote_plus(str(k)) + '=' + urllib.quote_plus(str(v)) 101 elem_list.append(elem) 102 return '&'.join(elem_list)
103
104 -def db_urldecode(qs):
105 """Database specific urldecode. 106 107 Decode key without '=' as None. 108 This also does not support one key several times. 109 """ 110 111 res = {} 112 for elem in qs.split('&'): 113 if not elem: 114 continue 115 pair = elem.split('=', 1) 116 name = urllib.unquote_plus(pair[0]) 117 if len(pair) == 1: 118 res[name] = None 119 else: 120 res[name] = urllib.unquote_plus(pair[1]) 121 return res
122 123 # 124 # Remove C-like backslash escapes 125 # 126 127 _esc_re = r"\\([0-7][0-7][0-7]|.)" 128 _esc_rc = re.compile(_esc_re) 129 _esc_map = { 130 't': '\t', 131 'n': '\n', 132 'r': '\r', 133 'a': '\a', 134 'b': '\b', 135 "'": "'", 136 '"': '"', 137 '\\': '\\', 138 } 139
140 -def _sub_unescape(m):
141 v = m.group(1) 142 if len(v) == 1: 143 return _esc_map[v] 144 else: 145 return chr(int(v, 8))
146
147 -def unescape(val):
148 """Removes C-style escapes from string.""" 149 return _esc_rc.sub(_sub_unescape, val)
150
151 -def unescape_copy(val):
152 """Removes C-style escapes, also converts "\N" to None.""" 153 if val == r"\N": 154 return None 155 return unescape(val)
156