There is a folder in a Google Storage bucket.
I need to delete (with JSON API) the folder (let denote it xxx/) if and only if it is empty.
The most obvious way is to check if it is empty and delete if it is empty. This requires an additional request and also may be subject to race conditions.
However, what about deleting the xxx/ object unconditionally? If it is empty deleting will do what we need, and if it is nonempty xxx/ will continue to behave like a folder because there are files with prefix xxx/.
Are there any troubles with this way (that is with removing the xxx/ object unconditionally on whether it has or doesn't have subobjects)?
Deleting the xxx/ object will not delete any objects "inside" the folder.
Note that that object is created by tools (like the Cloud Storage web console) to support the illusion of a folder inside what's actually a flat namespace in GCS (i.e., to the service there are no folders, and the "/" character is used by tools to mimic there being folders inside the bucket).
The only way to do what you want is to get a list of the objects under the xxx/ prefix and not delete the xxx/ object if that list is non-empty. However, doing that has an inherent race condition, since someone could write a new object after you make the check.
Related
I have a function in my firebase rules file userRolesIncludesPermission, this function checks a property on the user to determine whether that user has a certain permission on their role, it does so by comparing references.
This works as expected in the firebase rules file when used for security rules for firestore. Unfortunately this does not work as expected with "storage".
After research I found out that the problem is the comparison between the references from the permissions list under user.data.roles[0] and my custom made path.
Is there any better way to produce a path that can be recognizable using a list function?
Is it an unknown limitation of storage security rules?
Note that the function getRootCollectionDocRef works perfectly when I try to build a queryable path even in the same request (for example when I try earlier in the code to query the user)
Another note is that in the rules playground (console debugger) it works. But in an actual request from the website (dev, for now) it doesn't.
function getRootCollectionDocRef(collection, docId) {
return /databases/(default)/documents/$(collection)/$(docId);
}
function userRolesIncludesPermission(user, permissionId) {
return firestore.get(user.data.roles[0]).data.permissions.hasAll([getRootCollectionDocRef("permissions", permissionId)]);
}
I tried to use every available list function such as "in", "hasAny" etc.
I tried to build the path while converting it with path() function.
I tried to convert to a set.
I tried to use a hard coded non-dynamic path. It failed as long as I use a custom-made path.
However when trying to query the path with a fixed index (i.e firebase.get(permissions[1]) it worked. But this is an invalid practice. I have to make it dynamic, but the problem is that I can't loop over the list and convert the paths to strings on the fly.
Thanks in advance!!
In short: I have a method name provided via a JSON configuration file. I'd like to call a method using this provided name. The method (with a matching name) will exist in the backend. What's the best way of going about this?
I am not quite sure what I should be searching for as an example.
To detail: I am working with a legacy application, hence the VB.NET. I am building a single PDF file from multiple PDF sources. Most of these are as is, I simply read the configuration and grab the relevant files and the job is done. However some require processing, I'd like the configuration file to pass in a method name to be called that will perform extra processing on the PDF, whatever that may be.
As there can be a lot of PDF files that can vary, I cannot simply use a property such as "PostProcessing: true".
Any ideas?
You could use reflection to reflect method names back and check them against the name passed from the property in the config file.
Like so
Type magicType = Type.GetType("MagicClass");
MethodInfo magicMethod = magicType.GetMethod("ItsMagic");
object magicValue = magicMethod.Invoke(magicClassObject, new object[]{100});
That would work.. but to be honest, I'd go with a case statement as you'll be hardcoding the method names anyway (because they are code), and it'll be strongly typed (less chance of typos and errors).
I'm writing a piece of code to simulate some stuff of diagnostic.
I've created with CANalyzer, a panel with tons of information that need to be shown using a picklist (called combobox)
What I want to do is to create a giant array of that struct that need to be selected using the SPN combobox (the picklist) , and the other parameters of the struct/object need to populate the other elements of the panel.
Is this possible without doing a tons of SysSetVariableInt or SysSetVariableString for each element?
Before I was doing this stuff using another technique, I parse the file with all the information that are stored in a giant matrix, then I use the method "on sysvar update" on the variable associated to the SPN picklist, to get the index of that, so I search for that index in the matrix, then I use the SysSetVariableInt or others, to set the values to the elements in the panel.
To populate the picklist I've found a pretty nice method "sysSetVariableDescriptionForValue" that helps to add elements, but the problem with this method, is that if you want to change elements, you can just overwrite, and not change all...so, if in a next iteration you push less element in the picklist, you will see also the old ones.
With "sysSetVariableDescriptionForValue" you basically are writing via code, the value table of that sysvariable, and is not possible (according to Vector), be flushed, on runtime... :/
I would love to do this thing using another approach, maybe with the struct is possible...i really don't know.
Any help will be very appreciated!
Regards!
TLDR; build a tool to create a .sysvar file from a structured input (comma-separated for instance), run it, get the .sysvar file and link it to the CANalyzer configuration.
I once had to create the entire testing interface with some components of the software. We didn't have a structured release procedure, and the test environment was rebuilt every time from scratch based on the new internal software interfaces. I too had to add hundreds of variables.
My solution was to generate .sysvar files programatically outside CANalyzer. Links to the .sysvar files are symbolic in the CANalyzer configuration, meaning if a file by the right name is in the right location, that file is going to be loaded.
What I want to do is to create a giant array of that struct that need
to be selected using the SPN combobox (the picklist) , and the other
parameters of the struct/object need to populate the other elements
of the panel. Is this possible without doing a tons of
SysSetVariableInt or SysSetVariableString for each element?
Create an external script to generate the .sysvar file. In the end it is just an xml file, you may study the structure of a demo one you save. Then, import that file in the CANalyzer config. You may need to close/re-open the configuration in case the .sysvar file changes.
PROs: no need to write a complicated CAPL script and update it every time a variable changes.
CONs: you must have a source for all the information, even a simple excel sheet, with all the description and such, and you have to create a tool that accepts the input file (let's assume a .csv file) and turns it into a .xml file with .sysvar extension instead.
I have a transmogrifier pipeline to insert objects to my Zope database (importing zexp files from a directory structure). This works - the objects are created; but I don't get them added to the portal_catalog.
I added a section to add the objects to the catalog explicitly, inspired by plone.app.transmogrifier.reindexobject: I call portal_catalog.catalog_object(obj) for each item.
The objects exist, and getPhysicalPath yields the correct values, but the objects are not added. There is no error message or exception whatsoever.
I tried to specify the list of indexes (the idxs argument), but this didn't change anything. If not specified, all indexes should be filled anyway, right?
Since it looks like a transaction problem to me (no errors, but nothing stored in the catalog either), I tried transaction code (begin, savepoint, commit, and in case of exceptions abort), but it didn't help. When I call the catalog immediately after the catalog_object call (portal_catalog(path='/Plonesite/full/path/to/object')), nothing has happened, and an empty list is returned.
The catalog does contain objects; even objects of my custom datatypes (AT-based). Not even the Folder objects of my imports are indexed.
Without the objects in the catalog, my import is useless. What can I do?
Thank you!
Edit: Any hint about how to get my object trees in the catalog is appreciated! Even if it can't be integrated in my process. I need the contents cataloged ...
My custom content types are contained in the Plone Catalog Tool page selection field, but I don't know whether this is sufficient.
Edit 2:
Somehow my objects have been catalogued - the unrestrictedSearchResults method shows them! However, it can't be the desired solution to use this method all over; so I need to "un-restrict" the entries somehow.
It turned out that I have a monkey:patch (xmlns:monkey="http://namespaces.plone.org/monkey") for the Products.CMFPlone.CatalogTool.CatalogTool.searchResults method; this filters the catalog for my additional field subportal unless a special value for it is given - even in the management view ... Unfortunately, I had no way to specify this special value in that view.
Thus, the solution was to weed out all wrong values (for subportals which don't exist in the other Zope tree) to have the default value take effect.
Quite specific to my setup, I'm afraid ...
I need a help for while creating the collection the below error is came in server console.How to solve the error ?
Error:
Warning: creating anonymous collection. It will not be saved or synchronized over the network. (Pass null for the collection name to turn off this warning.)
TLDR: you need to provide a collection name as an argument when you create a shared collection.
In most cases, you want to provide a name as a parameter when you define a collection:
Docs = new Meteor.Collection('docs');
When you don't, you create anonymous collection:
Items = new Meteor.Collection();
In the first case, the collection is shared and synchronized between client and server, and the name you've provided is used as a table name in order to store the collection in Mongo.
Anonymous collections are local in the place they've been created. Their contents are never synchronized. Therefore, even if you create such collection in a piece of code that will be run on the server and on the client, those two collections will be separate things: data created on the server won't be visible on client, data created on the client won't be visible on server, and both won't be stored in the database.
There are legitimate use cases for anonymous collections, mostly on the client side when you need to create some temporary data, but want to retain all the benefits of Minimongo and reactivity. However, it's one of those things that are needed rarely and you really do know when you need to do it. It's more probable that a beginner made a mistake and forget to provide the collection name when he wanted to create a typical shared collection. Therefore, the system issues a warning to make sure that you really wanted to do what you just did.
Therefore:
If your goal was to create an anonymous collection, and you know what you're doing, don't worry about that message. It's just a warning, the code will be functional and do what it's told to.
If you wanted to create a normal collection, or are just starting out and don't know what's this all about, just add a parameter to your collection definition.