æåã®éšåã¯
åºè«ã§ãã
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, const char *zSql, int nByte, sqlite3_stmt **ppStmt, const char **pzTail ); int sqlite3_prepare16_v2( sqlite3 *db, const void *zSql, int nByte, sqlite3_stmt **ppStmt, const void **pzTail );
åºæ¬æååã®åœ¢åŒã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ãå®è¡ããŸãã
static int allSpaces(const char *z, int n){ while( n>0 && z[n-1]==' ' ){ n--; } return n==0; } 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) ){ }else{ rc = nKey1 - nKey2; } } return rc; }
ãããŠãç
§å
NOCASEã®æååæ¯èŒé¢æ°ã¯
次ã®ãšããã§ãã
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]; }
äœã泚ç®ãéããŠããŸããïŒ æååã¯ãããã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é¢æ°ã³ãŒããèŠãŠã¿ãŸãããã é¢æ°æ¬äœã®æåã®ã³ã¡ã³ãã«èå³ããããŸãã
static int sqlite3Prepare16( sqlite3 *db, const void *zSql, int nBytes, int saveSqlFlag, sqlite3_stmt **ppStmt, const void **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*),
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
äžè¬ã«ãã³ãŒãã¯åçŽã§ãããããããè¿œå ã®èª¬æã¯äžèŠã§ãã
䜿çšæ¹æ³ïŒ
ããŒãã«ãäœæãããšãã«ã
åååã®æ¯èŒã¿ã€ããèšå®ããŸãã
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 ãã€ãŸãããã®èšäºã®èè
ã¯äžå責任ãè² ããŸããã