* Find the mapper root and its dialect. Two shapes are recognized: * - MyBatis 3: ` ` — namespace required. * - iBatis 2: ` `, or a namespace-less * ` ` whose statement ids carry the qualifier as `Map.statement`. *
()
| 134 | * (`namespace='X'` is legal XML and common in older mappers). |
| 135 | */ |
| 136 | private findMapperRoot(): |
| 137 | | { namespace: string; dialect: 'mybatis' | 'ibatis'; bodyStart: number; bodyEnd: number } |
| 138 | | null { |
| 139 | const mapper = /<mapper\b([^>]*)>/.exec(this.source); |
| 140 | if (mapper) { |
| 141 | const nsMatch = /\bnamespace\s*=\s*(["'])([^"']+)\1/.exec(mapper[1] ?? ''); |
| 142 | if (nsMatch) { |
| 143 | const bodyStart = mapper.index + mapper[0].length; |
| 144 | const closeIdx = this.source.indexOf('</mapper>', bodyStart); |
| 145 | return { |
| 146 | namespace: nsMatch[2]!, |
| 147 | dialect: 'mybatis', |
| 148 | bodyStart, |
| 149 | bodyEnd: closeIdx >= 0 ? closeIdx : this.source.length, |
| 150 | }; |
| 151 | } |
| 152 | } |
| 153 | // iBatis 2 SqlMap. `\b` keeps `<sqlMapConfig>` (the iBatis config root, |
| 154 | // which holds no statements) from matching here. namespace is optional. |
| 155 | const sqlMap = /<sqlMap\b([^>]*)>/.exec(this.source); |
| 156 | if (sqlMap) { |
| 157 | const nsMatch = /\bnamespace\s*=\s*(["'])([^"']+)\1/.exec(sqlMap[1] ?? ''); |
| 158 | const bodyStart = sqlMap.index + sqlMap[0].length; |
| 159 | const closeIdx = this.source.indexOf('</sqlMap>', bodyStart); |
| 160 | return { |
| 161 | namespace: nsMatch?.[2] ?? '', |
| 162 | dialect: 'ibatis', |
| 163 | bodyStart, |
| 164 | bodyEnd: closeIdx >= 0 ? closeIdx : this.source.length, |
| 165 | }; |
| 166 | } |
| 167 | return null; |
| 168 | } |
| 169 | |
| 170 | private extractMapper( |
| 171 | fileNodeId: string, |