|
|
|
Valued Member
      
Group: General Forum Members
Last Login: Wednesday, January 09, 2013 10:15 AM
Points: 61,
Visits: 691
|
|
|
|
|
|
Mr or Mrs. 500
      
Group: General Forum Members
Last Login: Friday, February 15, 2013 7:29 AM
Points: 509,
Visits: 718
|
|
While I like the idea, I'm not sure about storing the drive information in a static field - you would be much better off declaring a class or struct in which to return results, using a generic List<> to store your instances, and return the data from there.
That way, you don't need the UNSAFE permission set, and achieve exactly the same thing.
Edit -> Ok, you still need UNSAFE because of the permissions required by the DriveInfo class, but I still wouldn't use a static
Atlantis Interactive - SQL Server Tools My blog Why I wrote a sql query analyzer clone
|
|
|
|
|
Valued Member
      
Group: General Forum Members
Last Login: Wednesday, February 06, 2013 4:46 AM
Points: 55,
Visits: 391
|
|
| Nice idea.thanks for sharing
|
|
|
|
|
Hall of Fame
       
Group: General Forum Members
Last Login: Today @ 8:50 AM
Points: 3,572,
Visits: 5,106
|
|
Nice stuff. Did I miss the link where I can download the source code and/or compiled object??
Best,
Kevin G. Boles SQL Server Consultant SQL MVP 2007-2012 TheSQLGuru at GMail
|
|
|
|
|
SSChampion
        
Group: General Forum Members
Last Login: Yesterday @ 12:22 PM
Points: 10,571,
Visits: 11,871
|
|
|
|
|
|
Valued Member
      
Group: General Forum Members
Last Login: Wednesday, January 09, 2013 10:15 AM
Points: 61,
Visits: 691
|
|
|
|
|
|
Mr or Mrs. 500
      
Group: General Forum Members
Last Login: Friday, February 15, 2013 7:29 AM
Points: 509,
Visits: 718
|
|
Jack
For going out to the OS, you generally can use EXTERNAL_ACCESS. In this instance, you actually do need UNSAFE - because of the permissions that are required to use DriveInfo under CAS. I usually check these things before I open my big mouth! :)
But I still wouldn't use a static field even so, seeing as the static field's life time will extend beyond the execution of the function (for example, if you use a singleton under UNSAFE, you can observe that it's lifetime is longer than that of the call into the CLR - subsequent calls to the same function would use the same instance).
Anyway, the code I would use would look like this:
sealed class _driveInfo { public readonly string DriveName; public readonly long TotalSizeMB; public readonly long UsedSizeMB; public readonly long FreeSizeMB; public readonly long PercentUsed;
public _driveInfo(string driveName, long totalSizeMB, long usedSizeMB, long freeSizeMB, long percentUsed) { DriveName = driveName; TotalSizeMB = totalSizeMB; UsedSizeMB = usedSizeMB; FreeSizeMB = freeSizeMB; PercentUsed = percentUsed; } }
[Microsoft.SqlServer.Server.SqlFunction ( FillRowMethodName = "_f_fill", TableDefinition = "Drive nvarchar(3), SizeMb bigint, UsedMb bigint, AvailableMb bigint, UsePct bigint" ) ] public static IEnumerable fn_fixeddrives() { foreach (DriveInfo d in DriveInfo.GetDrives()) { if (d.DriveType == DriveType.Fixed && d.IsReady) { yield return new _driveInfo(d.Name, (d.TotalSize) / 1048576, (d.TotalSize - d.TotalFreeSpace) / 1048576, (d.TotalFreeSpace) / 1048576, (d.TotalFreeSpace * 100) / d.TotalSize); } } }
private static void _f_fill(Object o, out string drvName, out long totalsizeMb, out long usedsizeMb, out long freesizeMb, out long pctused) { _driveInfo dI = (_driveInfo)o; drvName = dI.DriveName; totalsizeMb = dI.TotalSizeMB; usedsizeMb = dI.UsedSizeMB; freesizeMb = dI.FreeSizeMB; pctused = dI.PercentUsed; }
Atlantis Interactive - SQL Server Tools My blog Why I wrote a sql query analyzer clone
|
|
|
|
|
Valued Member
      
Group: General Forum Members
Last Login: Wednesday, January 09, 2013 10:15 AM
Points: 61,
Visits: 691
|
|
Hi Matt,
I agree using a static field will force the assembly to be considered as UNSAFE, but diving into the IO system would lead to the same path anyway.
I use a static field because I need the list to be available outside of the main scope, especially in the fill method. What you will usually see in sqlclr developments is to pass the full object to the fill method, because it is more convenient, but you'll have to call a DriveInfo constructor to get the job done. The idea in this example was to pass a simple array pointing to fixed and ready drives, so you save a call to the object's ctor. And remember a call to the object's ctor will be called every time a row is fetched from the list.
Appreciate for the comments ,
David B.
|
|
|
|
|
SSCrazy
      
Group: General Forum Members
Last Login: Yesterday @ 8:51 AM
Points: 2,100,
Visits: 1,789
|
|
Nicely written. Thanks for the explanation
Francis
|
|
|
|
|
Mr or Mrs. 500
      
Group: General Forum Members
Last Login: Friday, February 15, 2013 7:29 AM
Points: 509,
Visits: 718
|
|
David
Yes, the DriveInfo class does require UNSAFE because of the permissions, I said that - my bad.
However, I can't agree with the rest of what you've said. I don't see that the constructor of a simple class would outweigh the cost of using an ArrayList instead of yield as well as the cost of boxing and unboxing all of the values stored in that ArrayList...
The other worry would be garbage collection. By putting everything in a static, the DriveInfo instances that are created are not naturally garbage collected because the reference to them is held by the static array. By doing away with that, everything is up for garbage collection as soon as the function terminates...
M
Atlantis Interactive - SQL Server Tools My blog Why I wrote a sql query analyzer clone
|
|
|
|