From be24c130da062ac40e6e8349385c11ee48fd0602 Mon Sep 17 00:00:00 2001 From: Serge Rider Date: Wed, 17 Jul 2019 13:52:09 +0200 Subject: [PATCH] #5930 Google Spanner extension --- .../feature.xml | 1 + .../org.jkiss.dbeaver.ext.bigquery/plugin.xml | 9 +- .../org.jkiss.dbeaver.ext.generic/plugin.xml | 15 -- .../dbeaver/ext/generic/model/TableCache.java | 9 +- .../META-INF/MANIFEST.MF | 16 ++ .../OSGI-INF/l10n/bundle.properties | 5 + .../OSGI-INF/l10n/bundle_ru.properties | 1 + .../build.properties | 7 + .../icons/spanner_icon.png | Bin 0 -> 874 bytes .../icons/spanner_icon@2x.png | Bin 0 -> 2234 bytes .../icons/spanner_icon_big.png | Bin 0 -> 5020 bytes .../icons/spanner_icon_big@2x.png | Bin 0 -> 8936 bytes .../icons/spanner_logo.png | Bin 0 -> 9023 bytes .../org.jkiss.dbeaver.ext.spanner/plugin.xml | 60 +++++++ plugins/org.jkiss.dbeaver.ext.spanner/pom.xml | 14 ++ .../dbeaver/ext/spanner/SpannerActivator.java | 57 +++++++ .../spanner/SpannerDataSourceProvider.java | 63 +++++++ .../ext/spanner/model/SpannerConstants.java | 29 ++++ .../ext/spanner/model/SpannerDataSource.java | 49 ++++++ .../ext/spanner/model/SpannerMetaModel.java | 59 +++++++ .../ext/spanner/model/SpannerSQLDialect.java | 28 +++ .../spanner/views/SpannerConnectionPage.java | 159 ++++++++++++++++++ .../ext/spanner/views/SpannerMessages.java | 18 ++ .../ext/spanner/views/messages.properties | 3 + .../ext/spanner/views/messages_ru.properties | 3 + plugins/pom.xml | 1 + 26 files changed, 585 insertions(+), 21 deletions(-) create mode 100644 plugins/org.jkiss.dbeaver.ext.spanner/META-INF/MANIFEST.MF create mode 100644 plugins/org.jkiss.dbeaver.ext.spanner/OSGI-INF/l10n/bundle.properties create mode 100644 plugins/org.jkiss.dbeaver.ext.spanner/OSGI-INF/l10n/bundle_ru.properties create mode 100644 plugins/org.jkiss.dbeaver.ext.spanner/build.properties create mode 100644 plugins/org.jkiss.dbeaver.ext.spanner/icons/spanner_icon.png create mode 100644 plugins/org.jkiss.dbeaver.ext.spanner/icons/spanner_icon@2x.png create mode 100644 plugins/org.jkiss.dbeaver.ext.spanner/icons/spanner_icon_big.png create mode 100644 plugins/org.jkiss.dbeaver.ext.spanner/icons/spanner_icon_big@2x.png create mode 100644 plugins/org.jkiss.dbeaver.ext.spanner/icons/spanner_logo.png create mode 100644 plugins/org.jkiss.dbeaver.ext.spanner/plugin.xml create mode 100644 plugins/org.jkiss.dbeaver.ext.spanner/pom.xml create mode 100644 plugins/org.jkiss.dbeaver.ext.spanner/src/org/jkiss/dbeaver/ext/spanner/SpannerActivator.java create mode 100644 plugins/org.jkiss.dbeaver.ext.spanner/src/org/jkiss/dbeaver/ext/spanner/SpannerDataSourceProvider.java create mode 100644 plugins/org.jkiss.dbeaver.ext.spanner/src/org/jkiss/dbeaver/ext/spanner/model/SpannerConstants.java create mode 100644 plugins/org.jkiss.dbeaver.ext.spanner/src/org/jkiss/dbeaver/ext/spanner/model/SpannerDataSource.java create mode 100644 plugins/org.jkiss.dbeaver.ext.spanner/src/org/jkiss/dbeaver/ext/spanner/model/SpannerMetaModel.java create mode 100644 plugins/org.jkiss.dbeaver.ext.spanner/src/org/jkiss/dbeaver/ext/spanner/model/SpannerSQLDialect.java create mode 100644 plugins/org.jkiss.dbeaver.ext.spanner/src/org/jkiss/dbeaver/ext/spanner/views/SpannerConnectionPage.java create mode 100644 plugins/org.jkiss.dbeaver.ext.spanner/src/org/jkiss/dbeaver/ext/spanner/views/SpannerMessages.java create mode 100644 plugins/org.jkiss.dbeaver.ext.spanner/src/org/jkiss/dbeaver/ext/spanner/views/messages.properties create mode 100644 plugins/org.jkiss.dbeaver.ext.spanner/src/org/jkiss/dbeaver/ext/spanner/views/messages_ru.properties diff --git a/features/org.jkiss.dbeaver.db.ui.feature/feature.xml b/features/org.jkiss.dbeaver.db.ui.feature/feature.xml index 8abfcfb5f7..a21e00a9b3 100644 --- a/features/org.jkiss.dbeaver.db.ui.feature/feature.xml +++ b/features/org.jkiss.dbeaver.db.ui.feature/feature.xml @@ -30,6 +30,7 @@ + diff --git a/plugins/org.jkiss.dbeaver.ext.bigquery/plugin.xml b/plugins/org.jkiss.dbeaver.ext.bigquery/plugin.xml index cca6414a3f..bfc418631d 100644 --- a/plugins/org.jkiss.dbeaver.ext.bigquery/plugin.xml +++ b/plugins/org.jkiss.dbeaver.ext.bigquery/plugin.xml @@ -12,21 +12,20 @@ description="%datasource.bq.description" id="bigquery" parent="generic" - label="BigQuery" + label="Google BigQuery" icon="icons/bigquery_icon.png"> @@ -41,7 +40,7 @@ diff --git a/plugins/org.jkiss.dbeaver.ext.generic/plugin.xml b/plugins/org.jkiss.dbeaver.ext.generic/plugin.xml index e94d0e61be..04025c5909 100644 --- a/plugins/org.jkiss.dbeaver.ext.generic/plugin.xml +++ b/plugins/org.jkiss.dbeaver.ext.generic/plugin.xml @@ -1069,21 +1069,6 @@ - - - - - - zf%5 z>*3|AeBXPox~g9h&N*R>5hg3=lsK%fhWJmY_L0MC8q~@KuYfa3GR)e2%9t7MwBG!C z!g@8zTQ!mRBF7#f{L!Iok4!L2ARSb~Z%SPKwrfnk`YVK(_mu4f@cZkYit6h?{1d<3d z*-d!#rVNVy0hGZn_yuxS2;?!K&0KzF(E&o*jm25jECh0Z?qL%zK-4V2uYGy=XJ%9U zJ+&@=`TadKYKu^>ea20~sJVf6BYOD5%hF(B78|X0K2&%<{B5`Z({r0J{dyCgFL~nm zq9-1_EW!O3W$18n(4c*i8|8zDd0Red3-Pv+ok=DNH@{l{-ilTQA0LYj!f_Nsqqa1Hh+mO)9)LqvZE`{MI( zus;iGI_o#2a^jdaHGvw;P%TJla*>YgRgKkRi?Qm*%rAb-UfpUQ%mqsFbr99xZmIfP zU(x3Mrqp~fK6ph2DN_wnCCUt=oFZrFU8j+ILgnj1HS(g_*bt5B715A*FB+2z;y~h~ z=+Pz}`Tr{#M%hn~iCVi(v-`tc{K;fDe>~RBXU7pI(o#u~;(nb@Ab*yFl zuy$V>D=cgLmHX{+~x%8uEZsLf*!Zze4+V|2&%=t9uJc-;SIGD@jR9uan3~&b*!oV(7 zN%VX}zjnEAj7UlWV>c1F4Z8bq4(Bolb1`R|+cmS}6ev7z+Adv=`o6EedGr8C!l`;A zlxj3XW1G#eh>d1=tYO~v68xs~=ny#?7>7~bd&dBpb}?fu~cCPr`8 zEg@`fwh0?w5o}`9ZG(fkn3K7^DtNk`(z}mKvS&njVQEh8z4-1X@$dMH zOLXF;Rnb2G#}eHaTc^RZbqclni+t1L*s!FOMXbSELX!=QV!PC_I8Lc=AM=|wg^h|8 zO4V8sb`C_`WHI_d7}%Gn(#!8Pgy;vK)aZlB4bi^v&KlkQTn=lYA`FB?j%PqbRH0(A z25af<1?kh2#IA&r+VilnG8HgbtlAWUZA8os3K<*3F_NlMzp{bSZ_wl%SHTgOoNLh2 z7nbP3GxOw6E>ci0iyVgFF{(~GHUq|{^RTfzl~ByDaTR=H@=tun)em*Q(ZuM>R@i7K z7{Y)@KmukJMym8svPy&I8m(0 zxj*D7@x}`Md$umx{`egEV>76TYa;9pk~vw&4haL-W*B^0BRIuRIZ2%qC*`+g> zT6Z2ul<4;#xsRRuYYAb;Y0P?iKOMk7=#rFzy^5sQpST-#bwy*~*(7h12 z_t`8x_0j^}SlgodmQ5#rxk$eqca7nm6HLxxDrOvid=@6w9Mx6a{i|}W77l_Bu z+;dP{oC@lwf?jM!^pfKtY?LUX=c#XGn$$O!#VE5k8g&12Sqdd)ff;&WI7@RY4QjPo z6n}k*9y&8kLHy5CAVHYnk4?kGOf#UBoP+w}&Bw5_5h<6CNqP-p1uLwVS_1}31_K=X zl10b3QWoONC5v{i(cX&P7gE>DDDHbkd9^pFuWw;rumL<7 zJZEb#fe7>^3&bSBcm|@`wzwNZ$!Sbe7SoZT0E8tL7Ez!j#WME(=*-rSM_<9qC?Pc6 zm(jM@@i*1BUKJD^$#9l`TK)5|gtaiBuUIUMrvO#RccL%^ z1d>?Y(d!VJ!W>Vz(F3m8L?Ct@qo1Rvl5YaeX{c)obY?h9=?!_6y+J#8K6aL+U3J z{Qu$jM-zu)e@`EdrPGI^>GZMqpUx#@ecPwm|MPLG@W*Kk$#VOH^Go1OqpXM=LyZfL zTRu*eFZ?)FyDH$VR1Kflm^(g7cj9fJw9&rCoZqQz@~ literal 0 HcmV?d00001 diff --git a/plugins/org.jkiss.dbeaver.ext.spanner/icons/spanner_icon_big.png b/plugins/org.jkiss.dbeaver.ext.spanner/icons/spanner_icon_big.png new file mode 100644 index 0000000000000000000000000000000000000000..a01b3d013e58d45148c62913ddc9acbe13c27c53 GIT binary patch literal 5020 zcmV;N6JzX&P)DquMIj+mU<}wGi^36@I7Ui@>@pF8)xNav_h@%! zA2T~W-6!YVd%LGcn%Nz#RwBFg)$Qr&zW4jSbMB*ix;=`bc&-kzN5=BA0JVL!{Fii+ z>=LfX4xzg145w{}%k?opxGvj~S69$JRgNQK*9mdazPdsdT$Ckd#Fd?3i`BO~r%5?*`)=jgl}*aQl}+k30@lsjIBp`4R^Z47Ywo@j`oAj#?tTh;&A z@g;raOfWSw5=hOZgM?N>ZkfUB4zO}&yk^70zM-Q|@_va&*zqn-zn zXO9qpP-`w9Y%Lgp)`A&qHO$~1!@8!xHh5bFgW4tz#DzE!H# zH*VI4KlG+dBsE{eXjlw;3V=Wp3UH0V+p^n54#b5x5jWx}yLc~87ZA};N==@JwYRrz zr0BQi4M6~nDA<7O1TH=`FHFcA#EG~O$1BN#+A@GmFY&q-dEc!eeR|MGeVwB35MU9x zu5gS<&9hAOrI1rvxCcHgvF|r~{z?0v{q;IVU(XrXFd(qec^V5W zQC?55Hi<((pJ$wi8*wDAa*YGxBGaBi=~Sml5zltz(4F4Y{ET1EW535nQ+byD0`M7u zweM$K@+Ou=;z(SHGjV6r_5#ylm9!V&Cah3!`FUTm^O#q+MD+94XB73S*}ysF4B|*! zi8IRrMRxRDSr>3kd;g}qvZa9rK7GyzvW5g&8K7pQTxBJ=kEtD&n^Oom5?A6}%d}W| zy>Is$oKoVle$ys>^sHYmSfP|-fEmKZYeuU4bFjiO!9~tl48(~UfEuV6=zzk z+!d;>_xZHf?D>ZF?k;i^D=s)Lw>lZHXvAFv8N#?7-jm0{tF(`{Xx634UL9R_Hp$Q2hST0yK+l<2X%YJvmO1Kcv;?jRbgYdqey&$@ zuvW@3u>qaH_pg)qcVX8#_WAB|p>~K{AjP>d&d9wN3i%-G_gHCa&LW2y zt|0oXLb{)pI^j(jf zn3^$Bs0l^Wg2V4;VfF4lSlu)PM}L=N`^bdJ=>mk*QSc>aY20DPaRWGNY1igU+`YO1 zq(x?z%cxDUFX@E=mkfNk=xOpiroR4QgKk1d$JA$)&58;cpjHHRAtJ>M7)TevvbfOa z-_5{ZJkf{fh38L9v8=Ex6Z$9cYESBi`uH#k;RbROX3INBkLW4Zb1Sx8TlcoPbS$+Ex=+D9f#WU$*Q z{b;}dG{pN6!zg}+WdJv$gpjMe1P*7;JB!nz38XD4vn+6?Mc1?!t=pv>yaO9aV}nIZ zU%beep^B`fhz~KsoH%s_GUH_1ybui7=lNK`VS@el!Kbracx(W?@d2oh^+7|zHerUF zpf7HM;B1iw+&1wX%!HXVX(X-ov}oVvs#D~s=PTMrFE-$y5lUu_V3IXtvVOcoFrvI3 z@N2W+Q!)@cnud>ib6}!yQy5^P0U!6}@w*9@`YifrK!YgjsXI_6BxhJ%0jg7M2VHGd zY@amHfSQ~(NE>QAs!CC3M!*g22AU@ySC06+dI2M!MWAaGeU*HpWz}mZ<1Je+6kS&r%(kiYN zSI}*)8zf2j+!n3pq%S#-&Si~&eF9aYUjHj@r^Wcm3F?i$s z)lG=nCS+YEOqZK*35OuxCjy$qtHpV^N9#Q$N%H4tEbz1@wtK#*9(&A5eRlA4$vNR{ zP0%lgI}>QzuT8_|J<~8U#b*SX75m09190kVh;jqmsBVIt3DXr#aB;G1P0R$;*pM{f z5%sM{=*Ed>xBToKcPB^M{mEH!h`IolXh4bx*9g7(cR}$Tj~XwxJe?H=SdIZ983(%< zb%8zxFO@7KIQV}4J(gs4JRjhWl8!o&;8oRFJlEvxC2g{ zmkU8OShkI5Y~^J*#liPy*?ymvg$5-HLl=uq7q~DwkE_BSCd@CDgtBgt;0E{;eU3Sm zO~{sUa5%ZOI2toWZ!!m4)!#ho2`007+-U}dL%gg(d<7#yLhzb+7E?V7>!l0|CPT7p z|GGpLylNH>9M3^+-gFj4Gr1x>{rUu~Ywm%&cJ(mPWW@TGURaHv*ERRTs+~Q|1Tv%E z$%G4z2?653OvqL@p`;P@X7Fk;GsXI1a>m5NHINK>j<$fJ!DfX4w2vTvMoI0FDE5*ahBs)YBv% zxMPzx)Q(dMI+Q7r31MNvqM*oQdaqARf%=PC$QMj!Sz9nHvE(f+duhctUof53;JLmW zeA=IL1k!h`XMoIX5q7^Y!m^}16S^yykZ}je;@UDr(%P6D=YwDhr@=?m zHy`urc?c&b4W0$;KpRjE!Q>R1(^p3);rZXru~eSRn`KdBX-+G?qUEG|I%~keV-rZ6 zMD)N9kEdaBhTkW!#IYPDv*>Rw&yV>&p8L1kyKwQ;!=oR&z>MIT(9d{<1iz3zW!ajT zF4X8v=5ZQ)lTU-V9Apcjd$sP9I6a`SDO?MP6H?TNssk(MeLOY^-}%+7L-aR)ng;dd zQRo`Z(={%ODlK~{l5hNX2EN?d2YGsw4I4IJ-u$ z{}L~aiZP-`WIzd*o4_)GMt+O5k;W}rcWEJ1S_&Wb`t&*M0+U7V+SH<15TXo7O)&$s z*Jhz(CXVbxQZ0hm3$G6U>P=oThSvOuC4 z7S}XcB#oriwG=L041HDm6G9RaC6adf;x?VLdRHg>`ooMcfR71e;^(*XI_ca^S`XZl zM8jITz$ec4#q4fC=;oOf?P60Vnt&Q6nI<1! z3_6Fv5-tTZN#mtoor0h`0c&xD-q_L&2j7~23GC}M&*yQ@r>^|lv(r3sL=+=V0+1AcUTf{FA~l%gdO6hSgz&8{vu^4>*f04?1(0q7jc!?qs{!us9a&iS^1zROLp zME%SJth?YvO%JK>Nt)bTenX^mOHAg!1WBn|Hfe)xL5&2bi(~*ZLFXbb1%8LP$hN)8 zMR@4@lW?kSwrnkMx_uTN{lNfy5mVepsmaLMrF**zP3VLte>wf^ zgAJGkKHI<;hfl!XrtfeZAQKQ>#rl?RD;z)H7L!|VQKW>pG3vf0R(4ag+4GqC>VsZf zD1@~M!#03t0t46xCEX_QeH#*!u)28!o_=i%KEXMjW&=uJ8XHQH7ZG$3wn4|-^;9Qp zXzql4Z;azCFb{iwF@`fm2Q$a#KEDD;G}bA^<94*uSRWaHN8?8y)Z~`ZO;OptDeBx7 zmtD8TrMkb@+D`cJDvNi8i`;}NSx}w{7uojO$S51ARv~dFEZ)sWXP5X&+k^le8|i{C zuyecME;NryC-r01A?l#Wlla1hNFUr2JAFcy+_%N$T7DRLZjE2diyf{P}Z5VoOn zp*Bc(326vwX=p@K0?HVY!t{=ifKHL>oqS)kiat5;iO(3Bf8o@TpJNq7RskMsd3hZss|Ure$LK#0d-sqgUGfN>T+@%EalB60e_L1^8w;XvJ|L#e zFzXJNi!V1JElikTp9AtJGoZoAgw6#cS@zvxQ7=WGWdKDUQ@@B=faUqIro_J6#FL~8 z|2SId=W)t{t;*ZGyc%V}7>)&L6hDE{rxKx~&`S{3(~bdntS}*snJ^+upnlyUOz1%J z!jRZi!D5JZkOA2D&llEV^uHc|W0yw13EI(DE`L&_>a#(m2PBd=ZPt3u2H3PXZg3MY z6NK1mxZDKH1Z9+o<|dS~flTn(nti3eo^oOKMkICVHh*wTK?+wq(>V?(3| z9*n)cp9Vg;%CvWNkIG8lxwTOp91LpXW}`M%469=n3bGneR4oYGP{(LIp`|ti-XjKy|{EnwSZAaRS_07GoHU7%BBwOz*%lxpk z1E~&;xN(cx@nJx{h=NCpxKLsyi1enLjZh7A3^!xU0X+^w<^<&-G@xCWV8dlXRBV%Q zzE4EI4X^e(txb_LXA+WnqfFDDi}UioFoFH+-<88*pE?DN>TsbkIckv!jY$Sz+Y7)x zHmungwa^4+Vo)Bm&;Udmifdy6sq{x#nsdQX>K^CCceMZ0!iJV^_*UY%FkkO4^9vJ| zUYSvFZT&Un^kFak>Z1+id3PA4alsTu)C3Z5n-Es{Hksff16oQ32;mI4je}krj`(dx zAo59mT}uz#AARqLD#fa<_piZAQ}MdEq~Cm>diJ;%X9Zg6xzl=S7-ijo21nK%A~Ytn ziLTJ*>K1&vp``;z{5{c=$753R=CWshmiwitO0UgfgXH)P4=Zo&*rJ|46IKUD!s<{O zyG6QDTMCBKbbgqX!|9ORpY}&SDWT;YmgmIhb0eE0r_X#N{^}0mpduG%%2sNR{?)%Y zsnCm)>@JI^N!fpUll;ueX62ccO;?C!cPVo;D+gBYmiMpREq!lg6JocG1byCjyCf+d zTI!Z@lCR;5lht3HRZ6eUDsk}&?Ny?zo`TqmV-o1HOm;Lwv0000P)C+Fmx`3_0`@^ilG;Ep*yixDCct14mcW-}*b*QRhk+r0O#oxN_kCZa zUer=a^?vuhZxJK4wnKWm{%Yy(2fz+pExmt+7+%ZY5B!Jt zc0FF>KL5e5;Wdju21bP9k)TN6`z!pM2Y|0P-R6H{a``T z!34c#y!I=lj}QAe=?mzSVvwK+k?%6OxI4abad6=1T5y0Z7)yZ3wuZQ34aOB4T0@+i zkrrgvXl=mjglmRtuL2)z2n-xWpZJSF0)rL6Q|aZzFKh_(AH@i;2cuEu3>g$a2H<7# zxiGv|yk@v|^g%TxLH|+o4f^PeQUI;h^KpEo!(95co4V>hl|t zK%qVWU!YI6iO26oAEB=}gH*r(meIUlDf;T5;Ct*l5cwd3FAyEsv7#?-Rg0l=^fOBqhJjcdeT2S3pZVxO5x0yLfWyMiTj}8%zPv6F zYP8T6C>AeAea^y=pl{Ge>w=+1H{bAO^d0r#awCAQ=RXUJn(gA-PFDC$%T{`^F^K*c zDO<{{4KaoK27H8F0s4#UV5FOhi-1iOiA^MW%mI(n;g&$uja8A>fz{$s}Y2g=@^*wOeavBScKvYJbZIMns zF8G|(mrGR;7M@j{*7nt#Zt)*k36(8Gel*S`t}Oj?FjN5reTKffNjS0+=S-HWAS`_J zGX=onrE+7S?;Ue6K^a|+?s*#c41KpD*#8d4`72eQ7F-1iU-)tUvv45eI^pH*RROi| z3jnhNF>G^4*=9HJmqL9eK|u&Uyw3mfb~ZRv_=0c=s(){#lfUa6M_|0u5`cmx5RF6r zhrAypWt*2N=sQb5PJk~v(5JL5EJX!Ki+--ov@P&=2`77OQUqtbSlh?8Wt+QUEkJ#U zz675Js0wg}Re{2`eVog*n}6_|mOy+8*$bvng9|C!0!;HCRf6~w`WAgm+rm;IfNr+$ zEa+KHo5jXwaZDTY7h`f+&KGB_7C@hFk{X{wAEU1e)fN_Nyq^|+H;B)e%{b2=n2y__ zkf8<_P_{)FE1nhfX$|-meVi-^3(yu8Ao^L`=jDXT4S|7UP_$s>A1_C4;mnR(@G1Hh zeT=>?R9jexK_5Ea|5M@5zd(lCrKuP_>A*BZ|1>Gv;tjy3T@?BjeT=>qb@K#8RRBNd zsi^ZG_^LfH*$*e0uu=I(@ELQ0d%)Dv&^5 zqtAB=kA52`+_*)|7A|_3*AJzZ7vW@pnUPqjN0BWszt^Rk4k9u1`Q?GO7yX=<&Aspo zQ-MXy_SKoL_dmbU98lndCSzErlxpPgMX_L**>_hEl|=b zprFsu_ty*0Z&XJJD;H7_E@-xoF7x68U%XfvJYfw)L6W9qdoV&u&1`{468LH%LRR`B z4#41hG|5Na#2-$e&G`R-;hx_2ZDI%2Kb+K!klF|1U2L?|d7TP=kw^Rg3 zEBv4Z*&)4kJ1hJk`qfsYbRs@NYIVS`;v!_n{nO<4@5jl=c${pybC6W~r;;S87N*G7 zgVSVmB0>J}flT+s_fR6h=hQZ&$Wju@K-U+chu@Jd^NfqFhPys6ZoV#Klf9PC@ z`eASiv?UQNN|aKPd)!v}BV-L9AwPR)n!I#OCXtvz@Mm&5K`ssUkTveUWHi+P0XE+g zAyZMd&ou1&@^P75_wY3R4E!vOEE>UzPlAYozDEoY3&7-Shz&Q-d4hT0-Gf!J5}|}?et(1vhFLTt@bM(51PA~M(9la(JG)7>r;C!Hni61|5`ex3 z_Se5>FeH;&X^a+%2z<$;1EvCCQ*p%PX5onybZlTAZQ&dXKi2l~oX>P=pyN$*Kvtu_ z^ok>kG)0TNzEK7|nxZHaR4oOd0<5m@A~oI~N`f`+eq9P+`{H}zarXY+5t%snZc@XK zs=!Yr6`&M~L>pj%m>@R%Jln!Kw|#i0%Fl&AY^8Vg1}0<{2~!aLSWK0USp$>g;yb1& z0kmkw9|TlSfK{LXHJ)xt0!#;&?;n8wF#>4&YVYkGi4!~DL)N;xh{ZpuRpHd|nA)}| z1{hEh0w#3%nE1!7`hu_^3cz!o3J=%trFDVPRx9m8r{bj;{WSjvm;&^VX(=F`09XTD zzQ2#GabXHzhOaN*-%J0e-&Z3*A1Z*qhg7*?|0D^fbtEXh5+EjkO`9LzQoUQ zo?uRGA4dNU@okS9{m}MBO0MvmjR2U>5m;0J8$|Q@yE}=M>!F6P@o)G)mM+rOqi-}0 z1n6c2@XSPlsiGBx6ccG8hAOaKc-uqoEu2GJIG6GMioN`yuUiAr2^%f^rf}d#S&j;z z6?cF6c#2$gcOUugu1;$B`VIISEBvxk03!e>fJ>_zN>B-CDws+zC5TS!^&kE^bOp1v zg|pt>gR^~Gq!UMI+b2!NN)`Co2%!CF;9`sS>o>yGSgV-&pZ1eQ0964r5>%C9I-r9? z3fUYuc?7YW?XIF(9_p~qbhH1+D!RrmFcGIkUkMg|nML4+JEwpEi7W-s@Qo+Zf!6;G z_sLcOSxo_`02&Ec8(HP<1QLvB)p&6WL#6@>VpS7R$j$yISE&m}^4?W6!!j=)WzI&a z`#lT2VPOK=zDaEVO4=;a1SLQ(L@ffCP!tvX^eCroo~}*I{GXOG(0YbrK!7f?*3}7} zLl-p!Kbr(oDhc3Rg6h_2qZm!dh}p(K_j`yTKg05|8E)&|Yr0l?<;Se>8<%a2WhEW` zsWxzugeI8+$nivm3S>vWK0PF(AGWg0K4WYW+rX}*0%%t4?V3ReCK(}&_klu>378>v zKLrfchfUER|Bv{V8K4aHy{@tQ&y#t&?!S877TA(X5&v*&?de z)Eg!IZ-*(E7wl%hTf8c`NfpSp+$5OFAc28?0L&0O#Lyx|BfI$rzeOjDGUf@g@9yE; zrcL6h=gm+=*rjoK`2f#MbFvMJLA2Tis0;W(a{jJ1QVV%}U`$Q|u5b77Zykd%0J{@_ z@1USseR^C(#;d3jrR+_dee>mryVtt z4B&?$`X>}Ls4B^FGIV&#@#FNh)jvqA-VR#Pvzj20st@Aq^=VLuHO>wl@TdUuGxnZb zBp6RSFGGBx;RjeErZ))BIM|eNsx3@=sDqc2{%M2Qd)y*L@Qv~17X9f;Fp;JN77@~d zFhqJrVtEyysW(PjJq^T#S{e!5j0CnU5*X@>IAVIS)c28>3;dJ*t|Hw-9qRG!o||eU zT;Us*Y2~^Mqd%V#Sj2I%u3?hS>}8G+Y6Cuu03Gv=`dO7AF9{6sfkLqq!!ly~6XCU+ z*qQ-$Zy_5c;yjgg{5}8dkV5^e@S8|5@RzRwWYz>0VVu+kCrHm|Vip1{F8cG<1ZgCg zFjfgzDo9uXTRUKkSR>|`3QS&3{370Sex>x`eKoky1DLX$qduQmQ2~GeI6`QI0;DTJ z=L||PVO&jsDgYQG*4XWNdGU)TiQ8MTlmFFsAV)-PYT>usr9UqL8jt`9LkW;hf)22D zAiz(|g|1NTM6-WTn7V(oO%~F)+e)fj(GtR7H7zi*v2LiMM zSRDm71b=oCEVUn)3YY^?a)tQmlR@rwlWC{_k$Hzn>|< zOkF^gI|WwZl|V-V*Gwc>s)BG_VK$*Sq|xEM{Nev&+A96yF#Iu|I&kSmaVkRQ9xci1 zf^Cg|oOBPz^Ns`H@b8K}ZN%!+12&5#_vzHVo^Ah35=^F%z%DJZ3P@oE3PQ3&_}gBS zJrL@$sZq~bh6z%Vrshbj1DrP$&-cbNR}mlNdKccb*i5dEs(?1>WT%60N&%J*69o+j5i#L- zzatRF;X(r2k}^D}bpWsfPWlIK03{eENB%ZVI)>sT_`(!f=?Rf)K1|j(uzhg<+Tb{~ zRo*Zy{O)}zLPjPuxzAqwk+~2=`{^H(NyBqPWKDe=xe(KW7l5U}wG%UJZN3h&vaXF> zaC<8WJUc{Abw$Z9|KBiK1%F$yTixHQ?VsDU&%$lBtBuZCIH*L22*U%eYYA|%GrTeA zBPK^+tP6ip52lm~@U=AR$H{76n1YOeYZW{Ki9bg_i;=7DW#qu~M-BKwX^ zl2bkLMa`Qud0BS1*7lB9c&fnEaHt+8ufBkea?Q?Jq!mSVY zfhx38f*=vhp8P~GoCFm3aDrmqF#MkBO7WvZI9ZT9SP@M-2L!&xABHFnkz0Q~Nj_?q z(}2`3+8B={$blClqzXuKp({jweE$S_>qIO`l3Yu^X8OrTgjbJEkSp)%BIoS{VE47r zXvbqG7n>x~_kZo939{{%-Bckk&s)8!?5lw5Ek6muNuLxFA0QWY0%V7HbgyX_|H!|r zlZFOZ3ka+zk_u=SXam{42&8@6!Ey4+@pK?FZ}MOcXRqHmEt97pJ;dUv1)ci4f)=tS zF!OUF(FFO`Yop|UPEMr}GV^AV&HuI1 z$nZXF192ee3i0D7Ez&f|Lr5;R0&LhnP9A=JIvHIFWo|&`Ug4``fI62|!5Qx%?0vb8 zk&ig3{n_8Uhhs#1W>5!sM@~b9$V~#h5-ifsVo0_GrpXoJCr<`&AV~7zQ1GMQu}V`> zU|YOcDu4x^mb-&cH$FO{f|D1h&TlpDHkAbUx|LY{11j(#YTE1h`8Z6mMU1bM-oFnqr;|ac>EHwZ z40)lS6@;M#qyxiMpvE5}Ke>OLMp-J7$qW*lTOBeZHd)cPN64*@^pX{OTFC19R;cLP zsjaGOB|q5PLiRk?M^1K4C-ZyqJn|eP*SYBnRQ-L1p~*P8EYLx!oUOz>Lu;5)0v!ol zKmuMP!I+K&bB+EGMt%Y(f*gQx+H|nCAOydc=BL7+Zo)|+hcqhN)i)Xiel3_q2tivH zrVnw*EYvjFe)0Wr>P-FMO+N6o*LZ*b9nTLzHQok5GvF;=EyCL9YbzN34}ZV+kHcgr zEYIOyg4F-UCgN!=A(BVG02S{ps^y`|$76bCCqNbn-1$flnjL%^{i8Bsix{UZ2+3R$ zwo&XlZlzPgp}3)G04~HPj*-jm3WM|6%^Wc~ktW+ey1R>fZ)XeHaz`h5^}}&m@#}Bq z%&ZNNFi-t;jBF6F3U8sg*Qx_vFS%$)40Jf|i_!Yr|AfdiRPyhXJvaA7XO#Uprvo5?JtqnB8)Au=Zjib^LX6Xwgy|QBa!%8Y{@>co zv?CaeYi)xeZJ>G~>!BEI9f&6#_(}UTx$TiYa^ap)iIz;B_EYf+tG_q9=A(fRaFUpaeNmp%z3 z*g*$YQjrAap2gICu~0)Gu|U*6Vn+MXj)|$|g4>(vIpO>8Jn=J74N&qQ{qrbQkq?`v z)a#hTIpnY!w_dGskw7gFGyI7dB9@z_6VD^IxtE1!-5Bz~x2%DQh@GmySi%t)0~Ht} zOKo^DHaPLX??%a{1^{_iGhB2lbsAnYzQ(PCgXrAZL>~Urhzdp`OP(=8x8KtRAhv)5 z*?Z?@-d2d_W^(gGJ?fNkZUO|K8zdL(1_E&G9Bb6~TY(T&P`rH)&huyYb<_P;*I^o3 zz`3Z#K3hGG8_2}>tH3kgQ6HxKsUUWUA!3P`BDOhi49R_K*xL=PEgXS@kg`izY6YMd z0k+zMw`5_y)?aWdjY=Ch_M&|)lmNf~-*8r?uT|c-z4mZ7S-G!;wO#X!ID8Lw2D^XV zn{%*9O92nQI!ylc=0=eB7J6>_^EIpIyApuE2tG^u-$E21r35;kxN?wywTcR2hS=2r zhKQy1J;XEK8kT-@=$+@R6Nh_jVmM(J$Knq4!^nJ=pf&_ zt%+1a%CdP=QjIMfk_io8F9!TH5~%GVB>~r;^c|Y|I*!=YibHd|IW*U|eqSrT_~ROE z3k6UC5kY}efCpG2)15psVU$jyR6AQJ@Rv#LK~&MNpSn4z2pawcP;2J z*Zd6MvjXzC^vnSLER_80mN3pUpHfQ4%;c5`@uj3dIUA zL+lX4bHKT8Q* zZFxvADkEl>i0$vONB#Kb_JD}&N5s^bZsGrHm066!hmOSUOaT;!nyZ(}82DrK!Hj#J z7$*Z^C2IsQ*Lc0YQh()xadLT}T^)H_n5}`_z5PI^nr?Cr6XzRlKG8W%esZvjeul-p z@N<~WG=;%!wX<0P5+FWtd@Md{g5c9=?dZa5wjFQS&1=_Mh!810Mm}c zqvV~FlR2N|lgsh{Xp4}W9_WVXZK8#lSuK{#?)e$M2Z39)ubI{n+*AFeYbch7h$L%z z`rT8LPQ67n}VH%vR{?QBdEXE6kvvjO;wWKFTv&K`2L z=Veb|j^7_J=dXry`5V5pPV8^BiO^$$5*U>R7!gLvdYmry4w4nnn*H*H0UBv_B?eE)WqYOa7>kLqJ_v;P@!9y(*u?`o1U`hVvA?N*7eOB?TB{Nv)e)Z^kW z7n-1z_6|N`_i#m=$=g<_x(v#_)J_07gCbnmUbyEry>9HCMBYH??l? zeE23}#Af?w5nt#pjBuK65guD%!Ka6a!(b!O7J^9#%+eYIA4xDw31Jt8R3MsE$2Y^) zSYyY;ZlO5G2ZQKuhT^X&zQ)xNznOn{g~+}&q+&_GGUiI*{fEpFedLO!0*cW}fUj-- z!5k!L`Mj9I)TU8hcpT20N(~pBO2efBK8-kxA!3dCG07%fRBLQyDG(+&) z$R*zYeKGkhVH`K_=wJBP$8)-`kLMryHy}XNAr8p^0;GdsLscMK2~-leGD&bIC_ocL ze^UaYU#@bsMQ`K&@3+;;zhXf+E|dWJf)LxnZQ{H4nxzS<0(J&U5lE1s1j3m`0#G%@ zOjFuvDEvCeR?q7PMYZkY7a08uR{;GyfzMM>=fC@_4soC#6#xf_mJcv5kOl$hHc@s{+E8i+Co(YMB`N;XF5nKLE~~R3>A9b zuG6vA&Q9`U@AJQ)Z6C*$dGW;}K=XdbJzfQ^?K<~Aj-juUclU67@d%(>K1LrleWP&1Y{vW7#eq0DU!f)e2*of_ z+YZ83BLO<{wB}Gq56i+(`XT?Him!3Clk54%%xt`W@zGxp0%YD*v_<&nSqt8#Bn-+$ zRe=m8z}I#l0R#WEssxS8L;+6A*!ErSdHXp*ySrx*gq^ z9E4(UNU22w5Q=61ek~;fBY{ID0pwF+fvp8dK({4njS8F}ME_|h{#vGX`wo9oB|t?X zqQ77S(6xnU;kQ*@EgqHd`}=Bz0aXQtpdcI~MY9YNP$h7sNWhe!M=j&s(Fy`5~Pa4232Z6O#brXlb%lK|DAqzs39Y1?OW zeb(vZ_Md~kEfnwtCqSACKtcF(|L?csJVC99Du5A)seo>aW)5u&g&`wBKZ|}!0v36e z5-=M5^fg9*JGs{T%yxCW|E&4W_8G1K+QTMrJ^E!r<2yEJ3o#Ycg40XE9CSNGYXMXP zyT6Z-zH0bcvXFC{3hQcs|4N!(a%>Fs_pT9^mF04O=d9+(cec4LZ}Hq1qMi|7=oWpf?nDYq;)v!ivR!u zj!8s8R7il^B{P(MDEvN)uW`1K>$s;j=@)q}TLS3sD#GPsm-|0^!%Ex2eyuH3N?Qqf zY4oR)pzwL0ZBNQo_043X`@O&T7rD% zzm^V87A_q)PhqdGu=?V&>D5s9UFrVQ-4Y$|=M9N|gA^crp1{WmU${(Y`YVnNtP}d8 zKmvtT;3b|8l1gy05QU*a2?blL>$506MdV`lhey5O8zTxo!wI0Zh3c(kCO6mcl}p5? zqh{I~_9a+NFrd)1P(sBaQv%%f)7Ojyr&JQ0T8I)r#6#q}&`!!w^d(k9(YGGJcX7e5 z;8ZWCPW2i^0)rKRb_EqUy5-@;v#;{MbI2l&5vwq&IvdC!_Q^mBv{=cQh}&NJ+Trhx z0dQa^Vi3LaF&PcyK7qtp>ud&VAy;@_KMcP30-NXe8w$Rm1V~o`e+5>$xTO46;n9^_ zgb#n~5cPVnGBj~Wm~0KaGi$T3hv3q%edX3YD~UKYmr&xV{$w{tah|Ff{r zOI|m}7Zrn|9=vSDx3Uw;1SmV9On|bL2~f7rr~Q8gpj-q_!uR_C0000iG8*1e!I~xEC1l`@mE`2Vn$ni5y0}_ly}#Jr=GygiD+gaIoHOFFOma#iOsmRB#xr0ZvxdVocS zOEaslQ{V)GDFZw{aF!mpjTHdvJQ3wUeb3{(xdnqB_qk(YKi+ZgXLiR}+xZO1Un2yT z-XKKgD|UI3IaSiN?v&oHHAPf7++(;OtN=~scOw}~2}5!id(ynK(S^oRWwf70*&aOn zZSoL5-LP@5Icfw-(>7PL^FA#RA0g^O2b)g|m_WK=NYrbdX=~^g>amly-47z%0N98k zL%gz@oU=a)3d!>Z3M>_hA$b3+1q3zC<)c6BTXYNbbA$YuDGs55$ea}H6*US(sYEerRxD>2^M%NHVe$H z-S26Ug}=K`AhT=2!qY7k4ve9)e;o?N>Zz!_w9^#A`UhR)+wGq-bVp6T0_8+_#KdCr zr_7oB@iMkFR^p015*1{#X4LijI1%YFuQx>YR};1-3m)Cyb3`!Y2J4>If=MU|T>dwf4U@cz?zfM+d8~kBEig2!_}n?zli!+;wJoYlrD0qFeLBKDAg5vw z&`l^JvNs{nJTCRSL@M*I(I*z`LMfYnB5&wgA7eHBadZ>t?))sAS_ZixZ~Q((+g7@zqA>rBQBa7u%U!`ZvTMM|UFgH9* zPfhy;`ys)bbkRi*KgoGvgTBMZE4|5?D$d}n${32r{CNd+X06e@96Y}s6|35;wbeUK zeE%%xu-W1l+dTJVWofzp`E#qi-*dwRJDJN*0$mNjFB@JX8BJe9oxNeA$_o+qvmqqd zAZadaVo2e%CRK?&xp8gH@Qb?4pg`}O4;(is&cL+kM|dG4h(%tMxuiVhvfJMF-RO!( z7h%Idu|8ox+y{3-Po?29KbjtqTFI1T8H=5194dH>cMi~KgV*StS8>X^u9$tR$)eD1 z*JXRayT8TGP;l=b`xeGK@4<0aF`f7{g>f11xBa^8qT?s4; z%lP#`G)K{qCr+0!hnp}(7O!oLgo!IgxS;?%kJY54z8CW(1CMcl9}uv$;Zt5%RD`RV z#rv~yMm)sp_Mou3i`=rbG=YF*y{;|CVZ8<8?C#SnwW2=8OsVy@lMuxY-dJ4xC33#PjoxD_xJf2Ptz$81GUFiWu+Hx|nC|E_~u2 z!;c$c?(~rOREmBz4q@OR&+)?dAE{j(Gsj3J(J3Sm<5;j^IVDglqkk-pUQwU*-KG<3 z;hG2qG)&G_v%6gSIi9rkw#{m~UH(0|?QkrgU&N72j)|F!%@%M>OJnvvC&ISQFb+SOHd9}5-7WPT>cT0PbvWk#Z{$Q%3Gy2pP1erOi_8cyuBpt z;4vDcr>6HNCMWYy^br9}n|0h-KpZ|&Rf`*3mt%}rdBR>dNrMrXy?uRIF66q$w~tcD z$1;Jhf7!6!6}8j`d33_EpO8xy;%1E#4M|#NgF5mhad#OCiTIedW--#-zCl!ZNBOnf z>=^=!xBWs^37~O&>esu$R%_6(+T+Qvo^Kxt7rEgf_UOU1r{0>`6+9^>XUi1&qGRD_ zYs;)g&hh7?TbE6t`n>{Onbsr;Ny$H%>vjL$UiIDK*z)_c#oGf0)hso9*?J>I#W6T9 zFR!j@rW_g&11F&~Co#CIh)Hgkc)7zJ)Kk)Q=a|H*Z_r}LSF4)MFF+DId}yhE|DI0u zj=;DN@4sY+fl3sezSPF0X|`pq8YzfN_v*%g2@~zz83U9E89c*b5EWy`EA~E>vQ>~D zfxjZq52bmeP0UizPqb*>qtGq%2b|n($DKzUTOveH&jitjY5=~mPAHu{4abs!&CP(Q zsHjf6e`))jKf(oq0iS!lEz3quNz6HkH{Q+~XCRtNxl1gkScJ+;WDTrXqP|BOV9sIU zi~(YreHIlnphV#7kM{_7E1d%}0s;ab=2E^!>zSvF-8L#>WigURv66);`}h7J zQJ(pa9iw96IOn*f!nL}0Zd`X6`&aD#iL&8uK>#6!Z_3%Izpf%~biKm7keFzus6B^|a0ZEV8$w)7MyM{$--_I-=U}1dxZDZT;5RD%U zowpyl)8l9)mGY@-ss5pDgfIkc z!Mt5X71u*ADNIz}rqxylI6w|7a~PeX@Gx;9Ib---s3f4pY!Fe995XNw!N`?~yp#s4 zqKPl7ZEPHMbK{aDq_gOxND^f7TuM>w!`ZkP_DqLB=z{nmm+n=1XAX5BD;>9Bp#SP1 z9Y(ZkII3GVD6$RS!t{|};Gnt@dtF`XwqcM+!OLL8)E4A~J_WOS3*onC|6-iXJ z2PEh7bQeA7Rz7a7n2)aohwXFAFE--_WU7D{t^;v?fzGb3owux$tT^)hl#C1X#_f6EhIgS z1cxd7D;R{oUDJ%x&_3ekW77kWBa->xOIyBsv5ui5sYm^2ClNFd7@%TT#{A+=ywik zpgDDMX)wW))r3LDLd?UKW>C*N<06fX_7mUiL!$Dv;Ro)WWWRaOqqna5H5%8Ma9fUB zeD>dcL5*`^JjWdQ_@Tp0p@rVZS5=8v z>T<1p-hXE(iWW1Xc$g->0$qz|DZt<-<-w zbX66Gd7Ze!%7(_qR!=cXpDg2d?bsT*8&A;>(6vh?m2w?2RoE<_MV6otblSqg%ThtX z$o~Q>W?Q`LN7E4=hVq^4R$O;r8tjxgwBOYzs7zkCf8<<$h~XGn!W3F8z{>AEnABYJ zi;okY4x$*A9Oszo3fbqjUvWCyY&8*b*&7`h496l{hDH&m+vmQ+`Cu|Lxw5jdXY=2- z96)j;F83aCJZGsjZ#5N-0{mf6GZ&6QReiZxw^<|Reb?6RQD$agrE@l_vkNT{K#%U6dp~R4gAP4S_aDrSp#X5f9N$hkj5gu z|2ve}a`vH9(w1g?8&QZ#(C#<4p21tRNM@qtS?k0Tk$j%CQu#Q@0^Ba;&0v+2o`-}Y zw6uqr4x3U4w{F1xTKvp%;)rV$ASi@c@8VNStUzYmAJGQwh8N)E#Ltsehs4+~^N z@)gv>Rgv0K_`!v(!PEfXhs9#E>urGJ+RgQ9BqKa>wDQe|KJ^V&e+zzgY5IwGy+QG|DODXQ5{dP`78-%R}LUK7nV1Y6k zr6@v2>p}h3bY#asvmpZ5KLXo*u9Aj$=IFvf1tvah!hFl76Y<9O5=SHX!bex>?83zJ zOtlvUgYwT^|F%RpSSVa_=4mHr0D(88bZR8H(S3!JC4*y)i-Y|kNV7eDJ}UX*uRAYt zkAB>fB#*YXwmMS3eBCd*=L2R*C(kaTJeD4I?S7SnD&Ah!RknZHw56dWGbr|m0Z$i62M&MiBysWx7h&2hc9;a zuFR#ML}&6-EQRv9(yaNj^Sd1eN*0&zE-5OqmWg^WBj#Zm$6}y6`6Q*)Wnbx|9;jgc zgwuU|q2$nae^GY}vOG{AV5*elr&FgNt6i=Ze2B1?zK79hGfN|Ah?x2%1*6?cR&L?KZgfl!VG_=_~IKli0VXjm*qy%0-Rom&6fT0_K|Gb(;UKnDkMvE`@^)A+H&OLh*!3iIKe zl;DSolv{9Nk3B_Yal^xo#C=8|zahmED*gf2x7O~;%AfrTqjY@H;;NYV06L{8aj|@C zIK9Yck=Ko5x4lsuz1}w?K;JEgXgn8q#1x9-qmz>hget6kssgb?WvW!>(_ko7O*iou zVo=ElBxK7%dyKu&l5Q^>k_7<35bgs@Z;w(m4kq-0-|VbwVfht|o_0-`M0`7D?xQQt zEAcNXnCk|%eXc;|e3%gseOK>lG@HcJ)*TaaYjiXz3i0m`@o(qN3d^$Dda5-sb(oK{ ztl9F12e6)TTd7m*)xWpZNMUFIOpJjySu6j#ZMe+uhc@1 zn$A+wO&(DIFUB01!VU&lo$LP5Oi@$Jr39HIBvs)Uoo0v7S6U)@wyC_b z!|po`h|MeSeZ#z-m7LQl@b3giPt(VbI%~H4*;s;S_tQa=TS|c+t*orr4LaP8#ifHQ zNWzj)MLy|%ir3DV`=;f+mXz7-JG=8!qWk%xbM5)EHvlxExp97Nfg}Bg@5|Czy>-4< zOG(c@D?P6$pzANanJUk3gYIx&N=i|WmWmsw#$)wEn52dBYG<|?BHB6|6;SQ5RjzHW z@Ev9RoICHO74P!=zHk3i->l8vzCuN0xq#r+20PY35(@~us>f|N6GLs%=*vhIRj0;B z=Kf>L1U&QG`q2ht{Tq3R!hC{JP2=^!HtI$7045-fRXI%V7kP_86>9A9ad#HKL(%6R zUxc1F@55_xzh||t>rX|FFaEv1%{)|E3~JOhq~TKLYQ*d6M#gq_mMJ~Af~;b=@KspI z^>mC|G&C(LXKnbo!bqT+B+=K6msv}|)~y#uO+~H$npLCNkaJEd(ZAQP@tp-_Wd}Vm zG3Y1PZK{w?KP{+I;hHjMm`4PGW+c!f_vZ08*37iuZA~gu&c~JF>S}u&@Z{+23u6&e z3loULL=Ze26Wz%6yQHNBq9-f+6Rm;nVcD*!RCFf#FB@1A73HPP->U0ftkPBW3?VN> zjNh1&mm=xZw-=uE_rc&inW3NttF$H{e+WCFND;9JenkwGNs6K|ayPgvZm?Kpi6y3R zX@r_tGWK)7$foDjD5=Ojf__opuK0YPklRA`V&Kap1$W#*u+EBhH}Zn$H4`%NIs< z{9l&bzR`_&K__*vyE$e)@xCUNMyE{+>Kk@7ne_T&X(^=|c$_Z+63UiAp<3y)7CG}-FL zd44H%$JJh`Yh8z|-X;HJB=Wf2@M{>rFKueNd-8v+H4hE6<^6Nn;eHA^98U!uvS;)b zH1t@aD*%I#0=)#_C`czh-@%GUHqV2jCQ|77o%XmuTdAH`zCTi6PCT zuozVN-q`1=7^u}!$~cs?EKcyP_k3Fi#@-gBOnregRiWIUIT3*D@r+4F#nk-gbVd=e z6r|wY67j>@l|1h!=9JXb^W#6wr!`P!%>!>NxDV-M%wZC~-uQRD>v%j@ie?!Tq*bXQ zJ+a|^$|m|e$wMsg){@U>a4wZTv3OWvP3QzltJ7O9u}#K!c=a2eg3^-QddJP4PJ%KE z?%_KCHZpu}!=hru73;m_xk8)lHSzpyHOH-*UO-7Gqi%&l{(Li}OT;FZ$gy$ie?WNE2--+tx zj6ve!GhQ_s>|9w%GkEbR85K4@TPG*0)kDgQ#&d*Re>LfAR~vQeR52;FsHH=SwrZto z3w}6p&ski-&L)7R zGaYghqkj>0JGyF^Ii&UPrGi63|LE&4QT6@%mbypQ6GN#ADS&z?7>_SF$4|LXOI{^U}MHY~+m`u~;nh9t*YV$Af6_fcQ%F)9la5`AKx%kRwFr2eXyQkkoE zXc9*$1}SG}V{^Sbnr%`}pSGnhE$zmaHM6ySGJ(OC)fCiETeY^bI=RSlB3f^A-u(m> z!D@cnzr|pW_a)SF%3{-N>h+kn-=DW`UR*vrb1>9{@$oFUaxNzIY}#nSiEcIk>cT=( z@{w8SS)wPD_dI^=_Vyn}wJ-7hsLmxIpsUyU_54a*;w2Cw5hGrXdcY8JNeZ{&<^$n4t27eDIF3zp27~eaqC0#Eyv5R$w=k zf17RX`q%7w$IBj=!Eg)_Ddy(U2H%QV3&WLq?Fge@a`7Z2KurC1e!!d8?Tq-dN(w=H zom%KVB9!+4BU!vACt@j^2W6Wz+pc7>!&AZ3J$_!r-vQ{pMP6tBNrk%iPdw|%zo-Ch#&z->fZ43#| z*6lM8acFQP{@r`Ut|oZaMkc$(0ZN3ghwyGS^z;;vfkT%M%Yx)_%|Czs9CggW>NbuK ztK)zN!pFbvqWs==^7T6URmkzzTa3MZ57$$aG9e)Z?79*cw4Jd@rJ8)@-5rsmb_nbo z#H<^kh2DWY&`L~+&>(xdg4wTxiXHTn*UdI=eA0mfV|L|Hjstw7Tz5>#JXJ*zQXG_h9+rA&tybF6CJu;}pL~mn8%bKTG99 z1NsIi9a%{hcO17keziaTN7dP|^ei{M}ZIo$bQ8 znFC%{22(BH6#8pTS+1Dri(L~XB!ma;_DC?l;{kue&+k{_Dl1naKb0| zqC9WGQ^pkiyO2%?KEBg0M$IGs0k-cxCDj;I6NeEMNsc-?f5i3>^COM7GY|BtRVm~b z1X0RSUAqve_hR_{UJ_@c(u1!_gi=Hmv7Z}-Y)Kn>^;>>4P1fe{k=;o2@BCDL6G?qT zqAzv$C-~&Uc|mwww-31qpG?S8nM@7?1?go|YU}~_hzsj@)b5-1>owrOz}~b#+>?o! zt@7%;yjMgZMmfuSx}sMy!{mTIO$V>0xY9B(<8Erl)!+nzxR_fUjtxIjOQqFzdjI zWsPI@IHt^|(J9IAsgo`JTIF&Nbi6e!n4>?Ialq}5-;TvncU_^T8p4bZPTFotQ zxz1U_I$kX%y!pKj2&V?jTvD1Z}!8eb<+RGB8{vb#GXIAl32BOHTlmPkb#r;=Je zny~+`hZeVZ8wEHzv2}f + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/org.jkiss.dbeaver.ext.spanner/pom.xml b/plugins/org.jkiss.dbeaver.ext.spanner/pom.xml new file mode 100644 index 0000000000..22db0c04f4 --- /dev/null +++ b/plugins/org.jkiss.dbeaver.ext.spanner/pom.xml @@ -0,0 +1,14 @@ + + + 4.0.0 + + org.jkiss.dbeaver + plugins + 1.0.0-SNAPSHOT + ../ + + org.jkiss.dbeaver.ext.spanner + 1.0.0-SNAPSHOT + eclipse-plugin + diff --git a/plugins/org.jkiss.dbeaver.ext.spanner/src/org/jkiss/dbeaver/ext/spanner/SpannerActivator.java b/plugins/org.jkiss.dbeaver.ext.spanner/src/org/jkiss/dbeaver/ext/spanner/SpannerActivator.java new file mode 100644 index 0000000000..3cda0fa05b --- /dev/null +++ b/plugins/org.jkiss.dbeaver.ext.spanner/src/org/jkiss/dbeaver/ext/spanner/SpannerActivator.java @@ -0,0 +1,57 @@ +/* + * DBeaver - Universal Database Manager + * Copyright (C) 2010-2019 Serge Rider (serge@jkiss.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jkiss.dbeaver.ext.spanner; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle + */ +public class SpannerActivator extends AbstractUIPlugin { + + // The plug-in ID + public static final String PLUGIN_ID = "org.jkiss.dbeaver.ext.spanner"; + + // The shared instance + private static SpannerActivator plugin; + + public SpannerActivator() { + + } + + @Override + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + } + + @Override + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + public static SpannerActivator getDefault() { + return plugin; + } + + public static ImageDescriptor getImageDescriptor(String path) { + return imageDescriptorFromPlugin(PLUGIN_ID, path); + } +} diff --git a/plugins/org.jkiss.dbeaver.ext.spanner/src/org/jkiss/dbeaver/ext/spanner/SpannerDataSourceProvider.java b/plugins/org.jkiss.dbeaver.ext.spanner/src/org/jkiss/dbeaver/ext/spanner/SpannerDataSourceProvider.java new file mode 100644 index 0000000000..f05103b1ba --- /dev/null +++ b/plugins/org.jkiss.dbeaver.ext.spanner/src/org/jkiss/dbeaver/ext/spanner/SpannerDataSourceProvider.java @@ -0,0 +1,63 @@ +/* + * DBeaver - Universal Database Manager + * Copyright (C) 2010-2019 Serge Rider (serge@jkiss.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jkiss.dbeaver.ext.spanner; + +import org.jkiss.code.NotNull; +import org.jkiss.dbeaver.DBException; +import org.jkiss.dbeaver.Log; +import org.jkiss.dbeaver.ext.spanner.model.SpannerDataSource; +import org.jkiss.dbeaver.ext.spanner.model.SpannerMetaModel; +import org.jkiss.dbeaver.ext.generic.GenericDataSourceProvider; +import org.jkiss.dbeaver.ext.generic.model.meta.GenericMetaModel; +import org.jkiss.dbeaver.model.DBPDataSource; +import org.jkiss.dbeaver.model.DBPDataSourceContainer; +import org.jkiss.dbeaver.model.app.DBPPlatform; +import org.jkiss.dbeaver.model.connection.DBPConnectionConfiguration; +import org.jkiss.dbeaver.model.connection.DBPDriver; +import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor; +import org.jkiss.utils.CommonUtils; + +public class SpannerDataSourceProvider extends GenericDataSourceProvider { + + private static final Log log = Log.getLog(SpannerDataSourceProvider.class); + + public SpannerDataSourceProvider() + { + } + + @Override + public void init(@NotNull DBPPlatform platform) { + + } + + @NotNull + @Override + public DBPDataSource openDataSource( + @NotNull DBRProgressMonitor monitor, + @NotNull DBPDataSourceContainer container) + throws DBException + { + return new SpannerDataSource(monitor, container, new SpannerMetaModel()); + } + + @Override + public String getConnectionURL(DBPDriver driver, DBPConnectionConfiguration connectionInfo) { + StringBuilder url = new StringBuilder(); + url.append("jdbc:cloudspanner://localhost;"); + return url.toString(); + } +} diff --git a/plugins/org.jkiss.dbeaver.ext.spanner/src/org/jkiss/dbeaver/ext/spanner/model/SpannerConstants.java b/plugins/org.jkiss.dbeaver.ext.spanner/src/org/jkiss/dbeaver/ext/spanner/model/SpannerConstants.java new file mode 100644 index 0000000000..7690d924a5 --- /dev/null +++ b/plugins/org.jkiss.dbeaver.ext.spanner/src/org/jkiss/dbeaver/ext/spanner/model/SpannerConstants.java @@ -0,0 +1,29 @@ +/* + * DBeaver - Universal Database Manager + * Copyright (C) 2010-2019 Serge Rider (serge@jkiss.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jkiss.dbeaver.ext.spanner.model; + +/** + * Snowflake constants + */ +public class SpannerConstants { + + public static final String DRIVER_PROP_PROJECT_ID = "Project"; + public static final String DRIVER_PROP_INSTANCE_ID = "Instance"; + public static final String DRIVER_PROP_DATABASE_ID = "Database"; + public static final String DRIVER_PROP_PVTKEYPATH = "PvtKeyPath"; + +} diff --git a/plugins/org.jkiss.dbeaver.ext.spanner/src/org/jkiss/dbeaver/ext/spanner/model/SpannerDataSource.java b/plugins/org.jkiss.dbeaver.ext.spanner/src/org/jkiss/dbeaver/ext/spanner/model/SpannerDataSource.java new file mode 100644 index 0000000000..d37a21d776 --- /dev/null +++ b/plugins/org.jkiss.dbeaver.ext.spanner/src/org/jkiss/dbeaver/ext/spanner/model/SpannerDataSource.java @@ -0,0 +1,49 @@ +/* + * DBeaver - Universal Database Manager + * Copyright (C) 2010-2019 Serge Rider (serge@jkiss.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jkiss.dbeaver.ext.spanner.model; + +import org.jkiss.dbeaver.DBException; +import org.jkiss.dbeaver.ext.generic.model.GenericDataSource; +import org.jkiss.dbeaver.model.DBPDataSourceContainer; +import org.jkiss.dbeaver.model.connection.DBPConnectionConfiguration; +import org.jkiss.dbeaver.model.connection.DBPDriver; +import org.jkiss.dbeaver.model.exec.DBCException; +import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor; + +import java.util.HashMap; +import java.util.Map; + +public class SpannerDataSource extends GenericDataSource { + + public SpannerDataSource(DBRProgressMonitor monitor, DBPDataSourceContainer container, SpannerMetaModel metaModel) + throws DBException + { + super(monitor, container, metaModel, new SpannerSQLDialect()); + } + + @Override + protected Map getInternalConnectionProperties(DBRProgressMonitor monitor, DBPDriver driver, String purpose, DBPConnectionConfiguration connectionInfo) throws DBCException { + Map props = new HashMap<>(); + props.put(SpannerConstants.DRIVER_PROP_PROJECT_ID, connectionInfo.getServerName()); + props.put(SpannerConstants.DRIVER_PROP_INSTANCE_ID, connectionInfo.getHostName()); + props.put(SpannerConstants.DRIVER_PROP_DATABASE_ID, connectionInfo.getDatabaseName()); + props.put(SpannerConstants.DRIVER_PROP_PVTKEYPATH, connectionInfo.getProviderProperty(SpannerConstants.DRIVER_PROP_PVTKEYPATH)); + + return props; + } + +} diff --git a/plugins/org.jkiss.dbeaver.ext.spanner/src/org/jkiss/dbeaver/ext/spanner/model/SpannerMetaModel.java b/plugins/org.jkiss.dbeaver.ext.spanner/src/org/jkiss/dbeaver/ext/spanner/model/SpannerMetaModel.java new file mode 100644 index 0000000000..1de055d03a --- /dev/null +++ b/plugins/org.jkiss.dbeaver.ext.spanner/src/org/jkiss/dbeaver/ext/spanner/model/SpannerMetaModel.java @@ -0,0 +1,59 @@ +/* + * DBeaver - Universal Database Manager + * Copyright (C) 2010-2019 Serge Rider (serge@jkiss.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jkiss.dbeaver.ext.spanner.model; + +import org.jkiss.code.NotNull; +import org.jkiss.code.Nullable; +import org.jkiss.dbeaver.ext.generic.model.meta.GenericMetaModel; +import org.jkiss.dbeaver.model.DBPErrorAssistant; +import org.jkiss.dbeaver.model.exec.DBCQueryTransformProvider; +import org.jkiss.dbeaver.model.exec.DBCQueryTransformType; +import org.jkiss.dbeaver.model.exec.DBCQueryTransformer; +import org.jkiss.dbeaver.model.impl.sql.QueryTransformerLimit; +import org.jkiss.utils.CommonUtils; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Spanner meta model + */ +public class SpannerMetaModel extends GenericMetaModel { + + private Pattern ERROR_POSITION_PATTERN = Pattern.compile(" at \\[([0-9]+)\\:([0-9]+)\\]"); + + public SpannerMetaModel() { + } + +/* + @Override + public DBPErrorAssistant.ErrorPosition getErrorPosition(Throwable error) { + String message = error.getMessage(); + if (!CommonUtils.isEmpty(message)) { + Matcher matcher = ERROR_POSITION_PATTERN.matcher(message); + if (matcher.find()) { + DBPErrorAssistant.ErrorPosition pos = new DBPErrorAssistant.ErrorPosition(); + pos.line = Integer.parseInt(matcher.group(1)) - 1; + pos.position = Integer.parseInt(matcher.group(2)) - 1; + return pos; + } + } + return null; + } +*/ + +} diff --git a/plugins/org.jkiss.dbeaver.ext.spanner/src/org/jkiss/dbeaver/ext/spanner/model/SpannerSQLDialect.java b/plugins/org.jkiss.dbeaver.ext.spanner/src/org/jkiss/dbeaver/ext/spanner/model/SpannerSQLDialect.java new file mode 100644 index 0000000000..e06a51a075 --- /dev/null +++ b/plugins/org.jkiss.dbeaver.ext.spanner/src/org/jkiss/dbeaver/ext/spanner/model/SpannerSQLDialect.java @@ -0,0 +1,28 @@ +/* + * DBeaver - Universal Database Manager + * Copyright (C) 2010-2019 Serge Rider (serge@jkiss.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jkiss.dbeaver.ext.spanner.model; + +import org.jkiss.dbeaver.ext.generic.model.GenericSQLDialect; + +/** + * Snowflake constants + */ +public class SpannerSQLDialect extends GenericSQLDialect { + public SpannerSQLDialect() { + super("Spanner"); + } +} diff --git a/plugins/org.jkiss.dbeaver.ext.spanner/src/org/jkiss/dbeaver/ext/spanner/views/SpannerConnectionPage.java b/plugins/org.jkiss.dbeaver.ext.spanner/src/org/jkiss/dbeaver/ext/spanner/views/SpannerConnectionPage.java new file mode 100644 index 0000000000..ee3edd83ac --- /dev/null +++ b/plugins/org.jkiss.dbeaver.ext.spanner/src/org/jkiss/dbeaver/ext/spanner/views/SpannerConnectionPage.java @@ -0,0 +1,159 @@ +/* + * DBeaver - Universal Database Manager + * Copyright (C) 2010-2019 Serge Rider (serge@jkiss.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jkiss.dbeaver.ext.spanner.views; + +import org.eclipse.jface.dialogs.IDialogPage; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Text; +import org.jkiss.dbeaver.Log; +import org.jkiss.dbeaver.ext.spanner.SpannerActivator; +import org.jkiss.dbeaver.ext.spanner.model.SpannerConstants; +import org.jkiss.dbeaver.model.DBPDataSourceContainer; +import org.jkiss.dbeaver.model.connection.DBPConnectionConfiguration; +import org.jkiss.dbeaver.ui.ICompositeDialogPage; +import org.jkiss.dbeaver.ui.UIUtils; +import org.jkiss.dbeaver.ui.controls.TextWithOpenFile; +import org.jkiss.dbeaver.ui.dialogs.connection.ConnectionPageAbstract; +import org.jkiss.dbeaver.ui.dialogs.connection.DriverPropertiesDialogPage; +import org.jkiss.utils.CommonUtils; + +import java.util.Locale; + +/** + * SpannerConnectionPage + */ +public class SpannerConnectionPage extends ConnectionPageAbstract implements ICompositeDialogPage +{ + private static final Log log = Log.getLog(SpannerConnectionPage.class); + + private Text projectText; + private Text instanceText; + private Text databaseText; + private TextWithOpenFile privateKeyFile; + + private static ImageDescriptor logoImage = SpannerActivator.getImageDescriptor("icons/spanner_logo.png"); //$NON-NLS-1$ + private DriverPropertiesDialogPage driverPropsPage; + + public SpannerConnectionPage() { + driverPropsPage = new DriverPropertiesDialogPage(this); + } + + @Override + public void dispose() + { + super.dispose(); + } + + @Override + public void createControl(Composite composite) + { + setImageDescriptor(logoImage); + + Composite settingsGroup = new Composite(composite, SWT.NONE); + settingsGroup.setLayout(new GridLayout(1, false)); + settingsGroup.setLayoutData(new GridData(GridData.FILL_BOTH)); + ModifyListener textListener = e -> site.updateButtons(); + + { + Composite addrGroup = UIUtils.createControlGroup(settingsGroup, SpannerMessages.label_connection, 2, 0, 0); + addrGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + projectText = UIUtils.createLabelText(addrGroup, SpannerMessages.label_project, ""); //$NON-NLS-2$ + projectText.addModifyListener(textListener); + + instanceText = UIUtils.createLabelText(addrGroup, "Instance", ""); //$NON-NLS-2$ + instanceText.setToolTipText("Spanner Instance ID"); //$NON-NLS-1$ + instanceText.addModifyListener(textListener); + + databaseText = UIUtils.createLabelText(addrGroup, "Database", ""); //$NON-NLS-2$ + databaseText.setToolTipText("Spanner Database ID"); //$NON-NLS-1$ + databaseText.addModifyListener(textListener); + + UIUtils.createControlLabel(addrGroup, SpannerMessages.label_private_key_path); + privateKeyFile = new TextWithOpenFile(addrGroup, SpannerMessages.label_private_key_path, new String[] { "*", "*.json" } ); //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL); + //gd.horizontalSpan = 3; + privateKeyFile.setLayoutData(gd); + } + + createDriverPanel(settingsGroup); + setControl(settingsGroup); + } + + @Override + public boolean isComplete() + { + return projectText != null && !CommonUtils.isEmpty(projectText.getText()) && + instanceText != null && !CommonUtils.isEmpty(instanceText.getText()) && + databaseText != null && !CommonUtils.isEmpty(databaseText.getText()); + } + + @Override + public void loadSettings() + { + super.loadSettings(); + + // Load values from new connection info + DBPConnectionConfiguration connectionInfo = site.getActiveDataSource().getConnectionConfiguration(); + if (projectText != null) { + projectText.setText(CommonUtils.notEmpty(connectionInfo.getServerName())); + } + if (instanceText != null) { + instanceText.setText(CommonUtils.notEmpty(connectionInfo.getHostName())); + } + if (databaseText != null) { + databaseText.setText(CommonUtils.notEmpty(connectionInfo.getDatabaseName())); + } + if (privateKeyFile != null) { + privateKeyFile.setText(CommonUtils.notEmpty(connectionInfo.getProviderProperty(SpannerConstants.DRIVER_PROP_PVTKEYPATH))); + } + } + + @Override + public void saveSettings(DBPDataSourceContainer dataSource) + { + DBPConnectionConfiguration connectionInfo = dataSource.getConnectionConfiguration(); + if (projectText != null) { + connectionInfo.setServerName(projectText.getText().trim()); + } + if (instanceText != null) { + connectionInfo.setHostName(instanceText.getText().trim()); + } + if (databaseText != null) { + connectionInfo.setDatabaseName(databaseText.getText().trim()); + } + if (privateKeyFile != null) { + connectionInfo.setProviderProperty(SpannerConstants.DRIVER_PROP_PVTKEYPATH, privateKeyFile.getText()); + } + super.saveSettings(dataSource); + } + + @Override + public IDialogPage[] getSubPages(boolean extrasOnly) + { + return new IDialogPage[] { + driverPropsPage + }; + } + +} diff --git a/plugins/org.jkiss.dbeaver.ext.spanner/src/org/jkiss/dbeaver/ext/spanner/views/SpannerMessages.java b/plugins/org.jkiss.dbeaver.ext.spanner/src/org/jkiss/dbeaver/ext/spanner/views/SpannerMessages.java new file mode 100644 index 0000000000..dadedd8cd5 --- /dev/null +++ b/plugins/org.jkiss.dbeaver.ext.spanner/src/org/jkiss/dbeaver/ext/spanner/views/SpannerMessages.java @@ -0,0 +1,18 @@ +package org.jkiss.dbeaver.ext.spanner.views; + +import org.eclipse.osgi.util.NLS; + +public class SpannerMessages extends NLS { + private static final String BUNDLE_NAME = "org.jkiss.dbeaver.ext.spanner.views.messages"; //$NON-NLS-1$ + + public static String label_connection; + public static String label_private_key_path; + public static String label_project; + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, SpannerMessages.class); + } + + private SpannerMessages() { + } +} diff --git a/plugins/org.jkiss.dbeaver.ext.spanner/src/org/jkiss/dbeaver/ext/spanner/views/messages.properties b/plugins/org.jkiss.dbeaver.ext.spanner/src/org/jkiss/dbeaver/ext/spanner/views/messages.properties new file mode 100644 index 0000000000..c8227d0a50 --- /dev/null +++ b/plugins/org.jkiss.dbeaver.ext.spanner/src/org/jkiss/dbeaver/ext/spanner/views/messages.properties @@ -0,0 +1,3 @@ +label_connection=Connection +label_private_key_path=Private key path (p12 or JSON) +label_project=Project diff --git a/plugins/org.jkiss.dbeaver.ext.spanner/src/org/jkiss/dbeaver/ext/spanner/views/messages_ru.properties b/plugins/org.jkiss.dbeaver.ext.spanner/src/org/jkiss/dbeaver/ext/spanner/views/messages_ru.properties new file mode 100644 index 0000000000..cbbdf91025 --- /dev/null +++ b/plugins/org.jkiss.dbeaver.ext.spanner/src/org/jkiss/dbeaver/ext/spanner/views/messages_ru.properties @@ -0,0 +1,3 @@ +label_connection=\u0421\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u0435 +label_private_key_path=\u041F\u0443\u0442\u044C \u043A \u0437\u0430\u043A\u0440\u044B\u0442\u043E\u043C\u0443 \u043A\u043B\u044E\u0447\u0443 (p12 \u0438\u043B\u0438 JSON) +label_project=\u041F\u0440\u043E\u0435\u043A\u0442 diff --git a/plugins/pom.xml b/plugins/pom.xml index f306f7445b..f51274eb65 100644 --- a/plugins/pom.xml +++ b/plugins/pom.xml @@ -81,6 +81,7 @@ org.jkiss.dbeaver.ext.snowflake.core org.jkiss.dbeaver.ext.snowflake.ui + org.jkiss.dbeaver.ext.spanner org.jkiss.dbeaver.ext.sqlite org.jkiss.dbeaver.ext.vertica org.jkiss.dbeaver.ext.vertica.ui -- GitLab