how to reference database item attachments in couchapp - couchdb

I'm learning couchapp and it looks pretty easy to query database items.
But I have items with attachments, and I'd like to add hyperlinks to the attachments:
{{description}}
I can get id, attachment and description setup properly, but how do I get the current database name (or URL) from within a couchapp javascript function?

If you don't want to use relative urls, you can fetch the db name in following way:
var dbname = unescape(document.location.href).split('/')[2]
since your href looks like: http://host:port/dbname/doc...
This is also the code jquery.couch.app.js uses. So if you are using it, it's available for you in initialization code:
$.couch.app(function(app) { alert(app.db.name); });

Related

In Kentico 7 I need to get attachment information from the attachment URL

When Kentico documents have images embedded in them, the image is inserted into the HTML as an <img> tag. I need to determine if this image is hosted by Kentico and if so, use the Kentico API to retrieve the database information for it.
So far I have parsed the File GUID out of the URL like this:
const string attachmentPrefix = "~/getattachment/";
if (imageElement.LinkAddress.StartsWith(attachmentPrefix))
{
var start = attachmentPrefix.Length;
var end = imageElement.LinkAddress.IndexOf("/", start);
var fileGuidString = imageElement.LinkAddress.Substring(start, end - start);
var fileGuid = new Guid(fileGuidString);
var info = AttachmentHistoryInfoProvider.GetInfoByGuid("-- what goes here --", fileGuid);
}
But I have not found any useful methods in the Kentico API that will retrieve information about the attachment from the GUID. The closest I found was AttachmentHistoryInfoProvider.GetInfoByGuid() but it takes an objectType parameter that I can't find any documentation for.
Does anyone know how to get information on attachments in Kentico 7 starting from a File GUID?
You mention that you're talking about images in the media library, but are trying to use the AttachmentHistoryInfoProvider in your code sample. I think it depends on what you are referring to when you say 'documents have media library images embedded in them'; in what way are you embedding them? Perhaps using the Editable image web part for example.
If you are using files from the media library, you should try using MediaFileInfoProvider.GetMediaFileInfo(Guid, string) which takes the Guid of the file and the site code name. This will return you a MediaFileInfo class. You can find it in the CMS.DataEngine assembly in Kentico 7. For a file from a media library, I'd expect to see a URL like /SampleSite/media/cats/nohandskitten.aspx to be rendered.
If you're not using images from the media library, but are inserting directly into content, then yes - this is an attachment. Rather than using AttachmentHistoryInfoProvider, you should use AttachmentInfoProvider. Calling AttachmentInfoProvider.GetAttachmentInfo(Guid, string) with the Guid of the file and the site code name will return the AttachmentInfoObject. I believe the AttachmentHistoryInfoProvider will only return things to you if you have object versioning enabled. For a file from an attachment, I'd expect to see a URL like /getattachment/75408145-0995-45dc-943a-d27296a45327/nohandskitten.jpg.aspx.
These InfoProviders do fundamentally different things, so long as you know what type of information you're looking for, you should be able to choose the correct one
If you don't have it already, the API reference for Kentico 7 may be helpful: https://devnet.kentico.com/docs/7_0/kenticocms_api.zip

pouchdb alldocs get nosql attachment

I have a piece of angular2 + pouchdb code that queries cloudant and fetches documents with their attachments. The console log of the returned doc looks like the below
{"type":"some_doc"},"_attachments":{"logo.png":{"digest":"md5-UK7aKiZSqQ6Xljz4wmUMkw==","content_type":"image/png","data":"iVBO....CCGE
Truncated the data...
I'm now trying to display the image in a list of items with
<img [src]=doc.some.path>
The challenge I'm facing is that I can't dynamically reach the data element to fetch the blob and invoke the
var url = URL.createObjectURL(blob);
All the posts I found are either very old and about alldocs not supporting attachment get, or hardcoding blobs in sample code.
Please help.
Thanks,
Elvis.
The answer to your question is best expressed here. In summary:
call the PouchDB db.getAttachment function to return the image as a Blob object
call URL.createObjectURL(blob) to turn the blob into a URL consumable by an image tag
attach the URL to the img tag's src attribute

MongoDB: Copy a collection of referenced documents as subdocuments

I made the mistake of designing a scheme so that I have two collections where one has documents which contain a manual reference to the other. I realized now that I should have created it so that the parent collection contained the other collection as sub-documents instead.
The problem is, I've already put this scheme out into a production environment where hundreds of entries have already been created. What I'd like to do is somehow scan over all of the existing data, and copy the items to their referenced parent_id as a sub-document.
Here is an example of my schema:
Collection 1 - User
_id
Name
Collection 2 - Photos
_id
url
user_id
Is there a quick way to change the existing documents to be one collection like this:
Collection - User
_id
Name
Photos: [...]
Once I have the database setup correctly, I can easily modify my code to use the new one, but the problem I'm having is figuring out how to quickly/procedural copy the documents to their parent.
Additional detail - I'm using MongoHQ.com to host my MongoDB.
Thank You.
I don't know the specifics of your environment, but this sort of change usually involves the following kinds of steps:
Ensure that your old code doesn't complain if there is a Photos array in the User object.
"Freeze" the application so that new User and Photo documents are not created
Run a migration script that copies the Photo documents into the User documents. This should be pretty easy to create either in javaScript or through app code using the driver (see example below)
Deploy the new version of the application that expects Photos to be embedded in the array
"Unfreeze" the application to start creating new documents
If you cannot "Freeze/Unfreeze" you will need to run a delta script after step 4 that will migrate newly created Photo documents after the new application is deployed.
The script will look something like this (untested):
db.User.find().forEach(function (u) {
u.Photos = new Array();
db.Photo.find({user_id : u._id}).forEach(function (p) {
u.Photos.push(p);
}
db.User.Save(u);
}

Getting URL or Document ID of an Unsaved Document

On save of a document I'm running SSJS that is doing a .save() and then I am wanting to include the document link (URL) in the body of a notification email that gets sent by using context.getUrl().
This works for documents that are already saved because it has the doc id in the URL when doc gets opened, but not for new docs. Is there a way I can accomplish this for new documents that do not have their ID yet?
You have to construct the URL yourself since (as you already know) the context.getUrl() method can not be used.
So after your .save() you could do something like the following:
var docUrl = context.getUrl().toString().split(view.getPageName())[0] + "/" + database.getFilePath() + view.getPageName() + "?action=openDocument&documentId=" + document.getNoteID();
The context.getUrl().toString().split(view.getPageName())[0] part should give you the hostname and database filepath according to David Leedys xpagescheatsheet.com URL test. I then add the current XPage name and the openDocument and docid parameters.
Another possibility: if you have a form behind the document and the property "open XPages instead" you can use the http://server/database.nsf/0/universalid syntax. When you have an unique identifier in your document you also can use a view sorted by that identifier and use http://server/database.nsf/sortedview/sortkey. With the sorted view you could predict the URL before saving.

How does a document-based database and CouchDB in particular handle ID references?

I really like the document-based approach of storing data like blog posts as a whole document with all information needed saved inside of it. Therefore the authorĀ“s username is stored as plain text. The author himself has his own document with personal information attached to it. What happens when the author decides to change his username? Do I have to update every document the contains a blog post by that author or is this just one of the drawbacks using a document-based database?
Thanks for any suggestions!
If you need to write a query(view) with content from the blogpost and the name of the author, then the name must be included in the blog content, and therefore all blogposts must be updated.
if the name is only for information ( i mean you do not query a blogpost-content like keywords AND name of author), you can add the id into the blog document (and of course now can Query blog content AND author-id) and emit {'_id':doc.author_id} as a Value.
include_docs=true then gives you the doc of the Author (and no longer the blogpost-doc.. you have to call it explicit with the id thats in the result rows). No Need to update the blogposts.
Example:
Case 1:
Use Author by Name, you have to include the name, and therefore update ALL docs.
{
"_id":"blogpost1",
"author":"Oliver",
"keyword":"couchDB"
}
to look for all couchdb posts from oliver:
emit ([doc.author,doc.keyword],1)
call:
&key=["Oliver","couchDB"]
Case 2:
No need to query by name
{
"_id":"blogpost1",
"author_id":"author-123",
"keyword":"couchDB"
}
emit (doc.keyword,{'_id':doc.author_id})
and the authors doc:
{
"_id":"author-123",
"name":"Oliver"
}
call:
?key=["couchDB"]&include_docs=true
result:
...
{"id":"blogpost1","key":"couchDB","value":{"_id":"author-123"},"doc":{"_id":"author-123","_rev":"xxx","name":"Oliver,....

Resources