NodaTime with Linq2Db - npgsql

How can I configure T4 POCO generation in Linq2Db to generate models that use NodaTime types instead of System.DateTime?
I'm using PostgreSQL with Npgsql.

To substitute standard DateTime classes you have to modify your T4 template in the following way:
// loading database schema
LoadPostgreSQLMetadata(...)
// modifying default mapping
foreach (var t in Tables.Values)
{
foreach (var c in t.Columns.Values)
{
switch (c.Type)
{
case "DateTime" : c.Type = "NodaTime.LocalDateTime"; break;
case "DateTime?" : c.Type = "NodaTime.LocalDateTime?"; break;
case "DateTimeOffset" : c.Type = "NodaTime.OffsetDateTime"; break;
case "DateTimeOffset?": c.Type = "NodaTime.OffsetDateTime?"; break;
}
}
}
// generating model
GenerateModel();

Related

Filter a sheet based on criteria selected on another sheet and carried as an array

A Google sheet I've designed for use in analyzing decennial censuses requires that cells be merged and that two rows be used to handle each census record. Because of the merged cells, my users can't use the normal Google Sheets filter process, so I need to create an alternate way to filter records. I'm hitting a snag. I've created a sheet that allows the user to set up the desired filter criteria. But I can't get the choices to translate into a usable GAS script that works. (I won't complicate this with all of the code that extracts the two-line records to another sheet and filters out all but one line per record, which can then be used to filter and rebuild the two-line records in their filtered form.)
The filtering criteria sheet (see below) allows up to nine levels of criteria. To the right, I have displayed columns that will be hidden from the user, but allow me to capture the information I need to create the filter in the script. Column I has the operator text needed in the script, column G is the column where (in the case of the first line) the Census Year is in the sheet being filtered, and column C has the criteria. I've collected the values in an array I'm calling filterArray.
I need to go through each line of the criteria, determining if there was a selection made. If so, I need to filter for the criteria. Here is my For loop:
// Gather filters from Filter Criteria
for (var i = 0; i <= 9; i = i + 1) {
if(filterArray[i][0]!==""){
myFilterText = SpreadsheetApp.newFilterCriteria()+"."+filterArray[i][8]+"("+filterArray[i][2]+")"
myFilter.setColumnFilterCriteria(filterArray[i][6],myFilterText)
}
}
The last line triggers this message:
Exception: The parameters (number,String) don't match the method signature for SpreadsheetApp.Filter.setColumnFilterCriteria.
If I was not using the array as a variable, I'd want it to basically look like this as it goes through the first loop:
for (var i = 0; i <= 9; i = i + 1) {
if('A7'!==""){
myFilterText = SpreadsheetApp.newFilterCriteria().whenNumberLessThan(1850);
myFilter.setColumnFilterCriteria(10,myFilterText)
}
}
In addition to trying the first code, with the array content, I've tried to create the whole string "SpreadsheetApp.newFilterCriteria()."+filterArray[i][8]+"("+filterArray[i][2]+")" as the contents of myFilterText. I get the same error.
How can I turn the criteria the user is selecting into a code that can run to filter records?
I found a solution, which is VERY code-heavy, unfortunately. I'm using a switch-case to evaluate every possible filter condition and to code the variable I need. The section of the code related to the question I posted is now this:
/**
* Activating Filter and pasting records to new sheet called "Filtered Records_Prep"
*/
var filterRange = spreadsheet.getActiveRange().getA1Notation();
var myFilter = spreadsheet.getRange(filterRange).createFilter();
var myFilterText = ""
var sheet = spreadsheet.getActiveSheet();
// Filter selection to row 1 of each set, eliminating 2s and blanks
var Filter_Criteria0 = SpreadsheetApp.newFilterCriteria().whenNumberEqualTo(1);
myFilter.setColumnFilterCriteria(3,Filter_Criteria0);
// Gather filters from Filter Criteria
for (var i = 0; i <= 9; i = i + 1) {
if(filterArray[i][0]!==""){
myCol = filterArray[i][6];
myFilterCondition = filterArray[i][8];
myFilterCriteria = filterArray[i][2];
switch(myFilterCondition)
{
case "whenNumberEqualTo":
myFilterText = SpreadsheetApp.newFilterCriteria().whenNumberEqualTo(myFilterCriteria);
break;
case "whenNumberNotEqualTo":
myFilterText = SpreadsheetApp.newFilterCriteria().whenNumberNotEqualTo(myFilterCriteria);
break;
case "whenNumberContains":
myFilterText = SpreadsheetApp.newFilterCriteria().whenNumberContains(myFilterCriteria);
break;
case "whenNumberDoesNotContain":
myFilterText = SpreadsheetApp.newFilterCriteria().whenNumberDoesNotContain(myFilterCriteria);
break;
case "whenCellEmpty":
myFilterText = SpreadsheetApp.newFilterCriteria().whenCellEmpty();
break;
case "whenCellNotEmpty":
myFilterText = SpreadsheetApp.newFilterCriteria().whenCellNotEmpty();
break;
case "whenNumberGreaterThan":
myFilterText = SpreadsheetApp.newFilterCriteria().whenNumberGreaterThan(myFilterCriteria);
break;
case "whenNumberGreaterThanOrEqualTo":
myFilterText = SpreadsheetApp.newFilterCriteria().whenNumberGreaterThanOrEqualTo(myFilterCriteria);
break;
case "whenNumberLessThan":
myFilterText = SpreadsheetApp.newFilterCriteria().whenNumberLessThan(myFilterCriteria);
break;
case "whenNumberLessThanOrEqualTo":
myFilterText = SpreadsheetApp.newFilterCriteria().whenNumberLessThanOrEqualTo(myFilterCriteria);
break;
case "whenNumberStartsWith":
myFilterText = SpreadsheetApp.newFilterCriteria().whenNumberStartsWith(myFilterCriteria);
break;
case "whenNumberEndsWith":
myFilterText = SpreadsheetApp.newFilterCriteria().whenNumberEndsWith
(myFilterCriteria);
break;
case "whenTextEqualTo":
myFilterText = SpreadsheetApp.newFilterCriteria().whenTextEqualTo(myFilterCriteria);
break;
case "whenTextNotEqualTo":
myFilterText = SpreadsheetApp.newFilterCriteria().whenTextNotEqualTo(myFilterCriteria);
break;
case "whenTextContains":
myFilterText = SpreadsheetApp.newFilterCriteria().whenTextContains(myFilterCriteria);
break;
case "whenTextDoesNotContain":
myFilterText = SpreadsheetApp.newFilterCriteria().whenTextDoesNotContain(myFilterCriteria);
break;
case "whenTextStartsWith":
myFilterText = SpreadsheetApp.newFilterCriteria().whenTextStartsWith(myFilterCriteria);
break;
case "whenTextEndsWith":
myFilterText = SpreadsheetApp.newFilterCriteria().whenTextEndsWith
(myFilterCriteria);
break;
default:
ui.alert("This criteria was not found.")
}
myFilter.setColumnFilterCriteria(myCol,myFilterText);
} else {
return false;
}
}

An array of enum members using implicit member syntax

Consider this enum.
enum FilmGenre: String, CaseIterable {
case horror = "Horror"
case comedy = "Comedy"
case animation = "Animation"
case romance = "Romance"
case fantasy = "Fantasy"
case adventure = "Adventure"
}
Is there a way to write it like this?
let filmGenres: [FilmGenre.RawValue] = [.horror.rawValue,
.comedy.rawValue,
.animation.rawValue]
The compiler complains with an error:
Type 'FilmGenre.RawValue' (aka 'String') has no member 'horror'
The best I can do is like this.
let filmGenres: [FilmGenre.RawValue] = [FilmGenre.horror.rawValue,
FilmGenre.comedy.rawValue,
FilmGenre.animation.rawValue]
I've tried various combinations from the auto-complete.
let filmGenres: [FilmGenre.AllCases.Element.RawValue] = [...]
Is it not possible to do it in Swift 5.4?
[FilmGenre.RawValue] translates to [String] in the case and clearly String doesn't know anything about .horror that is defined in other type FilmGenre.
What you can do is -
enum FilmGenre: String, CaseIterable {
case horror = "Horror"
case comedy = "Comedy"
case animation = "Animation"
case romance = "Romance"
case fantasy = "Fantasy"
case adventure = "Adventure"
}
/// Have a variable that is of `[FilmGenre]` type
/// This will allow you to use the type safety you are looking for
let filmGenres: [FilmGenre] = [.horror, .comedy, .animation]
/// This one you can use anywhere else as you like
/// This will give you `[String]` which is what you want in this case
let filmGenreRawValues = filmGenres.map({ $0.rawValue })
You can add a static function with var args to your enum for a more dynamic way to create the array
static func arrayWithRawValues(_ genre: FilmGenre...) -> [Self.RawValue] {
genre.map(\.rawValue)
}
Example
print(FilmGenre.arrayWithRawValues(.horror, .comedy, .animation))
Output
["Horror", "Comedy", "Animation"]

Programmatically add Aggregate Transform - Count Distinct to SSIS package

I am working on programmatically creating Aggregate transform with aggregation type as count distinct and i am able to create other aggregations like min,max,count.. but when it comes to count distinct i am getting below error
The component has detected potential metadata corruption during
validation. Error at Data Flow Task - Load Count Dist [Aggregate -
All [2]]: The "Aggregate - All.Outputs[Aggregate Output
1].Columns[col1]" is missing the required property
"CountDistinctScale". The object is required to have the specified
custom property.
I am unable to find "CountDistinctScale" custom property as this custom property doesn't exit for other aggregation and magically appears when count distinct is selected,is there a method which i need to call to create new custom property?
I understand there are not a lot of people who know how to programmatically create package, please help me find someone with knowledge or suggest me how i can get some help.
IDTSComponentMetaData100 Aggregate = pipeline.ComponentMetaDataCollection.New();
Aggregate.ComponentClassID = app.PipelineComponentInfos["Aggregate"].CreationName;
// Get the design time instance of the derived column
var DesignAggregate = Aggregate.Instantiate();
DesignAggregate.ProvideComponentProperties(); //design time
Aggregate.Name = "AggregateComponent";
IDTSPath100 AggregatePath = pipeline.PathCollection.New();
AggregatePath.AttachPathAndPropagateNotifications(pipeline.ComponentMetaDataCollection[Prev_Transform.Transformation_Name].OutputCollection[Prev_Transform.Output_Number], Aggregate.InputCollection[0]);
//update the metadata for the derived columns
DesignAggregate.AcquireConnections(null);
DesignAggregate.ReinitializeMetaData();
DesignAggregate.ReleaseConnections();
// Mark the columns we are joining on
IDTSInput100 AggregateInput = Aggregate.InputCollection[0];
IDTSInputColumnCollection100 AggregateInputColumns = AggregateInput.InputColumnCollection;
IDTSVirtualInput100 AggregateVirtualInput = AggregateInput.GetVirtualInput();
IDTSVirtualInputColumnCollection100 AggregateVirtualInputColumns = AggregateVirtualInput.VirtualInputColumnCollection;
IDTSOutput100 AggregateoutputCollection = Aggregate.OutputCollection[0];
// Note: input columns should be marked as READONLY
foreach (IDTSVirtualInputColumn100 vColumn in AggregateVirtualInputColumns)
{
int sourceColumnLineageId = AggregateVirtualInput.VirtualInputColumnCollection[vColumn.Name].LineageID;
DesignAggregate.SetUsageType(AggregateInput.ID, AggregateVirtualInput, sourceColumnLineageId, DTSUsageType.UT_READONLY);
// create a new output column
IDTSOutputColumn100 newOutputColumn = DesignAggregate.InsertOutputColumnAt(AggregateoutputCollection.ID, 0, vColumn.Name, string.Empty);
// set the data type porperties to the same values as these of the input column
newOutputColumn.SetDataTypeProperties(AggregateVirtualInput.VirtualInputColumnCollection[vColumn.Name].DataType, AggregateVirtualInput.VirtualInputColumnCollection[vColumn.Name].Length, 0, 0, AggregateVirtualInput.VirtualInputColumnCollection[vColumn.Name].CodePage);
newOutputColumn.MappedColumnID = 0;
for (int i = 0; i < newOutputColumn.CustomPropertyCollection.Count; i++)
{
IDTSCustomProperty100 property = newOutputColumn.CustomPropertyCollection[i];
switch (property.Name)
{
case "AggregationColumnId":
property.Value = sourceColumnLineageId;
break;
case "AggregationType":
property.Value = 3;
break;
case "IsBig":
property.Value = 1;
break;
case "AggregationComparisonFlags":
property.Value = 0;
break;
}
}
}

I have a two differnt array & i want to remove items in the second one that have the same property value of array1

inside the code $response['results'] is for google api. And $da is my databse records I am comparing these two using foreach on the basis of latitude of both data records. please help me out.
Here is my code :
$setarraymy= [];
$setarray = [];
foreach($da as $data1){
foreach ($response['results'] as $res){
switch (true){
case (round($data1['location']['lat'],4)!== round($res['geometry']
['location']['lat'],4) && !in_array($res['geometry']['location']['lat'],$setarray)):
array_push($setarray,$res);
break;
case (!in_array($data1['location']['lat'],$setarraymy)):
array_push($setarraymy,$data1);
break;
default:
break;
}
}
}
echo json_encode(array( 'Results' =>$setarraymy,
'status'=>'OK'),JSON_PRETTY_PRINT);
$new_array = array_unique($setarray, SORT_REGULAR);
echo json_encode( array('Results'=>$new_array,
'status'=>'OK'),JSON_PRETTY_PRINT);
return;
Manipulating array will be difficult, better to use collections and lastly convert collection to array as per your logic.
Avinash

Audit of what records a given user can see in SalesForce.com

I am trying to determine a way to audit which records a given user can see by;
Object Type
Record Type
Count of records
Ideally would also be able to see which fields for each object/record type the user can see.
We will need to repeat this often and for different users and in different orgs, so would like to avoid manually determining this.
My first thought was to create an app using the partner WSDL, but would like to ask if there are any easier approaches or perhaps existing solutions.
Thanks all
I think that you can follow the documentation to solve it, using a query similar to this one:
SELECT RecordId
FROM UserRecordAccess
WHERE UserId = [single ID]
AND RecordId = [single ID] //or Record IN [list of IDs]
AND HasReadAccess = true
The following query returns the records for which a queried user has
read access to.
In addition, you should add limit 1 and get from record metadata the object type,record type, and so on.
I ended up using the below (C# using the Partner WSDL) to get an idea of what kinds of objects the user had visibility into.
Just a quick'n'dirty utility for my own use (read - not prod code);
var service = new SforceService();
var result = service.login("UserName", "Password");
service.Url = result.serverUrl;
service.SessionHeaderValue = new SessionHeader { sessionId = result.sessionId };
var queryResult = service.describeGlobal();
int total = queryResult.sobjects.Count();
int batcheSize = 100;
var batches = Math.Ceiling(total / (double)batcheSize);
using (var output = new StreamWriter(#"C:\test\sfdcAccess.txt", false))
{
for (int batch = 0; batch < batches; batch++)
{
var toQuery =
queryResult.sobjects.Skip(batch * batcheSize).Take(batcheSize).Select(x => x.name).ToArray();
var batchResult = service.describeSObjects(toQuery);
foreach (var x in batchResult)
{
if (!x.queryable)
{
Console.WriteLine("{0} is not queryable", x.name);
continue;
}
var test = service.query(string.Format("SELECT Id FROM {0} limit 100", x.name));
if(test == null || test.records == null)
{
Console.WriteLine("{0}:null records", x.name);
continue;
}
foreach (var record in test.records)
{
output.WriteLine("{0}\t{1}",x.name, record.Id);
}
Console.WriteLine("{0}:\t{1} records(0)", x.name, test.size);
}
}
output.Flush();
}

Resources