Coral8 Stream reader in Powershell
A little something I cooked up last night
# ./Get-C8Tuple ccl://localhost:6789/Stream/Default/Proj/outStream
param([string]$curl,[int]$maxRows=-1)
function Resolve-Url($url)
{
$wc = new-object Net.WebClient
$urib = [UriBuilder] $url
$urib.Scheme = "http"
$urib.Path= "/Manager/ResolveUri"
$wc.UploadString($urib.uri,$url)
}
function Get-TD($url)
{
$urib = [UriBuilder] $url
$urib.Scheme = "http"
$urib.Path= "/Manager"
$wc = new-object Net.WebClient
$wc.Headers.Add("Content-Type",'application/soap+xml; charset=utf-8; action="urn:coral8.com:SOAPAction"')
$soapBody = "<soap:Envelope xmlns:soap='http://www.w3.org/2003/05/soap-envelope' xmlns:soapenc='http://www.w3.org/2003/05/soap-encoding' xmlns:tns='urn:coral8.com:Manager' xmlns:types='urn:coral8.com:Manager/encodedTypes' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema'><soap:Body> <tns:GetTD><uri xsi:type='xsd:string'>$url</uri></tns:GetTD></soap:Body></soap:Envelope>"
$soapResp = $wc.UploadString($urib.uri,$soapBody)
$td = ([xml]$soapResp).Envelope.Body.GetTDResponse.Return."#text"
([xml]$td).TupleDescriptor.Field
}
function ConvertFrom-C8CSV($csv,$names,$types)
{
# TODO - support quoted csv values
$vals = $csv.Split(",")
$o = new-object PSObject
for ($ii=0;$ii -lt $vals.Count;$ii++)
{
$t = $types[$ii]
if ($t -eq "datetime")
{
$v = ([datetime]"1/1/1970 GMT").AddTicks( ([long]$vals[$ii]) * 10 )
}
else
{
$v = $vals[$ii] -as $t
}
$o | add-member -membertype noteproperty -name $names[$ii] -value $v
}
return $o
}
function ConvertFrom-C8TypeName([string] $c8Type)
{
switch -wildcard ($c8Type)
{
"Integer*" { return "int" }
"Long*" { return "long" }
"Float*" {return "double" }
"Bool*" { return "bool" }
"String*" { return "string" }
"Time*" { return "datetime" }
"XML*" { return "xml" }
default { throw "Type '$c8Type' not implemented" }
}
}
write-progress "Resolve URL" "Pending"
$url = Resolve-Url $curl
$td = Get-TD $curl
$fieldNames = @("Timestamp") + ($td | % { $_.Name })
$fieldTypes = @("datetime") + ($td | % { ConvertFrom-C8TypeName $_.type })
write-progress "Resolve URL" "Done"
$urib = [UriBuilder] $url
$urib.Scheme = "http"
$req = [Net.WebRequest]::Create($urib.uri)
$req.Headers.Add('X-C8-StreamFormat', 'CSV')
$req.Headers.Add('X-C8-StreamFormatOptions', 'TitleRow=false')
$req.Method = "GET"
$resp = $req.GetResponse()
$rdr = [IO.StreamReader] $resp.GetResponseStream()
$cnt=0
while ($MaxRows -eq -1 -or $cnt -lt $MaxRows)
{
write-progress "Reading tuples" "in progress" -currentOperation "count - $cnt"
$csv = $rdr.ReadLine()
ConvertFrom-C8CSV $csv $fieldNames $fieldTypes
$cnt++
}
$resp.Close()
Code comments -
- I couldn't find a WSDL for the manager service or a light weight .net/powershell SOAP api, so I had to resort to sending in a canned request.
- A nice Powershell feature is how the casting operator will search the type's constructors to new up the object needed. I love it.