Advertisement
Averell7

Python class to improve Unicode support for sqlite

Feb 7th, 2019
1,069
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.65 KB | None | 0 0
  1. class SqliteUnicode :
  2.     #
  3.     def __init__(self) :
  4.         self.collation = { u"a" : u"àáâãäåą",
  5.                            u"e" : u"eèéêëęε",
  6.                            u"i" : u"iìíîï",
  7.                            u"o" : u"òóôõöøő",
  8.                            u"u" : u"uûü",
  9.                            u"c" : u"cç",
  10.                            u"l" : u"ł",
  11.                            u"n" : u"ñńŋ",
  12.                            u"r" : u"ř",
  13.                            u"s" : u"sš",
  14.                            u"y" : u"ýÿ",
  15.                            u"z" : u"źżž",
  16.                            u"ae" : u"æÆ",
  17.                            u"oe" : u"œŒ"
  18.  
  19.                            }
  20.  
  21.         self.collation_ci = {}
  22.         self.reg_exp = {}
  23.  
  24.         for key, value in self.collation.iteritems() :
  25.             for letter in value :
  26.                 self.collation_ci[letter] = value + value.upper()
  27.  
  28.  
  29.         self.remove_accents = copy.deepcopy(self.collation)
  30.         for key, value in remove_accents1.iteritems() :
  31.             for letter in value :
  32.                 self.remove_accents[letter] = key
  33.  
  34.         # remove some other characters
  35.         for letter in u"()[]<>…" :
  36.             self.remove_accents[letter] = ""
  37.  
  38.  
  39.  
  40.  
  41.         # regular expressions
  42.         # We compile them to improve performance
  43.  
  44.         # These ones are used by collate
  45.         self.re1 = re.compile(u"[àâä]")
  46.         self.re2 = re.compile(u"[éèêë]")
  47.         self.re3 = re.compile(u"[îï]")
  48.         self.re4 = re.compile(u"[ôö]")
  49.         self.re5 = re.compile(u"[ûü]")
  50.  
  51.  
  52.  
  53.  
  54.     def replace_accents(self, string) :
  55.     # This function will replace accentuated characters to allow a friendly like
  56.     # e will find éèê etc. oe will find œ
  57.  
  58.         string2 = ""
  59.         for letter in string :
  60.             if letter in self.remove_accents :
  61.                 string2 += self.remove_accents[letter]
  62.             else :
  63.                 string2 += letter
  64.         return string2
  65.  
  66.  
  67.     def convert_to_regex(self, data) :
  68.  
  69.         c = ""
  70.         if data in self.reg_exp :
  71.             return self.reg_exp[data]
  72.  
  73.         reg_string = "(?ims)"     # create the regular expression
  74.         for c in data :         # divide string in letters
  75.             if c in "*.[]$()" :    # escape special characters
  76.                                 # TODO : are there others to escape ? What about % and ?
  77.                 reg_string += "\\" + c
  78.             elif c == "%" :
  79.                 reg_string += ".*"
  80.             elif c in self.collation_ci :
  81.                 reg_string += "[" + self.collation_ci[c] + "]"     # using collation_ci is not useful with (?i)
  82.                                                                    # It should not, but presently it is for an unknown reason
  83.             else :
  84.                 reg_string += c
  85.         if c != "%" :           # if the last character is not %
  86.             reg_string += "$"   # necessary to match only the whole string
  87.         try :
  88.             comp_reg = re.compile(reg_string)
  89.         except re.error as e :
  90.             print "compile error", reg_string
  91.         self.reg_exp[data] = comp_reg
  92.         return comp_reg
  93.  
  94.     def like(self, a, b) :
  95.         # On a 80000 rows table :
  96.         # original like takes 0.032s
  97.         # this like takes 0.25 s (about 8x)
  98.         #print a,b
  99.         try :
  100.             if b == None or a == None :
  101.                 return False
  102.  
  103.             data = self.convert_to_regex(a)
  104.  
  105.             if data.match(b) :
  106.                 return True
  107.             else :
  108.                 return False
  109.         except :
  110.             print "echec de like : ", a, "/", b
  111.             utils.printExcept()
  112.             return False
  113.  
  114.  
  115.     def like2(self, a, b) :
  116.         # On a 80000 rows table :
  117.         # original like takes 0.032s
  118.         # this like takes 0.25 s (about 8x)
  119. ##        print a,b
  120.         try :
  121.             if b == None or a == None :
  122.                 return False
  123.             a = self.replace_accents(a.lower())
  124.             b = self.replace_accents(b.lower())
  125.             a= a.replace("%", "")
  126.  
  127.             if a == b[0:len(a)]  :
  128.                 return True
  129.             else :
  130.                 return False
  131.         except :
  132.             print "echec de like : ", a, "/", b
  133.             utils.printExcept()
  134.             return False
  135.  
  136.  
  137.     def regexp(self,a,b) :
  138.         if b == None :
  139.             return False
  140.         if re.match(a,b) :
  141.             return True
  142.         else :
  143.             return False
  144.  
  145.     def collate(self,string1, string2):
  146.  
  147.         string1 = unicode(string1,"utf_8")
  148.         string2 = unicode(string2,"utf_8")
  149.         string1 = string1.lower()
  150.         string2 = string2.lower()
  151.  
  152.         string1 = self.re1.sub("a",string1)
  153.         string1 = self.re2.sub("e",string1)
  154.         string1 = self.re3.sub("i",string1)
  155.         string1 = self.re4.sub("o",string1)
  156.         string1 = self.re5.sub("u",string1)
  157.  
  158.         string2 = self.re1.sub("a",string2)
  159.         string2 = self.re2.sub("e",string2)
  160.         string2 = self.re3.sub("i",string2)
  161.         string2 = self.re4.sub("o",string2)
  162.         string2 = self.re5.sub("u",string2)
  163.  
  164.         compare = cmp(string1, string2)
  165.  
  166.         return compare
  167.  
  168.     def concat_ws(self, *args) :
  169.         separator = args[0]
  170.         data1 = args[1:]
  171.         x= []
  172.         # Remove None values
  173.         for a in data1 :
  174.             if a :
  175.                 x.append(a)
  176.         return separator.join(x)
  177.  
  178.  
  179.     def clean_commas(self, data1) :
  180.         if data1 :
  181.             data2 = re.findall("[0-9]+",data1)
  182.             data3 =",".join(data2)
  183.             return data3
  184.         else :
  185.             return data1
  186.  
  187.     def date2year(self,date1) :
  188.  
  189.         if date1 == None :
  190.             return date1
  191.         date1 =date1.split(",")[0]  # Delete all after a comma
  192.         date2 = date1.split("-")
  193.         if len(date2) < 2 :
  194.             date2 = date1.split("/")
  195.         if len(date2) == 3 :
  196.             return date2[2]
  197.         else :
  198.             return date1
  199.  
  200.  
  201.     def date2ymd(self,date1) :
  202.         # converts dmy format to ymd to allow sorting
  203.         # The job could be done with a regex
  204.         separator = "-"
  205.         if date1 == None :
  206.             return date1
  207.         date2 = date1.split("-")
  208.         if len(date2) < 3 :
  209.             date2 = date1.split("/")
  210.             separator = "/"
  211.         if len(date2) == 3 :
  212.             if len(date2[0]) == 1 :
  213.                 date2[0] = "0" + date2[0]
  214.             if len(date2[1]) == 1 :
  215.                 date2[1] = "0" + date2[1]
  216.  
  217.             return date2[2] + separator + date2[1] + separator + date2[0]
  218.         else :
  219.             return date1
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement