2çªç®ã®éšåã¯ã¯ã€ãã¯ã¹ã¿ãŒãã§ãã
3çªç®ã®éšåã¯æ©èœã§ã ã
ãã®ãããã¯ã¯Habréã§ä»¥åã«è°è«ããããšããäºå®ã«ãããããããããã€ãã®éèŠãªäºæã¯çºé³ãããŠããŸããã ãã®èšäºã¯ããããã¯ãéãããããšãè©Šã¿ãŸãã è¿œå /ä¿®æ£ã«é¢ããã³ã¡ã³ããæè¿ããŸãã
ããŒã¿ããŒã¹å ã®æžåŒæåå
SQLiteããŒã¿ããŒã¹ã¯ãããã¹ãïŒæååå€ïŒãããŒã¿ããŒã¹ã«UTF-8圢åŒãŸãã¯UTF-16圢åŒã§ä¿åã§ããŸãã 16ãããUTF-16æåã®ãã€ãé ã¯ããªãã«ãšã³ãã£ã¢ã³ãŸãã¯ããã°ãšã³ãã£ã¢ã³ã®ããããã§ãã
ã€ãŸããå®éã«ã¯3ã€ã®ç°ãªãSQLiteããŒã¿ããŒã¹åœ¢åŒããããŸãïŒ UTF-8ãUTF-16leãUTF-16beã§ãã
ãããã®åœ¢åŒã¯ãããã®ãã©ãããã©ãŒã ã§ã䜿çšã§ããŸãïŒã€ãŸããUTF-16be圢åŒã§x86ããŒã¹ã®ããŒã¿ããŒã¹ãäœæããããšã劚ãããã®ã¯ãããŸããããããã¯äžåçã§ããã以äžãåç §ããŠãã ããïŒã
æååã®åœ¢åŒã¯ã ããŒã¿ããŒã¹ãäœæããåã« èšå®ãããããŒã¿ããŒã¹èšå®ã§ãã ããŒã¿ããŒã¹ãäœæããåŸã圢åŒãå€æŽããããšã¯ã§ããŸãã ã ããããµã€ã¬ã³ãã«å®è¡ããããšãããšãSQLiteã«ãŒãã«ã¯ç¡èŠããŸãã
ã ãã
SQLiteããŒã¿ããŒã¹ã®è¡åœ¢åŒã¯æ¬¡ã®ããããã§ãã
-UTF-8ïŒããã©ã«ãã§äœ¿çšïŒ;
-UTF-16leïŒx86ãã€ãã£ãïŒ;
-UTF-16be
ããŒã¿ããŒã¹ã®äœæåŸã«å€æŽããããšã¯ã§ããŸããã
泚é
1. UTF-8ãšUTF-16ã®äž¡æ¹ïŒããµãã²ãŒããã¢ããåç §ïŒã¯ã1ãã€ãã®æåãæ ŒçŽããããã«å¯å€ïŒéåºå®ïŒãã€ãæ°ã䜿çšããŸãã
2.ããŒã¿ããŒã¹ã«ã¢ã¿ãããããšãåãæåå圢åŒã§ã®ã¿ããŒã¹ã§ããŸããããããªããšãšã©ãŒãçºçããŸãã
3. SQLiteã®ããŒãžã§ã³ãããã¢ã»ã³ããªäžã«UTF-16ãµããŒãããåé€ããããå¯èœæ§ããããŸãïŒSQLITE_OMIT_UTF16ã«ã€ããŠã¯sqlite3.cãåç § ïŒã
APIåŒã³åºãã«æååãæž¡ã
SQLite APIåŒã³åºãïŒCèšèªïŒã¯ãUTF-16圢åŒïŒãã©ãããã©ãŒã ã®ãã€ãã£ããã€ãé ïŒã§æååãåä¿¡ããããšãšãUTF-8圢åŒã§æååãåä¿¡ããããšã®2ã€ã®ã¿ã€ãã«åããããŸãã äŸïŒ
int sqlite3_prepare_v2( sqlite3 *db, /* Database handle */ const char *zSql, /* SQL statement, UTF-8 encoded */ int nByte, /* Maximum length of zSql in bytes. */ sqlite3_stmt **ppStmt, /* OUT: Statement handle */ const char **pzTail /* OUT: Pointer to unused portion of zSql */ ); int sqlite3_prepare16_v2( sqlite3 *db, /* Database handle */ const void *zSql, /* SQL statement, UTF-16 encoded */ int nByte, /* Maximum length of zSql in bytes. */ sqlite3_stmt **ppStmt, /* OUT: Statement handle */ const void **pzTail /* OUT: Pointer to unused portion of zSql */ );
åºæ¬æååã®åœ¢åŒãAPIã«æž¡ãããæååã®åœ¢åŒãšäžèŽããªãã£ãå Žåãéä¿¡ãããæååã¯ãã®å Žã§åºæ¬åœ¢åŒã«å€æãããŸãã ãã®ããã»ã¹ã¯ãªãœãŒã¹ãæ¶è²»ããã®ã§ããã¡ãããé¿ããã¹ãã§ãã ãã ãããããæªãã ãã§ãªãã以äžãåç §ããŠãã ããã
ç §åïŒæååæ¯èŒã¡ãœãã
次ã®ãããã¯ã¯ãçžäºã«çžå¯Ÿçãªè¡ã®é åºïŒæé ãŸãã¯éé ïŒã«é¢é£ããŠããããããã2è¡ã¯çããã§ããïŒããšãã質åã«å¯ŸããçããååŸããŸãã 2è¡ãæ¯èŒãããèªç¶ãªãæ¹æ³ã¯ãããŸããã å°ãªããšãã倧æåãšå°æåãåºå¥ããã®ãã倧æåãšå°æåãåºå¥ããªãã®ããšããçåãçããŸãã ããã«ãåãããŒã¿ããŒã¹ã§ãç°ãªããã£ãŒã«ãã®ãã®ãããªæ¯èŒã®äž¡æ¹ã䜿çšã§ããŸãã
SQLiteïŒããã³ä»»æã®ããŒã¿ããŒã¹ïŒã§ã¯ã ç §åã®æŠå¿µãå°å ¥ãããŠããŸããããã¯ã2ã€ã®è¡ãçžäºã«æ¯èŒããæ¹æ³ã§ãã æšæºïŒçµã¿èŸŒã¿ïŒç §åããããä»»æã®æ°éã§ç¬èªã®ç §åãäœæã§ããŸãã
ç §åã¯ãåºæ¬çã«æååAãšBãååŸãã次ã®3ã€ã®çµæã®ãããããè¿ãã¡ãœããã§ãã
ãè¡Aã¯è¡Bããå°ãããã
ãã©ã€ã³AãšBã¯çãããã
ãè¡Aã¯è¡Bããã倧ãããã
ããããããã ãã§ã¯ãããŸããã æååã®æ¯èŒã¯æšç§»çã§ãªããã°ãªããŸãããããã§ãªããã°ãç¹å®ã®ä»®å®ããçããæ€çŽ¢ã¡ã«ããºã ããç Žå£ãããŸãã ããå³å¯ã«ïŒãã¹ãŠã®è¡AãBãCã«ã€ããŠã次ã®ããšãä¿èšŒããå¿ èŠããããŸãã
1. A == Bã®å ŽåãB ==Aã
2. A == Bããã³B == Cã®å ŽåãA ==Cã
3. A <B then B> Aã®å Žå
4 A <Bããã³B <Cã®å ŽåãA <Cã
ããã§ãªãå ŽåïŒã€ãŸããã«ãŒã«ã®1ã€ã«éåããç §åãäœæããŠäœ¿çšããå ŽåïŒã ãSQLiteã®åäœã¯æªå®çŸ©ã§ãã ã
éåžžãç §åã¯ããŒãã«åã«èšå®ããããã®åã®å€ã«äœ¿çšãããæ¯èŒã®ã¿ã€ãã決å®ããŸãã
ãããŠããã€æååæ¯èŒã䜿çšããå¿ èŠããããŸããïŒ
1.æååå€ã§ã€ã³ããã¯ã¹ãäœæããã³æŽæ°ããŸãã
2.ã=ããã<ããã>ãã®æäœãå«ãæååå€ãå«ãSQLåŒã®èšç®äž
ïŒ ... WHERE name = 'Alice'ïŒ ã
ã ãã
SQLiteã2ã€ã®è¡ãæ¯èŒããå¿ èŠãããå Žåããã®æ¯èŒã¯åžžã«äœããã®ç §åã«åºã¥ããŠããŸãã
æ¯èŒãããæååã®ç §åãäžèŽããªãå Žåãããç §åãå¥ã®ç §åãããåªå ãããcãªã¡ã«ããºã ã䜿çšãããŸãã
æšæºïŒåã蟌ã¿ïŒç §å
UNICODEæåã®æ¯èŒïŒå€§æåãšå°æåãåºå¥ããªãïŒãå®å šã«ãµããŒãããã«ã¯ãéåžžã«å€ãã®è¿œå ããŒã¿ïŒããŒãã«ïŒãå¿ èŠã§ãã SQLiteéçºè ã¯ã«ãŒãã«ããèšåŒµãããããæãåçŽãªæ¯èŒæ¹æ³ãçµã¿èŸŒã¿ãŸããã
3ã€ã®çµã¿èŸŒã¿ç §åé åºããããŸãã
BINARY ïŒ2ã€ã®ã¡ã¢ãªãããã¯ã®éåžžã®ãã€ãåäœã®æ¯èŒïŒå€ããè¯ãmemcmpïŒïŒ
ïŒå¥ã®ç §åãæå®ãããªãéããããã©ã«ãã§äœ¿çšãããŸãïŒ;
RTRIM ïŒBINARYãšåãã§ãããæ«å°Ÿã®ã¹ããŒã¹ãç¡èŠããŸãïŒ 'abc' = 'abc'ïŒ;
NOCASE ïŒBINARYãšåãã§ããã26åã®ã©ãã³æåã®å€§æåãšå°æåãç¡èŠããŸãïŒå€§æåãšå°æåã®ã¿ïŒã
æšæºç §åã®å®è£
SQLiteã®å éšãèŠãŠãããŸããŸãªç §åã®ããã®æ¯èŒé¢æ°ã®å®è£ ãèŠãŠãã ããã
BinCollFuncïŒïŒé¢æ°ã padFlag <> 0ã®å Žåã RTRIMæ¯èŒãè¡ããããã§ãªãå Žåã¯BINARYãå®è¡ããŸãã
/* ** Return true if the buffer z[0..n-1] contains all spaces. */ static int allSpaces(const char *z, int n){ while( n>0 && z[n-1]==' ' ){ n--; } return n==0; } /* ** This is the default collating function named "BINARY" which is always ** available. ** ** If the padFlag argument is not NULL then space padding at the end ** of strings is ignored. This implements the RTRIM collation. */ static int binCollFunc( void *padFlag, int nKey1, const void *pKey1, int nKey2, const void *pKey2 ){ int rc, n; n = nKey1<nKey2 ? nKey1 : nKey2; rc = memcmp(pKey1, pKey2, n); if( rc==0 ){ if( padFlag && allSpaces(((char*)pKey1)+n, nKey1-n) && allSpaces(((char*)pKey2)+n, nKey2-n) ){ /* Leave rc unchanged at 0 */ }else{ rc = nKey1 - nKey2; } } return rc; }
ãããŠãç §åNOCASEã®æååæ¯èŒé¢æ°ã¯æ¬¡ã®ãšããã§ãã
/* ** ** IMPLEMENTATION-OF: R-30243-02494 The sqlite3_stricmp() and ** sqlite3_strnicmp() APIs allow applications and extensions to compare ** the contents of two buffers containing UTF-8 strings in a ** case-independent fashion, using the same definition of "case ** independence" that SQLite uses internally when comparing identifiers. */ SQLITE_API int sqlite3_stricmp(const char *zLeft, const char *zRight){ register unsigned char *a, *b; a = (unsigned char *)zLeft; b = (unsigned char *)zRight; while( *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; } return UpperToLower[*a] - UpperToLower[*b]; } SQLITE_API int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){ register unsigned char *a, *b; a = (unsigned char *)zLeft; b = (unsigned char *)zRight; while( N-- > 0 && *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; } return N<0 ? 0 : UpperToLower[*a] - UpperToLower[*b]; } // UpperToLower - , " " 'A'..'Z' ( 'a'..'z')
äœã泚ç®ãéããŠããŸããïŒ æååã¯ããããUTF-8圢åŒã§ãããæååã®ãã¹ãŠã®æåã¯é£ç¶ããŠåŠçãããŸããUTF-32ã®æåã®æœåºãšå€æã¯ãããŸããã
ãã®ã³ãŒããé·æéçæ³ãããšãå¥åŠãªããšã«ãUTF-8æååãšãã®ä»ã®åäžæåãšã³ã³ãŒãã£ã³ã°ïŒããšãã°ã windows-1251 ïŒã®äž¡æ¹ã§æ£ããæ©èœããããšãç解ã§ããŸãã ããªãããšããç解ã®å瀺ã¯ãã³ã¡ã³ãã§å ±æã§ããŸã:)ã
ããã«ããã次ã®éèŠãªè«æãã¹ã ãŒãºã«ç解ã§ããŸãã
SQLiteã¯ãæååãUTF-16ã«å€æããå¿ èŠããããŸã§ãUTF-8æååã®å®éã®åœ¢åŒã«é¢å¿ããããŸãã ã
ãã¡ãããæšæºã®ç §åã§å®éã®UTF-8æååãé 眮ãããšãããªãå¥åŠãªçµæãçæãããŸãã ããããå¹³çã¯æ£ããæ©èœããæ¯èŒã¯æšç§»çã§ãããSQLiteãæ··ä¹±ãããããšã¯ãããŸããã
å®éãUTF-16ãã©ãã§ã䜿çšããŠããªããšããæ¡ä»¶ã§ãããšãã°windows-1251ã®ãšã³ã³ãŒãã£ã³ã°ã§SQLiteããŒã¿ããŒã¹ã«æååãä¿åã§ããããšãããããŸããã ããã¯ãSQLå ã®æååãªãã©ã«ãšãã©ã¡ãŒã¿ãŒãã€ã³ãã£ã³ã°ãä»ããŠæž¡ãããæååã®äž¡æ¹ã«é©çšãããŸãã
ããã©ã«ã圢åŒãšããŠUTF-8圢åŒãæ¯æããåŒæ°
SQLã¹ããŒãã¡ã³ãã解æããã³ã³ã³ãã€ã«ããsqlite3Prepare16ïŒïŒ APIé¢æ°ã³ãŒããèŠãŠã¿ãŸãããã é¢æ°æ¬äœã®æåã®ã³ã¡ã³ãã«èå³ããããŸãã
/* ** Compile the UTF-16 encoded SQL statement zSql into a statement handle. */ static int sqlite3Prepare16( sqlite3 *db, /* Database handle. */ const void *zSql, /* UTF-16 encoded SQL statement. */ int nBytes, /* Length of zSql in bytes. */ int saveSqlFlag, /* True to save SQL text into the sqlite3_stmt */ sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ const void **pzTail /* OUT: End of parsed string */ ){ /* This function currently works by first transforming the UTF-16 ** encoded string to UTF-8, then invoking sqlite3_prepare(). The ** tricky bit is figuring out the pointer to return in *pzTail. */ ... // }
ã€ãŸãã
UTF-16圢åŒã®SQLã¹ããŒãã¡ã³ãã®ããŒãµãŒã¯ãçŸåšSQLiteã«ãŒãã«ã«ååšããŸããïŒå°æ¥ã®å€èŠ³ãé€å€ããŸããïŒ ã
ãã®ãããSQLã¹ããŒãã¡ã³ããå«ãæååãUTF-16圢åŒã§éä¿¡ãããå Žåã åžžã«æåã«UTF-8圢åŒã«å€æãããŸãã
ãããã£ãŠãUTF-8圢åŒãæ¯æããŠïŒ
-SQLã®ã³ã³ãã€ã«æã«äœåãªå€æã¯ãããŸããã
-ããŒã¿ã¯ïŒéåžžïŒäœ¿çšãããã£ã¹ã¯å®¹éãå°ãªããªããŸãã
-UTF-16ãã©ãã§ã䜿çšãããŠããªãå Žåã¯ããã€ãããšã®ãšã³ã³ãŒãã§ããŒã¿ãä¿åã§ããŸãïŒãããŠãèªå·±èšè¿°ã®ç §åã§ã¯æ°ããæåå圢åŒãèæ ®ãããŸãïŒã
ç¬èªã®ç §åãäœæããŠäœ¿çšããæ¹æ³
sqlite3_create_collatââion_v2ïŒïŒ API é¢æ°ã䜿çšããŸã ã
int sqlite3_create_collation_v2( sqlite3*, // const char *zName, // int eTextRep, // void *pArg, // custom- int(*xCompare)(void*,int,const void*,int,const void*), // void(*xDestroy)(void*) );
eTextRepãã©ã¡ãŒã¿ãŒã§ã¯ã ã©ã®åœ¢åŒã§è¡ãäºæ³ãããããæå®ããå¿ èŠããããŸãã
SQLITE_UTF8 = 1; SQLITE_UTF16 = 2; SQLITE_UTF16BE = 3; SQLITE_UTF16LE = 4; SQLITE_ANY = 5;
åãç §åã«å¯ŸããŠè€æ°ã®é¢æ°ãæå®ã§ããŸãããç°ãªã圢åŒãåãå ¥ããŸãã
SQLiteã¯ãã©ãŒãããã®ã¡ãœãããéžæããããšããŸããããã§ãªãå ŽåïŒéä¿¡ãããæååãšç»é²ãããé¢æ°ã®ãã©ãŒããããç°ãªãå ŽåïŒãå€æã¯ãã®å Žã§åã³å®è¡ãããŸãã æåã®è¡ã2çªç®ã®è¡ãããå°ããå Žåãæ¯èŒé¢æ°ã¯è² ã®æ°ãè¿ããŸãã ãŒã-è¡ãçããå Žåã æåã®è¡ã2çªç®ã®è¡ããã倧ããå Žåã¯æ£ã®æ°ã ãã§ã«è¿°ã¹ãããã«ãæ¯èŒã¯æšç§»çã§ãªããã°ãªããŸããã
次ã®ãããªç §åé åºïŒãRUããšããååïŒãäœæããŸãã
-ããªã«æåãšã©ãã³æåã®å€§æåãšå°æåãåºå¥ããªãæ¯èŒ
-ä»ã®ãã¹ãŠã®ãã£ã©ã¯ã¿ãŒã®éåžžã®æ¯èŒã
-æåããã®ã¢ã«ãã¡ãããã®æ£ããäœçœ®ïŒããæ£ç¢ºã«ã¯ãããã¯ãeããšçãããšèŠãªãããŸãïŒã
ããã¯ããããŸã§ã®ãšãããUNICODEãå®å šã«ã¯ãµããŒãããŠããŸãããã95ïŒ ã®ã±ãŒã¹ã«é©ããã·ã³ãã«ãªãœãªã¥ãŒã·ã§ã³ã§ãã
äŸã¯Delphiã«ãããŸãããå¿é ããå¿ èŠã¯ãããŸããã
unit UnicodeUnit; interface // UTF-8 UTF-32 -1, function GetCharUTF8(var P: PByte; var L: integer): integer; // UTF-32 ( !) function LowerUTF32(ACode: integer): integer; // UTF-8 (case-insensitive ) function CompareUTF8IgnoreCase(L1: integer; P1: PByte; L2: integer; P2: PByte): integer; implementation uses SysUtils; // UTF-8 type TParseItem = record Mask: integer; Count: integer; end; var // UTF-8 ParseTable: array[0..255] of TParseItem; // LowerTable: array[0..65535] of integer; function CompareUTF8IgnoreCase(L1: integer; P1: PByte; L2: integer; P2: PByte): integer; var C1, C2: integer; begin repeat if (L1 = 0) and (L2 = 0) then begin result := 0; exit; end; // C1 := GetCharUTF8(P1, L1); if C1 < 0 then begin result := -1; exit; end; C2 := GetCharUTF8(P2, L2); if C2 < 0 then begin result := +1; exit; end; // if C1 < 65536 then C1 := LowerTable[C1]; if C2 < 65536 then C2 := LowerTable[C2]; if C1 < C2 then begin result := -1; exit; end else if C1 > C2 then begin result := +1; exit; end; until false; end; function LowerUTF32(ACode: integer): integer; begin case ACode of 1105, 1025: // , result := 1077; // 1040..1071: result := ACode + 32; // Ord('A')..Ord('Z'): result := ACode + 32; // else result := ACode; end; end; function GetCharUTF8(var P: PByte; var L: integer): integer; var B: byte; I: integer; begin if L > 0 then begin B := P^; Inc(P); Dec(L); with ParseTable[B] do if Count > 0 then begin // result := B and Mask; // for I := 1 to Count - 1 do if L > 0 then begin result := (result shl 6) or (P^ and $3F); Inc(P); Dec(L); end else begin result := -1; exit; end; exit; end; end; result := -1; end; var I: integer; initialization // UTF-8 for I := 0 to 255 do with ParseTable[I] do if I <= 127 then begin Mask := $7F; Count := 1; end else if I >= 248 then begin Mask := 0; Count := 0; end else if I >= 240 then begin Mask := 7; Count := 4; end else if I >= 224 then begin Mask := 15; Count := 3; end else if I >= 192 then begin Mask := $1F; Count := 2; end else begin Mask := 0; Count := 0; end; // Lower for I := 0 to 65535 do LowerTable[I] := LowerUTF32(I); end.
äžè¬ã«ãã³ãŒãã¯åçŽã§ãããããããè¿œå ã®èª¬æã¯äžèŠã§ãã
䜿çšæ¹æ³ïŒ
// function RU_CollationCompare(UserData: pointer; l1: integer; p1: pointer; l2: integer; p2: pointer): integer; cdecl; begin result := CompareUTF8IgnoreCase(L1, P1, L2, P2); end; ... // collation RU sqlite3_create_collation(Fdb, 'RU', SQLITE_UTF8, nil, RU_CollationCompare);
ããŒãã«ãäœæãããšãã«ã åååã®æ¯èŒã¿ã€ããèšå®ããŸãã
CREATE TABLE foo( name TEXT COLLATE RU, ... )
éèŠïŒ ç §åç»é²ã¯ãããŒã¿ããŒã¹ã«é¢é£ããŠå®è¡ãããŸã ïŒããŒã¿ããŒã¹èªäœã§ã¯ãããŸããïŒã ããã¯ãåºæ¬çã«ã³ãŒããSQLiteã³ãŒãã«æ·»ä»ããããšã§ãã åãç §åãæå®ããªãã£ãå¥ã®æ¥ç¶ã§ã¯ããã®ããŒã¹ã䜿çšã§ããŸããã
LIKEãäžéšïŒïŒãäžéšïŒïŒãªã©
ç §åã³ãŒããRUãã¯ããã¡ãããä»ã®ã¢ã«ãã¡ãããããµããŒãããããã«ç°¡åã«å€æŽã§ããŸãã ãŸããWindows APIåŒã³åºãã䜿çšããŠLowerTableããŒãã«ã«ããŒã¿ãå ¥åãããšãïŒã»ãŒïŒå®å šãªUNICODEæ¯èŒãè¡ãããšãã§ããŸãã
ãªããã»ãŒãïŒ UNICODEã®ãæ£èŠåããã€ãŸããæ確ãªè¡šçŸãžã®çž®å°ãªã©ããããŸãã Googleãå©ãã«ãªããŸãïŒ
ãã ããUNICODEã®ãµããŒãã¯ãç §åã®ã¿ã§èŠã€ããããã§ã¯ãããŸããã ãŸããããŸãïŒ
-LIKEæŒç®åïŒãã¿ãŒã³ãããã³ã°ïŒ;
-SQLé¢æ°lowerïŒïŒããã³upperïŒïŒ ïŒã¹ããªã³ã°æåãå°æå/倧æåã«å€æïŒã
ãã®ä»ã®æååæäœé¢æ°ïŒ foldïŒïŒãtitleïŒïŒãªã©
ãããã¯ãç §åããŸã£ãã䜿çšããªãå¥åã®ã¡ã«ããºã ã§ãã
ãã ããSQLiteã§ã¯ããããã®é¢æ°ïŒLIKEãé¢æ°ã§ãïŒãç¬èªã®é¢æ°ã§ãªãŒããŒã©ã€ãã§ããŸãã
ãããè¡ãã«ã¯ã sqlite3_create_function_v2ïŒïŒ APIåŒã³åºãã䜿çšããŸãã
ã»ãŒå®å šãªãŠãã³ãŒãã®å°ããªè¡
以åã®èšäºã§ã¯ã ICUã©ã€ãã©ãªãŒïŒUnicodeã®åœéã³ã³ããŒãã³ãã«ã€ããŠèª¬æããŸãã ã ããã¯ãUNICODEã®å®å šãªãµããŒãã§ãã ãã ããåé¡ã¯ãèšå€§ãªéã®ã³ãŒããšããŒã¿ããã©ãã°ããããšã§ããã95ïŒ ã®ã±ãŒã¹ã§ã¯å¿ èŠãããŸããã SQLiteã«ãã§ã«ICUãçµã¿èŸŒãŸããŠããå Žåã¯ãããã«èªãããšãã¹ãããã§ããŸãã
ãã®ããããã®ã³ãŒãããäžèŠãªãã®ãèŠã€ãåºããICUããäžçš®ã®ãã¹ã¯ã€ãŒãºããäœæããè³¢ã人ã1人ããŸããã
圌ã®å ã®ã¡ãã»ãŒãžã¯ãã©ãããããã§ãã
ããããã®ç®çã§ãã ICUã³ãŒãã«åºã¥ããŠã圌ã¯DLLïŒéåžžã¯sqlite3u.dll ïŒã«ã³ã³ãã€ã«ãããsqlite3_unicode.cãã¡ã€ã«ãäœæããŸããã çµæã®DLLã¯sqlite3_unicode_initïŒïŒé¢æ°ããšã¯ã¹ããŒãããŸãïŒ
function sqlite3_unicode_init(db: TSQLiteDB): Integer; cdecl; external 'sqlite3u.dll' name 'sqlite3_unicode_init';
ãã®é¢æ°ãåŒã³åºããŠæ¥ç¶ãããšã次ã®ããã«ãªããŸãã
-lowerãupperãfoldãtitleãunaccenté¢æ°ã®ã»ãŒå®å šãªUNICODEããŒãžã§ã³ãç»é²ããŸãã
- ã»ãŒå®å šãªUNICODE倧æåãšå°æåãåºå¥ããªãLIKEãå°å ¥ããŸãã
ãã®DLLã®ãµã€ãºã¯80 KBã®ã¿ã§ãããã«åäœããŸãïŒããŒãã«ã䜿çšãããŸãïŒã ãã»ãŒããšããå¥ã¯éèŠã§ããããã¯å®å šãªUNICODEã§ã¯ãããŸãããã95ïŒ ã®ã±ãŒã¹ã§ãã®ã©ã€ãã©ãªã§ååã§ãã
泚ã
1. LIKEããªãŒããŒã©ã€ãããããšãSQLiteã¯ã€ã³ããã¯ã¹ã«ãã£ãŠæé©åã§ããŸããïŒLIKE 'XXXïŒ 'ã¯Aã«ããã€ã³ããã¯ã¹ã䜿çšããŸããïŒããå ŽåïŒïŒã
2.äžè¬çã«èšãã°ãé¢æ°lowerïŒïŒãupperïŒïŒãªã©ã¯ãããŒã¿ããŒã¹ãšã³ãžã³ã«ããå¿ èŠã¯ãããŸãããã¢ããªã±ãŒã·ã§ã³ã³ãŒãã§ãããã®å€æãå®è¡ããããšãã§ããŸãã
Yuz zis librari et yor oun risk ãã€ãŸãããã®èšäºã®èè ã¯äžå責任ãè² ããŸããã