Skip to content

Commit e9dc9a5

Browse files
committed
Adding Table bindings for entire table, including filter/take options
1 parent 3e7c0bb commit e9dc9a5

File tree

6 files changed

+116
-15
lines changed

6 files changed

+116
-15
lines changed

sample/QueueTrigger-Powershell/queueTrigger.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ $in = [Console]::ReadLine()
44

55
$output = $Env:output
66
$json = $in | ConvertFrom-Json
7-
$entity = [string]::Format('{{ "timestamp": "{0}", "title": "Powershell Table Entity for message {1}" }}', $(get-date -f MM-dd-yyyy_HH_mm_ss), $json.id)
7+
$entity = [string]::Format('{{ "timestamp": "{0}", "status": 0, "title": "Powershell Table Entity for message {1}" }}', $(get-date -f MM-dd-yyyy_HH_mm_ss), $json.id)
88
$entity | Out-File -Encoding Ascii $output

sample/QueueTrigger-Python/function.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@
44
{
55
"type": "queueTrigger",
66
"queueName": "samples-python"
7+
},
8+
{
9+
"type": "table",
10+
"name": "input",
11+
"tableName": "samples",
12+
"partitionKey": "samples",
13+
"take": 5,
14+
"filter": "status eq 1"
715
}
816
],
917
"output": [
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
11
import os
2+
import json
23

34
# read the queue message and write to stdout
45
input = raw_input();
56
message = "Python script processed queue message '{0}'".format(input)
67
print(message)
78

9+
# read the entities from the table binding
10+
tableData = open(os.environ['input'])
11+
table = json.load(tableData)
12+
print("Read {0} Table entities".format(len(table)))
13+
for entity in table:
14+
print(entity)
15+
816
# write to the output binding
917
f = open(os.environ['output'], 'w')
1018
f.write(input)

src/WebJobs.Script/Binding/Binding.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using System.IO;
88
using System.Threading.Tasks;
99
using Microsoft.Azure.WebJobs.Host;
10+
using Microsoft.WindowsAzure.Storage.Table;
1011
using Newtonsoft.Json.Linq;
1112

1213
namespace Microsoft.Azure.WebJobs.Script
@@ -76,7 +77,14 @@ internal static Collection<Binding> GetBindings(JobHostConfiguration config, JAr
7677
string tableName = (string)binding["tableName"];
7778
string partitionKey = (string)binding["partitionKey"];
7879
string rowKey = (string)binding["rowKey"];
79-
bindings.Add(new TableBinding(config, name, tableName, partitionKey, rowKey, fileAccess));
80+
81+
TableQuery tableQuery = new TableQuery
82+
{
83+
TakeCount = (int?)binding["take"],
84+
FilterString = (string)binding["filter"]
85+
};
86+
87+
bindings.Add(new TableBinding(config, name, tableName, partitionKey, rowKey, fileAccess, tableQuery));
8088
}
8189
}
8290
}

src/WebJobs.Script/Binding/QueueBinding.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ public override async Task BindAsync(IBinder binder, Stream stream, IReadOnlyDic
3939

4040
boundQueueName = Resolve(boundQueueName);
4141

42+
// only an output binding is supported
4243
IAsyncCollector<byte[]> collector = binder.Bind<IAsyncCollector<byte[]>>(new QueueAttribute(boundQueueName));
4344
byte[] bytes;
4445
using (MemoryStream ms = new MemoryStream())

src/WebJobs.Script/Binding/TableBinding.cs

Lines changed: 89 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using Microsoft.Azure.WebJobs.Host.Bindings.Path;
99
using Microsoft.WindowsAzure.Storage;
1010
using Microsoft.WindowsAzure.Storage.Table;
11+
using Newtonsoft.Json;
1112
using Newtonsoft.Json.Linq;
1213

1314
namespace Microsoft.Azure.WebJobs.Script
@@ -16,14 +17,27 @@ internal class TableBinding : Binding
1617
{
1718
private readonly BindingTemplate _partitionKeyBindingTemplate;
1819
private readonly BindingTemplate _rowKeyBindingTemplate;
20+
private readonly TableQuery _tableQuery;
1921

20-
public TableBinding(JobHostConfiguration config, string name, string tableName, string partitionKey, string rowKey, FileAccess fileAccess) : base(config, name, "queue", fileAccess, false)
22+
public TableBinding(JobHostConfiguration config, string name, string tableName, string partitionKey, string rowKey, FileAccess fileAccess, TableQuery tableQuery = null) : base(config, name, "queue", fileAccess, false)
2123
{
2224
TableName = tableName;
2325
PartitionKey = partitionKey;
2426
RowKey = rowKey;
2527
_partitionKeyBindingTemplate = BindingTemplate.FromString(PartitionKey);
26-
_rowKeyBindingTemplate = BindingTemplate.FromString(RowKey);
28+
if (!string.IsNullOrEmpty(RowKey))
29+
{
30+
_rowKeyBindingTemplate = BindingTemplate.FromString(RowKey);
31+
}
32+
33+
_tableQuery = tableQuery;
34+
if (_tableQuery == null)
35+
{
36+
_tableQuery = new TableQuery
37+
{
38+
TakeCount = 50
39+
};
40+
}
2741
}
2842

2943
public string TableName { get; private set; }
@@ -35,7 +49,7 @@ public override bool HasBindingParameters
3549
get
3650
{
3751
return _partitionKeyBindingTemplate.ParameterNames.Any() ||
38-
_rowKeyBindingTemplate.ParameterNames.Any();
52+
(_rowKeyBindingTemplate != null && _rowKeyBindingTemplate.ParameterNames.Any());
3953
}
4054
}
4155

@@ -46,11 +60,17 @@ public override async Task BindAsync(IBinder binder, Stream stream, IReadOnlyDic
4660
if (bindingData != null)
4761
{
4862
boundPartitionKey = _partitionKeyBindingTemplate.Bind(bindingData);
49-
boundRowKey = _rowKeyBindingTemplate.Bind(bindingData);
63+
if (_rowKeyBindingTemplate != null)
64+
{
65+
boundRowKey = _rowKeyBindingTemplate.Bind(bindingData);
66+
}
5067
}
5168

5269
boundPartitionKey = Resolve(boundPartitionKey);
53-
boundRowKey = Resolve(boundRowKey);
70+
if (!string.IsNullOrEmpty(boundRowKey))
71+
{
72+
boundRowKey = Resolve(boundRowKey);
73+
}
5474

5575
if (FileAccess == FileAccess.Write)
5676
{
@@ -77,25 +97,81 @@ public override async Task BindAsync(IBinder binder, Stream stream, IReadOnlyDic
7797
}
7898
else
7999
{
80-
DynamicTableEntity tableEntity = binder.Bind<DynamicTableEntity>(new TableAttribute(TableName, boundPartitionKey, boundRowKey));
81-
if (tableEntity != null)
100+
if (!string.IsNullOrEmpty(boundPartitionKey) &&
101+
!string.IsNullOrEmpty(boundRowKey))
82102
{
83-
OperationContext context = new OperationContext();
84-
var entityProperties = tableEntity.WriteEntity(context);
103+
// singleton
104+
DynamicTableEntity tableEntity = binder.Bind<DynamicTableEntity>(new TableAttribute(TableName, boundPartitionKey, boundRowKey));
105+
if (tableEntity != null)
106+
{
107+
string json = ConvertEntityToJObject(tableEntity).ToString();
108+
using (StreamWriter sw = new StreamWriter(stream))
109+
{
110+
await sw.WriteAsync(json);
111+
}
112+
}
113+
}
114+
else
115+
{
116+
// binding to entire table (query multiple table entities)
117+
CloudTable table = binder.Bind<CloudTable>(new TableAttribute(TableName, boundPartitionKey, boundRowKey));
118+
var entities = table.ExecuteQuery(_tableQuery);
85119

86-
JObject jsonObject = new JObject();
87-
foreach (var entityProperty in entityProperties)
120+
JArray entityArray = new JArray();
121+
foreach (var entity in entities)
88122
{
89-
jsonObject.Add(entityProperty.Key, entityProperty.Value.StringValue);
123+
entityArray.Add(ConvertEntityToJObject(entity));
90124
}
91-
string json = jsonObject.ToString();
92125

126+
string json = entityArray.ToString(Formatting.None);
93127
using (StreamWriter sw = new StreamWriter(stream))
94128
{
95129
await sw.WriteAsync(json);
96130
}
97131
}
98132
}
99133
}
134+
135+
private static JObject ConvertEntityToJObject(DynamicTableEntity tableEntity)
136+
{
137+
OperationContext context = new OperationContext();
138+
var entityProperties = tableEntity.WriteEntity(context);
139+
140+
JObject jsonObject = new JObject();
141+
foreach (var entityProperty in entityProperties)
142+
{
143+
JValue value = null;
144+
switch (entityProperty.Value.PropertyType)
145+
{
146+
case EdmType.String:
147+
value = new JValue(entityProperty.Value.StringValue);
148+
break;
149+
case EdmType.Int32:
150+
value = new JValue(entityProperty.Value.Int32Value);
151+
break;
152+
case EdmType.Int64:
153+
value = new JValue(entityProperty.Value.Int64Value);
154+
break;
155+
case EdmType.DateTime:
156+
value = new JValue(entityProperty.Value.DateTime);
157+
break;
158+
case EdmType.Boolean:
159+
value = new JValue(entityProperty.Value.BooleanValue);
160+
break;
161+
case EdmType.Guid:
162+
value = new JValue(entityProperty.Value.GuidValue);
163+
break;
164+
case EdmType.Double:
165+
value = new JValue(entityProperty.Value.DoubleValue);
166+
break;
167+
case EdmType.Binary:
168+
value = new JValue(entityProperty.Value.BinaryValue);
169+
break;
170+
}
171+
172+
jsonObject.Add(entityProperty.Key, value);
173+
}
174+
return jsonObject;
175+
}
100176
}
101177
}

0 commit comments

Comments
 (0)