1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346
|
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
-
- This file is part of the OpenLink Software Virtuoso Open-Source (VOS)
- project.
-
- Copyright (C) 1998-2018 OpenLink Software
-
- This project is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the
- Free Software Foundation; only version 2 of the License, dated June 1991.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-
-->
<sect1 id="createassembly"><title>CREATE ASSEMBLY Syntax - External Libraries</title>
<para>External CLR libraries can be hosted inside Virtuoso by creating an assembly
from the library itself using the syntax as follows:</para>
<programlisting><![CDATA[
CREATE ASSEMBLY <assembly_name> FROM <assembly_location>
[WITH PERMISSION_SET = <perm>] [WITH AUTOREGISTER];
]]></programlisting>
<simplelist>
<member><emphasis>assembly_name</emphasis> - is how Virtuoso will reference the library.</member>
<member><emphasis>assembly_location</emphasis> - is where Virtuoso will find the library within the CLR.</member>
</simplelist>
<para>Every .NET assembly deployed inside Virtuoso will be verifiable, which
means it will contain code the CLR can verify to be safe in the way it writes
to memory. </para>
<para>Virtuoso also respects the Common Language Runtime's code access
security model. By default, code does not have any permissions to create a
graphical user interface, create threads, access the file system, or call
unmanaged code. The only permissions implemented are those granted for
in-process data access.</para>
<para>Administrators will control the permissions granted to assemblies using a
standard .NET machine and user-level security policy. At runtime, any code
accessing protected resources produces a stack walk that triggers a permissions
check against that code and any code that called it.</para>
<para>To simplify security administration, Virtuoso supports these standard
permission sets for .NET assemblies:</para>
<simplelist>
<member><emphasis>SAFE</emphasis> - This is the default permission set.
It allows internal computation and data access. There is no access to resources outside
of Virtuoso. Calls to unmanaged code are not allowed. Code must be verifiable.</member>
<!-- member><emphasis>EXTERNAL_ACCESS</emphasis> - The caller has to have these
added permissions to create tables, assemblies, or other objects. </member -->
<member><emphasis>UNRESTRICTED</emphasis> - Code can access any resource.
Only system administrators (dba group/role) can run unrestricted code. This level allows
calls to unmanaged code, and can be unverifiable.</member>
</simplelist>
<para>The restricted assemblies (SAFE mode) are not permitted to execute
any code that infringes upon any of the following permissions:</para>
<simplelist>
<member>AspNetHostingPermission</member>
<member>EnvironmentPermission </member>
<member>FileIOPermission</member>
<member>IsolatedStoragePermission</member>
<member>ReflectionPermission</member>
<member>RegistryPermission</member>
<member>SecurityPermission</member>
<member>SocketPermission</member>
<member>WebPermissionPermission</member>
<member>DNSPermission</member>
<member>PrintingPermission</member>
<member>OleDBPermissionPermission</member>
<member>SqlClientPermissionPermission</member>
<member>EventLogPermission</member>
<member>MessageQueuePermission</member>
<member>ServiceControllerPermission</member>
<member>PerformanceCountersPermission </member>
<member>DirectoryServicePermission</member>
</simplelist>
<para>If the assembly generates a security exception the error text
will be returned to the client.</para>
<note><title>Note:</title>
<para>Currently on the Microsoft .Net Framework implementation supports
permission sets. Virtuoso does not currently support the
<computeroutput>EXTERNAL_ACCESS</computeroutput> permission set.</para></note>
<para><emphasis>WITH AUTOREGISTER</emphasis> marks the assembly as a stored
procedure, trigger, user-defined function, etc., based on custom attributes you add
to your .NET code.</para>
<para>Assemblies are stored in the database and are therefore backed-up
and restored with the data. Once assemblies are registered using the
<computeroutput>CREATE ASSEMBLY</computeroutput> syntax there will be no
further dependency on the library file (dll or exe) itself. </para>
<para>You can remove assemblies using the familiar SQL DROP statement: </para>
<programlisting><![CDATA[
DROP ASSEMBLY <assembly_name>;
]]></programlisting>
<tip><title>See Also:</title>
<para><link linkend="fn_import_clr">import_clr()</link></para></tip>
<example id="ex_createassembly"><title>Working with assemblies</title>
<para>This example is based on the tutorial HO_S_10. we start by obtaining a C#
library compile from the following code (included in the tutorial):</para>
<programlisting><![CDATA[
using System;
[Serializable]
public class Point_10
{
public Double x;
public Double y;
public Point_10 ()
{
x = 0;
y = 0;
}
public Point_10 (Double new_x, Double new_y)
{
x = new_x;
y = new_y;
}
public Double distance (Point_10 p)
{
Double ret;
ret = Math.Sqrt ((p.x - this.x) * (p.x - this.x) + (p.y - this.y) * (p.y - this.y));
return ret;
}
}
]]></programlisting>
<para>This gives us the Point_10 class with two constructors and one method
for finding the distance between two points.</para>
<para>Now we must create the library reference in Virtuoso using the following:</para>
<programlisting><![CDATA[
DROP ASSEMBLY "myPoint";
CREATE ASSEMBLY "myPoint" as concat (http_root() , '\\tutorial\\hosting\\ho_s_10\\Point_ho_s_10.dll')
WITH PERMISSION_SET = SAFE WITH AUTOREGISTER;
]]></programlisting>
<para>Now for a quick test, we will find the distance between two points:</para>
<programlisting><![CDATA[
SQL> select new Point_10(0,0).distance(Point_10(3,4));
callret
DOUBLE PRECISION
_______________________________________________________
5
]]></programlisting>
<para>Now we will create a table with a column of type Point_10 and then insert
some test data:</para>
<programlisting><![CDATA[
drop table CLR..Supplier_ho_s_10;
create table CLR..Supplier_ho_s_10 (id integer primary key, name varchar (20), location Point_10);
insert into CLR..Supplier_ho_s_10 (id, name, location) values (1, 'S1', new Point_10 (1, 1));
insert into CLR..Supplier_ho_s_10 (id, name, location) values (2, 'S2', new Point_10 (3, 3));
insert into CLR..Supplier_ho_s_10 (id, name, location) values (3, 'S3', new Point_10 (5, 5));
]]></programlisting>
<para>Now we will demonstrate how this assembly's class can be used in SQL by
showing some queries on the sample data:</para>
<programlisting><![CDATA[
SQL> select name, s.location.x from CLR..Supplier_ho_s_10 s;
name callret
VARCHAR DOUBLE PRECISION
_______________________________________________________________________________
S1 1
S2 3
S3 5
]]></programlisting>
<para>The distances from (0, 0):</para>
<programlisting><![CDATA[
SQL> select name, s.location.distance(Point_10(0,0)) from CLR..Supplier_ho_s_10 s ;
name callret
VARCHAR DOUBLE PRECISION
_______________________________________________________________________________
S1 1.414213562373095
S2 4.242640687119285
S3 7.071067811865476
]]></programlisting>
<para>Now, the points that are more than 3 units away from it:</para>
<programlisting><![CDATA[
SQL> select name from CLR..Supplier_ho_s_10 s where s.location.distance(Point_10(0,0)) > 3;
name
VARCHAR
_______________________________________________________________________________
S2
S3
]]></programlisting>
</example>
<example id="ex_createassembly2"><title>Using CREATE ASSEMBLY</title>
<para>This example demonstrates the creation of trivial CLR
classes and referencing them from Virtuoso.</para>
<itemizedlist>
<listitem><emphasis>lib.cs</emphasis>
<programlisting><![CDATA[
namespace lib
{
public class t1
{
public static int addit (int a1, int a2) { return a1 + a2; }
}
}
]]></programlisting>
</listitem>
<listitem><emphasis>exe.cs</emphasis>
<programlisting><![CDATA[
using lib;
public class exe
{
public static int call_addit (int a1, int a2)
{
return t1.addit (a1, a2);
}
public static void Main (String [] args)
{
Console.WriteLine ("result=" + call_addit (12, 13));
}
}
]]></programlisting>
</listitem>
<listitem><emphasis>compilation</emphasis>
<programlisting><![CDATA[
csc /t:library lib.cs
csc /r:lib.dll exe.cs
]]></programlisting>
</listitem>
<listitem><emphasis>Now Virtuoso can use</emphasis>
<programlisting><![CDATA[
create assembly sql_lib from 'c:\sample\lib.dll'
create assembly sql_exe from 'c:\sample\exe.exe'
]]></programlisting>
</listitem>
</itemizedlist>
</example>
<example id="ex_ctasspermset"><title>Creating Assemblies with Permission Sets</title>
<para>These examples will use an assembly called test.dll, whose source code is:</para>
<programlisting><![CDATA[
using System;
using System.IO;
public class Sample
{
public static String GetEnv ()
{
return Environment.GetEnvironmentVariable("PATH");
}
}
]]></programlisting>
<para>The assembly will be registered using:</para>
<programlisting><![CDATA[
CREATE ASSEMBLY "test" from 'test.dll' WITH PERMISSION_SET = SAFE WITH AUTOREGISTER;
]]></programlisting>
<para>and subsequently called using:</para>
<programlisting><![CDATA[
SQL> select Sample::GetEnv ();
]]></programlisting>
<para>returning the following error for attempting to exceed the SAFE permission set.</para>
<programlisting><![CDATA[
*** Error 42000: [Virtuoso Driver][Virtuoso Server]CLR05: Request for the permission of type System.Security.Permissions.EnvironmentPermission,
mscorlib, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 failed.
in
__udt_method_call:(BIF),
<Top Level>
at line 4 of Top-Level:
select Sample::GetEnv ()
]]></programlisting>
<para>Now we can try the same sample using PERMISSION_SET = UNRESTRICTED.</para>
<programlisting><![CDATA[
drop ASSEMBLY "test";
CREATE ASSEMBLY "test" from 'test.dll' WITH PERMISSION_SET = UNRESTRICTED WITH AUTOREGISTER;
SQL> select Sample::GetEnv ();
callret
VARCHAR
_______________________________________________________________________________
D:\Virtuoso\bin...;
1 Rows. -- 32 msec.
<]]></programlisting>
<para>Unrestricted assemblies do not have any restrictions on usage.</para>
</example>
</sect1>
|