-
Notifications
You must be signed in to change notification settings - Fork 72
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
ddcw
committed
Jan 9, 2024
1 parent
b40925b
commit 9cbb218
Showing
15 changed files
with
2,938 additions
and
396 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# select * from information_schema.COLLATIONS | ||
# select concat("{",group_concat(concat(id,":('",CHARACTER_SET_NAME, "','", COLLATION_NAME, "')")),"}") from information_schema.COLLATIONS; | ||
|
||
COLLID_TO_CHAR = {32:('armscii8','armscii8_general_ci'),64:('armscii8','armscii8_bin'),11:('ascii','ascii_general_ci'),65:('ascii','ascii_bin'),1:('big5','big5_chinese_ci'),84:('big5','big5_bin'),63:('binary','binary'),26:('cp1250','cp1250_general_ci'),34:('cp1250','cp1250_czech_cs'),44:('cp1250','cp1250_croatian_ci'),66:('cp1250','cp1250_bin'),99:('cp1250','cp1250_polish_ci'),14:('cp1251','cp1251_bulgarian_ci'),23:('cp1251','cp1251_ukrainian_ci'),50:('cp1251','cp1251_bin'),51:('cp1251','cp1251_general_ci'),52:('cp1251','cp1251_general_cs'),57:('cp1256','cp1256_general_ci'),67:('cp1256','cp1256_bin'),29:('cp1257','cp1257_lithuanian_ci'),58:('cp1257','cp1257_bin'),59:('cp1257','cp1257_general_ci'),4:('cp850','cp850_general_ci'),80:('cp850','cp850_bin'),40:('cp852','cp852_general_ci'),81:('cp852','cp852_bin'),36:('cp866','cp866_general_ci'),68:('cp866','cp866_bin'),95:('cp932','cp932_japanese_ci'),96:('cp932','cp932_bin'),3:('dec8','dec8_swedish_ci'),69:('dec8','dec8_bin'),97:('eucjpms','eucjpms_japanese_ci'),98:('eucjpms','eucjpms_bin'),19:('euckr','euckr_korean_ci'),85:('euckr','euckr_bin'),248:('gb18030','gb18030_chinese_ci'),249:('gb18030','gb18030_bin'),250:('gb18030','gb18030_unicode_520_ci'),24:('gb2312','gb2312_chinese_ci'),86:('gb2312','gb2312_bin'),28:('gbk','gbk_chinese_ci'),87:('gbk','gbk_bin'),92:('geostd8','geostd8_general_ci'),93:('geostd8','geostd8_bin'),25:('greek','greek_general_ci'),70:('greek','greek_bin'),16:('hebrew','hebrew_general_ci'),71:('hebrew','hebrew_bin'),6:('hp8','hp8_english_ci'),72:('hp8','hp8_bin'),37:('keybcs2','keybcs2_general_ci'),73:('keybcs2','keybcs2_bin'),7:('koi8r','koi8r_general_ci'),74:('koi8r','koi8r_bin'),22:('koi8u','koi8u_general_ci'),75:('koi8u','koi8u_bin'),5:('latin1','latin1_german1_ci'),8:('latin1','latin1_swedish_ci'),15:('latin1','latin1_danish_ci'),31:('latin1','latin1_german2_ci'),47:('latin1','latin1_bin'),48:('latin1','latin1_general_ci'),49:('latin1','latin1_general_cs'),94:('latin1','latin1_spanish_ci'),2:('latin2','latin2_czech_cs'),9:('latin2','latin2_general_ci'),21:('latin2','latin2_hungarian_ci'),27:('latin2','latin2_croatian_ci'),77:('latin2','latin2_bin'),30:('latin5','latin5_turkish_ci'),78:('latin5','latin5_bin'),20:('latin7','latin7_estonian_cs'),41:('latin7','latin7_general_ci'),42:('latin7','latin7_general_cs'),79:('latin7','latin7_bin'),38:('macce','macce_general_ci'),43:('macce','macce_bin'),39:('macroman','macroman_general_ci'),53:('macroman','macroman_bin'),13:('sjis','sjis_japanese_ci'),88:('sjis','sjis_bin'),10:('swe7','swe7_swedish_ci'),82:('swe7','swe7_bin'),18:('tis620','tis620_thai_ci'),89:('tis620','tis620_bin'),35:('ucs2','ucs2_general_ci'),90:('ucs2','ucs2_bin'),128:('ucs2','ucs2_unicode_ci'),129:('ucs2','ucs2_icelandic_ci'),130:('ucs2','ucs2_latvian_ci'),131:('ucs2','ucs2_romanian_ci'),132:('ucs2','ucs2_slovenian_ci'),133:('ucs2','ucs2_polish_ci'),134:('ucs2','ucs2_estonian_ci'),135:('ucs2','ucs2_spanish_ci'),136:('ucs2','ucs2_swedish_ci'),137:('ucs2','ucs2_turkish_ci'),138:('ucs2','ucs2_czech_ci'),139:('ucs2','ucs2_danish_ci'),140:('ucs2','ucs2_lithuanian_ci'),141:('ucs2','ucs2_slovak_ci'),142:('ucs2','ucs2_spanish2_ci'),143:('ucs2','ucs2_roman_ci'),144:('ucs2','ucs2_persian_ci'),145:('ucs2','ucs2_esperanto_ci'),146:('ucs2','ucs2_hungarian_ci'),147:('ucs2','ucs2_sinhala_ci'),148:('ucs2','ucs2_german2_ci'),149:('ucs2','ucs2_croatian_ci'),150:('ucs2','ucs2_unicode_520_ci'),151:('ucs2','ucs2_vietnamese_ci'),159:('ucs2','ucs2_general_mysql500_ci'),12:('ujis','ujis_japanese_ci'),91:('ujis','ujis_bin'),54:('utf16','utf16_general_ci'),55:('utf16','utf16_bin'),101:('utf16','utf16_unicode_ci'),102:('utf16','utf16_icelandic_ci'),103:('utf16','utf16_latvian_ci'),104:('utf16','utf16_romanian_ci'),105:('utf16','utf16_slovenian_ci'),106:('utf16','utf16_polish_ci'),107:('utf16','utf16_estonian_ci'),108:('utf16','utf16_spanish_ci'),109:('utf16','utf16_swedish_ci'),110:('utf16','utf16_turkish_ci'),111:('utf16','utf16_czech_ci'),112:('utf16','utf16_danish_ci'),113:('utf16','utf16_lithuanian_ci'),114:('utf16','utf16_slovak_ci'),115:('utf16','utf16_spanish2_ci'),116:('utf16','utf16_roman_ci'),117:('utf16','utf16_persian_ci'),118:('utf16','utf16_esperanto_ci'),119:('utf16','utf16_hungarian_ci'),120:('utf16','utf16_sinhala_ci'),121:('utf16','utf16_german2_ci'),122:('utf16','utf16_croatian_ci'),123:('utf16','utf16_unicode_520_ci'),124:('utf16','utf16_vietnamese_ci'),56:('utf16le','utf16le_general_ci'),62:('utf16le','utf16le_bin'),60:('utf32','utf32_general_ci'),61:('utf32','utf32_bin'),160:('utf32','utf32_unicode_ci'),161:('utf32','utf32_icelandic_ci'),162:('utf32','utf32_latvian_ci'),163:('utf32','utf32_romanian_ci'),164:('utf32','utf32_slovenian_ci'),165:('utf32','utf32_polish_ci'),166:('utf32','utf32_estonian_ci'),167:('utf32','utf32_spanish_ci'),168:('utf32','utf32_swedish_ci'),169:('utf32','utf32_turkish_ci'),170:('utf32','utf32_czech_ci'),171:('utf32','utf32_danish_ci'),172:('utf32','utf32_lithuanian_ci'),173:('utf32','utf32_slovak_ci'),174:('utf32','utf32_spanish2_ci'),175:('utf32','utf32_roman_ci'),176:('utf32','utf32_persian_ci'),177:('utf32','utf32_esperanto_ci'),178:('utf32','utf32_hungarian_ci'),179:('utf32','utf32_sinhala_ci'),180:('utf32','utf32_german2_ci'),181:('utf32','utf32_croatian_ci'),182:('utf32','utf32_unicode_520_ci'),183:('utf32','utf32_vietnamese_ci'),33:('utf8','utf8_general_ci'),76:('utf8','utf8_tolower_ci'),83:('utf8','utf8_bin'),192:('utf8','utf8_unicode_ci'),193:('utf8','utf8_icelandic_ci'),194:('utf8','utf8_latvian_ci'),195:('utf8','utf8_romanian_ci'),196:('utf8','utf8_slovenian_ci'),197:('utf8','utf8_polish_ci'),198:('utf8','utf8_estonian_ci'),199:('utf8','utf8_spanish_ci'),200:('utf8','utf8_swedish_ci'),201:('utf8','utf8_turkish_ci'),202:('utf8','utf8_czech_ci'),203:('utf8','utf8_danish_ci'),204:('utf8','utf8_lithuanian_ci'),205:('utf8','utf8_slovak_ci'),206:('utf8','utf8_spanish2_ci'),207:('utf8','utf8_roman_ci'),208:('utf8','utf8_persian_ci'),209:('utf8','utf8_esperanto_ci'),210:('utf8','utf8_hungarian_ci'),211:('utf8','utf8_sinhala_ci'),212:('utf8','utf8_german2_ci'),213:('utf8','utf8_croatian_ci'),214:('utf8','utf8_unicode_520_ci'),215:('utf8','utf8_vietnamese_ci'),223:('utf8','utf8_general_mysql500_ci'),45:('utf8mb4','utf8mb4_general_ci'),46:('utf8mb4','utf8mb4_bin'),224:('utf8mb4','utf8mb4_unicode_ci'),225:('utf8mb4','utf8mb4_icelandic_ci'),226:('utf8mb4','utf8mb4_latvian_ci'),227:('utf8mb4','utf8mb4_romanian_ci'),228:('utf8mb4','utf8mb4_slovenian_ci'),229:('utf8mb4','utf8mb4_polish_ci'),230:('utf8mb4','utf8mb4_estonian_ci'),231:('utf8mb4','utf8mb4_spanish_ci'),232:('utf8mb4','utf8mb4_swedish_ci'),233:('utf8mb4','utf8mb4_turkish_ci'),234:('utf8mb4','utf8mb4_czech_ci'),235:('utf8mb4','utf8mb4_danish_ci'),236:('utf8mb4','utf8mb4_lithuanian_ci'),237:('utf8mb4','utf8mb4_slovak_ci'),238:('utf8mb4','utf8mb4_spanish2_ci'),239:('utf8mb4','utf8mb4_roman_ci'),240:('utf8mb4','utf8mb4_persian_ci'),241:('utf8mb4','utf8mb4_esperanto_ci'),242:('utf8mb4','utf8mb4_hungarian_ci'),243:('utf8mb4','utf8mb4_sinhala_ci'),244:('utf8mb4','utf8mb4_german2_ci'),245:('utf8mb4','utf8mb4_croatian_ci'),246:('utf8mb4','utf8mb4_unicode_520_ci'),247:('utf8mb4','utf8mb4_vietnamese_ci'),255:('utf8mb4','utf8mb4_0900_ai_ci'),256:('utf8mb4','utf8mb4_de_pb_0900_ai_ci'),257:('utf8mb4','utf8mb4_is_0900_ai_ci'),258:('utf8mb4','utf8mb4_lv_0900_ai_ci'),259:('utf8mb4','utf8mb4_ro_0900_ai_ci'),260:('utf8mb4','utf8mb4_sl_0900_ai_ci'),261:('utf8mb4','utf8mb4_pl_0900_ai_ci'),262:('utf8mb4','utf8mb4_et_0900_ai_ci'),263:('utf8mb4','utf8mb4_es_0900_ai_ci'),264:('utf8mb4','utf8mb4_sv_0900_ai_ci'),265:('utf8mb4','utf8mb4_tr_0900_ai_ci'),266:('utf8mb4','utf8mb4_cs_0900_ai_ci'),267:('utf8mb4','utf8mb4_da_0900_ai_ci'),268:('utf8mb4','utf8mb4_lt_0900_ai_ci'),269:('utf8mb4','utf8mb4_sk_0900_ai_ci'),270:('utf8mb4','utf8mb4_es_trad_0900_ai_ci'),271:('utf8mb4','utf8mb4_la_0900_ai_ci'),273:('utf8mb4','utf8mb4_eo_0900_ai_ci'),274:('utf8mb4','utf8mb4_hu_0900_ai_ci'),275:('utf8mb4','utf8mb4_hr_0900_ai_ci'),277:('utf8mb4','utf8mb4_vi_0900_ai_ci'),278:('utf8mb4','utf8mb4_0900_as_cs'),279:('utf8mb4','utf8mb4_de_pb_0900_as_cs'),280:('utf8mb4','utf8mb4_is_0900_as_cs'),281:('utf8mb4','utf8mb4_lv_0900_as_cs'),282:('utf8mb4','utf8mb4_ro_0900_as_cs'),283:('utf8mb4','utf8mb4_sl_0900_as_cs'),284:('utf8mb4','utf8mb4_pl_0900_as_cs'),285:('utf8mb4','utf8mb4_et_0900_as_cs'),286:('utf8mb4','utf8mb4_es_0900_as_cs'),287:('utf8mb4','utf8mb4_sv_0900_as_cs'),288:('utf8mb4','utf8mb4_tr_0900_as_cs'),289:('utf8mb4','utf8mb4_cs_0900_as_cs'),290:('utf8mb4','utf8mb4_da_0900_as_cs'),291:('utf8mb4','utf8mb4_lt_0900_as_cs'),292:('utf8mb4','utf8mb4_sk_0900_as_cs'),293:('utf8mb4','utf8mb4_es_trad_0900_as_cs'),294:('utf8mb4','utf8mb4_la_0900_as_cs'),296:('utf8mb4','utf8mb4_eo_0900_as_cs'),297:('utf8mb4','utf8mb4_hu_0900_as_cs'),298:('utf8mb4','utf8mb4_hr_0900_as_cs'),300:('utf8mb4','utf8mb4_vi_0900_as_cs'),303:('utf8mb4','utf8mb4_ja_0900_as_cs'),304:('utf8mb4','utf8mb4_ja_0900_as_cs_ks'),305:('utf8mb4','utf8mb4_0900_as_ci'),306:('utf8mb4','utf8mb4_ru_0900_ai_ci'),307:('utf8mb4','utf8mb4_ru_0900_as_cs'),308:('utf8mb4','utf8mb4_zh_0900_as_cs'),309:('utf8mb4','utf8mb4_0900_bin')} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
#from .innodb_page import * | ||
VERSION = (1,0) | ||
|
||
__version__ = ".".join(str(x) for x in VERSION) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,322 @@ | ||
#!/usr/bin/env python3 | ||
|
||
import datetime | ||
from ibd2sql.innodb_page_sdi import * | ||
from ibd2sql.innodb_page_spaceORxdes import * | ||
from ibd2sql.innodb_page_inode import * | ||
from ibd2sql.innodb_page_index import * | ||
import sys | ||
|
||
|
||
class ibd2sql(object): | ||
def __init__(self,*args,**kwargs): | ||
self.LIMIT = -1 | ||
self.STATUS = False | ||
self.PAGESIZE = 16384 | ||
#先初始化一堆信息. | ||
self.DEBUG = False | ||
self.DEBUG_FD = sys.stdout | ||
self.FILENAME = '' | ||
self.DELETE = False | ||
self.FORCE = False | ||
self.SET = False | ||
self.MULTIVALUE = False | ||
self.COMPLETE_SQL = False | ||
self.REPLACE = False | ||
self.WHERE1 = '' | ||
self.WHERE2 = (0,2**48) | ||
self.WHERE3 = (0,2**56) | ||
self.PAGE_ID = 0 | ||
self.AUTO_DEBUG = True #自动DEBUG, 如果page解析有问题的话, 然后退出 | ||
self.SQL_PREFIX = '' | ||
self.SQL = True | ||
self.IS_PARTITION = False #是否为分区表 | ||
|
||
self.PAGE_MIN = 0 | ||
self.PAGE_MAX = 2**32 | ||
self.PAGE_START = -1 | ||
self.PAGE_COUNT = -1 | ||
self.PAGE_SKIP = -1 | ||
|
||
|
||
def _init_table_name(self): | ||
try: | ||
self.debug(f"OLD TABLENAME:{self.tablename}") | ||
except: | ||
pass | ||
self.tablename = f"`{self.table.schema}`.`{self.table.table_name}`" | ||
self.debug(f"NEW TABLENAME:{self.tablename}") | ||
self._init_sql_prefix() | ||
|
||
def replace_schema(self,name): | ||
self.table.schema = name | ||
return self._init_table_name() | ||
|
||
def replace_name(self,name): | ||
self.table.table_name = name | ||
return self._init_table_name() | ||
|
||
def read(self): | ||
""" | ||
RETURN PAGE RAW DATA | ||
""" | ||
self.debug(f"ibd2sql.read PAGE: {self.PAGE_ID} ") | ||
self.f.seek(self.PAGESIZE*self.PAGE_ID,0) | ||
#self.PAGE_ID += 1 | ||
return self.f.read(self.PAGESIZE) | ||
|
||
def _init_sql_prefix(self): | ||
#self.table.remove_virtual_column() #把虚拟字段干掉 | ||
#self.SQL_PREFIX = f"{ 'REPLACE' if self.REPLACE else 'INSERT'} INTO {self.tablename}{'(`'+'`,`'.join([ self.table.column[x]['name'] for x in self.table.column ]) + '`)' if self.COMPLETE_SQL else ''} VALUES " | ||
SQL_PREFIX = f"{'REPLACE' if self.REPLACE else 'INSERT'} INTO {self.tablename}(" | ||
for x in self.table.column: | ||
if self.table.column[x]['is_virtual'] or not self.COMPLETE_SQL: | ||
continue | ||
else: | ||
SQL_PREFIX += f"`{self.table.column[x]['name']}`," | ||
SQL_PREFIX = SQL_PREFIX[:-1] + ") VALUES " if self.COMPLETE_SQL else SQL_PREFIX[:-1] + " VALUES " | ||
self.SQL_PREFIX = SQL_PREFIX | ||
|
||
def init(self): | ||
self.debug("DEBUG MODE ON") | ||
self.debug("INIT ibd2sql") | ||
self.debug("FORCE",self.FORCE) | ||
self.debug("SET",self.SET) | ||
self.debug("MULTIVALUE",self.MULTIVALUE) | ||
self.debug("AUTO_DEBUG",self.AUTO_DEBUG) | ||
self.debug(f"FILTER: \n\t{self.WHERE1} \n\t{self.WHERE2[0]} < TRX < {self.WHERE2[1]} \n\t{self.WHERE3[0]} < ROLLPTR < {self.WHERE3[1]}") | ||
self.STATUS = True | ||
self.debug(f"OPEN IBD FILE:",self.FILENAME) | ||
self.f = open(self.FILENAME,'rb') | ||
self.PAGE_ID = 0 | ||
|
||
#first page | ||
self.PAGE_ID = 0 | ||
self.debug("ANALYZE FIRST PAGE: FIL_PAGE_TYPE_FSP_HDR") | ||
self.space_page = xdes(self.read()) #第一页 | ||
if not self.space_page.fsp_status: | ||
sys.stderr.write(f"\nrow_format = compressed or its damaged or its mysql 5.7 file\n\n") | ||
sys.exit(2) | ||
self.debug("ANALYZE FIRST PAGE FINISH") | ||
sdino = self.space_page.SDI_PAGE_NO | ||
self.debug("SDI PAGE NO:",sdino) | ||
|
||
#sdi page | ||
if self.IS_PARTITION: | ||
self.debug("THIS TABLE IS PARTITION TABLE") | ||
self.tablename = "PARTITION TABLE NO NAME" | ||
pass | ||
else: | ||
self.debug('ANALYZE SDI PAGE') | ||
self.PAGE_ID = sdino | ||
self.sdi = sdi(self.read(),debug=self.debug) #sdi页 | ||
if not self.sdi: | ||
self.debug("ANALYZE SDI PAGE FAILED (maybe page is not 17853), will exit 2") | ||
sys.exit(2) | ||
self.debug('ANALYZE SDI PAGE FINISH') | ||
self.debug('SET ibd2sql.table = sdi.table (SDI的使命已结束 >_<)') | ||
self.table = self.sdi.table | ||
self.tablename = self.table.name | ||
self.debug("META INFO") | ||
for colno in self.table.column: | ||
self.debug(f"COLNO: {colno} \n{self.table.column[colno]}") | ||
for idxno in self.table.index: | ||
self.debug(f"IDXNO: {colno} \n{self.table.index[idxno]}") | ||
self.debug("INIT SQL PREFIX") | ||
self.debug("DDL:\n",self.table.get_ddl()) | ||
self._init_sql_prefix() #初始化表前缀, 要获取到SDI信息才能做 | ||
|
||
#inode page | ||
self.debug(f'ANALYZE PAGE INODE (PAGE_ID=2) (for get index)') | ||
self.PAGE_ID = 2 #inode | ||
self.inode = inode(self.read()) | ||
self.debug("FIRST INDEX (Non-leaf and leaf page) :",self.inode.index_page[0]," (-1 is None)") | ||
self.first_no_leaf_page = self.inode.index_page[0][0] | ||
self.first_leaf_page = self.inode.index_page[0][1] | ||
#self.debug("START FIND FIRST LEAF PAGE") | ||
if self.first_leaf_page < 3 or self.first_leaf_page >= 4294967295 or True: | ||
self.init_first_leaf_page() | ||
self.debug("FIRST LEAF PAGE ID:",self.first_leaf_page ) | ||
self.debug("#############################################################################") | ||
self.debug(" INIT ibd2sql FINISH ") | ||
self.debug("#############################################################################\n\n") | ||
return True | ||
|
||
def init_first_leaf_page(self): | ||
_n = 0 | ||
self.debug(f"INIT FIRST PAGE TO FIRST_NO_LEAF_PAGE ({self.first_no_leaf_page})") | ||
self.PAGE_ID = self.first_no_leaf_page | ||
while self.PAGE_ID < 4294967295 and self.PAGE_ID > 2: | ||
_n += 1 | ||
self.debug(f'COUNT: {_n} FIND LEAF PAGE, CURRENT PAGE ID:',self.PAGE_ID) | ||
aa = find_leafpage(self.read(),table=self.table, idx=self.table.cluster_index_id, debug=self.debug) | ||
aa.pageno = self.PAGE_ID | ||
IS_LEAF_PAGE,PAGE_ID = aa.find() | ||
if IS_LEAF_PAGE: | ||
self.debug("FIND FINISH, PAGE_ID:",self.PAGE_ID,'\n') | ||
self.first_leaf_page = self.PAGE_ID | ||
break | ||
else: | ||
self.first_leaf_page = self.PAGE_ID = PAGE_ID | ||
|
||
|
||
def debug(self,*args): | ||
if self.DEBUG: | ||
msg = f"[{datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] [DEBUG] {' '.join([ str(x) for x in args ])}\n" | ||
self.DEBUG_FD.write(msg) | ||
|
||
def _get_index_page(self): | ||
pn = 0 | ||
while self.PAGE_ID > 0 and self.PAGE_ID < 4294967295: | ||
pn += 1 | ||
self.debug(f"CURRENT PAGE ID {self.PAGE_ID} PAGE NO:{pn}") | ||
aa = page(self.read()) | ||
self.PAGE_ID = aa.FIL_PAGE_NEXT | ||
|
||
def get_sql(self,): | ||
self.PAGE_ID = self.PAGE_START if self.PAGE_START > 2 else self.first_leaf_page | ||
self.MULTIVALUE = False if self.REPLACE else self.MULTIVALUE #冲突 | ||
if self.FORCE: | ||
self.debug("============================= WARNING ================================") | ||
self.debug("========================== FORCE IS TRUE =============================") | ||
self.debug("============================= WARNING ================================") | ||
self.debug("ibd2sql get_sql BEGIN:",self.PAGE_ID,self.PAGE_MIN,self.PAGE_MAX,self.PAGE_COUNT) | ||
while self.PAGE_ID > self.PAGE_MIN and self.PAGE_ID <= self.PAGE_MAX and self.PAGE_ID < 4294967295 and self.PAGE_COUNT != 0: | ||
self.debug("INIT INDEX OBJECT") | ||
aa = index(self.read(),table=self.table, idx=self.table.cluster_index_id, debug=self.debug) | ||
aa.DELETED = True if self.DELETE else False | ||
aa.pageno = self.PAGE_ID | ||
self.debug("SET FILTER",self.WHERE2,self.WHERE3) | ||
aa.mintrx = self.WHERE2[0] | ||
aa.maxtrx = self.WHERE2[1] | ||
aa.minrollptr = self.WHERE3[0] | ||
aa.maxrollptr = self.WHERE3[1] | ||
self.PAGE_ID = aa.FIL_PAGE_NEXT | ||
|
||
if self.PAGE_SKIP > 0: | ||
self.PAGE_SKIP -= 1 | ||
self.debug("SKIP THIS PAGE") | ||
continue | ||
self.PAGE_COUNT -= 1 | ||
|
||
sql = self.SQL_PREFIX | ||
if self.MULTIVALUE: | ||
try: | ||
_tdata = aa.read_row() | ||
except Exception as e: | ||
if self.FORCE: | ||
continue | ||
else: | ||
self.debug(e) | ||
break | ||
for x in _tdata: | ||
if self.LIMIT == 0: | ||
return None | ||
self.LIMIT -= 1 | ||
sql += self._tosql(x['row']) + ',' | ||
sql = (sql[:-1] + ';') | ||
print(sql) | ||
|
||
else: | ||
try: | ||
_tdata = aa.read_row() | ||
except Exception as e: | ||
if self.FORCE: | ||
continue | ||
else: | ||
self.debug(e) | ||
break | ||
for x in _tdata: | ||
if self.LIMIT == 0: | ||
return None | ||
self.LIMIT -= 1 | ||
_sql = f"{sql}{self._tosql(x['row'])};" | ||
print(_sql) | ||
if self.PAGE_COUNT == 0: | ||
break | ||
|
||
|
||
def test(self): | ||
""" | ||
TEST ONLY | ||
""" | ||
#self.DEBUG = False | ||
self.debug('AUTO TEST\n\n\n##########################################################\n\t\tBEGIN TEST -_- \n##########################################################\n\n') | ||
#self.PAGE_ID = 4 | ||
self.debug('CLUSTER INDEX ID:',self.table.cluster_index_id) | ||
self.debug('FIRST LEAF PAGE:',self.first_leaf_page) | ||
self.PAGE_ID = self.first_leaf_page | ||
|
||
self.debug('ANALYZE INDEX PAGE BEGIN: (FIRST LEAF PAGE):',self.PAGE_ID) | ||
#DATA | ||
_n = 0 | ||
|
||
#self.replace_schema('db2') | ||
#aa = index(self.read(),table=self.table, idx=self.table.cluster_index_id, debug=self.debug) | ||
pc = -1 #页数限制, 方便DEBUG | ||
sp = 2329 #跳过的page数量 也是方便DEBUG的 | ||
sp = 0 | ||
#self.PAGE_ID = 2361 | ||
self.MULTIVALUE = False if self.REPLACE else self.MULTIVALUE | ||
while self.PAGE_ID > 0 and self.PAGE_ID < 4294967295 and pc != 0: | ||
aa = index(self.read(),table=self.table, idx=self.table.cluster_index_id, debug=self.debug) | ||
sp -= 1 | ||
if sp >= 0: | ||
self.PAGE_ID = aa.FIL_PAGE_NEXT | ||
continue | ||
#aa = index(self.read(),table=self.table, idx=self.table.cluster_index_id, ) | ||
aa.pageno = self.PAGE_ID | ||
aa.mintrx = self.WHERE2[0] | ||
aa.maxtrx = self.WHERE2[1] | ||
sql = self.SQL_PREFIX | ||
if self.MULTIVALUE: | ||
for x in aa.read_row(): | ||
sql += self._tosql(x['row']) + ',' | ||
_n += 1 | ||
print(sql[:-1],';') | ||
else: | ||
for x in aa.read_row(): | ||
print(f"{sql}{self._tosql(x['row'])};") | ||
_n += 1 | ||
self.PAGE_ID = aa.FIL_PAGE_NEXT | ||
pc -= 1 | ||
#break | ||
self.debug('TOTAL ROWS:',_n) | ||
|
||
def get_ddl(self): | ||
return self.table.get_ddl() | ||
|
||
def _tosql(self,row): | ||
""" | ||
把 row 转为SQL, 不含INSERT INTO ;等 主要是数据类型引号处理 | ||
""" | ||
sql = '(' | ||
for colno in self.table.column: | ||
data = row[colno] | ||
if data is None: | ||
sql = f"{sql}NULL, " | ||
elif self.table.column[colno]['ct'] in ['tinyint','smallint','int','float','double','bigint','mediumint','year','decimal',] : | ||
sql = f"{sql}{data}, " | ||
elif (not self.SET) and (self.table.column[colno]['ct'] in ['enum','set']): | ||
sql = f"{sql}{data}, " | ||
elif self.table.column[colno]['ct'] == 'binary': | ||
sql = f"{sql}{hex(data)}, " #转为16进制, 好看点,但没必要, 就int吧 | ||
else: | ||
sql += repr(data) + ", " | ||
|
||
return sql[:-2] + ")" | ||
|
||
def _get_first_page(self,): | ||
pass | ||
|
||
def close(self): | ||
try: | ||
self.f.close() | ||
except: | ||
pass | ||
try: | ||
if self.DEBUG: | ||
self.DEBUG_FD.close() | ||
except: | ||
pass | ||
return True |
Oops, something went wrong.